1#ifndef N 2#error "N must be #defined" 3#endif 4 5#include "symcat.h" 6 7/* NOTE: see end of file for #undef of these macros */ 8#define unsignedN XCONCAT3(uint,N,_t) 9#define MAX_INT XCONCAT2(MAX_INT,N) 10#define MIN_INT XCONCAT2(MIN_INT,N) 11#define alu_N_tests XCONCAT3(alu_,N,_tests) 12#define do_alu_N_tests XCONCAT3(do_alu_,N,_tests) 13#define OP_BEGIN XCONCAT3(ALU,N,_BEGIN) 14#define OP_ADDC XCONCAT3(ALU,N,_ADDC) 15#define OP_ADDC_C XCONCAT3(ALU,N,_ADDC_C) 16#define OP_SUBC XCONCAT3(ALU,N,_SUBC) 17#define OP_SUBB XCONCAT3(ALU,N,_SUBB) 18#define OP_SUBB_B XCONCAT3(ALU,N,_SUBB_B) 19#define OP_SUBC_X XCONCAT3(ALU,N,_SUBC_X) 20#define OP_NEGC XCONCAT3(ALU,N,_NEGC) 21#define OP_NEGB XCONCAT3(ALU,N,_NEGB) 22#define HAD_CARRY_BORROW (XCONCAT3(ALU,N,_HAD_CARRY_BORROW) != 0) 23#define HAD_OVERFLOW (XCONCAT3(ALU,N,_HAD_OVERFLOW) != 0) 24#define RESULT XCONCAT3(ALU,N,_RESULT) 25#define CARRY_BORROW_RESULT XCONCAT3(ALU,N,_CARRY_BORROW_RESULT) 26#define OVERFLOW_RESULT XCONCAT3(ALU,N,_OVERFLOW_RESULT) 27#define do_op_N XCONCAT2(do_op_,N) 28 29 30void 31do_op_N (const alu_test *tst) 32{ 33 const alu_op *op; 34 int borrow_p = 0; 35 OP_BEGIN (tst->begin); 36 print_hex (tst->begin, N); 37 for (op = tst->ops; op->op != NULL; op++) 38 { 39 printf (" %s ", op->op); 40 print_hex (op->arg, N); 41 if (strcmp (op->op, "ADDC") == 0) 42 OP_ADDC (op->arg); 43 else if (strcmp (op->op, "ADDC_C0") == 0) 44 OP_ADDC_C (op->arg, 0); 45 else if (strcmp (op->op, "ADDC_C1") == 0) 46 OP_ADDC_C (op->arg, 1); 47 else if (strcmp (op->op, "SUBC") == 0) 48 OP_SUBC (op->arg); 49 else if (strcmp (op->op, "SUBC_X0") == 0) 50 OP_SUBC_X (op->arg, 0); 51 else if (strcmp (op->op, "SUBC_X1") == 0) 52 OP_SUBC_X (op->arg, 1); 53 else if (strcmp (op->op, "SUBB") == 0) 54 { 55 OP_SUBB (op->arg); 56 borrow_p ++; 57 } 58 else if (strcmp (op->op, "SUBB_B0") == 0) 59 { 60 OP_SUBB_B (op->arg, 0); 61 borrow_p ++; 62 } 63 else if (strcmp (op->op, "SUBB_B1") == 0) 64 { 65 OP_SUBB_B (op->arg, 1); 66 borrow_p ++; 67 } 68 else if (strcmp (op->op, "NEGC") == 0) 69 OP_NEGC (); 70 else if (strcmp (op->op, "NEGB") == 0) 71 { 72 OP_NEGB (); 73 borrow_p ++; 74 } 75 else 76 { 77 printf (" -- operator unknown\n"); 78 abort (); 79 } 80 } 81 printf (" = "); 82 print_hex (tst->result, N); 83 if (borrow_p) 84 printf (" B:%d", tst->carry_borrow); 85 else 86 printf (" C:%d", tst->carry_borrow); 87 printf (" V:%d", tst->overflow); 88 if (tst->carry_borrow != HAD_CARRY_BORROW) 89 { 90 if (borrow_p) 91 printf (" -- borrow (%d) wrong", HAD_CARRY_BORROW); 92 else 93 printf (" -- carry (%d) wrong", HAD_CARRY_BORROW); 94 errors ++; 95 } 96 if (tst->overflow != HAD_OVERFLOW) 97 { 98 printf (" -- overflow (%d) wrong", HAD_OVERFLOW); 99 errors ++; 100 } 101 if ((unsignedN) CARRY_BORROW_RESULT != (unsignedN) tst->result) 102 { 103 printf (" -- result for carry/borrow wrong "); 104 print_hex (CARRY_BORROW_RESULT, N); 105 errors ++; 106 } 107 if ((unsignedN) OVERFLOW_RESULT != (unsignedN) tst->result) 108 { 109 printf (" -- result for overflow wrong "); 110 print_hex (OVERFLOW_RESULT, N); 111 errors ++; 112 } 113 if ((unsignedN) RESULT != (unsignedN) tst->result) 114 { 115 printf (" -- result wrong "); 116 print_hex (RESULT, N); 117 errors ++; 118 } 119 printf ("\n"); 120} 121 122 123const alu_test alu_N_tests[] = { 124 125 /* 0 + 0; 0 + 1; 1 + 0; 1 + 1 */ 126 { 0, { { "ADDC", 0 }, }, 0, 0, 0, }, 127 { 0, { { "ADDC", 1 }, }, 1, 0, 0, }, 128 { 1, { { "ADDC", 0 }, }, 1, 0, 0, }, 129 { 1, { { "ADDC", 1 }, }, 2, 0, 0, }, 130 131 /* 0 + 0 + 0; 0 + 0 + 1; 0 + 1 + 0; 0 + 1 + 1 */ 132 /* 1 + 0 + 0; 1 + 0 + 1; 1 + 1 + 0; 1 + 1 + 1 */ 133 { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, }, 134 { 0, { { "ADDC_C0", 1 }, }, 1, 0, 0, }, 135 { 0, { { "ADDC_C1", 0 }, }, 1, 0, 0, }, 136 { 0, { { "ADDC_C1", 1 }, }, 2, 0, 0, }, 137 { 1, { { "ADDC_C0", 0 }, }, 1, 0, 0, }, 138 { 1, { { "ADDC_C0", 1 }, }, 2, 0, 0, }, 139 { 1, { { "ADDC_C1", 0 }, }, 2, 0, 0, }, 140 { 1, { { "ADDC_C1", 1 }, }, 3, 0, 0, }, 141 142 /* */ 143 { MAX_INT, { { "ADDC", 1 }, }, MIN_INT, 0, 1, }, 144 { MIN_INT, { { "ADDC", -1 }, }, MAX_INT, 1, 1, }, 145 { MAX_INT, { { "ADDC", MIN_INT }, }, -1, 0, 0, }, 146 { MIN_INT, { { "ADDC", MAX_INT }, }, -1, 0, 0, }, 147 { MAX_INT, { { "ADDC", MAX_INT }, }, MAX_INT << 1, 0, 1, }, 148 { MIN_INT, { { "ADDC", MIN_INT }, }, 0, 1, 1, }, 149 /* */ 150 { 0, { { "ADDC_C1", -1 }, }, 0, 1, 0, }, 151 { 0, { { "ADDC_C1", -2 }, }, -1, 0, 0, }, 152 { -1, { { "ADDC_C1", 0 }, }, 0, 1, 0, }, 153 { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, }, 154 { -1, { { "ADDC_C1", -1 }, }, -1, 1, 0, }, 155 { -1, { { "ADDC_C1", 1 }, }, 1, 1, 0, }, 156 { 0, { { "ADDC_C1", MAX_INT }, }, MIN_INT, 0, 1, }, 157 { MAX_INT, { { "ADDC_C1", 1 }, }, MIN_INT + 1, 0, 1, }, 158 { MAX_INT, { { "ADDC_C1", MIN_INT }, }, 0, 1, 0, }, 159 { MAX_INT, { { "ADDC_C1", MAX_INT }, }, (MAX_INT << 1) + 1, 0, 1, }, 160 { MAX_INT, { { "ADDC_C0", MAX_INT }, }, MAX_INT << 1, 0, 1, }, 161 162 /* 0 - 0 */ 163 { 0, { { "SUBC", 0 }, }, 0, 1, 0, }, 164 { 0, { { "SUBB", 0 }, }, 0, 0, 0, }, 165 166 /* 0 - 1 */ 167 { 0, { { "SUBC", 1 }, }, -1, 0, 0, }, 168 { 0, { { "SUBB", 1 }, }, -1, 1, 0, }, 169 170 /* 1 - 0 */ 171 { 1, { { "SUBC", 0 }, }, 1, 1, 0, }, 172 { 1, { { "SUBB", 0 }, }, 1, 0, 0, }, 173 174 /* 1 - 1 */ 175 { 1, { { "SUBC", 1 }, }, 0, 1, 0, }, 176 { 1, { { "SUBB", 1 }, }, 0, 0, 0, }, 177 178 /* 0 - 0 - 0 */ 179 { 0, { { "SUBC_X0", 0 }, }, -1, 0, 0, }, 180 { 0, { { "SUBB_B0", 0 }, }, 0, 0, 0, }, 181 182 /* 0 - 0 - 1 */ 183 { 0, { { "SUBC_X0", 1 }, }, -2, 0, 0, }, 184 { 0, { { "SUBB_B0", 1 }, }, -1, 1, 0, }, 185 186 /* 0 - 1 - 0 */ 187 { 0, { { "SUBC_X1", 0 }, }, 0, 1, 0, }, 188 { 0, { { "SUBB_B1", 0 }, }, -1, 1, 0, }, 189 190 /* 0 - 1 - 1 */ 191 { 0, { { "SUBC_X1", 1 }, }, -1, 0, 0, }, 192 { 0, { { "SUBB_B1", 1 }, }, -2, 1, 0, }, 193 194 /* 1 - 0 - 0 */ 195 { 1, { { "SUBC_X0", 0 }, }, 0, 1, 0, }, 196 { 1, { { "SUBB_B0", 0 }, }, 1, 0, 0, }, 197 198 /* 1 - 0 - 1 */ 199 { 1, { { "SUBC_X0", 1 }, }, -1, 0, 0, }, 200 { 1, { { "SUBB_B0", 1 }, }, 0, 0, 0, }, 201 202 /* 1 - 1 - 0 */ 203 { 1, { { "SUBC_X1", 0 }, }, 1, 1, 0, }, 204 { 1, { { "SUBB_B1", 0 }, }, 0, 0, 0, }, 205 206 /* 1 - 1 - 1 */ 207 { 1, { { "SUBC_X1", 1 }, }, 0, 1, 0, }, 208 { 1, { { "SUBB_B1", 1 }, }, -1, 1, 0, }, 209 210 /* */ 211 { 0, { { "SUBC", MIN_INT }, }, MIN_INT, 0, 1, }, 212 { MIN_INT, { { "SUBC", 1 }, }, MAX_INT, 1, 1, }, 213 { MAX_INT, { { "SUBC", MAX_INT }, }, 0, 1, 0, }, 214 215 /* */ 216 { 0, { { "SUBC_X0", MIN_INT }, }, MAX_INT, 0, 0, }, 217 { MIN_INT, { { "SUBC_X1", 0 }, }, MIN_INT, 1, 0, }, 218 { MAX_INT, { { "SUBC_X0", MAX_INT }, }, -1, 0, 0, }, 219 220 /* */ 221 { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, }, 222 { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, }, 223 { MIN_INT, { { "NEGC", 0 }, }, MIN_INT, 0, 1, }, 224 { 0, { { "NEGC", 0 }, }, 0, 1, 0, }, 225 { -1, { { "NEGC", 0 }, }, 1, 0, 0, }, 226 { 1, { { "NEGC", 0 }, }, -1, 0, 0, }, 227}; 228 229 230static void 231do_alu_N_tests (void) 232{ 233 int i; 234 for (i = 0; i < sizeof (alu_N_tests) / sizeof (*alu_N_tests); i++) 235 { 236 const alu_test *tst = &alu_N_tests[i]; 237 do_op_N (tst); 238 } 239} 240 241 242#undef OP_BEGIN 243#undef OP_ADDC 244#undef OP_ADDC_C 245#undef OP_SUBB 246#undef OP_SUBC 247#undef OP_SUBC_X 248#undef OP_SUBB_B 249#undef HAD_OVERFLOW 250#undef HAD_CARRY_BORROW 251#undef OVERFLOW_RESULT 252#undef CARRY_BORROW_RESULT 253#undef RESULT 254#undef do_op_N 255#undef unsignedN 256#undef MAX_INT 257#undef MIN_INT 258#undef alu_N_tests 259#undef do_alu_N_tests 260 261