1 /* { dg-do run { target { powerpc*-*-linux* } } } */
2 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
3 /* { dg-skip-if "" { powerpc*-*-*spe* } } */
4 /* { dg-require-effective-target powerpc_fprs } */
5 /* { dg-require-effective-target longdouble128 } */
6 /* { dg-options "-O2 -mhard-float" } */
7 
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <math.h>
11 
12 #ifdef DEBUG
13 #include <stdio.h>
14 #endif
15 
16 #if defined(__LONG_DOUBLE_IEEE128__)
17 /* If long double is IEEE 128-bit, we need to use the __ibm128 type instead of
18    long double, and to use the appropriate pack/unpack routines.  We can't use
19    __ibm128 on systems that don't support IEEE 128-bit floating point, because
20    the type is not enabled on those systems.  */
21 #define PACK __builtin_pack_ibm128
22 #define UNPACK __builtin_unpack_ibm128
23 #define LDOUBLE __ibm128
24 
25 #elif defined(__LONG_DOUBLE_IBM128__)
26 #define PACK __builtin_pack_longdouble
27 #define UNPACK __builtin_unpack_longdouble
28 #define LDOUBLE long double
29 
30 #else
31 #error "long double must be either IBM 128-bit or IEEE 128-bit"
32 #endif
33 
34 int
main(void)35 main (void)
36 {
37   double high = pow (2.0, 60);
38   double low  = 2.0;
39   LDOUBLE a = ((LDOUBLE)high) + ((LDOUBLE)low);
40   double x0 = UNPACK (a, 0);
41   double x1 = UNPACK (a, 1);
42   LDOUBLE b = PACK (x0, x1);
43 
44 #ifdef DEBUG
45   {
46     size_t i;
47     union {
48       LDOUBLE ld;
49       double d;
50       unsigned char uc[sizeof (LDOUBLE)];
51       char c[sizeof (LDOUBLE)];
52     } u;
53 
54     printf ("a  = 0x");
55     u.ld = a;
56     for (i = 0; i < sizeof (LDOUBLE); i++)
57       printf ("%.2x", u.uc[i]);
58 
59     printf (", %Lg\n", a);
60 
61     printf ("b  = 0x");
62     u.ld = b;
63     for (i = 0; i < sizeof (LDOUBLE); i++)
64       printf ("%.2x", u.uc[i]);
65 
66     printf (", %Lg\n", b);
67 
68     printf ("hi = 0x");
69     u.d = high;
70     for (i = 0; i < sizeof (double); i++)
71       printf ("%.2x", u.uc[i]);
72 
73     printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", high);
74 
75     printf ("lo = 0x");
76     u.d = low;
77     for (i = 0; i < sizeof (double); i++)
78       printf ("%.2x", u.uc[i]);
79 
80     printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", low);
81 
82     printf ("x0 = 0x");
83     u.d = x0;
84     for (i = 0; i < sizeof (double); i++)
85       printf ("%.2x", u.uc[i]);
86 
87     printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", x0);
88 
89     printf ("x1 = 0x");
90     u.d = x1;
91     for (i = 0; i < sizeof (double); i++)
92       printf ("%.2x", u.uc[i]);
93 
94     printf (",%*s %g\n", (int)(2 * (sizeof (LDOUBLE) - sizeof (double))), "", x1);
95   }
96 #endif
97 
98   if (high != x0)
99     abort ();
100 
101   if (low != x1)
102     abort ();
103 
104   if (a != b)
105     abort ();
106 
107   if (x0 != high)
108     abort ();
109 
110   if (x1 != low)
111     abort ();
112 
113   return 0;
114 }
115