[RS6000] Tests that use int128_t and -m32
[official-gcc.git] / gcc / testsuite / gcc.target / powerpc / recip-test2.h
blob3ec356cdfd863b24c10c22097225114162d376b3
1 /*
2 * Included file to common source float/double checking
3 * The following macros should be defined:
4 * TYPE -- floating point type
5 * NAME -- convert a name to include the type
6 * UNS_TYPE -- type to hold TYPE as an unsigned number
7 * EXP_SIZE -- size in bits of the exponent
8 * MAN_SIZE -- size in bits of the mantissa
9 * UNS_ABS -- absolute value for UNS_TYPE
10 * FABS -- absolute value function for TYPE
11 * FMAX -- maximum function for TYPE
12 * FMIN -- minimum function for TYPE
13 * SQRT -- square root function for TYPE
14 * RMIN -- minimum random number to generate
15 * RMAX -- maximum random number to generate
16 * ASMDIV -- assembler instruction to do divide
17 * ASMSQRT -- assembler instruction to do square root
18 * BDIV -- # of bits of inaccuracy to allow for division
19 * BRSQRT -- # of bits of inaccuracy to allow for 1/sqrt
20 * INIT_DIV -- Initial values to test 1/x against
21 * INIT_RSQRT -- Initial values to test 1/sqrt(x) against
24 typedef union
26 UNS_TYPE i;
27 TYPE x;
28 } NAME (union);
31 * Input/output arrays.
34 static NAME (union) NAME (div_input) [] __attribute__((__aligned__(32))) = INIT_DIV;
35 static NAME (union) NAME (rsqrt_input)[] __attribute__((__aligned__(32))) = INIT_RSQRT;
37 #define DIV_SIZE (sizeof (NAME (div_input)) / sizeof (TYPE))
38 #define RSQRT_SIZE (sizeof (NAME (rsqrt_input)) / sizeof (TYPE))
40 static TYPE NAME (div_expected)[DIV_SIZE] __attribute__((__aligned__(32)));
41 static TYPE NAME (div_output) [DIV_SIZE] __attribute__((__aligned__(32)));
43 static TYPE NAME (rsqrt_expected)[RSQRT_SIZE] __attribute__((__aligned__(32)));
44 static TYPE NAME (rsqrt_output) [RSQRT_SIZE] __attribute__((__aligned__(32)));
48 * Crack a floating point number into sign bit, exponent, and mantissa.
51 static void
52 NAME (crack) (TYPE number, unsigned int *p_sign, unsigned *p_exponent, UNS_TYPE *p_mantissa)
54 NAME (union) u;
55 UNS_TYPE bits;
57 u.x = number;
58 bits = u.i;
60 *p_sign = (unsigned int)((bits >> (EXP_SIZE + MAN_SIZE)) & 0x1);
61 *p_exponent = (unsigned int)((bits >> MAN_SIZE) & ((((UNS_TYPE)1) << EXP_SIZE) - 1));
62 *p_mantissa = bits & ((((UNS_TYPE)1) << MAN_SIZE) - 1);
63 return;
68 * Prevent optimizer from eliminating + 0.0 to remove -0.0.
71 volatile TYPE NAME (math_diff_0) = ((TYPE) 0.0);
74 * Return negative if two numbers are significanly different or return the
75 * number of bits that are different in the mantissa.
78 static int
79 NAME (math_diff) (TYPE a, TYPE b, int bits)
81 TYPE zero = NAME (math_diff_0);
82 unsigned int sign_a, sign_b;
83 unsigned int exponent_a, exponent_b;
84 UNS_TYPE mantissa_a, mantissa_b, diff;
85 int i;
87 /* eliminate signed zero. */
88 a += zero;
89 b += zero;
91 /* special case Nan. */
92 if (__builtin_isnan (a))
93 return (__builtin_isnan (b) ? 0 : -1);
95 if (a == b)
96 return 0;
98 /* special case infinity. */
99 if (__builtin_isinf (a))
100 return (__builtin_isinf (b) ? 0 : -1);
102 /* punt on denormal numbers. */
103 if (!__builtin_isnormal (a) || !__builtin_isnormal (b))
104 return -1;
106 NAME (crack) (a, &sign_a, &exponent_a, &mantissa_a);
107 NAME (crack) (b, &sign_b, &exponent_b, &mantissa_b);
109 /* If the sign is different, there is no hope. */
110 if (sign_a != sign_b)
111 return -1;
113 /* If the exponent is off by 1, see if the values straddle the power of two,
114 and adjust things to do the mantassa check if we can. */
115 if ((exponent_a == (exponent_b+1)) || (exponent_a == (exponent_b-1)))
117 TYPE big = FMAX (a, b);
118 TYPE small = FMIN (a, b);
119 TYPE diff = FABS (a - b);
120 unsigned int sign_big, sign_small, sign_test;
121 unsigned int exponent_big, exponent_small, exponent_test;
122 UNS_TYPE mantissa_big, mantissa_small, mantissa_test;
124 NAME (crack) (big, &sign_big, &exponent_big, &mantissa_big);
125 NAME (crack) (small, &sign_small, &exponent_small, &mantissa_small);
127 NAME (crack) (small - diff, &sign_test, &exponent_test, &mantissa_test);
128 if ((sign_test == sign_small) && (exponent_test == exponent_small))
130 mantissa_a = mantissa_small;
131 mantissa_b = mantissa_test;
134 else
136 NAME (crack) (big + diff, &sign_test, &exponent_test, &mantissa_test);
137 if ((sign_test == sign_big) && (exponent_test == exponent_big))
139 mantissa_a = mantissa_big;
140 mantissa_b = mantissa_test;
143 else
144 return -1;
148 else if (exponent_a != exponent_b)
149 return -1;
151 diff = UNS_ABS (mantissa_a - mantissa_b);
152 for (i = MAN_SIZE; i > 0; i--)
154 if ((diff & ((UNS_TYPE)1) << (i-1)) != 0)
155 return i;
158 return -1;
163 * Turn off inlining to make code inspection easier.
166 static void NAME (asm_div) (void) __attribute__((__noinline__));
167 static void NAME (vector_div) (void) __attribute__((__noinline__));
168 static void NAME (scalar_div) (void) __attribute__((__noinline__));
169 static void NAME (asm_rsqrt) (void) __attribute__((__noinline__));
170 static void NAME (vector_rsqrt) (void) __attribute__((__noinline__));
171 static void NAME (scalar_rsqrt) (void) __attribute__((__noinline__));
172 static void NAME (check_div) (const char *) __attribute__((__noinline__));
173 static void NAME (check_rsqrt) (const char *) __attribute__((__noinline__));
174 static void NAME (run) (void) __attribute__((__noinline__));
178 * Division function that might be vectorized.
181 static void
182 NAME (vector_div) (void)
184 size_t i;
186 for (i = 0; i < DIV_SIZE; i++)
187 NAME (div_output)[i] = ((TYPE) 1.0) / NAME (div_input)[i].x;
191 * Division function that is not vectorized.
194 static void
195 NAME (scalar_div) (void)
197 size_t i;
199 for (i = 0; i < DIV_SIZE; i++)
201 TYPE x = ((TYPE) 1.0) / NAME (div_input)[i].x;
202 TYPE y;
203 __asm__ ("" : "=d" (y) : "0" (x));
204 NAME (div_output)[i] = y;
209 * Generate the division instruction via asm.
212 static void
213 NAME (asm_div) (void)
215 size_t i;
217 for (i = 0; i < DIV_SIZE; i++)
219 TYPE x;
220 __asm__ (ASMDIV " %0,%1,%2"
221 : "=d" (x)
222 : "d" ((TYPE) 1.0), "d" (NAME (div_input)[i].x));
223 NAME (div_expected)[i] = x;
228 * Reciprocal square root function that might be vectorized.
231 static void
232 NAME (vector_rsqrt) (void)
234 size_t i;
236 for (i = 0; i < RSQRT_SIZE; i++)
237 NAME (rsqrt_output)[i] = ((TYPE) 1.0) / SQRT (NAME (rsqrt_input)[i].x);
241 * Reciprocal square root function that is not vectorized.
244 static void
245 NAME (scalar_rsqrt) (void)
247 size_t i;
249 for (i = 0; i < RSQRT_SIZE; i++)
251 TYPE x = ((TYPE) 1.0) / SQRT (NAME (rsqrt_input)[i].x);
252 TYPE y;
253 __asm__ ("" : "=d" (y) : "0" (x));
254 NAME (rsqrt_output)[i] = y;
259 * Generate the 1/sqrt instructions via asm.
262 static void
263 NAME (asm_rsqrt) (void)
265 size_t i;
267 for (i = 0; i < RSQRT_SIZE; i++)
269 TYPE x;
270 TYPE y;
271 __asm__ (ASMSQRT " %0,%1" : "=d" (x) : "d" (NAME (rsqrt_input)[i].x));
272 __asm__ (ASMDIV " %0,%1,%2" : "=d" (y) : "d" ((TYPE) 1.0), "d" (x));
273 NAME (rsqrt_expected)[i] = y;
279 * Functions to abort or report errors.
282 static int NAME (error_count) = 0;
284 #ifdef VERBOSE
285 static int NAME (max_bits_div) = 0;
286 static int NAME (max_bits_rsqrt) = 0;
287 #endif
291 * Compare the expected value with the value we got.
294 static void
295 NAME (check_div) (const char *test)
297 size_t i;
298 int b;
300 for (i = 0; i < DIV_SIZE; i++)
302 TYPE exp = NAME (div_expected)[i];
303 TYPE out = NAME (div_output)[i];
304 b = NAME (math_diff) (exp, out, BDIV);
306 #ifdef VERBOSE
307 if (b != 0)
309 NAME (union) u_in = NAME (div_input)[i];
310 NAME (union) u_exp;
311 NAME (union) u_out;
312 char explanation[64];
313 const char *p_exp;
315 if (b < 0)
316 p_exp = "failed";
317 else
319 p_exp = explanation;
320 sprintf (explanation, "%d bit error%s", b, (b > BDIV) ? ", failed" : "");
323 u_exp.x = exp;
324 u_out.x = out;
325 printf ("%s %s %s for 1.0 / %g [0x%llx], expected %g [0x%llx], got %g [0x%llx]\n",
326 TNAME (TYPE), test, p_exp,
327 (double) u_in.x, (unsigned long long) u_in.i,
328 (double) exp, (unsigned long long) u_exp.i,
329 (double) out, (unsigned long long) u_out.i);
331 #endif
333 if (b < 0 || b > BDIV)
334 NAME (error_count)++;
336 #ifdef VERBOSE
337 if (b > NAME (max_bits_div))
338 NAME (max_bits_div) = b;
339 #endif
343 static void
344 NAME (check_rsqrt) (const char *test)
346 size_t i;
347 int b;
349 for (i = 0; i < RSQRT_SIZE; i++)
351 TYPE exp = NAME (rsqrt_expected)[i];
352 TYPE out = NAME (rsqrt_output)[i];
353 b = NAME (math_diff) (exp, out, BRSQRT);
355 #ifdef VERBOSE
356 if (b != 0)
358 NAME (union) u_in = NAME (rsqrt_input)[i];
359 NAME (union) u_exp;
360 NAME (union) u_out;
361 char explanation[64];
362 const char *p_exp;
364 if (b < 0)
365 p_exp = "failed";
366 else
368 p_exp = explanation;
369 sprintf (explanation, "%d bit error%s", b, (b > BDIV) ? ", failed" : "");
372 u_exp.x = exp;
373 u_out.x = out;
374 printf ("%s %s %s for 1 / sqrt (%g) [0x%llx], expected %g [0x%llx], got %g [0x%llx]\n",
375 TNAME (TYPE), test, p_exp,
376 (double) u_in.x, (unsigned long long) u_in.i,
377 (double) exp, (unsigned long long) u_exp.i,
378 (double) out, (unsigned long long) u_out.i);
380 #endif
382 if (b < 0 || b > BRSQRT)
383 NAME (error_count)++;
385 #ifdef VERBOSE
386 if (b > NAME (max_bits_rsqrt))
387 NAME (max_bits_rsqrt) = b;
388 #endif
394 * Now do everything.
397 static void
398 NAME (run) (void)
400 #ifdef VERBOSE
401 printf ("start run_%s, divide size = %ld, rsqrt size = %ld, %d bit%s for a/b, %d bit%s for 1/sqrt(a)\n",
402 TNAME (TYPE),
403 (long)DIV_SIZE,
404 (long)RSQRT_SIZE,
405 BDIV, (BDIV == 1) ? "" : "s",
406 BRSQRT, (BRSQRT == 1) ? "" : "s");
407 #endif
409 NAME (asm_div) ();
411 NAME (scalar_div) ();
412 NAME (check_div) ("scalar");
414 NAME (vector_div) ();
415 NAME (check_div) ("vector");
417 NAME (asm_rsqrt) ();
419 NAME (scalar_rsqrt) ();
420 NAME (check_rsqrt) ("scalar");
422 NAME (vector_rsqrt) ();
423 NAME (check_rsqrt) ("vector");
425 #ifdef VERBOSE
426 printf ("end run_%s, errors = %d, max div bits = %d, max rsqrt bits = %d\n",
427 TNAME (TYPE),
428 NAME (error_count),
429 NAME (max_bits_div),
430 NAME (max_bits_rsqrt));
431 #endif