/* { dg-do run { target int128 } } */ /* { dg-options "-std=gnu99" { target c } } */ /* { dg-options "" { target c++ } } */ #ifndef __cplusplus extern void abort (void); #else extern "C" void abort (void); #endif #define MK_CONST128(A,B,C,D) \ ( (((unsigned __int128) (unsigned int) A) << 96) \ | (((unsigned __int128) (unsigned int) B) << 64) \ | (((unsigned __int128) (unsigned int) C) << 32) \ | ((unsigned __int128) (unsigned int) D) ) #define MK_CONST128_SIGNED(A,B,C,D) \ ((__int128) MK_CONST128(A, B, C, D)) #define MINUS_2 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \ 0xfffffffeu) #define MINUS_3 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \ 0xfffffffdu) #define MINUS_6 MK_CONST128_SIGNED (0xffffffffu, 0xffffffffu, 0xffffffffu, \ 0xfffffffau) #define PLUS_1 MK_CONST128_SIGNED (0, 0, 0, 1) #define PLUS_2 MK_CONST128_SIGNED (0, 0, 0, 2) #define PLUS_3 MK_CONST128_SIGNED (0, 0, 0, 3) #define PLUS_6 MK_CONST128_SIGNED (0, 0, 0, 6) #define PLUS_10 MK_CONST128_SIGNED (0, 0, 0, 10) #define U_8 MK_CONST128 (0, 0, 0, 8) #define U_MAX MK_CONST128 (0xffffffff,0xffffffff,0xffffffff,0xffffffff) #define U_CST1 MK_CONST128 (0xbeeffeed, 0xdeafcafe, 0xaffefade, 0x12345678) #define U_CST2 MK_CONST128 (0x41100112, 0x21503501, 0x50010521, 0xedcba987) signed __int128 foo_neg (signed __int128 v) { return -v; } unsigned __int128 foo_xor (unsigned __int128 x, unsigned __int128 y) { return x ^ y; } unsigned __int128 foo_inv (unsigned __int128 v) { return ~v; } unsigned __int128 foo_rotate_left (unsigned __int128 v) { unsigned __int128 c; int i; for (i = 0; i < 128; i++) { c = v >> 127; v <<= 1; v |= c; } return v; } unsigned __int128 foo_rotate_right (unsigned __int128 v) { unsigned __int128 c; int i; for (i = 0; i < 128; i++) { c = (v & ((unsigned __int128) 1)) << 127; v >>= 1; v |= c; } return v; } void foo_swap (unsigned __int128 *x, unsigned __int128 *y) { unsigned __int128 x1 = x[0]; unsigned __int128 y1 = y[0]; x1 ^= y1 ^= x1 ^= y1; x[0] = x1; y[0] = y1; } __int128 foo_add (signed __int128 a, unsigned __int128 b) { return (__int128) (a + (__int128) b); } __int128 foo_sub (unsigned __int128 a, signed __int128 b) { return (__int128) ((__int128) a - b); } __int128 foo_mul (signed __int128 a, signed __int128 b) { return a * b; } __int128 foo_div (signed __int128 a, signed __int128 b) { return a / b; } __int128 foo_shl (signed __int128 a, int shift) { return a << (shift & 127); } __int128 foo_shr (signed __int128 a, int shift) { return a >> (shift & 127); } int main(void) { __int128 rslt; unsigned __int128 u1, u2; rslt = foo_add (MINUS_2, U_8); if (rslt != PLUS_6) abort (); rslt = foo_sub (U_8, MINUS_2); if (rslt != PLUS_10) abort (); rslt = foo_sub ((unsigned __int128) foo_mul (MINUS_2, MINUS_2), MINUS_2); if (rslt != PLUS_6) abort (); if (rslt != foo_shl (PLUS_3, 1)) abort (); rslt = foo_shl (MINUS_3, 1); if (rslt != MINUS_6) abort (); if (foo_shr (MINUS_6, 1) != MINUS_3) abort (); if (foo_div (MINUS_6, MINUS_3) != PLUS_2) abort (); if (foo_rotate_left (U_CST1) != U_CST1) abort (); if (foo_rotate_right (U_CST1) != U_CST1) abort (); u1 = U_CST1; u2 = U_8; foo_swap (&u1, &u2); if (u1 != U_8 || u2 != U_CST1) abort (); if (foo_inv (U_CST2) != U_CST1) abort (); if (foo_neg (PLUS_2) != MINUS_2) abort (); if (foo_neg ((signed __int128) U_CST1) != foo_add (PLUS_1, foo_xor (U_CST1, U_MAX))) abort (); return 0; }