OSDN Git Service

errno: hide __libc_resp, __libc_errno, and __libc_h_errno
[uclinux-h8/uClibc.git] / libm / ldouble_wrappers.c
1 /* vi: set sw=4 ts=4: */
2 /*
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.
7  *
8  * Copyright (C) 2005 by Erik Andersen <andersen@uclibc.org>
9  *
10  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
11  */
12
13 #include <features.h>
14 /* Prevent math.h from defining colliding inlines */
15 #undef __USE_EXTERN_INLINES
16 #include "math.h"
17 #include <complex.h>
18
19 #define WRAPPER1(func) \
20 long double func##l(long double x) \
21 { \
22         return (long double) func((double) x); \
23 }
24 #define int_WRAPPER1(func) \
25 int func##l(long double x) \
26 { \
27         return func((double) x); \
28 }
29 #define long_WRAPPER1(func) \
30 long func##l(long double x) \
31 { \
32         return func((double) x); \
33 }
34 #define long_long_WRAPPER1(func) \
35 long long func##l(long double x) \
36 { \
37         return func((double) x); \
38 }
39
40 #if defined __i386__ && defined __OPTIMIZE__
41 # undef WRAPPER1
42 # undef int_WRAPPER1
43 # undef long_WRAPPER1
44 # undef long_long_WRAPPER1
45 /* gcc 4.3.1 generates really ugly code with redundant pair of store/load:
46  *      sub     $0x10,%esp
47  *      fldt    0x14(%esp)
48  *      fstpl   0x8(%esp)
49  *      fldl    0x8(%esp) <-- ??
50  *      fstpl   (%esp)    <-- ??
51  *      call    function
52  *      add     $0x10,%esp
53  *      ret
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...
64  */
65 # define WRAPPER1(func) \
66 long double func##l(long double x) \
67 { \
68         long double st_top; \
69         __asm ( \
70         "       fldt    %1\n" \
71         "       fstpl   %1\n" \
72         "       jmp     " __stringify(__GI_##func) "\n" \
73         : "=t" (st_top) \
74         : "m" (x) \
75         ); \
76         return st_top; \
77 }
78 # define int_WRAPPER1(func) \
79 int func##l(long double x) \
80 { \
81         int ret; \
82         __asm ( \
83         "       fldt    %1\n" \
84         "       fstpl   %1\n" \
85         "       jmp     " __stringify(__GI_##func) "\n" \
86         : "=a" (ret) \
87         : "m" (x) \
88         ); \
89         return ret; \
90 }
91 # define long_WRAPPER1(func) \
92 long func##l(long double x) \
93 { \
94         long ret; \
95         __asm ( \
96         "       fldt    %1\n" \
97         "       fstpl   %1\n" \
98         "       jmp     " __stringify(__GI_##func) "\n" \
99         : "=a" (ret) \
100         : "m" (x) \
101         ); \
102         return ret; \
103 }
104 # define long_long_WRAPPER1(func) \
105 long long func##l(long double x) \
106 { \
107         long long ret; \
108         __asm ( \
109         "       fldt    %1\n" \
110         "       fstpl   %1\n" \
111         "       jmp     " __stringify(__GI_##func) "\n" \
112         : "=A" (ret) \
113         : "m" (x) \
114         ); \
115         return ret; \
116 }
117 #endif /* __i386__ && __OPTIMIZE__ */
118
119 #if defined __NO_LONG_DOUBLE_MATH
120 # define int_WRAPPER_C99(func) /* not needed */
121 # else
122 # define int_WRAPPER_C99(func) \
123 int func##l(long double x) \
124 { \
125     return func((double) x); \
126 } \
127 libm_hidden_def(func##l)
128 #endif
129
130 /* Implement the following, as defined by SuSv3 */
131 #if 0
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);
189 #endif
190
191 #ifdef L_acoshl
192 WRAPPER1(acosh)
193 #endif
194
195 #ifdef L_acosl
196 WRAPPER1(acos)
197 #endif
198
199 #ifdef L_asinhl
200 WRAPPER1(asinh)
201 #endif
202
203 #ifdef L_asinl
204 WRAPPER1(asin)
205 #endif
206
207 #ifdef L_atan2l
208 long double atan2l (long double x, long double y)
209 {
210         return (long double) atan2( (double)x, (double)y );
211 }
212 #endif
213
214 #ifdef L_atanhl
215 WRAPPER1(atanh)
216 #endif
217
218 #ifdef L_atanl
219 WRAPPER1(atan)
220 #endif
221
222 #ifdef L_cargl
223 long double cargl (long double complex x)
224 {
225         return (long double) carg( (double complex)x );
226 }
227 #endif
228
229 #ifdef L_cbrtl
230 WRAPPER1(cbrt)
231 #endif
232
233 #ifdef L_ceill
234 WRAPPER1(ceil)
235 #endif
236
237 #ifdef L_copysignl
238 long double copysignl (long double x, long double y)
239 {
240         return (long double) copysign( (double)x, (double)y );
241 }
242 #endif
243
244 #ifdef L_coshl
245 WRAPPER1(cosh)
246 #endif
247
248 #ifdef L_cosl
249 WRAPPER1(cos)
250 #endif
251
252 #ifdef L_erfcl
253 WRAPPER1(erfc)
254 #endif
255
256 #ifdef L_erfl
257 WRAPPER1(erf)
258 #endif
259
260 #ifdef L_exp2l
261 WRAPPER1(exp2)
262 #endif
263
264 #ifdef L_expl
265 WRAPPER1(exp)
266 #endif
267
268 #ifdef L_expm1l
269 WRAPPER1(expm1)
270 #endif
271
272 #ifdef L_fabsl
273 WRAPPER1(fabs)
274 #endif
275
276 #ifdef L_fdiml
277 long double fdiml (long double x, long double y)
278 {
279         return (long double) fdim( (double)x, (double)y );
280 }
281 #endif
282
283 #ifdef L_floorl
284 WRAPPER1(floor)
285 #endif
286
287 #ifdef L_fmal
288 long double fmal (long double x, long double y, long double z)
289 {
290         return (long double) fma( (double)x, (double)y, (double)z );
291 }
292 #endif
293
294 #ifdef L_fmaxl
295 long double fmaxl (long double x, long double y)
296 {
297         return (long double) fmax( (double)x, (double)y );
298 }
299 #endif
300
301 #ifdef L_fminl
302 long double fminl (long double x, long double y)
303 {
304         return (long double) fmin( (double)x, (double)y );
305 }
306 #endif
307
308 #ifdef L_fmodl
309 long double fmodl (long double x, long double y)
310 {
311         return (long double) fmod( (double)x, (double)y );
312 }
313 #endif
314
315 #ifdef L_frexpl
316 long double frexpl (long double x, int *ex)
317 {
318         return (long double) frexp( (double)x, ex );
319 }
320 #endif
321
322 #ifdef L_gammal
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)
326 {
327         return (long double) gamma((double) x);
328 }
329 #endif
330
331 #ifdef L_hypotl
332 long double hypotl (long double x, long double y)
333 {
334         return (long double) hypot( (double)x, (double)y );
335 }
336 #endif
337
338 #ifdef L_ilogbl
339 int_WRAPPER1(ilogb)
340 #endif
341
342 #ifdef L_ldexpl
343 long double ldexpl (long double x, int ex)
344 {
345         return (long double) ldexp( (double)x, ex );
346 }
347 #endif
348
349 #ifdef L_lgammal
350 WRAPPER1(lgamma)
351 #endif
352
353 #ifdef L_llrintl
354 long_long_WRAPPER1(llrint)
355 #endif
356
357 #ifdef L_llroundl
358 long_long_WRAPPER1(llround)
359 #endif
360
361 #ifdef L_log10l
362 WRAPPER1(log10)
363 #endif
364
365 #ifdef L_log1pl
366 WRAPPER1(log1p)
367 #endif
368
369 #ifdef L_log2l
370 /* WRAPPER1(log2) won't work */
371 long double log2l(long double x)
372 {
373         return (long double) log2((double)x);
374 }
375 #endif
376
377 #ifdef L_logbl
378 WRAPPER1(logb)
379 #endif
380
381 #ifdef L_logl
382 WRAPPER1(log)
383 #endif
384
385 #ifdef L_lrintl
386 long_WRAPPER1(lrint)
387 #endif
388
389 #ifdef L_lroundl
390 long_WRAPPER1(lround)
391 #endif
392
393 #ifdef L_modfl
394 long double modfl (long double x, long double *iptr)
395 {
396         double y, result;
397         result = modf ( x, &y );
398         *iptr = (long double)y;
399         return (long double) result;
400 }
401 #endif
402
403 #ifdef L_nearbyintl
404 WRAPPER1(nearbyint)
405 #endif
406
407 #ifdef L_nextafterl
408 long double nextafterl (long double x, long double y)
409 {
410         return (long double) nextafter( (double)x, (double)y );
411 }
412 #endif
413
414 /* Disabled in Makefile.in */
415 #if 0 /* def L_nexttowardl */
416 long double nexttowardl (long double x, long double y)
417 {
418         return (long double) nexttoward( (double)x, (double)y );
419 }
420 libm_hidden_def(nexttowardl)
421 #endif
422
423 #ifdef L_powl
424 long double powl (long double x, long double y)
425 {
426         return (long double) pow( (double)x, (double)y );
427 }
428 #endif
429
430 #ifdef L_remainderl
431 long double remainderl (long double x, long double y)
432 {
433         return (long double) remainder( (double)x, (double)y );
434 }
435 #endif
436
437 #ifdef L_remquol
438 long double remquol (long double x, long double y, int *quo)
439 {
440         return (long double) remquo( (double)x, (double)y, quo );
441 }
442 #endif
443
444 #ifdef L_rintl
445 WRAPPER1(rint)
446 #endif
447
448 #ifdef L_roundl
449 WRAPPER1(round)
450 #endif
451
452 #ifdef L_scalblnl
453 long double scalblnl (long double x, long ex)
454 {
455         return (long double) scalbln( (double)x, ex );
456 }
457 #endif
458
459 #ifdef L_scalbnl
460 long double scalbnl (long double x, int ex)
461 {
462         return (long double) scalbn( (double)x, ex );
463 }
464 #endif
465
466 /* scalb is an obsolete function */
467
468 #ifdef L_sinhl
469 WRAPPER1(sinh)
470 #endif
471
472 #ifdef L_sinl
473 WRAPPER1(sin)
474 #endif
475
476 #ifdef L_sqrtl
477 WRAPPER1(sqrt)
478 #endif
479
480 #ifdef L_tanhl
481 WRAPPER1(tanh)
482 #endif
483
484 #ifdef L_tanl
485 WRAPPER1(tan)
486 #endif
487
488 #ifdef L_tgammal
489 WRAPPER1(tgamma)
490 #endif
491
492 #ifdef L_truncl
493 WRAPPER1(trunc)
494 #endif
495
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)
500 {
501         return (long double) significand((double) x);
502 }
503 #endif
504
505 #ifdef __DO_C99_MATH__
506
507 #ifdef L___fpclassifyl
508 int_WRAPPER_C99(__fpclassify)
509 #endif
510
511 #ifdef L___finitel
512 int_WRAPPER_C99(__finite)
513 #endif
514
515 #ifdef L___signbitl
516 int_WRAPPER_C99(__signbit)
517 #endif
518
519 #ifdef L___isnanl
520 int_WRAPPER_C99(__isnan)
521 #endif
522
523 #ifdef L___isinfl
524 int_WRAPPER_C99(__isinf)
525 #endif
526
527 #endif