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