1 /*
2  * Copyright (c) 1994 Cygnus Support.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * and/or other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * at Cygnus Support, Inc.  Cygnus Support, Inc. may not be used to
11  * endorse or promote products derived from this software without
12  * specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 /*
18   Test the library maths functions using trusted precomputed test
19   vectors.
20 
21   These vectors were originally generated on a sun3 with a 68881 using
22   80 bit precision, but ...
23 
24   Each function is called with a variety of interesting arguments.
25   Note that many of the polynomials we use behave badly when the
26   domain is stressed, so the numbers in the vectors depend on what is
27   useful to test - eg sin(1e30) is pointless - the arg has to be
28   reduced modulo pi, and after that there's no bits of significance
29   left to evaluate with - any number would be just as precise as any
30   other.
31 
32 
33 */
34 
35 #include "test.h"
36 #include <math.h>
37 #include <float.h>
38 #include <errno.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <stdbool.h>
42 
43 #ifndef _IEEE_754_2008_SNAN
44 # define _IEEE_754_2008_SNAN 1
45 #endif
46 
47 extern int inacc;
48 
49 int merror;
50 double mretval = 64;
51 int traperror = 1;
52 char *mname;
53 
54 void
translate_to(FILE * file,double r)55 translate_to (FILE *file,
56 	    double r)
57 {
58   __ieee_double_shape_type bits;
59   bits.value = r;
60   fprintf(file, "0x%08lx, 0x%08lx", (unsigned long) bits.parts.msw, (unsigned long) bits.parts.lsw);
61 }
62 
63 double
64 thedouble (uint32_t msw,
65            uint32_t lsw, volatile double *r);
66 
67 /* Convert double to float, preserving issignaling status and NaN sign */
68 
69 #define to_float(f,d)	do {					\
70 		if (__issignaling(d)) {				\
71 			if (signbit(d))				\
72 				(f) = -__builtin_nansf("");	\
73 			else					\
74 				(f) =  __builtin_nansf("");	\
75 		} else if (isnan(d)) {				\
76 			if (signbit(d))				\
77 				(f) = -__builtin_nanf("");	\
78 			else					\
79 				(f) =  __builtin_nanf("");	\
80 		} else						\
81 			(f) = (float) (d);			\
82 	} while(0)
83 
84 #define to_double(d,f)	do {					\
85 		if (__issignalingf(f)) {				\
86 			if (signbit(f))				\
87 				(d) = -__builtin_nans("");	\
88 			else					\
89 				(d) =  __builtin_nans("");	\
90 		} else if (isnanf(f)) {				\
91 			if (signbit(f))				\
92 				(d) = -__builtin_nan("");	\
93 			else					\
94 				(d) =  __builtin_nan("");	\
95 		} else						\
96 			(d) = (double) (f);			\
97 	} while(0)
98 
99 int
ffcheck_id(double is,one_line_type * p,char * name,int serrno,int merror,int id)100 ffcheck_id(double is,
101 	   one_line_type *p,
102 	   char *name,
103 	   int serrno,
104 	   int merror,
105 	   int id)
106 {
107   /* Make sure the answer isn't to far wrong from the correct value */
108   __ieee_double_shape_type correct = {}, isbits;
109   int mag;
110   isbits.value = is;
111 
112   (void) serrno;
113   (void) merror;
114 
115   thedouble(p->qs[id].msw, p->qs[id].lsw, &correct.value);
116 
117   int error_bit = p->error_bit;
118 
119   mag = mag_of_error(correct.value, is);
120 
121   if (error_bit > 63)
122     error_bit = 63;
123 
124   /* All signaling nans are the "same", as are all quiet nans.
125    * On i386, just returning a value converts signaling nans to quiet
126    * nans, let that pass
127    */
128   if (isnan(correct.value) && isnan(is)
129 #if !defined(__i386__) && !defined(__HAVE_68881__)
130       && (issignaling(correct.value) == issignaling(is))
131 #endif
132     )
133   {
134     mag = 64;
135   }
136 
137   if (mag < error_bit)
138   {
139     inacc ++;
140 
141     printf("%s:%d, inaccurate answer: bit %d (%08lx%08lx %08lx%08lx) (%g %g)\n",
142 	   name,  p->line, mag,
143 	   (unsigned long) correct.parts.msw,
144 	   (unsigned long) correct.parts.lsw,
145 	   (unsigned long) isbits.parts.msw,
146 	   (unsigned long) isbits.parts.lsw,
147 	   correct.value, is);
148   }
149 
150 #if 0
151   if (p->qs[id].merror != merror)
152   {
153     /* Beware, matherr doesn't exist anymore.  */
154     printf("testing %s_vec.c:%d, matherr wrong: %d %d\n",
155 	   name, p->line, merror, p->qs[id].merror);
156   }
157 
158   if (p->qs[id].errno_val != errno)
159   {
160     printf("testing %s_vec.c:%d, errno wrong: %d %d\n",
161 	   name, p->line, errno, p->qs[id].errno_val);
162 
163   }
164 #endif
165   return mag;
166 }
167 
168 int
ffcheck(double is,one_line_type * p,char * name,int serrno,int merror)169 ffcheck(double is,
170 	one_line_type *p,
171 	char *name,
172 	int serrno,
173 	int merror)
174 {
175   return ffcheck_id(is, p, name, serrno, merror, 0);
176 }
177 
178 int
fffcheck_id(float is,one_line_type * p,char * name,int serrno,int merror,int id)179 fffcheck_id (float is,
180 	     one_line_type *p,
181 	     char *name,
182 	     int serrno,
183 	     int merror,
184 	     int id)
185 {
186   /* Make sure the answer isn't to far wrong from the correct value */
187   __ieee_float_shape_type correct, isbits;
188   __ieee_double_shape_type correct_double;
189   __ieee_double_shape_type is_double;
190   int mag;
191 
192   (void) serrno;
193   (void) merror;
194 
195   isbits.value = is;
196   to_double(is_double.value, is);
197 
198   thedouble(p->qs[id].msw,p->qs[id].lsw, &correct_double.value);
199 
200   to_float(correct.value, correct_double.value);
201 //  printf("%s got 0x%08x want 0x%08x\n", name, isbits.p1, correct.p1);
202 
203   int error_bit = p->error_bit;
204 
205   if (error_bit > 31)
206     error_bit = 31;
207 
208   mag = fmag_of_error(correct.value, is);
209 
210   /* All signaling nans are the "same", as are all quiet nans */
211   if (isnan(correct.value) && isnan(is)
212 #if !defined(__i386__) && !defined(__m68k__)
213       /* i386 calling convention ends up always converting snan into qnan */
214       && (__issignalingf(correct.value) == __issignalingf(is))
215 #endif
216 	  )
217   {
218 	mag = 32;
219   }
220 
221   if (mag < error_bit)
222   {
223     inacc ++;
224 
225     printf("%s:%d, inaccurate answer: bit %d (%08lx is %08lx) (%g is %g) (is double 0x%08lx, 0x%08lx)\n",
226 	   name,  p->line, mag,
227 	   (unsigned long) (uint32_t) correct.p1,
228 	   (unsigned long) (uint32_t) isbits.p1,
229 	   (double) correct.value,
230 	   (double) is,
231 	   (unsigned long) (uint32_t) is_double.parts.msw,
232 	   (unsigned long) (uint32_t) is_double.parts.lsw);
233   }
234 
235 #if 0
236   if (p->qs[id].merror != merror)
237   {
238     /* Beware, matherr doesn't exist anymore.  */
239     printf("testing %s_vec.c:%d, matherr wrong: %d %d\n",
240 	   name, p->line, merror, p->qs[id].merror);
241   }
242 
243   if (p->qs[id].errno_val != errno)
244   {
245     printf("testing %s_vec.c:%d, errno wrong: %d %d\n",
246 	   name, p->line, errno, p->qs[id].errno_val);
247 
248   }
249 #endif
250   return mag;
251 }
252 
253 int
fffcheck(float is,one_line_type * p,char * name,int serrno,int merror)254 fffcheck (float is,
255 	  one_line_type *p,
256 	  char *name,
257 	  int serrno,
258 	  int merror)
259 {
260   return fffcheck_id(is, p, name, serrno, merror, 0);
261 }
262 
263 static
volatile_memcpy(volatile void * dest,void * src,size_t len)264 volatile_memcpy(volatile void *dest, void *src, size_t len)
265 {
266     volatile uint8_t *d = dest;
267     uint8_t *s = src;
268     while (len--)
269         *d++ = *s++;
270 }
271 
272 double
thedouble(uint32_t msw,uint32_t lsw,volatile double * r)273 thedouble (uint32_t msw,
274   uint32_t lsw, volatile double *r)
275 {
276   __ieee_double_shape_type x;
277 
278   x.parts.msw = msw;
279   x.parts.lsw = lsw;
280 #if !_IEEE_754_2008_SNAN
281   if (isnan(x.value))
282       x.parts.msw ^= 0x000c0000;
283 #endif
284   if (r)
285     volatile_memcpy(r, &x.value, sizeof(double));
286   return x.value;
287 }
288 
289 int calc;
290 extern int reduce;
291 
292 
293 void
frontline(FILE * f,int mag,one_line_type * p,double result,int merror,int my_errno,char * args,char * name)294 frontline (FILE *f,
295        int mag,
296        one_line_type *p,
297        double result,
298        int merror,
299        int my_errno,
300        char *args,
301        char *name)
302 {
303   (void) name;
304   /* float returns can never have more than 32 bits of accuracy */
305   if (*args == 'f' && mag > 32)
306     mag = 32;
307 
308   if (reduce && p->error_bit < mag)
309   {
310     fprintf(f, "{%2d,", p->error_bit);
311   }
312   else
313   {
314     fprintf(f, "{%2d,",mag);
315   }
316 
317 
318   fprintf(f,"%2d,%3d,", merror,my_errno);
319   fprintf(f, "__LINE__, ");
320 
321   if (calc)
322   {
323     translate_to(f, result);
324   }
325   else
326   {
327     translate_to(f, thedouble(p->qs[0].msw, p->qs[0].lsw, NULL));
328   }
329 
330   fprintf(f, ", ");
331 
332   fprintf(f,"0x%08lx, 0x%08lx", (unsigned long) p->qs[1].msw, (unsigned long) p->qs[1].lsw);
333 
334 
335   if (args[2])
336   {
337     fprintf(f, ", ");
338     fprintf(f,"0x%08lx, 0x%08lx", (unsigned long) p->qs[2].msw, (unsigned long) p->qs[2].lsw);
339   }
340 
341   fprintf(f,"},	/* %g=f(%g",result,
342   	  thedouble(p->qs[1].msw, p->qs[1].lsw, NULL));
343 
344   if (args[2])
345   {
346     fprintf(f,", %g", thedouble(p->qs[2].msw,p->qs[2].lsw, NULL));
347   }
348   fprintf(f, ")*/\n");
349 }
350 
351 void
finish(FILE * f,int vector,double result,one_line_type * p,char * args,char * name)352 finish (FILE *f,
353        int vector,
354        double result,
355        one_line_type *p,
356        char *args,
357        char *name)
358 {
359   int mag;
360 
361   mag = ffcheck(result, p,name,  merror, errno);
362   (void) f;
363   (void) vector;
364   (void) args;
365   (void) mag;
366 #ifdef INCLUDE_GENERATE
367   if (vector)
368   {
369     frontline(f, mag, p, result, merror, errno, args , name);
370   }
371 #endif
372 }
373 
374 void
finish2(FILE * f,int vector,double result,double result2,one_line_type * p,char * args,char * name)375 finish2 (FILE *f,
376 	 int vector,
377 	 double result,
378 	 double result2,
379 	 one_line_type *p,
380 	 char *args,
381 	 char *name)
382 {
383   int mag, mag2;
384 
385   mag = ffcheck(result, p,name,  merror, errno);
386   mag2 = ffcheck_id(result2, p,name,  merror, errno, 2);
387   if (mag2 < mag)
388     mag = mag2;
389   (void) f;
390   (void) vector;
391   (void) mag;
392   (void) args;
393 #ifdef INCLUDE_GENERATE
394   if (vector)
395   {
396     __ieee_double_shape_type result2_double;
397     result2_double.value = result2;
398     p->qs[2].msw = result2_double.parts.msw;
399     p->qs[2].lsw = result2_double.parts.lsw;
400     frontline(f, mag, p, result, merror, errno, args , name);
401   }
402 #endif
403 }
404 
405 void
ffinish(FILE * f,int vector,float fresult,one_line_type * p,char * args,char * name)406 ffinish (FILE *f,
407        int vector,
408        float fresult,
409        one_line_type *p,
410        char *args,
411        char *name)
412 {
413   int mag;
414 
415   mag = fffcheck(fresult, p,name,  merror, errno);
416   (void) f;
417   (void) vector;
418   (void) args;
419   (void) mag;
420 #ifdef INCLUDE_GENERATE
421   if (vector)
422   {
423     frontline(f, mag, p, (double) fresult, merror, errno, args , name);
424   }
425 #endif
426 }
427 
428 void
ffinish2(FILE * f,int vector,float fresult,float fresult2,one_line_type * p,char * args,char * name)429 ffinish2 (FILE *f,
430 	  int vector,
431 	  float fresult,
432 	  float fresult2,
433 	  one_line_type *p,
434 	  char *args,
435 	  char *name)
436 {
437   int mag, mag2;
438 
439   mag = fffcheck(fresult, p,name,  merror, errno);
440   mag2 = fffcheck_id(fresult2, p, name, merror, errno, 2);
441   if (mag2 < mag)
442     mag = mag2;
443   (void) f;
444   (void) vector;
445   (void) args;
446   (void) mag;
447 #ifdef INCLUDE_GENERATE
448   if (vector)
449   {
450     __ieee_double_shape_type result2_double;
451     to_double(result2_double.value, (double) fresult2);
452     p->qs[2].msw = result2_double.parts.msw;
453     p->qs[2].lsw = result2_double.parts.lsw;
454     frontline(f, mag, p, (double) fresult, merror, errno, args , name);
455   }
456 #endif
457 }
458 
459 extern int redo;
460 
461 bool
in_float_range(double arg)462 in_float_range(double arg)
463 {
464 	if (isinf(arg) || isnan(arg))
465 		return true;
466 	return -(double) FLT_MAX <= arg && arg <= (double) FLT_MAX;
467 }
468 
469 void
run_vector_1(int vector,one_line_type * p,char * func,char * name,char * args)470 run_vector_1 (int vector,
471        one_line_type *p,
472        char *func,
473        char *name,
474        char *args)
475 {
476   FILE *f = NULL;
477   double result;
478   float fresult;
479 
480 #ifdef INCLUDE_GENERATE
481   if (vector)
482   {
483 
484     VECOPEN(name, f);
485 
486     if (redo)
487     {
488       double k;
489       union {
490 	struct { uint32_t a, b; };
491 	double d;
492       } d, d4;
493 
494       for (k = -.2; k < .2; k+= 0.00132)
495       {
496 	d.d = k;
497 	d4.d = k + 4;
498 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
499 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
500 
501       }
502 
503       for (k = -1.2; k < 1.2; k+= 0.01)
504       {
505 	d.d = k;
506 	d4.d = k + 4;
507 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
508 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
509 
510       }
511       for (k = -M_PI *2; k < M_PI *2; k+= M_PI/2)
512       {
513 	d.d = k;
514 	d4.d = k + 4;
515 	fprintf(f,"{1,1, 1,1, 0,0,0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
516 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
517 
518       }
519 
520       for (k = -30; k < 30; k+= 1.7)
521       {
522 	d.d = k;
523 	d4.d = k + 4;
524 	fprintf(f,"{2,2, 1,1, 0,0, 0x%08lx,0x%08lx, 0x%08lx, 0x%08lx},\n",
525 		(unsigned long) d.a, (unsigned long) d.b, (unsigned long) d4.a, (unsigned long) d4.b);
526 
527       }
528       VECCLOSE(f, name, args);
529       return;
530     }
531   }
532 #endif
533 
534   newfunc(name);
535   while (p->line)
536   {
537     volatile double arg1;
538     thedouble(p->qs[1].msw, p->qs[1].lsw, &arg1);
539     volatile double arg2;
540     thedouble(p->qs[2].msw, p->qs[2].lsw, &arg2);
541 
542     errno = 0;
543     merror = 0;
544     mname = 0;
545 
546 
547     line(p->line);
548 
549     merror = 0;
550     errno = 123;
551 
552     if (strcmp(args,"dd")==0)
553     {
554       typedef double (*pdblfunc) (double);
555 
556       /* Double function returning a double */
557 
558       result = ((pdblfunc)(func))(arg1);
559 
560       finish(f,vector, result, p, args, name);
561     }
562     else  if (strcmp(args,"ff")==0)
563     {
564       float arga;
565 
566       typedef float (*pdblfunc) (float);
567 
568       /* Double function returning a double */
569 
570       if (in_float_range(arg1))
571       {
572 	to_float(arga, arg1);
573 	fresult = ((pdblfunc)(func))(arga);
574 	ffinish(f, vector, fresult, p,args, name);
575       }
576     }
577     else if (strcmp(args,"ddd")==0)
578      {
579        typedef double (*pdblfunc) (double,double);
580 
581        result = ((pdblfunc)(func))(arg1,arg2);
582        finish(f, vector, result, p,args, name);
583      }
584      else  if (strcmp(args,"fff")==0)
585      {
586        volatile float arga;
587        volatile float argb;
588 
589        typedef float (*pdblfunc) (float,float);
590 
591        if (in_float_range(arg1) && in_float_range(arg2))
592        {
593 	 to_float(arga, arg1);
594 	 to_float(argb, arg2);
595 	 fresult = ((pdblfunc)(func))(arga, argb);
596 //	 printf("0x%08x = %s(0x%08x, 0x%08x)\n",
597 //		float_bits(fresult), name, float_bits(arga), float_bits(argb));
598 	 ffinish(f, vector, fresult, p,args, name);
599        }
600      }
601      else if (strcmp(args,"did")==0)
602      {
603        typedef double (*pdblfunc) (int,double);
604 
605        result = ((pdblfunc)(func))((int)arg1,arg2);
606        finish(f, vector, result, p,args, name);
607      }
608      else  if (strcmp(args,"fif")==0)
609      {
610        float argb;
611 
612        typedef float (*pdblfunc) (int,float);
613 
614 
615        if (in_float_range(arg2))
616        {
617 	 to_float(argb, arg2);
618 	 fresult = ((pdblfunc)(func))((int)arg1, argb);
619 	 ffinish(f, vector, fresult, p,args, name);
620        }
621      }
622      else if (strcmp(args,"id")==0)
623      {
624        typedef int (*pdblfunc)(double);
625 
626        result = (double) ((pdblfunc)(func))(arg1);
627        finish(f, vector, result, p, args, name);
628      }
629      else if (strcmp(args,"ddp") == 0)
630      {
631        typedef double (*pdblfunc)(double, double *);
632        double result2;
633 
634        result = (double) ((pdblfunc)(func))(arg1, &result2);
635        finish2(f, vector, result, result2, p, args, name);
636      }
637      else if (strcmp(args,"ffp") == 0)
638      {
639        typedef float (*pdblfunc)(float, float *);
640        float result2;
641 
642        fresult = (float) ((pdblfunc)(func))(arg1, &result2);
643        ffinish2(f, vector, fresult, result2, p, args, name);
644      }
645      else if (strcmp(args,"ddi") == 0)
646      {
647        typedef double (*pdblfunc)(double, int);
648 
649        result = ((pdblfunc)func) (arg1, (int) arg2);
650        finish(f, vector, result, p, args, name);
651      }
652      else if (strcmp(args,"ffi") == 0)
653      {
654        typedef float (*pdblfunc)(float, int);
655 
656        fresult = ((pdblfunc)func) (arg1, (int) arg2);
657        ffinish(f, vector, fresult, p, args, name);
658      }
659     p++;
660   }
661   if (vector && f)
662   {
663     VECCLOSE(f, name, args);
664   }
665 }
666 
667 void
test_math(int vector)668 test_math (int vector)
669 {
670   (void) vector;
671 #if TEST_PART == 0 || TEST_PART == -1
672   test_acos(vector);
673   test_acosf(vector);
674   test_acosh(vector);
675   test_acoshf(vector);
676   test_asin(vector);
677   test_asinf(vector);
678   test_asinh(vector);
679   test_asinhf(vector);
680   test_atan(vector);
681 #endif
682 #if TEST_PART > 0 || TEST_PART == -1
683   test_atan2(vector);
684   test_atan2f(vector);
685 #endif
686 #if TEST_PART == 0 || TEST_PART == -1
687   test_atanf(vector);
688   test_atanh(vector);
689   test_atanhf(vector);
690   test_ceil(vector);
691   test_ceilf(vector);
692   test_copysign(vector);
693   test_copysignf(vector);
694   test_cos(vector);
695   test_cosf(vector);
696   test_cosh(vector);
697   test_coshf(vector);
698   test_erf(vector);
699   test_erfc(vector);
700   test_erfcf(vector);
701   test_erff(vector);
702   test_exp(vector);
703   test_expf(vector);
704 #endif
705 #if TEST_PART == 1 || TEST_PART == -1
706   test_fabs(vector);
707   test_fabsf(vector);
708   test_floor(vector);
709   test_floorf(vector);
710   test_fmod(vector);
711   test_fmodf(vector);
712   test_gamma(vector);
713   test_gammaf(vector);
714   test_hypot(vector);
715   test_hypotf(vector);
716   test_issignaling(vector);
717   test_j0(vector);
718   test_j0f(vector);
719   test_j1(vector);
720   test_j1f(vector);
721   test_jn(vector);
722   test_jnf(vector);
723   test_log(vector);
724   test_log10(vector);
725   test_log10f(vector);
726   test_log1p(vector);
727   test_log1pf(vector);
728   test_log2(vector);
729   test_log2f(vector);
730   test_logf(vector);
731 #endif
732 #if TEST_PART == 2 || TEST_PART == -1
733   test_modf(vector);
734   test_modff(vector);
735   test_pow_vec(vector);
736   test_powf_vec(vector);
737   test_scalb(vector);
738   test_scalbf(vector);
739   test_scalbn(vector);
740   test_scalbnf(vector);
741   test_sin(vector);
742   test_sinf(vector);
743   test_sinh(vector);
744   test_sinhf(vector);
745   test_sqrt(vector);
746   test_sqrtf(vector);
747   test_tan(vector);
748   test_tanf(vector);
749   test_tanh(vector);
750   test_tanhf(vector);
751   test_trunc(vector);
752   test_truncf(vector);
753   test_y0(vector);
754   test_y0f(vector);
755   test_y1(vector);
756   test_y1f(vector);
757   test_y1f(vector);
758   test_ynf(vector);
759 #endif
760 }
761 
762 /* These have to be played with to get to compile on machines which
763    don't have the fancy <foo>f entry points
764 */
765 
766 #if 0
767 float cosf (float a) { return cos((double)a); }
768 float sinf (float  a) { return sin((double)a); }
769 float log1pf (float a) { return log1p((double)a); }
770 float tanf (float a) { return tan((double)a); }
771 float ceilf (float a) { return ceil(a); }
772 float floorf (float a) { return floor(a); }
773 #endif
774 
775 /*ndef HAVE_FLOAT*/
776 #if 0
777 
778 float fmodf(a,b) float a,b; { return fmod(a,b); }
779 float hypotf(a,b) float a,b; { return hypot(a,b); }
780 
781 float acosf(a) float a; { return acos(a); }
782 float acoshf(a) float a; { return acosh(a); }
783 float asinf(a) float a; { return asin(a); }
784 float asinhf(a) float a; { return asinh(a); }
785 float atanf(a) float a; { return atan(a); }
786 float atanhf(a) float a; { return atanh(a); }
787 
788 float coshf(a) float a; { return cosh(a); }
789 float erff(a) float a; { return erf(a); }
790 float erfcf(a) float a; { return erfc(a); }
791 float expf(a) float a; { return exp(a); }
792 float fabsf(a) float a; { return fabs(a); }
793 
794 float gammaf(a) float a; { return gamma(a); }
795 float j0f(a) float a; { return j0(a); }
796 float j1f(a) float a; { return j1(a); }
797 float log10f(a) float a; { return log10(a); }
798 
799 float logf(a) float a; { return log(a); }
800 
801 float sinhf(a) float a; { return sinh(a); }
802 float sqrtf(a) float a; { return sqrt(a); }
803 
804 float tanhf(a) float a; { return tanh(a); }
805 float y0f(a) float a; { return y0(a); }
806 float y1f(a) float a; { return y1(a); }
807 #endif
808