1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-require-effective-target ppc_float128_sw } */
/* { dg-require-effective-target vsx_hw } */
/* { dg-options "-mvsx -O2" } */
#ifdef DEBUG
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#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.0q;
__float128 two = 2.0q;
__float128 three = 3.0q;
__float128 four = 4.0q;
__float128 five = 5.0q;
__float128 add_result = (1.0q + 2.0q);
__float128 mul_result = ((1.0q + 2.0q) * 3.0q);
__float128 div_result = (((1.0q + 2.0q) * 3.0q) / 4.0q);
__float128 sub_result = ((((1.0q + 2.0q) * 3.0q) / 4.0q) - 5.0q);
__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;
}
|