@@ -236,9 +236,24 @@ static void finishOutput()
236236 DEFINE_BINOP_DIV_LIKE_FUNC_LL(u, name, func, post)
237237
238238
239+ typedef struct Op_
240+ {
241+ bool isBinary ;
242+ bool isUnsigned ;
243+ const char * name ;
244+ void (* b )();
245+ void (* s )();
246+ void (* i )();
247+ void (* l )();
248+ void (* i48 )();
249+ void (* ll )();
250+ } Op ;
251+
239252#define DEFINE_UNOP_TYPE (u ) \
240253 typedef struct u##UnOp_ \
241254 { \
255+ bool isBinary; \
256+ bool isUnsigned; \
242257 const char *name; \
243258 u##int8_t (*b)(u##int8_t); \
244259 u##int16_t (*s)(u##int16_t); \
@@ -251,6 +266,8 @@ static void finishOutput()
251266#define DEFINE_BINOP_TYPE (u ) \
252267 typedef struct u##BinOp_ \
253268 { \
269+ bool isBinary; \
270+ bool isUnsigned; \
254271 const char *name; \
255272 u##int8_t (*b)(u##int8_t, u##int8_t); \
256273 u##int16_t (*s)(u##int16_t, u##int16_t); \
@@ -266,44 +283,47 @@ DEFINE_UNOP_TYPE(u)
266283DEFINE_BINOP_TYPE ()
267284DEFINE_BINOP_TYPE (u )
268285
286+ static const bool _0IsUnsigned = 0 ;
287+ static const bool _0IsUnsignedu = 1 ;
288+
269289#define DEFINE_UNOP_STRUCT_B (u , name ) \
270- static const u ##UnOp unop_##name = {#name, b##name##_};
290+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_};
271291#define DEFINE_UNOP_STRUCT_B_TO_S (u , name ) \
272- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_};
292+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_};
273293#define DEFINE_UNOP_STRUCT_B_TO_I (u , name ) \
274- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_, i##name##_};
294+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_};
275295#define DEFINE_UNOP_STRUCT_B_TO_L (u , name ) \
276- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_};
296+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_};
277297#define DEFINE_UNOP_STRUCT_B_TO_I48 (u , name ) \
278- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_};
298+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_};
279299#define DEFINE_UNOP_STRUCT_B_TO_LL (u , name ) \
280- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_, ll##name##_};
300+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_, ll##name##_};
281301#define DEFINE_UNOP_STRUCT_B_TO_LL_EXCEPT_I48 (u , name ) \
282- static const u##UnOp unop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_, NULL, ll##name##_};
302+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_, NULL, ll##name##_};
283303// clang version 15.0.0 (https://github.com/CE-Programming/llvm-project
284304// 23b78267b5d376b232475d0805a937e54b61e0d0): unable to legalize instruction:
285305// %5:_(s48) = G_BSWAP %0:_ (in function: i48bswap_)
286306#define DEFINE_UNOP_STRUCT_BSWAP (u , name ) \
287- static const u##UnOp unop_##name = {#name, NULL, s##name##_, i##name##_, l##name##_, NULL, ll##name##_};
307+ static const u##UnOp u## unop_##name = {0, _0IsUnsigned##u, #name, NULL, s##name##_, i##name##_, l##name##_, NULL, ll##name##_};
288308
289309#define DEFINE_BINOP_STRUCT_B (u , name ) \
290- static const u##BinOp binop_##name = {#name, b##name##_};
310+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_};
291311#define DEFINE_BINOP_STRUCT_B_TO_S (u , name ) \
292- static const u##BinOp binop_##name = {#name, b##name##_, s##name##_};
312+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_, s##name##_};
293313#define DEFINE_BINOP_STRUCT_B_TO_I (u , name ) \
294- static const u##BinOp binop_##name = {#name, b##name##_, s##name##_, i##name##_};
314+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_};
295315#define DEFINE_BINOP_STRUCT_B_TO_L (u , name ) \
296- static const u##BinOp binop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_};
316+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_};
297317#define DEFINE_BINOP_STRUCT_B_TO_I48 (u , name ) \
298- static const u##BinOp binop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_};
318+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_};
299319#define DEFINE_BINOP_STRUCT_B_TO_LL (u , name ) \
300- static const u##BinOp binop_##name = {#name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_, ll##name##_};
320+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, b##name##_, s##name##_, i##name##_, l##name##_, i48##name##_, ll##name##_};
301321#define DEFINE_BINOP_STRUCT_I_TO_L (u , name ) \
302- static const u##BinOp binop_##name = {#name, NULL, NULL, i##name##_, l##name##_};
322+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, NULL, NULL, i##name##_, l##name##_};
303323// #define DEFINE_BINOP_STRUCT_I_TO_I48(u, name) \
304- // static const u##BinOp binop_##name = {#name, NULL, NULL, i##name##_, l##name##_, i48##name##_};
324+ // static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, NULL, NULL, i##name##_, l##name##_, i48##name##_};
305325#define DEFINE_BINOP_STRUCT_I_TO_LL (u , name ) \
306- static const u##BinOp binop_##name = {#name, NULL, NULL, i##name##_, l##name##_, NULL, ll##name##_};
326+ static const u##BinOp u## binop_##name = {1, _0IsUnsigned##u, #name, NULL, NULL, i##name##_, l##name##_, NULL, ll##name##_};
307327
308328
309329#define DEFINE_UNOP_PREFIX_B (u , name , op ) \
@@ -345,14 +365,14 @@ DEFINE_BINOP_TYPE(u)
345365 DEFINE_BINOP_STRUCT_B_TO_LL(u, name)
346366
347367
348- static void testOp (bool isBinOp , const BinOp * op , int64_t x , int64_t y )
368+ static void testOp (const Op * op , int64_t x , int64_t y )
349369{
350370 unsigned lhsLength = 9 ;
351371 unsigned nameLength = strlen (op -> name );
352372 unsigned prefixLength = lhsLength - nameLength ;
353373
354374 x_printffull ("%*s=%016llX" , lhsLength , "x" , (long long )x );
355- if (!isBinOp )
375+ if (!op -> isBinary )
356376 {
357377 x_printf ("\n" );
358378 }
@@ -362,12 +382,27 @@ static void testOp(bool isBinOp, const BinOp *op, int64_t x, int64_t y)
362382 }
363383 x_printf ("\n" );
364384
365- #define TEST_OP (prefix , bits ) \
366- if (op->prefix) \
367- { \
368- unsigned digits = (bits + 3) / 4; \
369- unsigned long long result = (op->prefix)(x, y) & ((1ULL << (bits - 1) << 1) - 1); \
370- x_printffull("%*s%s=%*s%0*llX", prefixLength, #prefix, op->name, 16 - digits, "", digits, result); \
385+ #define TEST_OP (prefix , bits ) \
386+ if (op->prefix) \
387+ { \
388+ unsigned digits = (bits + 3) / 4; \
389+ unsigned long long result = \
390+ !op->isBinary \
391+ ? !op->isUnsigned \
392+ ? ((const UnOp *)(op))->prefix(x) \
393+ : ((const uUnOp *)(op))->prefix(x) \
394+ : !op->isUnsigned \
395+ ? ((const BinOp *)(op))->prefix(x, y) \
396+ : ((const uBinOp *)(op))->prefix(x, y); \
397+ result &= ((1ULL << (bits - 1) << 1) - 1); \
398+ x_printffull("%*s%s=%*s%0*llX", \
399+ prefixLength, \
400+ #prefix, \
401+ op->name, \
402+ 16 - digits, \
403+ "", \
404+ digits, \
405+ result); \
371406 } \
372407 else \
373408 { \
@@ -384,16 +419,6 @@ static void testOp(bool isBinOp, const BinOp *op, int64_t x, int64_t y)
384419 finishOutput ();
385420}
386421
387- static void testUnOp (const UnOp * op , int64_t x )
388- {
389- testOp (false, (const BinOp * )op , x , 0 );
390- }
391-
392- static void testBinOp (const BinOp * op , int64_t x , int64_t y )
393- {
394- testOp (true, op , x , y );
395- }
396-
397422
398423DEFINE_UNOP_PREFIX_B_TO_LL ( , not , ~)
399424DEFINE_UNOP_PREFIX_B_TO_LL ( , neg , - )
@@ -449,31 +474,28 @@ DEFINE_BINOP_DIV_LIKE_FUNC_I_TO_LL( , div_r, div, .rem)
449474DEFINE_BINOP_STRUCT_I_TO_LL ( , div_r )
450475
451476
452- static const UnOp * unops [] = {
453- & unop_not ,
454- & unop_neg ,
455- & unop_abs ,
456- & unop_bitrev ,
457- (const UnOp * )& unop_bswap ,
458- (const UnOp * )& unop_popcnt ,
459- };
460-
461- static const BinOp * binops [] = {
462- & binop_and ,
463- & binop_or ,
464- & binop_xor ,
465- & binop_add ,
466- & binop_sub ,
467- & binop_shl ,
468- (const BinOp * )& binop_shru ,
469- & binop_shrs ,
470- (const BinOp * )& binop_mulu ,
471- (const BinOp * )& binop_divu ,
472- (const BinOp * )& binop_remu ,
473- & binop_divs ,
474- & binop_rems ,
475- & binop_div_q ,
476- & binop_div_r ,
477+ static const Op * ops [] = {
478+ (const Op * )& unop_not ,
479+ (const Op * )& unop_neg ,
480+ (const Op * )& unop_abs ,
481+ (const Op * )& unop_bitrev ,
482+ (const Op * )& uunop_bswap ,
483+ (const Op * )& uunop_popcnt ,
484+ (const Op * )& binop_and ,
485+ (const Op * )& binop_or ,
486+ (const Op * )& binop_xor ,
487+ (const Op * )& binop_add ,
488+ (const Op * )& binop_sub ,
489+ (const Op * )& binop_shl ,
490+ (const Op * )& ubinop_shru ,
491+ (const Op * )& binop_shrs ,
492+ (const Op * )& ubinop_mulu ,
493+ (const Op * )& ubinop_divu ,
494+ (const Op * )& ubinop_remu ,
495+ (const Op * )& binop_divs ,
496+ (const Op * )& binop_rems ,
497+ (const Op * )& binop_div_q ,
498+ (const Op * )& binop_div_r ,
477499};
478500
479501
@@ -484,14 +506,9 @@ int main(int argc, char *argv[])
484506
485507 separateOutput ();
486508
487- for (size_t i = 0 ; i < sizeof (unops ) / sizeof (* unops ); i + + )
488- {
489- testUnOp (unops [i ], x );
490- }
491-
492- for (size_t i = 0 ; i < sizeof (binops ) / sizeof (* binops ); i + + )
509+ for (size_t i = 0 ; i < sizeof (ops ) / sizeof (* ops ); i + + )
493510 {
494- testBinOp ( binops [i ], x , y );
511+ testOp ( ops [i ], x , y );
495512 }
496513
497514 return 0 ;
0 commit comments