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