blob: 00b18881a0b966e08dd69c05f810b3c06d4f08b5 [file] [log] [blame]
/* { 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 <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.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;
}