..
[glibc.git] / soft-fp / testit.c
blob46a50c44012a283346a0040851a8877f2f56711c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
5 #include "soft-fp.h"
6 #include "single.h"
7 #include "double.h"
9 #include <fpu_control.h>
11 /*======================================================================*/
12 /* declarations for the functions we are testing */
14 double __adddf3(double, double);
15 double __subdf3(double, double);
16 double __muldf3(double, double);
17 double __divdf3(double, double);
18 double __negdf2(double);
19 double __sqrtdf2(double);
20 double __negdf3(double a, double dummy) { return __negdf2(a); }
21 double __sqrtdf3(double a, double dummy) { return __sqrtdf2(a); }
23 float __addsf3(float, float);
24 float __subsf3(float, float);
25 float __mulsf3(float, float);
26 float __divsf3(float, float);
27 float __negsf2(float);
28 float __sqrtsf2(float);
29 float __negsf3(float a, float dummy) { return __negsf2(a); }
30 float __sqrtsf3(float a, float dummy) { return __sqrtsf2(a); }
32 int __fixdfsi(double);
33 int __fixsfsi(float);
34 double __floatsidf(int);
35 float __floatsisf(int);
36 double __extendsfdf2(float);
37 float __truncdfsf2(double);
39 int __eqdf2(double, double);
40 int __nedf2(double, double);
41 int __gtdf2(double, double);
42 int __gedf2(double, double);
43 int __ltdf2(double, double);
44 int __ledf2(double, double);
46 int __eqsf2(float, float);
47 int __nesf2(float, float);
48 int __gtsf2(float, float);
49 int __gesf2(float, float);
50 int __ltsf2(float, float);
51 int __lesf2(float, float);
53 /*======================================================================*/
54 /* definitions for functions we are checking against */
56 double r_adddf3(double a, double b) { return a + b; }
57 double r_subdf3(double a, double b) { return a - b; }
58 double r_muldf3(double a, double b) { return a * b; }
59 double r_divdf3(double a, double b) { return a / b; }
60 double r_negdf3(double a, double b) { return -a; }
61 double sqrt(double x);
62 double r_sqrtdf3(double a, double b) { return sqrt(a); }
64 float r_addsf3(float a, float b) { return a + b; }
65 float r_subsf3(float a, float b) { return a - b; }
66 float r_mulsf3(float a, float b) { return a * b; }
67 float r_divsf3(float a, float b) { return a / b; }
68 float r_negsf3(float a, float b) { return -a; }
69 float sqrtf(float x);
70 float r_sqrtsf3(float a, float b) { return sqrtf(a); }
72 int r_fixdfsi(double a) { return (int)a; }
73 int r_fixsfsi(float a) { return (int)a; }
74 double r_floatsidf(int a) { return (double)a; }
75 float r_floatsisf(int a) { return (float)a; }
76 double r_extendsfdf2(float a) { return (double)a; }
77 float r_truncdfsf2(double a) { return (float)a; }
79 int r_eqdf2(double a, double b) { return !(a == b); }
80 int r_nedf2(double a, double b) { return a != b; }
81 int r_gtdf2(double a, double b) { return a > b; }
82 int r_gedf2(double a, double b) { return (a >= b) - 1; }
83 int r_ltdf2(double a, double b) { return -(a < b); }
84 int r_ledf2(double a, double b) { return 1 - (a <= b); }
86 int r_eqsf2(float a, float b) { return !(a == b); }
87 int r_nesf2(float a, float b) { return a != b; }
88 int r_gtsf2(float a, float b) { return a > b; }
89 int r_gesf2(float a, float b) { return (a >= b) - 1; }
90 int r_ltsf2(float a, float b) { return -(a < b); }
91 int r_lesf2(float a, float b) { return 1 - (a <= b); }
93 /*======================================================================*/
95 void print_float(float x)
97 union _FP_UNION_S ux;
98 ux.flt = x;
99 printf("%-20.8e %X %02X %06lX",
100 x, ux.bits.sign, ux.bits.exp, (unsigned long)ux.bits.frac);
103 void print_double(double x)
105 union _FP_UNION_D ux;
106 ux.flt = x;
107 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
108 printf("%-30.18e %X %04X %06lX%08lX",
109 x, ux.bits.sign, ux.bits.exp,
110 (unsigned long)ux.bits.frac1, (unsigned long)ux.bits.frac0);
111 #else
112 printf("%-30.18e %X %04X %014lX",
113 x, ux.bits.sign, ux.bits.exp,
114 (unsigned long)ux.bits.frac);
115 #endif
118 float rand_float(void)
120 union {
121 union _FP_UNION_S u;
122 int i;
123 } u;
125 u.i = lrand48() << 1;
127 if (u.u.bits.exp == _FP_EXPMAX_S)
128 u.u.bits.exp--;
129 else if (u.u.bits.exp == 0 && u.u.bits.frac != 0)
130 u.u.bits.exp++;
132 return u.u.flt;
136 double rand_double(void)
138 union {
139 union _FP_UNION_D u;
140 int i[2];
141 } u;
143 u.i[0] = lrand48() << 1;
144 u.i[1] = lrand48() << 1;
146 if (u.u.bits.exp == _FP_EXPMAX_D)
147 u.u.bits.exp--;
148 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
149 else if (u.u.bits.exp == 0 && !(u.u.bits.frac0 == 0 && u.u.bits.frac1 == 0))
150 u.u.bits.exp++;
151 #else
152 else if (u.u.bits.exp == 0 && u.u.bits.frac != 0)
153 u.u.bits.exp++;
154 #endif
156 return u.u.flt;
159 #define NSPECIALS 10
161 float gen_special_float(int i)
163 FP_DECL_EX;
164 FP_DECL_S(X);
165 float x;
167 switch (i & ~1)
169 case 0:
170 X_c = FP_CLS_NAN; X_f = 0x1234;
171 break;
172 case 2:
173 X_c = FP_CLS_NAN; X_f = 0x1;
174 break;
175 case 4:
176 X_c = FP_CLS_INF;
177 break;
178 case 6:
179 X_c = FP_CLS_ZERO;
180 break;
181 case 8:
182 X_c = FP_CLS_NORMAL; X_e = 0;
183 X_f = 0x4321;
184 break;
186 X_s = (i & 1);
188 FP_PACK_S(x, X);
189 return x;
192 double gen_special_double(int i)
194 FP_DECL_EX;
195 FP_DECL_D(X);
196 double x;
198 switch (i & ~1)
200 case 0:
201 X_c = FP_CLS_NAN;
202 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
203 __FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1234);
204 #else
205 _FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1234);
206 #endif
207 break;
208 case 2:
209 X_c = FP_CLS_NAN;
210 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
211 __FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1);
212 #else
213 _FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1);
214 #endif
215 break;
216 case 4:
217 X_c = FP_CLS_INF;
218 break;
219 case 6:
220 X_c = FP_CLS_ZERO;
221 break;
222 case 8:
223 X_c = FP_CLS_NORMAL; X_e = 0;
224 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
225 __FP_FRAC_SET_2(X, 0, 0x87654321);
226 #else
227 _FP_FRAC_SET_1(X, 0x87654321);
228 #endif
229 break;
231 X_s = (i & 1);
233 FP_PACK_D(x, X);
234 return x;
237 float build_float(const char *s, const char *e, const char *f)
239 union _FP_UNION_S u;
241 u.bits.sign = strtoul(s, 0, 16);
242 u.bits.exp = strtoul(e, 0, 16);
243 u.bits.frac = strtoul(f, 0, 16);
245 return u.flt;
248 double build_double(const char *s, const char *e, const char *f)
250 union _FP_UNION_D u;
252 u.bits.sign = strtoul(s, 0, 16);
253 u.bits.exp = strtoul(e, 0, 16);
254 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
256 size_t len = strlen(f)+1;
257 char *dup = memcpy(alloca(len), f, len);
258 char *low = dup + len - _FP_W_TYPE_SIZE/4 - 1;
260 u.bits.frac0 = strtoul(low, 0, 16);
261 *low = 0;
262 u.bits.frac1 = strtoul(dup, 0, 16);
264 #else
265 u.bits.frac = strtoul(f, 0, 16);
266 #endif
268 return u.flt;
271 /*======================================================================*/
273 fpu_control_t fcw0, fcw1;
275 void test_float_arith(float (*tf)(float, float),
276 float (*rf)(float, float),
277 float x, float y)
279 float tr, rr;
280 rr = (*rf)(x, y);
281 tr = (*tf)(x, y);
282 if (memcmp(&tr, &rr, sizeof(float)) != 0)
284 fputs("error:\n\tx = ", stdout); print_float(x);
285 fputs("\n\ty = ", stdout); print_float(y);
286 fputs("\n\ttrue = ", stdout); print_float(rr);
287 fputs("\n\tfalse = ", stdout); print_float(tr);
288 putchar('\n');
292 void test_double_arith(double (*tf)(double, double),
293 double (*rf)(double, double),
294 double x, double y)
296 double tr, rr;
297 #ifdef __i386__
298 /* Don't worry. Even this does not make it error free
299 on ia32. If the result is denormal, it will not
300 honour the double precision and generate bad results
301 anyway. On the other side, who wants to use ia32
302 for IEEE math? I don't. */
303 _FPU_GETCW(fcw0);
304 fcw1 = ((fcw0 & ~_FPU_EXTENDED) | _FPU_DOUBLE);
305 _FPU_SETCW(fcw1);
306 #endif
307 rr = (*rf)(x, y);
308 #ifdef __i386__
309 _FPU_SETCW(fcw0);
310 #endif
311 tr = (*tf)(x, y);
312 if (memcmp(&tr, &rr, sizeof(double)) != 0)
314 fputs("error:\n\tx = ", stdout); print_double(x);
315 fputs("\n\ty = ", stdout); print_double(y);
316 fputs("\n\ttrue = ", stdout); print_double(rr);
317 fputs("\n\tfalse = ", stdout); print_double(tr);
318 putchar('\n');
322 void test_float_double_conv(float x)
324 double tr, rr;
325 rr = r_extendsfdf2(x);
326 tr = __extendsfdf2(x);
327 if (memcmp(&tr, &rr, sizeof(double)) != 0)
329 fputs("error:\n\tx = ", stdout); print_float(x);
330 fputs("\n\ttrue = ", stdout); print_double(rr);
331 fputs("\n\tfalse = ", stdout); print_double(tr);
332 putchar('\n');
336 void test_double_float_conv(double x)
338 float tr, rr;
339 rr = r_truncdfsf2(x);
340 tr = __truncdfsf2(x);
341 if (memcmp(&tr, &rr, sizeof(float)) != 0)
343 fputs("error:\n\tx = ", stdout); print_double(x);
344 fputs("\n\ttrue = ", stdout); print_float(rr);
345 fputs("\n\tfalse = ", stdout); print_float(tr);
346 putchar('\n');
350 void test_int_float_conv(int x)
352 float tr, rr;
353 rr = r_floatsisf(x);
354 tr = __floatsisf(x);
355 if (memcmp(&tr, &rr, sizeof(float)) != 0)
357 printf("error\n\tx = %d", x);
358 fputs("\n\ttrue = ", stdout); print_float(rr);
359 fputs("\n\tfalse = ", stdout); print_float(tr);
360 putchar('\n');
364 void test_int_double_conv(int x)
366 double tr, rr;
367 rr = r_floatsidf(x);
368 tr = __floatsidf(x);
369 if (memcmp(&tr, &rr, sizeof(double)) != 0)
371 printf("error\n\tx = %d", x);
372 fputs("\n\ttrue = ", stdout); print_double(rr);
373 fputs("\n\tfalse = ", stdout); print_double(tr);
374 putchar('\n');
378 void test_float_int_conv(float x)
380 int tr, rr;
381 rr = r_fixsfsi(x);
382 tr = __fixsfsi(x);
383 if (rr != tr)
385 fputs("error:\n\tx = ", stdout); print_float(x);
386 printf("\n\ttrue = %d\n\tfalse = %d\n", rr, tr);
390 void test_double_int_conv(double x)
392 int tr, rr;
393 rr = r_fixsfsi(x);
394 tr = __fixsfsi(x);
395 if (rr != tr)
397 fputs("error:\n\tx = ", stdout); print_double(x);
398 printf("\n\ttrue = %d\n\tfalse = %d\n", rr, tr);
402 int eq0(int x) { return x == 0; }
403 int ne0(int x) { return x != 0; }
404 int le0(int x) { return x <= 0; }
405 int lt0(int x) { return x < 0; }
406 int ge0(int x) { return x >= 0; }
407 int gt0(int x) { return x > 0; }
409 void test_float_cmp(int (*tf)(float, float),
410 int (*rf)(float, float),
411 int (*cmp0)(int),
412 float x, float y)
414 int tr, rr;
415 rr = (*rf)(x, y);
416 tr = (*tf)(x, y);
417 if (cmp0(rr) != cmp0(tr))
419 fputs("error:\n\tx = ", stdout); print_float(x);
420 fputs("\n\ty = ", stdout); print_float(y);
421 printf("\n\ttrue = %d\n\tfalse = %d\n", rr, tr);
425 void test_double_cmp(int (*tf)(double, double),
426 int (*rf)(double, double),
427 int (*cmp0)(int),
428 double x, double y)
430 int tr, rr;
431 rr = (*rf)(x, y);
432 tr = (*tf)(x, y);
433 if (cmp0(rr) != cmp0(tr))
435 fputs("error:\n\tx = ", stdout); print_double(x);
436 fputs("\n\ty = ", stdout); print_double(y);
437 printf("\n\ttrue = %d\n\tfalse = %d\n", rr, tr);
442 /*======================================================================*/
445 int main(int ac, char **av)
447 #ifdef __alpha__
448 __ieee_set_fp_control(0);
449 #endif
450 av++, ac--;
451 switch (*(*av)++)
454 float (*r)(float, float);
455 float (*t)(float, float);
457 do {
458 case 'a': r = r_addsf3; t = __addsf3; break;
459 case 's': r = r_subsf3; t = __subsf3; break;
460 case 'm': r = r_mulsf3; t = __mulsf3; break;
461 case 'd': r = r_divsf3; t = __divsf3; break;
462 case 'r': r = r_sqrtsf3; t = __sqrtsf3; break;
463 case 'j': r = r_negsf3; t = __negsf3; break;
464 } while (0);
466 switch (*(*av)++)
468 case 'n':
470 int count = (ac > 1 ? atoi(av[1]) : 100);
471 while (count--)
472 test_float_arith(t, r, rand_float(), rand_float());
474 break;
476 case 's':
478 int i, j;
479 for (i = 0; i < NSPECIALS; i++)
480 for (j = 0; j < NSPECIALS; j++)
481 test_float_arith(t, r, gen_special_float(i),
482 gen_special_float(j));
484 break;
486 case 0:
487 if (ac < 7) abort();
488 test_float_arith(t, r, build_float(av[1], av[2], av[3]),
489 build_float(av[4], av[5], av[6]));
490 break;
493 break;
496 double (*r)(double, double);
497 double (*t)(double, double);
499 do {
500 case 'A': r = r_adddf3; t = __adddf3; break;
501 case 'S': r = r_subdf3; t = __subdf3; break;
502 case 'M': r = r_muldf3; t = __muldf3; break;
503 case 'D': r = r_divdf3; t = __divdf3; break;
504 case 'R': r = r_sqrtdf3; t = __sqrtdf3; break;
505 case 'J': r = r_negdf3; t = __negdf3; break;
506 } while (0);
508 switch (*(*av)++)
510 case 'n':
512 int count = (ac > 1 ? atoi(av[1]) : 100);
513 while (count--)
514 test_double_arith(t, r, rand_double(), rand_double());
516 break;
518 case 's':
520 int i, j;
521 for (i = 0; i < NSPECIALS; i++)
522 for (j = 0; j < NSPECIALS; j++)
523 test_double_arith(t, r, gen_special_double(i),
524 gen_special_double(j));
526 break;
528 case 0:
529 if (ac < 7) abort();
530 test_double_arith(t, r, build_double(av[1], av[2], av[3]),
531 build_double(av[4], av[5], av[6]));
532 break;
535 break;
537 case 'c':
538 switch (*(*av)++)
540 case 'n':
542 int count = (ac > 1 ? atoi(av[1]) : 100);
543 while (count--)
544 test_float_double_conv(rand_float());
546 break;
548 case 's':
550 int i;
551 for (i = 0; i < NSPECIALS; i++)
552 test_float_double_conv(gen_special_float(i));
554 break;
556 case 0:
557 if (ac < 4) abort();
558 test_float_double_conv(build_float(av[1], av[2], av[3]));
559 break;
561 break;
563 case 'C':
564 switch (*(*av)++)
566 case 'n':
568 int count = (ac > 1 ? atoi(av[1]) : 100);
569 while (count--)
570 test_double_float_conv(rand_double());
572 break;
574 case 's':
576 int i;
577 for (i = 0; i < NSPECIALS; i++)
578 test_double_float_conv(gen_special_double(i));
580 break;
582 case 0:
583 if (ac < 4) abort();
584 test_double_float_conv(build_double(av[1], av[2], av[3]));
585 break;
587 break;
589 case 'i':
590 switch (*(*av)++)
592 case 'n':
594 int count = (ac > 1 ? atoi(av[1]) : 100);
595 while (count--)
596 test_int_float_conv(lrand48() << 1);
598 break;
600 case 0:
601 if (ac < 2) abort();
602 test_int_float_conv(strtol(av[1], 0, 0));
603 break;
605 break;
607 case 'I':
608 switch (*(*av)++)
610 case 'n':
612 int count = (ac > 1 ? atoi(av[1]) : 100);
613 while (count--)
614 test_int_double_conv(lrand48() << 1);
616 break;
618 case 0:
619 if (ac < 2) abort();
620 test_int_double_conv(strtol(av[1], 0, 0));
621 break;
623 break;
625 case 'f':
626 switch (*(*av)++)
628 case 'n':
630 int count = (ac > 1 ? atoi(av[1]) : 100);
631 while (count--)
632 test_float_int_conv(rand_float());
634 break;
636 case 's':
638 int i;
639 for (i = 0; i < NSPECIALS; i++)
640 test_float_int_conv(gen_special_float(i));
642 break;
644 case 0:
645 if (ac < 4) abort();
646 test_float_int_conv(build_float(av[1], av[2], av[3]));
647 break;
649 break;
651 case 'F':
652 switch (*(*av)++)
654 case 'n':
656 int count = (ac > 1 ? atoi(av[1]) : 100);
657 while (count--)
658 test_double_int_conv(rand_double());
660 break;
662 case 's':
664 int i;
665 for (i = 0; i < NSPECIALS; i++)
666 test_double_int_conv(gen_special_double(i));
668 break;
670 case 0:
671 if (ac < 4) abort();
672 test_double_int_conv(build_double(av[1], av[2], av[3]));
673 break;
675 break;
678 int (*r)(float, float);
679 int (*t)(float, float);
680 int (*c)(int);
682 do {
683 case 'e': r = r_eqsf2; t = __eqsf2; c = eq0; break;
684 case 'n': r = r_nesf2; t = __nesf2; c = ne0; break;
685 case 'l':
686 switch (*(*av)++)
688 case 'e': r = r_lesf2; t = __lesf2; c = le0; break;
689 case 't': r = r_ltsf2; t = __ltsf2; c = lt0; break;
691 break;
692 case 'g':
693 switch (*(*av)++)
695 case 'e': r = r_gesf2; t = __gesf2; c = ge0; break;
696 case 't': r = r_gtsf2; t = __gtsf2; c = gt0; break;
698 break;
699 } while (0);
701 switch (*(*av)++)
703 case 'n':
705 int count = (ac > 1 ? atoi(av[1]) : 100);
706 while (count--)
707 test_float_cmp(t, r, c, rand_float(), rand_float());
709 break;
711 case 's':
713 int i, j;
714 for (i = 0; i < NSPECIALS; i++)
715 for (j = 0; j < NSPECIALS; j++)
716 test_float_cmp(t, r, c, gen_special_float(i),
717 gen_special_float(j));
719 break;
721 case 0:
722 if (ac < 7) abort();
723 test_float_cmp(t, r, c, build_float(av[1], av[2], av[3]),
724 build_float(av[4], av[5], av[6]));
725 break;
728 break;
731 int (*r)(double, double);
732 int (*t)(double, double);
733 int (*c)(int);
735 do {
736 case 'E': r = r_eqdf2; t = __eqdf2; c = eq0; break;
737 case 'N': r = r_nedf2; t = __nedf2; c = ne0; break;
738 case 'L':
739 switch (*(*av)++)
741 case 'E': r = r_ledf2; t = __ledf2; c = le0; break;
742 case 'T': r = r_ltdf2; t = __ltdf2; c = lt0; break;
744 break;
745 case 'G':
746 switch (*(*av)++)
748 case 'E': r = r_gedf2; t = __gedf2; c = ge0; break;
749 case 'T': r = r_gtdf2; t = __gtdf2; c = gt0; break;
751 break;
752 } while (0);
754 switch (*(*av)++)
756 case 'n':
758 int count = (ac > 1 ? atoi(av[1]) : 100);
759 while (count--)
760 test_double_cmp(t, r, c, rand_double(), rand_double());
762 break;
764 case 's':
766 int i, j;
767 for (i = 0; i < NSPECIALS; i++)
768 for (j = 0; j < NSPECIALS; j++)
769 test_double_cmp(t, r, c, gen_special_double(i),
770 gen_special_double(j));
772 break;
774 case 0:
775 if (ac < 7) abort();
776 test_double_cmp(t, r, c, build_double(av[1], av[2], av[3]),
777 build_double(av[4], av[5], av[6]));
778 break;
781 break;
783 default:
784 abort();
787 return 0;