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);
__negdf3(double a,double dummy)20 double __negdf3(double a, double dummy) { return __negdf2(a); }
__sqrtdf3(double a,double dummy)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);
__negsf3(float a,float dummy)29 float __negsf3(float a, float dummy) { return __negsf2(a); }
__sqrtsf3(float a,float dummy)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 
r_adddf3(double a,double b)56 double r_adddf3(double a, double b) { return a + b; }
r_subdf3(double a,double b)57 double r_subdf3(double a, double b) { return a - b; }
r_muldf3(double a,double b)58 double r_muldf3(double a, double b) { return a * b; }
r_divdf3(double a,double b)59 double r_divdf3(double a, double b) { return a / b; }
r_negdf3(double a,double b)60 double r_negdf3(double a, double b) { return -a; }
61 double sqrt(double x);
r_sqrtdf3(double a,double b)62 double r_sqrtdf3(double a, double b) { return sqrt(a); }
63 
r_addsf3(float a,float b)64 float r_addsf3(float a, float b) { return a + b; }
r_subsf3(float a,float b)65 float r_subsf3(float a, float b) { return a - b; }
r_mulsf3(float a,float b)66 float r_mulsf3(float a, float b) { return a * b; }
r_divsf3(float a,float b)67 float r_divsf3(float a, float b) { return a / b; }
r_negsf3(float a,float b)68 float r_negsf3(float a, float b) { return -a; }
69 float sqrtf(float x);
r_sqrtsf3(float a,float b)70 float r_sqrtsf3(float a, float b) { return sqrtf(a); }
71 
r_fixdfsi(double a)72 int r_fixdfsi(double a) { return (int)a; }
r_fixsfsi(float a)73 int r_fixsfsi(float a) { return (int)a; }
r_floatsidf(int a)74 double r_floatsidf(int a) { return (double)a; }
r_floatsisf(int a)75 float r_floatsisf(int a) { return (float)a; }
r_extendsfdf2(float a)76 double r_extendsfdf2(float a) { return (double)a; }
r_truncdfsf2(double a)77 float r_truncdfsf2(double a) { return (float)a; }
78 
r_eqdf2(double a,double b)79 int r_eqdf2(double a, double b) { return !(a == b); }
r_nedf2(double a,double b)80 int r_nedf2(double a, double b) { return a != b; }
r_gtdf2(double a,double b)81 int r_gtdf2(double a, double b) { return a > b; }
r_gedf2(double a,double b)82 int r_gedf2(double a, double b) { return (a >= b) - 1; }
r_ltdf2(double a,double b)83 int r_ltdf2(double a, double b) { return -(a < b); }
r_ledf2(double a,double b)84 int r_ledf2(double a, double b) { return 1 - (a <= b); }
85 
r_eqsf2(float a,float b)86 int r_eqsf2(float a, float b) { return !(a == b); }
r_nesf2(float a,float b)87 int r_nesf2(float a, float b) { return a != b; }
r_gtsf2(float a,float b)88 int r_gtsf2(float a, float b) { return a > b; }
r_gesf2(float a,float b)89 int r_gesf2(float a, float b) { return (a >= b) - 1; }
r_ltsf2(float a,float b)90 int r_ltsf2(float a, float b) { return -(a < b); }
r_lesf2(float a,float b)91 int r_lesf2(float a, float b) { return 1 - (a <= b); }
92 
93 /*======================================================================*/
94 
print_float(float x)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 
print_double(double x)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 
rand_float(void)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 
rand_double(void)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 
gen_special_float(int i)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 
gen_special_double(int i)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 
build_float(const char * s,const char * e,const char * f)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 
build_double(const char * s,const char * e,const char * f)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 
test_float_arith(float (* tf)(float,float),float (* rf)(float,float),float x,float y)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 
test_double_arith(double (* tf)(double,double),double (* rf)(double,double),double x,double y)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 
test_float_double_conv(float x)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 
test_double_float_conv(double x)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 
test_int_float_conv(int x)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 
test_int_double_conv(int x)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 
test_float_int_conv(float x)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 
test_double_int_conv(double x)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 
eq0(int x)402 int eq0(int x) { return x == 0; }
ne0(int x)403 int ne0(int x) { return x != 0; }
le0(int x)404 int le0(int x) { return x <= 0; }
lt0(int x)405 int lt0(int x) { return x < 0; }
ge0(int x)406 int ge0(int x) { return x >= 0; }
gt0(int x)407 int gt0(int x) { return x > 0; }
408 
test_float_cmp(int (* tf)(float,float),int (* rf)(float,float),int (* cmp0)(int),float x,float y)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 
test_double_cmp(int (* tf)(double,double),int (* rf)(double,double),int (* cmp0)(int),double x,double y)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 
main(int ac,char ** av)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 }
789