/* { dg-do run { target { powerpc*-*-linux* } } } */ /* { dg-require-effective-target ppc_float128_sw } */ /* { dg-require-effective-target vsx_hw } */ /* { dg-options "-mvsx -O2" } */ /* This is the same as test float128-1.c, using the _Float128 keyword instead of __float128, and not using -mfloat128. */ #ifdef DEBUG #include #include #include #include #endif #if !defined(__FLOAT128__) || !defined(_ARCH_PPC) static _Float128 pass_through (_Float128 x) { return x; } _Float128 (*no_optimize) (_Float128) = pass_through; #endif #ifdef DEBUG __attribute__((__noinline__)) static void print_f128 (_Float128 x) { unsigned sign; unsigned exponent; uint64_t mantissa1; uint64_t mantissa2; uint64_t upper; uint64_t lower; #if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__) struct ieee128 { uint64_t upper; uint64_t lower; }; #elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__) struct ieee128 { uint64_t lower; uint64_t upper; }; #else #error "Unknown system" #endif union { _Float128 f128; struct ieee128 s128; } u; u.f128 = x; upper = u.s128.upper; lower = u.s128.lower; sign = (unsigned)((upper >> 63) & 1); exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1)); mantissa1 = (upper & ((((uint64_t)1) << 48) - 1)); mantissa2 = lower; printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64, sign ? '-' : '+', exponent, mantissa1, mantissa2); } #endif __attribute__((__noinline__)) static void do_test (_Float128 expected, _Float128 got, const char *name) { int equal_p = (expected == got); #ifdef DEBUG printf ("Test %s, expected: ", name); print_f128 (expected); printf (" %5g, got: ", (double) expected); print_f128 (got); printf (" %5g, result %s\n", (double) got, (equal_p) ? "equal" : "not equal"); #endif if (!equal_p) __builtin_abort (); } int main (void) { _Float128 one = 1.0f128; _Float128 two = 2.0f128; _Float128 three = 3.0f128; _Float128 four = 4.0f128; _Float128 five = 5.0f128; _Float128 add_result = (1.0f128 + 2.0f128); _Float128 mul_result = ((1.0f128 + 2.0f128) * 3.0f128); _Float128 div_result = (((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128); _Float128 sub_result = ((((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128) - 5.0f128); _Float128 neg_result = - sub_result; _Float128 add_xresult; _Float128 mul_xresult; _Float128 div_xresult; _Float128 sub_xresult; _Float128 neg_xresult; #if defined(__FLOAT128__) && defined(_ARCH_PPC) __asm__ (" #prevent constant folding, %x0" : "+wa" (one)); __asm__ (" #prevent constant folding, %x0" : "+wa" (two)); __asm__ (" #prevent constant folding, %x0" : "+wa" (three)); __asm__ (" #prevent constant folding, %x0" : "+wa" (four)); __asm__ (" #prevent constant folding, %x0" : "+wa" (five)); #else one = no_optimize (one); two = no_optimize (two); three = no_optimize (three); four = no_optimize (four); five = no_optimize (five); #endif add_xresult = (one + two); do_test (add_result, add_xresult, "add"); mul_xresult = add_xresult * three; do_test (mul_result, mul_xresult, "mul"); div_xresult = mul_xresult / four; do_test (div_result, div_xresult, "div"); sub_xresult = div_xresult - five; do_test (sub_result, sub_xresult, "sub"); neg_xresult = - sub_xresult; do_test (neg_result, neg_xresult, "neg"); #ifdef DEBUG printf ("Passed\n"); #endif return 0; }