1 /* vi: set sw=4 ts=4: */
3 * Wrapper functions implementing all the long double math functions
4 * defined by SuSv3 by actually calling the double version of
5 * each function and then casting the result back to a long double
6 * to return to the user.
8 * Copyright (C) 2005 by Erik Andersen <andersen@uclibc.org>
10 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
14 /* Prevent math.h from defining colliding inlines */
15 #undef __USE_EXTERN_INLINES
19 #define WRAPPER1(func) \
20 long double func##l(long double x) \
22 return (long double) func((double) x); \
24 #define int_WRAPPER1(func) \
25 int func##l(long double x) \
27 return func((double) x); \
29 #define long_WRAPPER1(func) \
30 long func##l(long double x) \
32 return func((double) x); \
34 #define long_long_WRAPPER1(func) \
35 long long func##l(long double x) \
37 return func((double) x); \
40 #if defined __i386__ && defined __OPTIMIZE__
44 # undef long_long_WRAPPER1
45 /* gcc 4.3.1 generates really ugly code with redundant pair of store/load:
49 * fldl 0x8(%esp) <-- ??
54 * I can hope newer gcc will eliminate that. However, I don't think
55 * it will be smart enough to reuse argument stack space and use
56 * jump instead of call. Let's do it by hand.
57 * The asm below loads long double x into st(0), then stores it back
58 * to the same location, but as a double. At this point, stack looks
59 * exactly as "double func(double)" expects it to be.
60 * The return value is returned in st(0) per ABI in both cases (returning
61 * a long double or returning a double). So we can simply jump to func.
62 * Using __GI_func in jump to make optimized intra-library jump.
63 * gcc will still generate a useless "ret" after asm. Oh well...
65 # define WRAPPER1(func) \
66 long double func##l(long double x) \
72 " jmp " __stringify(__GI_##func) "\n" \
78 # define int_WRAPPER1(func) \
79 int func##l(long double x) \
85 " jmp " __stringify(__GI_##func) "\n" \
91 # define long_WRAPPER1(func) \
92 long func##l(long double x) \
98 " jmp " __stringify(__GI_##func) "\n" \
104 # define long_long_WRAPPER1(func) \
105 long long func##l(long double x) \
111 " jmp " __stringify(__GI_##func) "\n" \
117 #endif /* __i386__ && __OPTIMIZE__ */
120 /* Implement the following, as defined by SuSv3 */
122 long double acoshl(long double);
123 long double acosl(long double);
124 long double asinhl(long double);
125 long double asinl(long double);
126 long double atan2l(long double, long double);
127 long double atanhl(long double);
128 long double atanl(long double);
129 long double cargl(long double complex);
130 long double cbrtl(long double);
131 long double ceill(long double);
132 long double copysignl(long double, long double);
133 long double coshl(long double);
134 long double cosl(long double);
135 long double erfcl(long double);
136 long double erfl(long double);
137 long double exp2l(long double);
138 long double expl(long double);
139 long double expm1l(long double);
140 long double fabsl(long double);
141 long double fdiml(long double, long double);
142 long double floorl(long double);
143 long double fmal(long double, long double, long double);
144 long double fmaxl(long double, long double);
145 long double fminl(long double, long double);
146 long double fmodl(long double, long double);
147 long double frexpl(long double value, int *);
148 long double hypotl(long double, long double);
149 int ilogbl(long double);
150 long double ldexpl(long double, int);
151 long double lgammal(long double);
152 long long llrintl(long double);
153 long long llroundl(long double);
154 long double log10l(long double);
155 long double log1pl(long double);
156 long double log2l(long double);
157 long double logbl(long double);
158 long double logl(long double);
159 long lrintl(long double);
160 long lroundl(long double);
161 long double modfl(long double, long double *);
162 long double nearbyintl(long double);
163 long double nextafterl(long double, long double);
164 long double nexttowardl(long double, long double);
165 long double powl(long double, long double);
166 long double remainderl(long double, long double);
167 long double remquol(long double, long double, int *);
168 long double rintl(long double);
169 long double roundl(long double);
170 long double scalblnl(long double, long);
171 long double scalbnl(long double, int);
172 long double sinhl(long double);
173 long double sinl(long double);
174 long double sqrtl(long double);
175 long double tanhl(long double);
176 long double tanl(long double);
177 long double tgammal(long double);
178 long double truncl(long double);
198 long double atan2l (long double x, long double y)
200 return (long double) atan2( (double)x, (double)y );
213 long double cargl (long double complex x)
215 return (long double) carg( (double complex)x );
228 long double copysignl (long double x, long double y)
230 return (long double) copysign( (double)x, (double)y );
267 long double fdiml (long double x, long double y)
269 return (long double) fdim( (double)x, (double)y );
278 long double fmal (long double x, long double y, long double z)
280 return (long double) fma( (double)x, (double)y, (double)z );
285 long double fmaxl (long double x, long double y)
287 return (long double) fmax( (double)x, (double)y );
292 long double fminl (long double x, long double y)
294 return (long double) fmin( (double)x, (double)y );
299 long double fmodl (long double x, long double y)
301 return (long double) fmod( (double)x, (double)y );
306 long double frexpl (long double x, int *exp)
308 return (long double) frexp( (double)x, exp );
313 /* WRAPPER1(gamma) won't work, tries to call __GI_xxx,
314 * and gamma() hasn't got one. */
315 long double gammal(long double x)
317 return (long double) gamma((double) x);
322 long double hypotl (long double x, long double y)
324 return (long double) hypot( (double)x, (double)y );
333 long double ldexpl (long double x, int exp)
335 return (long double) ldexp( (double)x, exp );
344 long_long_WRAPPER1(llrint)
348 long_long_WRAPPER1(llround)
360 /* WRAPPER1(log2) won't work */
361 long double log2l(long double x)
363 return (long double) log2((double)x);
380 long_WRAPPER1(lround)
384 long double modfl (long double x, long double *iptr)
387 result = modf ( x, &y );
388 *iptr = (long double)y;
389 return (long double) result;
398 long double nextafterl (long double x, long double y)
400 return (long double) nextafter( (double)x, (double)y );
405 long double nexttowardl (long double x, long double y)
407 return (long double) nexttoward( (double)x, (double)y );
412 long double powl (long double x, long double y)
414 return (long double) pow( (double)x, (double)y );
419 long double remainderl (long double x, long double y)
421 return (long double) remainder( (double)x, (double)y );
426 long double remquol (long double x, long double y, int *quo)
428 return (long double) remquo( (double)x, (double)y, quo );
441 long double scalblnl (long double x, long exp)
443 return (long double) scalbln( (double)x, exp );
448 long double scalbnl (long double x, int exp)
450 return (long double) scalbn( (double)x, exp );
454 /* scalb is an obsolete function */
484 #ifdef L_significandl
485 /* WRAPPER1(significand) won't work, tries to call __GI_xxx,
486 * and significand() hasn't got one. */
487 long double significandl(long double x)
489 return (long double) significand((double) x);
493 #ifdef __DO_C99_MATH__
496 int_WRAPPER1(__fpclassify)
497 libm_hidden_def(__fpclassifyl)
501 int_WRAPPER1(__finite)
502 libm_hidden_def(__finitel)
506 int_WRAPPER1(__signbit)
507 libm_hidden_def(__signbitl)
511 int_WRAPPER1(__isnan)
512 libm_hidden_def(__isnanl)
516 int_WRAPPER1(__isinf)
517 libm_hidden_def(__isinfl)