c++: normalizing ttp constraints [PR115656]
[official-gcc.git] / gcc / testsuite / gcc.target / powerpc / float128-2.c
blob63b0f8d35bdb7dbde8a0b1a0ae48c1657c4a3fb4
1 /* { dg-do run { target { powerpc*-*-linux* } } } */
2 /* { dg-require-effective-target ppc_float128_sw } */
3 /* { dg-require-effective-target vsx_hw } */
4 /* { dg-options "-mvsx -O2" } */
6 /*
7 * Test program to make sure we are getting more precision than the 53 bits we
8 * get with IEEE double.
9 */
11 #include <stdio.h>
12 #include <math.h>
13 #include <stdlib.h>
14 #include <stddef.h>
16 #ifndef TYPE
17 #define TYPE __float128
18 #endif
20 #ifndef NO_INLINE
21 #define NO_INLINE __attribute__((__noinline__))
22 #endif
24 static TYPE power_of_two (ssize_t) NO_INLINE;
25 static TYPE calc1 (TYPE) NO_INLINE;
26 static TYPE calc2 (TYPE) NO_INLINE;
27 static TYPE calc3 (TYPE) NO_INLINE;
29 #ifndef POWER2
30 #define POWER2 60
31 #endif
35 * Print TYPE in hex.
39 #if defined(DEBUG) || defined(DEBUG2)
40 static void print_hex (const char *prefix, TYPE, const char *suffix) NO_INLINE;
42 #if defined (__i386__) || defined (__x86_64__) || defined (__LITTLE_ENDIAN__)
43 #define ENDIAN_REVERSE(N, MAX) ((MAX) - 1 - (N))
45 #else
46 #define ENDIAN_REVERSE(N, MAX) (N)
47 #endif
49 static void
50 print_hex (const char *prefix, TYPE value, const char *suffix)
52 union {
53 TYPE f128;
54 unsigned char uc[sizeof (TYPE)];
55 } u;
57 size_t i;
59 u.f128 = value;
60 printf ("%s0x", prefix);
61 for (i = 0; i < sizeof (TYPE); i++)
62 printf ("%.2x", u.uc[ ENDIAN_REVERSE (i, sizeof (TYPE)) ]);
64 printf (", %24.2Lf%s", (long double)value, suffix);
66 #endif
70 * Return a power of two.
73 static TYPE
74 power_of_two (ssize_t num)
76 TYPE ret = (TYPE) 1.0;
77 ssize_t i;
79 if (num >= 0)
81 for (i = 0; i < num; i++)
82 ret *= (TYPE) 2.0;
84 else
86 ssize_t num2 = -num;
87 for (i = 0; i < num2; i++)
88 ret /= (TYPE) 2.0;
91 #ifdef DEBUG
92 printf ("power_of_two (%2ld) = ", (long) num);
93 print_hex ("", ret, "\n");
94 #endif
96 return ret;
100 #ifdef ADDSUB
101 static TYPE add (TYPE a, TYPE b) NO_INLINE;
102 static TYPE sub (TYPE a, TYPE b) NO_INLINE;
104 static TYPE
105 add (TYPE a, TYPE b)
107 TYPE c;
108 #ifdef DEBUG
109 print_hex ("add, arg1 = ", a, "\n");
110 print_hex ("add, arg2 = ", b, "\n");
111 #endif
112 c = a + b;
113 #ifdef DEBUG
114 print_hex ("add, result = ", c, "\n");
115 #endif
116 return c;
119 static TYPE
120 sub (TYPE a, TYPE b)
122 TYPE c;
123 #ifdef DEBUG
124 print_hex ("sub, arg1 = ", a, "\n");
125 print_hex ("sub, arg2 = ", b, "\n");
126 #endif
127 c = a - b;
128 #ifdef DEBUG
129 print_hex ("sub, result = ", c, "\n");
130 #endif
131 return c;
134 #else
135 #define add(x, y) ((x) + (y))
136 #define sub(x, y) ((x) - (y))
137 #endif
140 * Various calculations. Add in 2**POWER2, and subtract 2**(POWER2-1) twice, and we should
141 * get the original value.
144 static TYPE
145 calc1 (TYPE num)
147 TYPE num2 = add (power_of_two (POWER2), num);
148 TYPE ret;
150 #ifdef DEBUG
151 print_hex ("calc1 (before call) = ", num2, "\n");
152 #endif
154 ret = calc2 (num2);
156 #ifdef DEBUG
157 print_hex ("calc1 (after call) = ", ret, "\n");
158 #endif
160 return ret;
163 static TYPE
164 calc2 (TYPE num)
166 TYPE num2 = sub (num, power_of_two (POWER2-1));
167 TYPE ret;
169 #ifdef DEBUG
170 print_hex ("calc2 (before call) = ", num2, "\n");
171 #endif
173 ret = calc3 (num2);
175 #ifdef DEBUG
176 print_hex ("calc2 (after call) = ", ret, "\n");
177 #endif
179 return ret;
182 static TYPE
183 calc3 (TYPE num)
185 TYPE ret = sub (num, (((TYPE) 2.0) * power_of_two (POWER2-2)));
187 #ifdef DEBUG
188 print_hex ("calc3 = ", ret, "\n");
189 #endif
191 return ret;
196 main (void)
198 TYPE input, output;
200 #ifdef DEBUG
201 printf ("Testing, %ld bytes\n", (long) sizeof (TYPE));
202 #endif
204 input = power_of_two (-1);
205 if ((double)input != 0.5)
207 #if defined(DEBUG) || defined(DEBUG2)
208 print_hex ("Input should be 0.5: ", output, "\n");
209 return 1;
210 #else
211 __builtin_abort ();
212 #endif
215 output = calc1 (input);
216 if ((double)output != 0.5)
218 #if defined(DEBUG) || defined(DEBUG2)
219 print_hex ("Output should be 0.5: ", output, "\n");
220 return 1;
221 #else
222 __builtin_abort ();
223 #endif
226 return 0;