OSDN Git Service

test/math/compile_test.c: "are long double functions even compile/link?" test
[uclinux-h8/uclibc-ng.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
120 /* Implement the following, as defined by SuSv3 */
121 #if 0
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);
179 #endif
180
181 #ifdef L_acoshl
182 WRAPPER1(acosh)
183 #endif
184
185 #ifdef L_acosl
186 WRAPPER1(acos)
187 #endif
188
189 #ifdef L_asinhl
190 WRAPPER1(asinh)
191 #endif
192
193 #ifdef L_asinl
194 WRAPPER1(asin)
195 #endif
196
197 #ifdef L_atan2l
198 long double atan2l (long double x, long double y)
199 {
200         return (long double) atan2( (double)x, (double)y );
201 }
202 #endif
203
204 #ifdef L_atanhl
205 WRAPPER1(atanh)
206 #endif
207
208 #ifdef L_atanl
209 WRAPPER1(atan)
210 #endif
211
212 #ifdef L_cargl
213 long double cargl (long double complex x)
214 {
215         return (long double) carg( (double complex)x );
216 }
217 #endif
218
219 #ifdef L_cbrtl
220 WRAPPER1(cbrt)
221 #endif
222
223 #ifdef L_ceill
224 WRAPPER1(ceil)
225 #endif
226
227 #ifdef L_copysignl
228 long double copysignl (long double x, long double y)
229 {
230         return (long double) copysign( (double)x, (double)y );
231 }
232 #endif
233
234 #ifdef L_coshl
235 WRAPPER1(cosh)
236 #endif
237
238 #ifdef L_cosl
239 WRAPPER1(cos)
240 #endif
241
242 #ifdef L_erfcl
243 WRAPPER1(erfc)
244 #endif
245
246 #ifdef L_erfl
247 WRAPPER1(erf)
248 #endif
249
250 #ifdef L_exp2l
251 WRAPPER1(exp2)
252 #endif
253
254 #ifdef L_expl
255 WRAPPER1(exp)
256 #endif
257
258 #ifdef L_expm1l
259 WRAPPER1(expm1)
260 #endif
261
262 #ifdef L_fabsl
263 WRAPPER1(fabs)
264 #endif
265
266 #ifdef L_fdiml
267 long double fdiml (long double x, long double y)
268 {
269         return (long double) fdim( (double)x, (double)y );
270 }
271 #endif
272
273 #ifdef L_floorl
274 WRAPPER1(floor)
275 #endif
276
277 #ifdef L_fmal
278 long double fmal (long double x, long double y, long double z)
279 {
280         return (long double) fma( (double)x, (double)y, (double)z );
281 }
282 #endif
283
284 #ifdef L_fmaxl
285 long double fmaxl (long double x, long double y)
286 {
287         return (long double) fmax( (double)x, (double)y );
288 }
289 #endif
290
291 #ifdef L_fminl
292 long double fminl (long double x, long double y)
293 {
294         return (long double) fmin( (double)x, (double)y );
295 }
296 #endif
297
298 #ifdef L_fmodl
299 long double fmodl (long double x, long double y)
300 {
301         return (long double) fmod( (double)x, (double)y );
302 }
303 #endif
304
305 #ifdef L_frexpl
306 long double frexpl (long double x, int *exp)
307 {
308         return (long double) frexp( (double)x, exp );
309 }
310 #endif
311
312 #ifdef L_gammal
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)
316 {
317         return (long double) gamma((double) x);
318 }
319 #endif
320
321 #ifdef L_hypotl
322 long double hypotl (long double x, long double y)
323 {
324         return (long double) hypot( (double)x, (double)y );
325 }
326 #endif
327
328 #ifdef L_ilogbl
329 int_WRAPPER1(ilogb)
330 #endif
331
332 #ifdef L_ldexpl
333 long double ldexpl (long double x, int exp)
334 {
335         return (long double) ldexp( (double)x, exp );
336 }
337 #endif
338
339 #ifdef L_lgammal
340 WRAPPER1(lgamma)
341 #endif
342
343 #ifdef L_llrintl
344 long_long_WRAPPER1(llrint)
345 #endif
346
347 #ifdef L_llroundl
348 long_long_WRAPPER1(llround)
349 #endif
350
351 #ifdef L_log10l
352 WRAPPER1(log10)
353 #endif
354
355 #ifdef L_log1pl
356 WRAPPER1(log1p)
357 #endif
358
359 #ifdef L_log2l
360 /* WRAPPER1(log2) won't work */
361 long double log2l(long double x)
362 {
363         return (long double) log2((double)x);
364 }
365 #endif
366
367 #ifdef L_logbl
368 WRAPPER1(logb)
369 #endif
370
371 #ifdef L_logl
372 WRAPPER1(log)
373 #endif
374
375 #ifdef L_lrintl
376 long_WRAPPER1(lrint)
377 #endif
378
379 #ifdef L_lroundl
380 long_WRAPPER1(lround)
381 #endif
382
383 #ifdef L_modfl
384 long double modfl (long double x, long double *iptr)
385 {
386         double y, result;
387         result = modf ( x, &y );
388         *iptr = (long double)y;
389         return (long double) result;
390 }
391 #endif
392
393 #ifdef L_nearbyintl
394 WRAPPER1(nearbyint)
395 #endif
396
397 #ifdef L_nextafterl
398 long double nextafterl (long double x, long double y)
399 {
400         return (long double) nextafter( (double)x, (double)y );
401 }
402 #endif
403
404 #ifdef L_nexttowardl
405 long double nexttowardl (long double x, long double y)
406 {
407         return (long double) nexttoward( (double)x, (double)y );
408 }
409 #endif
410
411 #ifdef L_powl
412 long double powl (long double x, long double y)
413 {
414         return (long double) pow( (double)x, (double)y );
415 }
416 #endif
417
418 #ifdef L_remainderl
419 long double remainderl (long double x, long double y)
420 {
421         return (long double) remainder( (double)x, (double)y );
422 }
423 #endif
424
425 #ifdef L_remquol
426 long double remquol (long double x, long double y, int *quo)
427 {
428         return (long double) remquo( (double)x, (double)y, quo );
429 }
430 #endif
431
432 #ifdef L_rintl
433 WRAPPER1(rint)
434 #endif
435
436 #ifdef L_roundl
437 WRAPPER1(round)
438 #endif
439
440 #ifdef L_scalblnl
441 long double scalblnl (long double x, long exp)
442 {
443         return (long double) scalbln( (double)x, exp );
444 }
445 #endif
446
447 #ifdef L_scalbnl
448 long double scalbnl (long double x, int exp)
449 {
450         return (long double) scalbn( (double)x, exp );
451 }
452 #endif
453
454 /* scalb is an obsolete function */
455
456 #ifdef L_sinhl
457 WRAPPER1(sinh)
458 #endif
459
460 #ifdef L_sinl
461 WRAPPER1(sin)
462 #endif
463
464 #ifdef L_sqrtl
465 WRAPPER1(sqrt)
466 #endif
467
468 #ifdef L_tanhl
469 WRAPPER1(tanh)
470 #endif
471
472 #ifdef L_tanl
473 WRAPPER1(tan)
474 #endif
475
476 #ifdef L_tgammal
477 WRAPPER1(tgamma)
478 #endif
479
480 #ifdef L_truncl
481 WRAPPER1(trunc)
482 #endif
483
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)
488 {
489         return (long double) significand((double) x);
490 }
491 #endif
492
493 #ifdef __DO_C99_MATH__
494
495 #ifdef L_fpclassifyl
496 int_WRAPPER1(__fpclassify)
497 libm_hidden_def(__fpclassifyl)
498 #endif
499
500 #ifdef L_finitel
501 int_WRAPPER1(__finite)
502 libm_hidden_def(__finitel)
503 #endif
504
505 #ifdef L___signbitl
506 int_WRAPPER1(__signbit)
507 libm_hidden_def(__signbitl)
508 #endif
509
510 #ifdef L_isnanl
511 int_WRAPPER1(__isnan)
512 libm_hidden_def(__isnanl)
513 #endif
514
515 #ifdef L_isinfl
516 int_WRAPPER1(__isinf)
517 libm_hidden_def(__isinfl)
518 #endif
519
520 #endif