Home | History | Annotate | Line # | Download | only in common
      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