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__ */
119 #if defined __NO_LONG_DOUBLE_MATH
120 # define int_WRAPPER_C99(func) /* not needed */
122 # define int_WRAPPER_C99(func) \
123 int func##l(long double x) \
125 return func((double) x); \
127 libm_hidden_def(func##l)
130 /* Implement the following, as defined by SuSv3 */
132 long double acoshl(long double);
133 long double acosl(long double);
134 long double asinhl(long double);
135 long double asinl(long double);
136 long double atan2l(long double, long double);
137 long double atanhl(long double);
138 long double atanl(long double);
139 long double cargl(long double complex);
140 long double cbrtl(long double);
141 long double ceill(long double);
142 long double copysignl(long double, long double);
143 long double coshl(long double);
144 long double cosl(long double);
145 long double erfcl(long double);
146 long double erfl(long double);
147 long double exp2l(long double);
148 long double expl(long double);
149 long double expm1l(long double);
150 long double fabsl(long double);
151 long double fdiml(long double, long double);
152 long double floorl(long double);
153 long double fmal(long double, long double, long double);
154 long double fmaxl(long double, long double);
155 long double fminl(long double, long double);
156 long double fmodl(long double, long double);
157 long double frexpl(long double value
, int *);
158 long double hypotl(long double, long double);
159 int ilogbl(long double);
160 long double ldexpl(long double, int);
161 long double lgammal(long double);
162 long long llrintl(long double);
163 long long llroundl(long double);
164 long double log10l(long double);
165 long double log1pl(long double);
166 long double log2l(long double);
167 long double logbl(long double);
168 long double logl(long double);
169 long lrintl(long double);
170 long lroundl(long double);
171 long double modfl(long double, long double *);
172 long double nearbyintl(long double);
173 long double nextafterl(long double, long double);
174 long double nexttowardl(long double, long double);
175 long double powl(long double, long double);
176 long double remainderl(long double, long double);
177 long double remquol(long double, long double, int *);
178 long double rintl(long double);
179 long double roundl(long double);
180 long double scalblnl(long double, long);
181 long double scalbnl(long double, int);
182 long double sinhl(long double);
183 long double sinl(long double);
184 long double sqrtl(long double);
185 long double tanhl(long double);
186 long double tanl(long double);
187 long double tgammal(long double);
188 long double truncl(long double);
208 long double atan2l (long double x
, long double y
)
210 return (long double) atan2( (double)x
, (double)y
);
223 long double cargl (long double complex x
)
225 return (long double) carg( (double complex)x
);
238 long double copysignl (long double x
, long double y
)
240 return (long double) copysign( (double)x
, (double)y
);
277 long double fdiml (long double x
, long double y
)
279 return (long double) fdim( (double)x
, (double)y
);
288 long double fmal (long double x
, long double y
, long double z
)
290 return (long double) fma( (double)x
, (double)y
, (double)z
);
295 long double fmaxl (long double x
, long double y
)
297 return (long double) fmax( (double)x
, (double)y
);
302 long double fminl (long double x
, long double y
)
304 return (long double) fmin( (double)x
, (double)y
);
309 long double fmodl (long double x
, long double y
)
311 return (long double) fmod( (double)x
, (double)y
);
316 long double frexpl (long double x
, int *ex
)
318 return (long double) frexp( (double)x
, ex
);
323 /* WRAPPER1(gamma) won't work, tries to call __GI_xxx,
324 * and gamma() hasn't got one. */
325 long double gammal(long double x
)
327 return (long double) gamma((double) x
);
332 long double hypotl (long double x
, long double y
)
334 return (long double) hypot( (double)x
, (double)y
);
343 long double ldexpl (long double x
, int ex
)
345 return (long double) ldexp( (double)x
, ex
);
354 long_long_WRAPPER1(llrint
)
358 long_long_WRAPPER1(llround
)
370 /* WRAPPER1(log2) won't work */
371 long double log2l(long double x
)
373 return (long double) log2((double)x
);
390 long_WRAPPER1(lround
)
394 long double modfl (long double x
, long double *iptr
)
397 result
= modf ( x
, &y
);
398 *iptr
= (long double)y
;
399 return (long double) result
;
408 long double nextafterl (long double x
, long double y
)
410 return (long double) nextafter( (double)x
, (double)y
);
414 /* Disabled in Makefile.in */
415 #if 0 /* def L_nexttowardl */
416 long double nexttowardl (long double x
, long double y
)
418 return (long double) nexttoward( (double)x
, (double)y
);
420 libm_hidden_def(nexttowardl
)
424 long double powl (long double x
, long double y
)
426 return (long double) pow( (double)x
, (double)y
);
431 long double remainderl (long double x
, long double y
)
433 return (long double) remainder( (double)x
, (double)y
);
438 long double remquol (long double x
, long double y
, int *quo
)
440 return (long double) remquo( (double)x
, (double)y
, quo
);
453 long double scalblnl (long double x
, long ex
)
455 return (long double) scalbln( (double)x
, ex
);
460 long double scalbnl (long double x
, int ex
)
462 return (long double) scalbn( (double)x
, ex
);
466 /* scalb is an obsolete function */
496 #ifdef L_significandl
497 /* WRAPPER1(significand) won't work, tries to call __GI_xxx,
498 * and significand() hasn't got one. */
499 long double significandl(long double x
)
501 return (long double) significand((double) x
);
505 #ifdef __DO_C99_MATH__
507 #ifdef L___fpclassifyl
508 int_WRAPPER_C99(__fpclassify
)
512 int_WRAPPER_C99(__finite
)
516 int_WRAPPER_C99(__signbit
)
520 int_WRAPPER_C99(__isnan
)
524 int_WRAPPER_C99(__isinf
)