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