123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #ifndef N
- #error "N must be #defined"
- #endif
- #include "symcat.h"
- /* NOTE: see end of file for #undef of these macros */
- #define unsignedN XCONCAT3(uint,N,_t)
- #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
|