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 XCONCAT2(unsigned,N)
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
30 void
do_op_N(const alu_test * tst)31 do_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
123 const 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
230 static void
do_alu_N_tests(void)231 do_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