soft-fp: make __unord* raise "invalid" for signaling NaNs (bug 16036).
[jlayton/glibc.git] / soft-fp / testit.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4
5 #include "soft-fp.h"
6 #include "single.h"
7 #include "double.h"
8
9 #include <fpu_control.h>
10
11 /*======================================================================*/
12 /* declarations for the functions we are testing */
13
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); }
22
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); }
31
32 int __fixdfsi(double);
33 int __fixsfsi(float);
34 double __floatsidf(int);
35 float __floatsisf(int);
36 double __extendsfdf2(float);
37 float __truncdfsf2(double);
38
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);
45
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);
52
53 /*======================================================================*/
54 /* definitions for functions we are checking against */
55
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); }
63
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); }
71
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; }
78
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); }
85
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); }
92
93 /*======================================================================*/
94
95 void print_float(float x)
96 {
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);
101 }
102
103 void print_double(double x)
104 {
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
116 }
117
118 float rand_float(void)
119 {
120     union {
121         union _FP_UNION_S u;
122         int i;
123     } u;
124
125     u.i = lrand48() << 1;
126
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++;
131
132     return u.u.flt;
133 }
134
135
136 double rand_double(void)
137 {
138     union {
139         union _FP_UNION_D u;
140         int i[2];
141     } u;
142
143     u.i[0] = lrand48() << 1;
144     u.i[1] = lrand48() << 1;
145
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
155
156     return u.u.flt;
157 }
158
159 #define NSPECIALS  10
160
161 float gen_special_float(int i)
162 {
163     FP_DECL_EX;
164     FP_DECL_S(X);
165     float x;
166
167     switch (i & ~1)
168     {
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;
185     }
186     X_s = (i & 1);
187
188     FP_PACK_S(x, X);
189     return x;
190 }
191
192 double gen_special_double(int i)
193 {
194     FP_DECL_EX;
195     FP_DECL_D(X);
196     double x;
197
198     switch (i & ~1)
199     {
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_QNANNEGATEDP ? 0 : _FP_QNANBIT_D, 0x1234);
204 #else
205         _FP_FRAC_SET_1(X, (_FP_QNANNEGATEDP ? 0 : _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_QNANNEGATEDP ? 0 : _FP_QNANBIT_D, 0x1);
212 #else
213         _FP_FRAC_SET_1(X, (_FP_QNANNEGATEDP ? 0 : _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;
230     }
231     X_s = (i & 1);
232
233     FP_PACK_D(x, X);
234     return x;
235 }
236
237 float build_float(const char *s, const char *e, const char *f)
238 {
239     union _FP_UNION_S u;
240
241     u.bits.sign = strtoul(s, 0, 16);
242     u.bits.exp = strtoul(e, 0, 16);
243     u.bits.frac = strtoul(f, 0, 16);
244
245     return u.flt;
246 }
247
248 double build_double(const char *s, const char *e, const char *f)
249 {
250     union _FP_UNION_D u;
251
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
255     {
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;
259
260         u.bits.frac0 = strtoul(low, 0, 16);
261         *low = 0;
262         u.bits.frac1 = strtoul(dup, 0, 16);
263     }
264 #else
265     u.bits.frac = strtoul(f, 0, 16);
266 #endif
267
268     return u.flt;
269 }
270
271 /*======================================================================*/
272
273 fpu_control_t fcw0, fcw1;
274
275 void test_float_arith(float (*tf)(float, float),
276                       float (*rf)(float, float),
277                       float x, float y)
278 {
279     float tr, rr;
280     rr = (*rf)(x, y);
281     tr = (*tf)(x, y);
282     if (memcmp(&tr, &rr, sizeof(float)) != 0)
283     {
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');
289     }
290 }
291
292 void test_double_arith(double (*tf)(double, double),
293                        double (*rf)(double, double),
294                        double x, double y)
295 {
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)
313     {
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');
319     }
320 }
321
322 void test_float_double_conv(float x)
323 {
324     double tr, rr;
325     rr = r_extendsfdf2(x);
326     tr = __extendsfdf2(x);
327     if (memcmp(&tr, &rr, sizeof(double)) != 0)
328     {
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');
333     }
334 }
335
336 void test_double_float_conv(double x)
337 {
338     float tr, rr;
339     rr = r_truncdfsf2(x);
340     tr = __truncdfsf2(x);
341     if (memcmp(&tr, &rr, sizeof(float)) != 0)
342     {
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');
347     }
348 }
349
350 void test_int_float_conv(int x)
351 {
352     float tr, rr;
353     rr = r_floatsisf(x);
354     tr = __floatsisf(x);
355     if (memcmp(&tr, &rr, sizeof(float)) != 0)
356     {
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');
361     }
362 }
363
364 void test_int_double_conv(int x)
365 {
366     double tr, rr;
367     rr = r_floatsidf(x);
368     tr = __floatsidf(x);
369     if (memcmp(&tr, &rr, sizeof(double)) != 0)
370     {
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');
375     }
376 }
377
378 void test_float_int_conv(float x)
379 {
380     int tr, rr;
381     rr = r_fixsfsi(x);
382     tr = __fixsfsi(x);
383     if (rr != tr)
384     {
385         fputs("error:\n\tx     = ", stdout); print_float(x);
386         printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
387     }
388 }
389
390 void test_double_int_conv(double x)
391 {
392     int tr, rr;
393     rr = r_fixsfsi(x);
394     tr = __fixsfsi(x);
395     if (rr != tr)
396     {
397         fputs("error:\n\tx     = ", stdout); print_double(x);
398         printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
399     }
400 }
401
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; }
408
409 void test_float_cmp(int (*tf)(float, float),
410                     int (*rf)(float, float),
411                     int (*cmp0)(int),
412                     float x, float y)
413 {
414     int tr, rr;
415     rr = (*rf)(x, y);
416     tr = (*tf)(x, y);
417     if (cmp0(rr) != cmp0(tr))
418     {
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);
422     }
423 }
424
425 void test_double_cmp(int (*tf)(double, double),
426                      int (*rf)(double, double),
427                      int (*cmp0)(int),
428                      double x, double y)
429 {
430     int tr, rr;
431     rr = (*rf)(x, y);
432     tr = (*tf)(x, y);
433     if (cmp0(rr) != cmp0(tr))
434     {
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);
438     }
439 }
440
441
442 /*======================================================================*/
443
444
445 int main(int ac, char **av)
446 {
447 #ifdef __alpha__
448     __ieee_set_fp_control(0);
449 #endif
450     av++, ac--;
451     switch (*(*av)++)
452     {
453         {
454             float (*r)(float, float);
455             float (*t)(float, float);
456
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);
465
466             switch (*(*av)++)
467             {
468               case 'n':
469                 {
470                     int count = (ac > 1 ? atoi(av[1]) : 100);
471                     while (count--)
472                         test_float_arith(t, r, rand_float(), rand_float());
473                 }
474                 break;
475
476               case 's':
477                 {
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));
483                 }
484                 break;
485
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;
491             }
492         }
493         break;
494
495         {
496             double (*r)(double, double);
497             double (*t)(double, double);
498
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);
507
508             switch (*(*av)++)
509             {
510               case 'n':
511                 {
512                     int count = (ac > 1 ? atoi(av[1]) : 100);
513                     while (count--)
514                         test_double_arith(t, r, rand_double(), rand_double());
515                 }
516                 break;
517
518               case 's':
519                 {
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));
525                 }
526                 break;
527
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;
533             }
534         }
535         break;
536
537       case 'c':
538         switch (*(*av)++)
539         {
540           case 'n':
541             {
542                 int count = (ac > 1 ? atoi(av[1]) : 100);
543                 while (count--)
544                     test_float_double_conv(rand_float());
545             }
546             break;
547
548           case 's':
549             {
550                 int i;
551                 for (i = 0; i < NSPECIALS; i++)
552                     test_float_double_conv(gen_special_float(i));
553             }
554             break;
555
556           case 0:
557             if (ac < 4) abort();
558             test_float_double_conv(build_float(av[1], av[2], av[3]));
559             break;
560         }
561         break;
562
563       case 'C':
564         switch (*(*av)++)
565         {
566           case 'n':
567             {
568                 int count = (ac > 1 ? atoi(av[1]) : 100);
569                 while (count--)
570                     test_double_float_conv(rand_double());
571             }
572             break;
573
574           case 's':
575             {
576                 int i;
577                 for (i = 0; i < NSPECIALS; i++)
578                     test_double_float_conv(gen_special_double(i));
579             }
580             break;
581
582           case 0:
583             if (ac < 4) abort();
584             test_double_float_conv(build_double(av[1], av[2], av[3]));
585             break;
586         }
587         break;
588
589       case 'i':
590         switch (*(*av)++)
591         {
592           case 'n':
593             {
594                 int count = (ac > 1 ? atoi(av[1]) : 100);
595                 while (count--)
596                     test_int_float_conv(lrand48() << 1);
597             }
598             break;
599
600           case 0:
601             if (ac < 2) abort();
602             test_int_float_conv(strtol(av[1], 0, 0));
603             break;
604         }
605         break;
606
607       case 'I':
608         switch (*(*av)++)
609         {
610           case 'n':
611             {
612                 int count = (ac > 1 ? atoi(av[1]) : 100);
613                 while (count--)
614                     test_int_double_conv(lrand48() << 1);
615             }
616             break;
617
618           case 0:
619             if (ac < 2) abort();
620             test_int_double_conv(strtol(av[1], 0, 0));
621             break;
622         }
623         break;
624
625       case 'f':
626         switch (*(*av)++)
627         {
628           case 'n':
629             {
630                 int count = (ac > 1 ? atoi(av[1]) : 100);
631                 while (count--)
632                     test_float_int_conv(rand_float());
633             }
634             break;
635
636           case 's':
637             {
638                 int i;
639                 for (i = 0; i < NSPECIALS; i++)
640                     test_float_int_conv(gen_special_float(i));
641             }
642             break;
643
644           case 0:
645             if (ac < 4) abort();
646             test_float_int_conv(build_float(av[1], av[2], av[3]));
647             break;
648         }
649         break;
650
651       case 'F':
652         switch (*(*av)++)
653         {
654           case 'n':
655             {
656                 int count = (ac > 1 ? atoi(av[1]) : 100);
657                 while (count--)
658                     test_double_int_conv(rand_double());
659             }
660             break;
661
662           case 's':
663             {
664                 int i;
665                 for (i = 0; i < NSPECIALS; i++)
666                     test_double_int_conv(gen_special_double(i));
667             }
668             break;
669
670           case 0:
671             if (ac < 4) abort();
672             test_double_int_conv(build_double(av[1], av[2], av[3]));
673             break;
674         }
675         break;
676
677         {
678             int (*r)(float, float);
679             int (*t)(float, float);
680             int (*c)(int);
681
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)++)
687                 {
688                   case 'e': r = r_lesf2; t = __lesf2; c = le0; break;
689                   case 't': r = r_ltsf2; t = __ltsf2; c = lt0; break;
690                 }
691                 break;
692               case 'g':
693                 switch (*(*av)++)
694                 {
695                   case 'e': r = r_gesf2; t = __gesf2; c = ge0; break;
696                   case 't': r = r_gtsf2; t = __gtsf2; c = gt0; break;
697                 }
698                 break;
699             } while (0);
700
701             switch (*(*av)++)
702             {
703               case 'n':
704                 {
705                     int count = (ac > 1 ? atoi(av[1]) : 100);
706                     while (count--)
707                         test_float_cmp(t, r, c, rand_float(), rand_float());
708                 }
709                 break;
710
711               case 's':
712                 {
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));
718                 }
719                 break;
720
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;
726             }
727         }
728         break;
729
730         {
731             int (*r)(double, double);
732             int (*t)(double, double);
733             int (*c)(int);
734
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)++)
740                 {
741                   case 'E': r = r_ledf2; t = __ledf2; c = le0; break;
742                   case 'T': r = r_ltdf2; t = __ltdf2; c = lt0; break;
743                 }
744                 break;
745               case 'G':
746                 switch (*(*av)++)
747                 {
748                   case 'E': r = r_gedf2; t = __gedf2; c = ge0; break;
749                   case 'T': r = r_gtdf2; t = __gtdf2; c = gt0; break;
750                 }
751                 break;
752             } while (0);
753
754             switch (*(*av)++)
755             {
756               case 'n':
757                 {
758                     int count = (ac > 1 ? atoi(av[1]) : 100);
759                     while (count--)
760                         test_double_cmp(t, r, c, rand_double(), rand_double());
761                 }
762                 break;
763
764               case 's':
765                 {
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));
771                 }
772                 break;
773
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;
779             }
780         }
781         break;
782
783       default:
784         abort();
785     }
786
787     return 0;
788 }