diff options
Diffstat (limited to 'sim/testsuite/common/alu-n-tst.h')
-rw-r--r-- | sim/testsuite/common/alu-n-tst.h | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/sim/testsuite/common/alu-n-tst.h b/sim/testsuite/common/alu-n-tst.h new file mode 100644 index 0000000..cd218d4 --- /dev/null +++ b/sim/testsuite/common/alu-n-tst.h @@ -0,0 +1,260 @@ +#ifndef N +#error "N must be #defined" +#endif + +#include "symcat.h" + +/* NOTE: see end of file for #undef of these macros */ +#define unsignedN XCONCAT2(unsigned,N) +#define MAX_INT XCONCAT2(MAX_INT,N) +#define MIN_INT XCONCAT2(MIN_INT,N) +#define alu_N_tests XCONCAT3(alu_,N,_tests) +#define do_alu_N_tests XCONCAT3(do_alu_,N,_tests) +#define OP_BEGIN XCONCAT3(ALU,N,_BEGIN) +#define OP_ADDC XCONCAT3(ALU,N,_ADDC) +#define OP_ADDC_C XCONCAT3(ALU,N,_ADDC_C) +#define OP_SUBC XCONCAT3(ALU,N,_SUBC) +#define OP_SUBB XCONCAT3(ALU,N,_SUBB) +#define OP_SUBB_B XCONCAT3(ALU,N,_SUBB_B) +#define OP_SUBC_X XCONCAT3(ALU,N,_SUBC_X) +#define OP_NEGC XCONCAT3(ALU,N,_NEGC) +#define OP_NEGB XCONCAT3(ALU,N,_NEGB) +#define HAD_CARRY_BORROW (XCONCAT3(ALU,N,_HAD_CARRY_BORROW) != 0) +#define HAD_OVERFLOW (XCONCAT3(ALU,N,_HAD_OVERFLOW) != 0) +#define RESULT XCONCAT3(ALU,N,_RESULT) +#define CARRY_BORROW_RESULT XCONCAT3(ALU,N,_CARRY_BORROW_RESULT) +#define OVERFLOW_RESULT XCONCAT3(ALU,N,_OVERFLOW_RESULT) +#define do_op_N XCONCAT2(do_op_,N) + + +void +do_op_N (const alu_test *tst) +{ + const alu_op *op; + int borrow_p = 0; + OP_BEGIN (tst->begin); + print_hex (tst->begin, N); + for (op = tst->ops; op->op != NULL; op++) + { + printf (" %s ", op->op); + print_hex (op->arg, N); + if (strcmp (op->op, "ADDC") == 0) + OP_ADDC (op->arg); + else if (strcmp (op->op, "ADDC_C0") == 0) + OP_ADDC_C (op->arg, 0); + else if (strcmp (op->op, "ADDC_C1") == 0) + OP_ADDC_C (op->arg, 1); + else if (strcmp (op->op, "SUBC") == 0) + OP_SUBC (op->arg); + else if (strcmp (op->op, "SUBC_X0") == 0) + OP_SUBC_X (op->arg, 0); + else if (strcmp (op->op, "SUBC_X1") == 0) + OP_SUBC_X (op->arg, 1); + else if (strcmp (op->op, "SUBB") == 0) + { + OP_SUBB (op->arg); + borrow_p ++; + } + else if (strcmp (op->op, "SUBB_B0") == 0) + { + OP_SUBB_B (op->arg, 0); + borrow_p ++; + } + else if (strcmp (op->op, "SUBB_B1") == 0) + { + OP_SUBB_B (op->arg, 1); + borrow_p ++; + } + else if (strcmp (op->op, "NEGC") == 0) + OP_NEGC (); + else if (strcmp (op->op, "NEGB") == 0) + { + OP_NEGB (); + borrow_p ++; + } + else + { + printf (" -- operator unknown\n"); + abort (); + } + } + printf (" = "); + print_hex (tst->result, N); + if (borrow_p) + printf (" B:%d", tst->carry_borrow); + else + printf (" C:%d", tst->carry_borrow); + printf (" V:%d", tst->overflow); + if (tst->carry_borrow != HAD_CARRY_BORROW) + { + if (borrow_p) + printf (" -- borrow (%d) wrong", HAD_CARRY_BORROW); + else + printf (" -- carry (%d) wrong", HAD_CARRY_BORROW); + errors ++; + } + if (tst->overflow != HAD_OVERFLOW) + { + printf (" -- overflow (%d) wrong", HAD_OVERFLOW); + errors ++; + } + if ((unsignedN) CARRY_BORROW_RESULT != (unsignedN) tst->result) + { + printf (" -- result for carry/borrow wrong "); + print_hex (CARRY_BORROW_RESULT, N); + errors ++; + } + if ((unsignedN) OVERFLOW_RESULT != (unsignedN) tst->result) + { + printf (" -- result for overflow wrong "); + print_hex (OVERFLOW_RESULT, N); + errors ++; + } + if ((unsignedN) RESULT != (unsignedN) tst->result) + { + printf (" -- result wrong "); + print_hex (RESULT, N); + errors ++; + } + printf ("\n"); +} + + +const alu_test alu_N_tests[] = { + + /* 0 + 0; 0 + 1; 1 + 0; 1 + 1 */ + { 0, { { "ADDC", 0 }, }, 0, 0, 0, }, + { 0, { { "ADDC", 1 }, }, 1, 0, 0, }, + { 1, { { "ADDC", 0 }, }, 1, 0, 0, }, + { 1, { { "ADDC", 1 }, }, 2, 0, 0, }, + + /* 0 + 0 + 0; 0 + 0 + 1; 0 + 1 + 0; 0 + 1 + 1 */ + /* 1 + 0 + 0; 1 + 0 + 1; 1 + 1 + 0; 1 + 1 + 1 */ + { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, }, + { 0, { { "ADDC_C0", 1 }, }, 1, 0, 0, }, + { 0, { { "ADDC_C1", 0 }, }, 1, 0, 0, }, + { 0, { { "ADDC_C1", 1 }, }, 2, 0, 0, }, + { 1, { { "ADDC_C0", 0 }, }, 1, 0, 0, }, + { 1, { { "ADDC_C0", 1 }, }, 2, 0, 0, }, + { 1, { { "ADDC_C1", 0 }, }, 2, 0, 0, }, + { 1, { { "ADDC_C1", 1 }, }, 3, 0, 0, }, + + /* */ + { MAX_INT, { { "ADDC", 1 }, }, MIN_INT, 0, 1, }, + { MIN_INT, { { "ADDC", -1 }, }, MAX_INT, 1, 1, }, + { MAX_INT, { { "ADDC", MIN_INT }, }, -1, 0, 0, }, + { MIN_INT, { { "ADDC", MAX_INT }, }, -1, 0, 0, }, + { MAX_INT, { { "ADDC", MAX_INT }, }, MAX_INT << 1, 0, 1, }, + { MIN_INT, { { "ADDC", MIN_INT }, }, 0, 1, 1, }, + /* */ + { 0, { { "ADDC_C1", -1 }, }, 0, 1, 0, }, + { 0, { { "ADDC_C1", -2 }, }, -1, 0, 0, }, + { -1, { { "ADDC_C1", 0 }, }, 0, 1, 0, }, + { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, }, + { -1, { { "ADDC_C1", -1 }, }, -1, 1, 0, }, + { -1, { { "ADDC_C1", 1 }, }, 1, 1, 0, }, + { 0, { { "ADDC_C1", MAX_INT }, }, MIN_INT, 0, 1, }, + { MAX_INT, { { "ADDC_C1", 1 }, }, MIN_INT + 1, 0, 1, }, + { MAX_INT, { { "ADDC_C1", MIN_INT }, }, 0, 1, 0, }, + { MAX_INT, { { "ADDC_C1", MAX_INT }, }, (MAX_INT << 1) + 1, 0, 1, }, + { MAX_INT, { { "ADDC_C0", MAX_INT }, }, MAX_INT << 1, 0, 1, }, + + /* 0 - 0 */ + { 0, { { "SUBC", 0 }, }, 0, 1, 0, }, + { 0, { { "SUBB", 0 }, }, 0, 0, 0, }, + + /* 0 - 1 */ + { 0, { { "SUBC", 1 }, }, -1, 0, 0, }, + { 0, { { "SUBB", 1 }, }, -1, 1, 0, }, + + /* 1 - 0 */ + { 1, { { "SUBC", 0 }, }, 1, 1, 0, }, + { 1, { { "SUBB", 0 }, }, 1, 0, 0, }, + + /* 1 - 1 */ + { 1, { { "SUBC", 1 }, }, 0, 1, 0, }, + { 1, { { "SUBB", 1 }, }, 0, 0, 0, }, + + /* 0 - 0 - 0 */ + { 0, { { "SUBC_X0", 0 }, }, -1, 0, 0, }, + { 0, { { "SUBB_B0", 0 }, }, 0, 0, 0, }, + + /* 0 - 0 - 1 */ + { 0, { { "SUBC_X0", 1 }, }, -2, 0, 0, }, + { 0, { { "SUBB_B0", 1 }, }, -1, 1, 0, }, + + /* 0 - 1 - 0 */ + { 0, { { "SUBC_X1", 0 }, }, 0, 1, 0, }, + { 0, { { "SUBB_B1", 0 }, }, -1, 1, 0, }, + + /* 0 - 1 - 1 */ + { 0, { { "SUBC_X1", 1 }, }, -1, 0, 0, }, + { 0, { { "SUBB_B1", 1 }, }, -2, 1, 0, }, + + /* 1 - 0 - 0 */ + { 1, { { "SUBC_X0", 0 }, }, 0, 1, 0, }, + { 1, { { "SUBB_B0", 0 }, }, 1, 0, 0, }, + + /* 1 - 0 - 1 */ + { 1, { { "SUBC_X0", 1 }, }, -1, 0, 0, }, + { 1, { { "SUBB_B0", 1 }, }, 0, 0, 0, }, + + /* 1 - 1 - 0 */ + { 1, { { "SUBC_X1", 0 }, }, 1, 1, 0, }, + { 1, { { "SUBB_B1", 0 }, }, 0, 0, 0, }, + + /* 1 - 1 - 1 */ + { 1, { { "SUBC_X1", 1 }, }, 0, 1, 0, }, + { 1, { { "SUBB_B1", 1 }, }, -1, 1, 0, }, + + /* */ + { 0, { { "SUBC", MIN_INT }, }, MIN_INT, 0, 1, }, + { MIN_INT, { { "SUBC", 1 }, }, MAX_INT, 1, 1, }, + { MAX_INT, { { "SUBC", MAX_INT }, }, 0, 1, 0, }, + + /* */ + { 0, { { "SUBC_X0", MIN_INT }, }, MAX_INT, 0, 0, }, + { MIN_INT, { { "SUBC_X1", 0 }, }, MIN_INT, 1, 0, }, + { MAX_INT, { { "SUBC_X0", MAX_INT }, }, -1, 0, 0, }, + + /* */ + { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, }, + { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, }, + { MIN_INT, { { "NEGC", 0 }, }, MIN_INT, 0, 1, }, + { 0, { { "NEGC", 0 }, }, 0, 1, 0, }, + { -1, { { "NEGC", 0 }, }, 1, 0, 0, }, + { 1, { { "NEGC", 0 }, }, -1, 0, 0, }, +}; + + +static void +do_alu_N_tests (void) +{ + int i; + for (i = 0; i < sizeof (alu_N_tests) / sizeof (*alu_N_tests); i++) + { + const alu_test *tst = &alu_N_tests[i]; + do_op_N (tst); + } +} + + +#undef OP_BEGIN +#undef OP_ADDC +#undef OP_ADDC_C +#undef OP_SUBB +#undef OP_SUBC +#undef OP_SUBC_X +#undef OP_SUBB_B +#undef HAD_OVERFLOW +#undef HAD_CARRY_BORROW +#undef OVERFLOW_RESULT +#undef CARRY_BORROW_RESULT +#undef RESULT +#undef do_op_N +#undef unsignedN +#undef MAX_INT +#undef MIN_INT +#undef alu_N_tests +#undef do_alu_N_tests + |