/* { 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 #include #include #ifdef DEBUG #include #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; }