1 /* { dg-do run { target { powerpc*-*-linux* } } } */
2 /* { dg-require-effective-target ppc_float128_sw } */
3 /* { dg-options "-mdejagnu-cpu=power7 -O2 -mfloat128 -lm" } */
4 
5 #ifdef DEBUG
6 #include <stdio.h>
7 #endif
8 
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <inttypes.h>
12 #include <stdlib.h>
13 #include <math.h>
14 
15 #if defined(__BIG_ENDIAN__)
16 struct ieee128 {
17   uint64_t upper;
18   uint64_t lower;
19 };
20 
21 #elif defined(__LITTLE_ENDIAN__)
22 struct ieee128 {
23   uint64_t lower;
24   uint64_t upper;
25 };
26 
27 #else
28 #error "Unknown system"
29 #endif
30 
31 union ieee_union {
32   __float128 f128;
33   struct ieee128 st128;
34 };
35 
36 #ifdef DEBUG
37 static int num_errors = 0;
38 
39 __attribute__((__noinline__))
40 static void
failure(int expected,int got,__float128 x)41 failure (int expected, int got, __float128 x)
42 {
43   unsigned sign;
44   unsigned exponent;
45   uint64_t mantissa1;
46   uint64_t mantissa2;
47   uint64_t upper;
48   uint64_t lower;
49 
50   union ieee_union u;
51 
52   u.f128 = x;
53   upper  = u.st128.upper;
54   lower  = u.st128.lower;
55 
56   sign      = (unsigned)((upper >> 63) & 1);
57   exponent  = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
58   mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
59   mantissa2 = lower;
60 
61   printf ("Expected %d, got %d, %c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
62 	  expected, got,
63 	  sign ? '-' : '+',
64 	  exponent,
65 	  mantissa1,
66 	  mantissa2);
67 
68   num_errors++;
69 }
70 
71 #else
72 
73 #define failure(E, G, F) abort ()
74 #endif
75 
76 __attribute__((__noinline__))
77 static void
test_signbit_arg(__float128 f128,int expected)78 test_signbit_arg (__float128 f128, int expected)
79 {
80   int sign = __builtin_signbit (f128);
81 
82   if ((expected != 0 && sign == 0)
83       || (expected == 0 && sign != 0))
84     failure (f128, expected, sign);
85 }
86 
87 __attribute__((__noinline__))
88 static void
test_signbit_mem(__float128 * ptr,int expected)89 test_signbit_mem (__float128 *ptr, int expected)
90 {
91   int sign = __builtin_signbit (*ptr);
92 
93   if ((expected != 0 && sign == 0)
94       || (expected == 0 && sign != 0))
95     failure (*ptr, expected, sign);
96 }
97 
98 __attribute__((__noinline__))
99 static void
test_signbit_gpr(__float128 * ptr,int expected)100 test_signbit_gpr (__float128 *ptr, int expected)
101 {
102   __float128 f128 = *ptr;
103   int sign;
104 
105   __asm__ (" # %0" : "+r" (f128));
106 
107   sign = __builtin_signbit (f128);
108   if ((expected != 0 && sign == 0)
109       || (expected == 0 && sign != 0))
110     failure (f128, expected, sign);
111 }
112 
113 __attribute__((__noinline__))
114 static void
test_signbit(__float128 f128,int expected)115 test_signbit (__float128 f128, int expected)
116 {
117 #ifdef DEBUG
118   union ieee_union u;
119   u.f128 = f128;
120   printf ("Expecting %d, trying %-5g "
121 	  "(0x%.16" PRIx64 " 0x%.16" PRIx64 ")\n",
122 	  expected, (double)f128,
123 	  u.st128.upper, u.st128.lower);
124 #endif
125 
126   test_signbit_arg (f128,  expected);
127   test_signbit_mem (&f128, expected);
128   test_signbit_gpr (&f128, expected);
129 }
130 
131 int
main(void)132 main (void)
133 {
134   union ieee_union u;
135 
136   test_signbit (+0.0q, 0);
137   test_signbit (+1.0q, 0);
138 
139   test_signbit (-0.0q, 1);
140   test_signbit (-1.0q, 1);
141 
142   test_signbit (__builtin_copysign (__builtin_infq (), +1.0q), 0);
143   test_signbit (__builtin_copysign (__builtin_infq (), -1.0q), 1);
144 
145   test_signbit (__builtin_copysign (__builtin_nanq (""), +1.0q), 0);
146   test_signbit (__builtin_copysign (__builtin_nanq (""), -1.0q), 1);
147 
148   /* force the bottom double word to have specific bits in the 'sign' bit to
149      make sure we are picking the right word.  */
150   u.f128 = 1.0q;
151   u.st128.lower = 0ULL;
152   test_signbit (u.f128, 0);
153 
154   u.st128.lower = ~0ULL;
155   test_signbit (u.f128, 0);
156 
157   u.f128 = -1.0q;
158   u.st128.lower = 0ULL;
159   test_signbit (u.f128, 1);
160 
161   u.st128.lower = ~0ULL;
162   test_signbit (u.f128, 1);
163 
164 #ifdef DEBUG
165   printf ("%d error(s) were found\n", num_errors);
166   if (num_errors)
167     return num_errors;
168 #endif
169 
170   return 0;
171 }
172 
173