diff options
author | Peter Johnson <peter@tortall.net> | 2001-11-01 02:36:22 +0000 |
---|---|---|
committer | Peter Johnson <peter@tortall.net> | 2001-11-01 02:36:22 +0000 |
commit | ad7cbcea04cd2011d352f0e3a9984f43fdfd565f (patch) | |
tree | fba022727f74b96e9810deba12ecee6728896e76 | |
parent | 00788fa80c52d3d8683fff6b2216bd59ad2acbdd (diff) | |
download | yasm-ad7cbcea04cd2011d352f0e3a9984f43fdfd565f.tar.gz |
Add memory expressions tests (checkea).
Split off errwarn functions so that they can be overridden in test cases.
svn path=/trunk/yasm/; revision=309
-rw-r--r-- | libyasm/tests/Makefile.am | 39 | ||||
-rw-r--r-- | libyasm/tests/memexpr_test.c | 422 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/tests/Makefile.am | 39 | ||||
-rw-r--r-- | src/tests/memexpr_test.c | 422 |
5 files changed, 906 insertions, 23 deletions
diff --git a/libyasm/tests/Makefile.am b/libyasm/tests/Makefile.am index 51edfab3..9c7d9920 100644 --- a/libyasm/tests/Makefile.am +++ b/libyasm/tests/Makefile.am @@ -6,34 +6,53 @@ if CHECK TESTS = \ bitvect_test \ bytecode_test \ - floatnum_test + floatnum_test \ + memexpr_test noinst_PROGRAMS = \ bitvect_test \ bytecode_test \ - floatnum_test + floatnum_test \ + memexpr_test + else TESTS = noinst_PROGRAMS = endif +LDADD = \ + $(top_builddir)/check/libcheck.a \ + $(top_builddir)/src/parsers/nasm/libparser.a \ + $(top_builddir)/src/preprocs/raw/libpreproc.a \ + $(top_builddir)/src/optimizers/dbg/liboptimizer.a \ + $(top_builddir)/src/objfmts/dbg/libobjfmt.a \ + $(top_builddir)/src/libyasm.a \ + $(INTLLIBS) + bitvect_test_SOURCES = \ bitvect_test.c +bitvect_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + bytecode_test_SOURCES = \ bytecode_test.c +bytecode_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + floatnum_test_SOURCES = \ floatnum_test.c +floatnum_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + +memexpr_test_SOURCES = \ + memexpr_test.c + INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \ -I$(top_builddir)/intl -LDADD = \ - $(top_builddir)/check/libcheck.a \ - $(top_builddir)/src/parsers/nasm/libparser.a \ - $(top_builddir)/src/preprocs/raw/libpreproc.a \ - $(top_builddir)/src/optimizers/dbg/liboptimizer.a \ - $(top_builddir)/src/objfmts/dbg/libobjfmt.a \ - $(top_builddir)/src/libyasm.a \ - $(INTLLIBS) diff --git a/libyasm/tests/memexpr_test.c b/libyasm/tests/memexpr_test.c new file mode 100644 index 00000000..6e0ae89d --- /dev/null +++ b/libyasm/tests/memexpr_test.c @@ -0,0 +1,422 @@ +/* $IdPath$ + * + * Copyright (C) 2001 Peter Johnson + * + * This file is part of YASM. + * + * YASM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * YASM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#endif + +#include <stdio.h> + +#include "check.h" + +#include "bitvect.h" + +#include "errwarn.h" + +#include "expr.h" +#include "intnum.h" +#include "floatnum.h" + +typedef enum { + REG_AX = 0, + REG_CX = 1, + REG_DX = 2, + REG_BX = 3, + REG_SP = 4, + REG_BP = 5, + REG_SI = 6, + REG_DI = 7 +} reg16type; + +/* Memory expression building functions. + * These try to exactly match how a parser will build up the expr for _in, + * and exactly what the output expr should be for _out. + */ + +/* [5] */ +static expr * +gen_5_in(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(5))); +} +#define gen_5_out gen_5_in +/* [1.2] */ +static expr * +gen_1pt2_in(void) +{ + return expr_new_ident(ExprFloat(floatnum_new("1.2"))); +} +/* No _out, it's invalid */ +/* [ecx] */ +static expr * +gen_ecx_in(void) +{ + return expr_new_ident(ExprReg(REG_CX, 32)); +} +#define gen_ecx_out NULL +/* [di] */ +static expr * +gen_di_in(void) +{ + return expr_new_ident(ExprReg(REG_DI, 16)); +} +#define gen_di_out NULL +/* [di-si+si+126] */ +static expr * +gen_dimsipsip126_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_DI, 16)), + EXPR_SUB, + expr_new_ident(ExprReg(REG_SI, 16))), + EXPR_ADD, + expr_new_ident(ExprReg(REG_SI, 16))), + EXPR_ADD, + expr_new_ident(ExprInt(intnum_new_int(126)))); +} +#define gen_dimsipsip126_out NULL +/* [bx-(bx-di)+bx-2] */ +static expr * +gen_bxmqbxmdiqpbxm2_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_BX, 16)), + EXPR_SUB, + expr_new_tree( + expr_new_ident(ExprReg(REG_BX, 16)), + EXPR_SUB, + expr_new_ident(ExprReg(REG_DI, 16)))), + EXPR_ADD, + expr_new_ident(ExprReg(REG_BX, 16))), + EXPR_SUB, + expr_new_ident(ExprInt(intnum_new_int(2)))); +} +static expr * +gen_bxmqbxmdiqpbxm2_out(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(-2))); +} +/* [bp] */ +static expr * +gen_bp_in(void) +{ + return expr_new_ident(ExprReg(REG_BP, 16)); +} +#define gen_bp_out NULL +/* [bp*1+500] */ +static expr * +gen_bpx1p500_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_BP, 16)), + EXPR_MUL, + expr_new_ident(ExprInt(intnum_new_int(1)))), + EXPR_ADD, + expr_new_ident(ExprInt(intnum_new_int(500)))); +} +static expr * +gen_bpx1p500_out(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(500))); +} + +typedef struct CheckEA_InOut { + /* Function to generate input/output expr. */ + expr *(*expr_gen)(void); + unsigned char addrsize; + unsigned char bits; + unsigned char nosplit; + unsigned char displen; + unsigned char modrm; + unsigned char v_modrm; + unsigned char n_modrm; + unsigned char sib; + unsigned char v_sib; + unsigned char n_sib; +} CheckEA_InOut; + +typedef struct CheckEA_Entry { + const char *ascii; /* Text description of input */ + CheckEA_InOut in; /* Input Parameter Values */ + int retval; /* Return value */ + CheckEA_InOut out; /* Correct output Parameter Values + (N/A if retval=0) */ +} CheckEA_Entry; + +/* Values used for tests */ +static CheckEA_Entry bits16_vals[] = { + { + "[5]", + {gen_5_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "a16 [5]", + {gen_5_in , 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "a32 [5]", + {gen_5_in , 32, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1} + }, + { + "[word 5]", + {gen_5_in , 0, 16, 0, 2, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "[dword 5]", + {gen_5_in , 0, 16, 0, 4, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1} + }, + { + "a16 [dword 5]", + {gen_5_in, 16, 16, 0, 4, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + /* should error */ + { + "[di+1.2]", + {gen_1pt2_in, 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + "[ecx]", + {gen_ecx_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_ecx_out, 32, 16, 0, 0, 0x01, 1, 1, 0, 0, 0} + }, + /* should error */ + { + "a16 [ecx]", + {gen_ecx_in, 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + "[di]", + {gen_di_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_di_out, 16, 16, 0, 0, 0x05, 1, 1, 0, 0, 0} + }, + { + "[di-si+si+126]", + {gen_dimsipsip126_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_dimsipsip126_out, 16, 16, 0, 1, 0x45, 1, 1, 0, 0, 0} + }, + { + "[bx-(bx-di)+bx-2]", + {gen_bxmqbxmdiqpbxm2_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bxmqbxmdiqpbxm2_out, 16, 16, 0, 1, 0x41, 1, 1, 0, 0, 0} + }, + { + "[bp]", + {gen_bp_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bp_out, 16, 16, 0, 1, 0x46, 1, 1, 0, 0, 0} + }, + { + "[bp*1+500]", + {gen_bpx1p500_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bpx1p500_out, 16, 16, 0, 2, 0x86, 1, 1, 0, 0, 0} + }, +}; + +/* input expression */ +expr *expn; + +/* failure messages */ +static char result_msg[1024]; + +int error_triggered; + +/* Replace errwarn functions */ +void InternalError_(const char *file, unsigned int line, const char *msg) +{ + exit(EXIT_FAILURE); +} + +void +Fatal(fatal_num num) +{ + exit(EXIT_FAILURE); +} + +void +Error(const char *msg, ...) +{ + error_triggered = 1; +} + +void +Warning(const char *msg, ...) +{ +} + +void +ErrorAt(const char *filename, unsigned long line, const char *fmt, ...) +{ + error_triggered = 1; +} + +void +WarningAt(const char *filename, unsigned long line, const char *fmt, ...) +{ +} + +static int +checkea_check(CheckEA_Entry *val) +{ + CheckEA_InOut chk = val->in; /* local structure copy of inputs */ + int retval; + + error_triggered = 0; + + /* execute function and check return value */ + retval = expr_checkea(&expn, &chk.addrsize, chk.bits, chk.nosplit, + &chk.displen, &chk.modrm, &chk.v_modrm, &chk.n_modrm, + &chk.sib, &chk.v_sib, &chk.n_sib); + if (retval != val->retval) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "return value", val->retval, retval); + return 1; + } + + /* If returned 0 (failure), check to see if ErrorAt() was called */ + if (retval == 0) { + if (error_triggered == 0) { + sprintf(result_msg, "%s: didn't call ErrorAt() and returned 0", + val->ascii); + return 1; + } + + return 0; /* don't check other return values */ + } + + /* check expr result */ + /* TODO */ + + /* Check other outputs */ + if (chk.addrsize != val->out.addrsize) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "addrsize", (int)val->out.addrsize, + (int)chk.addrsize); + return 1; + } + if (chk.displen != val->out.displen) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "displen", (int)val->out.displen, + (int)chk.displen); + return 1; + } + if (chk.modrm != val->out.modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)", + val->ascii, "modrm", (int)val->out.modrm, (int)chk.modrm); + return 1; + } + if (chk.v_modrm != val->out.v_modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "v_modrm", (int)val->out.v_modrm, + (int)chk.v_modrm); + return 1; + } + if (chk.n_modrm != val->out.n_modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "n_modrm", (int)val->out.n_modrm, + (int)chk.n_modrm); + return 1; + } + if (chk.sib != val->out.sib) { + sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)", + val->ascii, "sib", (int)val->out.sib, (int)chk.sib); + return 1; + } + if (chk.v_sib != val->out.v_sib) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "v_sib", (int)val->out.v_sib, (int)chk.v_sib); + return 1; + } + if (chk.n_sib != val->out.n_sib) { + sprintf(result_msg, "%s: incorrect %s (expected %x, got %x)", + val->ascii, "n_sib", (int)val->out.n_sib, (int)chk.n_sib); + return 1; + } + return 0; +} + +START_TEST(test_checkea_bits16) +{ + CheckEA_Entry *vals = bits16_vals; + int i, num = sizeof(bits16_vals)/sizeof(CheckEA_Entry); + + for (i=0; i<num; i++) { + expn = vals[i].in.expr_gen(); + fail_unless(checkea_check(&vals[i]) == 0, result_msg); + expr_delete(expn); + } +} +END_TEST + +static Suite * +memexpr_suite(void) +{ + Suite *s = suite_create("memexpr"); + TCase *tc_checkea = tcase_create("checkea"); + + suite_add_tcase(s, tc_checkea); + tcase_add_test(tc_checkea, test_checkea_bits16); + + return s; +} + +int +main(void) +{ + int nf; + Suite *s = memexpr_suite(); + SRunner *sr = srunner_create(s); + BitVector_Boot(); + srunner_run_all(sr, CRNORMAL); + nf = srunner_ntests_failed(sr); + srunner_free(sr); + suite_free(s); + return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/Makefile.am b/src/Makefile.am index 16dc8998..30d5aa31 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,10 @@ INCLUDES = -I$(top_builddir)/intl bin_PROGRAMS = yasm -yasm_SOURCES = main.c +yasm_SOURCES = \ + main.c \ + errwarn.c \ + errwarn.h yasm_LDADD = \ parsers/nasm/libparser.a \ @@ -21,8 +24,6 @@ noinst_LIBRARIES = libyasm.a libyasm_a_SOURCES = \ bytecode.c \ bytecode.h \ - errwarn.c \ - errwarn.h \ expr.c \ expr.h \ symrec.c \ diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 51edfab3..9c7d9920 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -6,34 +6,53 @@ if CHECK TESTS = \ bitvect_test \ bytecode_test \ - floatnum_test + floatnum_test \ + memexpr_test noinst_PROGRAMS = \ bitvect_test \ bytecode_test \ - floatnum_test + floatnum_test \ + memexpr_test + else TESTS = noinst_PROGRAMS = endif +LDADD = \ + $(top_builddir)/check/libcheck.a \ + $(top_builddir)/src/parsers/nasm/libparser.a \ + $(top_builddir)/src/preprocs/raw/libpreproc.a \ + $(top_builddir)/src/optimizers/dbg/liboptimizer.a \ + $(top_builddir)/src/objfmts/dbg/libobjfmt.a \ + $(top_builddir)/src/libyasm.a \ + $(INTLLIBS) + bitvect_test_SOURCES = \ bitvect_test.c +bitvect_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + bytecode_test_SOURCES = \ bytecode_test.c +bytecode_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + floatnum_test_SOURCES = \ floatnum_test.c +floatnum_test_LDADD = \ + $(top_builddir)/src/errwarn.o \ + $(LDADD) + +memexpr_test_SOURCES = \ + memexpr_test.c + INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/check \ -I$(top_builddir)/intl -LDADD = \ - $(top_builddir)/check/libcheck.a \ - $(top_builddir)/src/parsers/nasm/libparser.a \ - $(top_builddir)/src/preprocs/raw/libpreproc.a \ - $(top_builddir)/src/optimizers/dbg/liboptimizer.a \ - $(top_builddir)/src/objfmts/dbg/libobjfmt.a \ - $(top_builddir)/src/libyasm.a \ - $(INTLLIBS) diff --git a/src/tests/memexpr_test.c b/src/tests/memexpr_test.c new file mode 100644 index 00000000..6e0ae89d --- /dev/null +++ b/src/tests/memexpr_test.c @@ -0,0 +1,422 @@ +/* $IdPath$ + * + * Copyright (C) 2001 Peter Johnson + * + * This file is part of YASM. + * + * YASM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * YASM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#endif + +#include <stdio.h> + +#include "check.h" + +#include "bitvect.h" + +#include "errwarn.h" + +#include "expr.h" +#include "intnum.h" +#include "floatnum.h" + +typedef enum { + REG_AX = 0, + REG_CX = 1, + REG_DX = 2, + REG_BX = 3, + REG_SP = 4, + REG_BP = 5, + REG_SI = 6, + REG_DI = 7 +} reg16type; + +/* Memory expression building functions. + * These try to exactly match how a parser will build up the expr for _in, + * and exactly what the output expr should be for _out. + */ + +/* [5] */ +static expr * +gen_5_in(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(5))); +} +#define gen_5_out gen_5_in +/* [1.2] */ +static expr * +gen_1pt2_in(void) +{ + return expr_new_ident(ExprFloat(floatnum_new("1.2"))); +} +/* No _out, it's invalid */ +/* [ecx] */ +static expr * +gen_ecx_in(void) +{ + return expr_new_ident(ExprReg(REG_CX, 32)); +} +#define gen_ecx_out NULL +/* [di] */ +static expr * +gen_di_in(void) +{ + return expr_new_ident(ExprReg(REG_DI, 16)); +} +#define gen_di_out NULL +/* [di-si+si+126] */ +static expr * +gen_dimsipsip126_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_DI, 16)), + EXPR_SUB, + expr_new_ident(ExprReg(REG_SI, 16))), + EXPR_ADD, + expr_new_ident(ExprReg(REG_SI, 16))), + EXPR_ADD, + expr_new_ident(ExprInt(intnum_new_int(126)))); +} +#define gen_dimsipsip126_out NULL +/* [bx-(bx-di)+bx-2] */ +static expr * +gen_bxmqbxmdiqpbxm2_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_BX, 16)), + EXPR_SUB, + expr_new_tree( + expr_new_ident(ExprReg(REG_BX, 16)), + EXPR_SUB, + expr_new_ident(ExprReg(REG_DI, 16)))), + EXPR_ADD, + expr_new_ident(ExprReg(REG_BX, 16))), + EXPR_SUB, + expr_new_ident(ExprInt(intnum_new_int(2)))); +} +static expr * +gen_bxmqbxmdiqpbxm2_out(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(-2))); +} +/* [bp] */ +static expr * +gen_bp_in(void) +{ + return expr_new_ident(ExprReg(REG_BP, 16)); +} +#define gen_bp_out NULL +/* [bp*1+500] */ +static expr * +gen_bpx1p500_in(void) +{ + return expr_new_tree( + expr_new_tree( + expr_new_ident(ExprReg(REG_BP, 16)), + EXPR_MUL, + expr_new_ident(ExprInt(intnum_new_int(1)))), + EXPR_ADD, + expr_new_ident(ExprInt(intnum_new_int(500)))); +} +static expr * +gen_bpx1p500_out(void) +{ + return expr_new_ident(ExprInt(intnum_new_int(500))); +} + +typedef struct CheckEA_InOut { + /* Function to generate input/output expr. */ + expr *(*expr_gen)(void); + unsigned char addrsize; + unsigned char bits; + unsigned char nosplit; + unsigned char displen; + unsigned char modrm; + unsigned char v_modrm; + unsigned char n_modrm; + unsigned char sib; + unsigned char v_sib; + unsigned char n_sib; +} CheckEA_InOut; + +typedef struct CheckEA_Entry { + const char *ascii; /* Text description of input */ + CheckEA_InOut in; /* Input Parameter Values */ + int retval; /* Return value */ + CheckEA_InOut out; /* Correct output Parameter Values + (N/A if retval=0) */ +} CheckEA_Entry; + +/* Values used for tests */ +static CheckEA_Entry bits16_vals[] = { + { + "[5]", + {gen_5_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "a16 [5]", + {gen_5_in , 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "a32 [5]", + {gen_5_in , 32, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1} + }, + { + "[word 5]", + {gen_5_in , 0, 16, 0, 2, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 16, 16, 0, 2, 0x06, 1, 1, 0, 0, 0} + }, + { + "[dword 5]", + {gen_5_in , 0, 16, 0, 4, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_5_out, 32, 16, 0, 4, 0x05, 1, 1, 0x25, 1, 1} + }, + { + "a16 [dword 5]", + {gen_5_in, 16, 16, 0, 4, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + /* should error */ + { + "[di+1.2]", + {gen_1pt2_in, 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + "[ecx]", + {gen_ecx_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_ecx_out, 32, 16, 0, 0, 0x01, 1, 1, 0, 0, 0} + }, + /* should error */ + { + "a16 [ecx]", + {gen_ecx_in, 16, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 0, + {NULL , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + }, + { + "[di]", + {gen_di_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_di_out, 16, 16, 0, 0, 0x05, 1, 1, 0, 0, 0} + }, + { + "[di-si+si+126]", + {gen_dimsipsip126_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_dimsipsip126_out, 16, 16, 0, 1, 0x45, 1, 1, 0, 0, 0} + }, + { + "[bx-(bx-di)+bx-2]", + {gen_bxmqbxmdiqpbxm2_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bxmqbxmdiqpbxm2_out, 16, 16, 0, 1, 0x41, 1, 1, 0, 0, 0} + }, + { + "[bp]", + {gen_bp_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bp_out, 16, 16, 0, 1, 0x46, 1, 1, 0, 0, 0} + }, + { + "[bp*1+500]", + {gen_bpx1p500_in , 0, 16, 0, 0, 0, 0, 1, 0, 0, 0xff}, + 1, + {gen_bpx1p500_out, 16, 16, 0, 2, 0x86, 1, 1, 0, 0, 0} + }, +}; + +/* input expression */ +expr *expn; + +/* failure messages */ +static char result_msg[1024]; + +int error_triggered; + +/* Replace errwarn functions */ +void InternalError_(const char *file, unsigned int line, const char *msg) +{ + exit(EXIT_FAILURE); +} + +void +Fatal(fatal_num num) +{ + exit(EXIT_FAILURE); +} + +void +Error(const char *msg, ...) +{ + error_triggered = 1; +} + +void +Warning(const char *msg, ...) +{ +} + +void +ErrorAt(const char *filename, unsigned long line, const char *fmt, ...) +{ + error_triggered = 1; +} + +void +WarningAt(const char *filename, unsigned long line, const char *fmt, ...) +{ +} + +static int +checkea_check(CheckEA_Entry *val) +{ + CheckEA_InOut chk = val->in; /* local structure copy of inputs */ + int retval; + + error_triggered = 0; + + /* execute function and check return value */ + retval = expr_checkea(&expn, &chk.addrsize, chk.bits, chk.nosplit, + &chk.displen, &chk.modrm, &chk.v_modrm, &chk.n_modrm, + &chk.sib, &chk.v_sib, &chk.n_sib); + if (retval != val->retval) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "return value", val->retval, retval); + return 1; + } + + /* If returned 0 (failure), check to see if ErrorAt() was called */ + if (retval == 0) { + if (error_triggered == 0) { + sprintf(result_msg, "%s: didn't call ErrorAt() and returned 0", + val->ascii); + return 1; + } + + return 0; /* don't check other return values */ + } + + /* check expr result */ + /* TODO */ + + /* Check other outputs */ + if (chk.addrsize != val->out.addrsize) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "addrsize", (int)val->out.addrsize, + (int)chk.addrsize); + return 1; + } + if (chk.displen != val->out.displen) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "displen", (int)val->out.displen, + (int)chk.displen); + return 1; + } + if (chk.modrm != val->out.modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)", + val->ascii, "modrm", (int)val->out.modrm, (int)chk.modrm); + return 1; + } + if (chk.v_modrm != val->out.v_modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "v_modrm", (int)val->out.v_modrm, + (int)chk.v_modrm); + return 1; + } + if (chk.n_modrm != val->out.n_modrm) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "n_modrm", (int)val->out.n_modrm, + (int)chk.n_modrm); + return 1; + } + if (chk.sib != val->out.sib) { + sprintf(result_msg, "%s: incorrect %s (expected %03o, got %03o)", + val->ascii, "sib", (int)val->out.sib, (int)chk.sib); + return 1; + } + if (chk.v_sib != val->out.v_sib) { + sprintf(result_msg, "%s: incorrect %s (expected %d, got %d)", + val->ascii, "v_sib", (int)val->out.v_sib, (int)chk.v_sib); + return 1; + } + if (chk.n_sib != val->out.n_sib) { + sprintf(result_msg, "%s: incorrect %s (expected %x, got %x)", + val->ascii, "n_sib", (int)val->out.n_sib, (int)chk.n_sib); + return 1; + } + return 0; +} + +START_TEST(test_checkea_bits16) +{ + CheckEA_Entry *vals = bits16_vals; + int i, num = sizeof(bits16_vals)/sizeof(CheckEA_Entry); + + for (i=0; i<num; i++) { + expn = vals[i].in.expr_gen(); + fail_unless(checkea_check(&vals[i]) == 0, result_msg); + expr_delete(expn); + } +} +END_TEST + +static Suite * +memexpr_suite(void) +{ + Suite *s = suite_create("memexpr"); + TCase *tc_checkea = tcase_create("checkea"); + + suite_add_tcase(s, tc_checkea); + tcase_add_test(tc_checkea, test_checkea_bits16); + + return s; +} + +int +main(void) +{ + int nf; + Suite *s = memexpr_suite(); + SRunner *sr = srunner_create(s); + BitVector_Boot(); + srunner_run_all(sr, CRNORMAL); + nf = srunner_ntests_failed(sr); + srunner_free(sr); + suite_free(s); + return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} |