114 lines
2.6 KiB
C
114 lines
2.6 KiB
C
/* { dg-do run { target { powerpc*-*-linux* } } } */
|
|
/* { dg-skip-if "" { powerpc*-*-darwin* } } */
|
|
/* { dg-require-effective-target powerpc_fprs } */
|
|
/* { dg-require-effective-target longdouble128 } */
|
|
/* { dg-options "-O2 -mhard-float" } */
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#ifdef DEBUG
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#if defined(__LONG_DOUBLE_IEEE128__)
|
|
/* If long double is IEEE 128-bit, we need to use the __ibm128 type instead of
|
|
long double, and to use the appropriate pack/unpack routines. We can't use
|
|
__ibm128 on systems that don't support IEEE 128-bit floating point, because
|
|
the type is not enabled on those systems. */
|
|
#define PACK __builtin_pack_ibm128
|
|
#define UNPACK __builtin_unpack_ibm128
|
|
#define LDOUBLE __ibm128
|
|
|
|
#elif defined(__LONG_DOUBLE_IBM128__)
|
|
#define PACK __builtin_pack_longdouble
|
|
#define UNPACK __builtin_unpack_longdouble
|
|
#define LDOUBLE long double
|
|
|
|
#else
|
|
#error "long double must be either IBM 128-bit or IEEE 128-bit"
|
|
#endif
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
double high = pow (2.0, 60);
|
|
double low = 2.0;
|
|
LDOUBLE a = ((LDOUBLE)high) + ((LDOUBLE)low);
|
|
double x0 = UNPACK (a, 0);
|
|
double x1 = UNPACK (a, 1);
|
|
LDOUBLE b = PACK (x0, x1);
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
size_t i;
|
|
union {
|
|
LDOUBLE ld;
|
|
double d;
|
|
unsigned char uc[sizeof (LDOUBLE)];
|
|
char c[sizeof (LDOUBLE)];
|
|
} u;
|
|
|
|
printf ("a = 0x");
|
|
u.ld = a;
|
|
for (i = 0; i < sizeof (LDOUBLE); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (", %Lg\n", a);
|
|
|
|
printf ("b = 0x");
|
|
u.ld = b;
|
|
for (i = 0; i < sizeof (LDOUBLE); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (", %Lg\n", b);
|
|
|
|
printf ("hi = 0x");
|
|
u.d = high;
|
|
for (i = 0; i < sizeof (double); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", high);
|
|
|
|
printf ("lo = 0x");
|
|
u.d = low;
|
|
for (i = 0; i < sizeof (double); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", low);
|
|
|
|
printf ("x0 = 0x");
|
|
u.d = x0;
|
|
for (i = 0; i < sizeof (double); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", x0);
|
|
|
|
printf ("x1 = 0x");
|
|
u.d = x1;
|
|
for (i = 0; i < sizeof (double); i++)
|
|
printf ("%.2x", u.uc[i]);
|
|
|
|
printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", x1);
|
|
}
|
|
#endif
|
|
|
|
if (high != x0)
|
|
abort ();
|
|
|
|
if (low != x1)
|
|
abort ();
|
|
|
|
if (a != b)
|
|
abort ();
|
|
|
|
if (x0 != high)
|
|
abort ();
|
|
|
|
if (x1 != low)
|
|
abort ();
|
|
|
|
return 0;
|
|
}
|