1 /* Inline math functions for i387.
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by John C. Bowman <bowman@math.ualberta.ca>, 1995.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <http://www.gnu.org/licenses/>. */
22 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
26 # define __MATH_INLINE __inline
28 # define __MATH_INLINE extern __inline
32 #if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
33 /* GCC 2.97 and up have builtins that actually can be used. */
34 # if !__GNUC_PREREQ (2,97)
35 /* ISO C99 defines some macros to perform unordered comparisons. The
36 ix87 FPU supports this with special opcodes and we should use them.
37 These must not be inline functions since we have to be able to handle
38 all floating-point types. */
40 # undef isgreaterequal
46 /* For the PentiumPro and more recent processors we can provide
48 # define isgreater(x, y) \
49 ({ register char __result; \
50 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
51 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
53 # define isgreaterequal(x, y) \
54 ({ register char __result; \
55 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
56 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
59 # define isless(x, y) \
60 ({ register char __result; \
61 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
62 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
65 # define islessequal(x, y) \
66 ({ register char __result; \
67 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
68 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
71 # define islessgreater(x, y) \
72 ({ register char __result; \
73 __asm__ ("fucomip %%st(1), %%st; setne %%al" \
74 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
77 # define isunordered(x, y) \
78 ({ register char __result; \
79 __asm__ ("fucomip %%st(1), %%st; setp %%al" \
80 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
83 /* This is the dumb, portable code for i386 and above. */
84 # define isgreater(x, y) \
85 ({ register char __result; \
86 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
87 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
90 # define isgreaterequal(x, y) \
91 ({ register char __result; \
92 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
93 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
96 # define isless(x, y) \
97 ({ register char __result; \
98 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
99 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
102 # define islessequal(x, y) \
103 ({ register char __result; \
104 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
105 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
108 # define islessgreater(x, y) \
109 ({ register char __result; \
110 __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
111 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
114 # define isunordered(x, y) \
115 ({ register char __result; \
116 __asm__ ("fucompp; fnstsw; sahf; setp %%al" \
117 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
119 # endif /* __i686__ */
120 # endif /* GCC 2.97 */
122 /* The gcc, version 2.7 or below, has problems with all this inlining
123 code. So disable it for this version of the compiler. */
124 # if __GNUC_PREREQ (2, 8)
125 /* Test for negative number. Used in the signbit() macro. */
127 __NTH (__signbitf (float __x))
129 __extension__ union { float __f; int __i; } __u = { __f: __x };
133 __NTH (__signbit (double __x))
135 __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
136 return __u.__i[1] < 0;
139 __NTH (__signbitl (long double __x))
141 __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
142 return (__u.__i[2] & 0x8000) != 0;
148 /* The gcc, version 2.7 or below, has problems with all this inlining
149 code. So disable it for this version of the compiler. */
150 #if __GNUC_PREREQ (2, 8)
152 #if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
153 && defined __OPTIMIZE__)
155 /* A macro to define float, double, and long double versions of various
156 math functions for the ix87 FPU. FUNC is the function name (which will
157 be suffixed with f and l for the float and long double version,
158 respectively). OP is the name of the FPU operation.
159 We define two sets of macros. The set with the additional NP
160 doesn't add a prototype declaration. */
162 #if defined __USE_MISC || defined __USE_ISOC99
163 # define __inline_mathop(func, op) \
164 __inline_mathop_ (double, func, op) \
165 __inline_mathop_ (float, __CONCAT(func,f), op) \
166 __inline_mathop_ (long double, __CONCAT(func,l), op)
167 # define __inline_mathopNP(func, op) \
168 __inline_mathopNP_ (double, func, op) \
169 __inline_mathopNP_ (float, __CONCAT(func,f), op) \
170 __inline_mathopNP_ (long double, __CONCAT(func,l), op)
172 # define __inline_mathop(func, op) \
173 __inline_mathop_ (double, func, op)
174 # define __inline_mathopNP(func, op) \
175 __inline_mathopNP_ (double, func, op)
178 #define __inline_mathop_(float_type, func, op) \
179 __inline_mathop_decl_ (float_type, func, op, "0" (__x))
180 #define __inline_mathopNP_(float_type, func, op) \
181 __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
184 #if defined __USE_MISC || defined __USE_ISOC99
185 # define __inline_mathop_decl(func, op, params...) \
186 __inline_mathop_decl_ (double, func, op, params) \
187 __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
188 __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
189 # define __inline_mathop_declNP(func, op, params...) \
190 __inline_mathop_declNP_ (double, func, op, params) \
191 __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
192 __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
194 # define __inline_mathop_decl(func, op, params...) \
195 __inline_mathop_decl_ (double, func, op, params)
196 # define __inline_mathop_declNP(func, op, params...) \
197 __inline_mathop_declNP_ (double, func, op, params)
200 #define __inline_mathop_decl_(float_type, func, op, params...) \
201 __MATH_INLINE float_type func (float_type) __THROW; \
202 __inline_mathop_declNP_ (float_type, func, op, params)
204 #define __inline_mathop_declNP_(float_type, func, op, params...) \
205 __MATH_INLINE float_type __NTH (func (float_type __x)) \
207 register float_type __result; \
208 __asm__ __volatile__ (op : "=t" (__result) : params); \
213 #if defined __USE_MISC || defined __USE_ISOC99
214 # define __inline_mathcode(func, arg, code) \
215 __inline_mathcode_ (double, func, arg, code) \
216 __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
217 __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
218 # define __inline_mathcodeNP(func, arg, code) \
219 __inline_mathcodeNP_ (double, func, arg, code) \
220 __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
221 __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
222 # define __inline_mathcode2(func, arg1, arg2, code) \
223 __inline_mathcode2_ (double, func, arg1, arg2, code) \
224 __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
225 __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
226 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
227 __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
228 __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
229 __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
230 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
231 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
232 __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
233 __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
234 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
235 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
236 __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
237 __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
239 # define __inline_mathcode(func, arg, code) \
240 __inline_mathcode_ (double, func, (arg), code)
241 # define __inline_mathcodeNP(func, arg, code) \
242 __inline_mathcodeNP_ (double, func, (arg), code)
243 # define __inline_mathcode2(func, arg1, arg2, code) \
244 __inline_mathcode2_ (double, func, arg1, arg2, code)
245 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
246 __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
247 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
248 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
249 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
250 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
253 #define __inline_mathcode_(float_type, func, arg, code) \
254 __MATH_INLINE float_type func (float_type) __THROW; \
255 __inline_mathcodeNP_(float_type, func, arg, code)
257 #define __inline_mathcodeNP_(float_type, func, arg, code) \
258 __MATH_INLINE float_type __NTH (func (float_type arg)) \
264 #define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
265 __MATH_INLINE float_type func (float_type, float_type) __THROW; \
266 __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
268 #define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
269 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
274 #define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
275 __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
276 __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
278 #define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
279 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
287 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
288 /* Miscellaneous functions */
290 __inline_mathcode (__sgn, __x, \
291 return __x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0))
293 /* __FAST_MATH__ is defined by gcc -ffast-math. */
295 __inline_mathcode (__pow2, __x, \
296 register long double __value; \
297 register long double __exponent; \
298 __extension__ long long int __p = (long long int) __x; \
299 if (__x == (long double) __p) \
301 __asm__ __volatile__ \
303 : "=t" (__value) : "0" (1.0), "u" (__x)); \
306 __asm__ __volatile__ \
308 "frndint # int(x)\n\t" \
310 "fsub %%st(1) # fract(x)\n\t" \
311 "f2xm1 # 2^(fract(x)) - 1\n\t" \
312 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
314 __asm__ __volatile__ \
316 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
320 # define __sincos_code \
321 register long double __cosr; \
322 register long double __sinr; \
323 __asm__ __volatile__ \
326 "testl $0x400, %%eax\n\t" \
333 "testl $0x400, %%eax\n\t" \
338 : "=t" (__cosr), "=u" (__sinr) : "0" (__x)); \
343 __NTH (__sincos (double __x, double *__sinx, double *__cosx))
349 __NTH (__sincosf (float __x, float *__sinx, float *__cosx))
355 __NTH (__sincosl (long double __x, long double *__sinx, long double *__cosx))
362 /* Optimized inline implementation, sometimes with reduced precision
363 and/or argument range. */
365 # if __GNUC_PREREQ (3, 5)
366 # define __expm1_code \
367 register long double __temp; \
368 __temp = __builtin_expm1l (__x); \
369 return __temp ? __temp : __x
371 # define __expm1_code \
372 register long double __value; \
373 register long double __exponent; \
374 register long double __temp; \
375 __asm__ __volatile__ \
376 ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
377 "fmul %%st(1) # x * log2(e)\n\t" \
379 "frndint # int(x * log2(e))\n\t" \
381 "fsub %%st(1) # fract(x * log2(e))\n\t" \
382 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
383 "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
384 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
385 __asm__ __volatile__ \
386 ("fscale # 2^int(x * log2(e))\n\t" \
387 : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
390 return __temp ? __temp : __x
392 __inline_mathcodeNP_ (long double, __expm1l, __x, __expm1_code)
394 # if __GNUC_PREREQ (3, 4)
395 __inline_mathcodeNP_ (long double, __expl, __x, return __builtin_expl (__x))
397 # define __exp_code \
398 register long double __value; \
399 register long double __exponent; \
400 __asm__ __volatile__ \
401 ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
402 "fmul %%st(1) # x * log2(e)\n\t" \
404 "frndint # int(x * log2(e))\n\t" \
406 "fsub %%st(1) # fract(x * log2(e))\n\t" \
407 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
408 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
410 __asm__ __volatile__ \
412 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
414 __inline_mathcodeNP (exp, __x, __exp_code)
415 __inline_mathcodeNP_ (long double, __expl, __x, __exp_code)
419 # if !__GNUC_PREREQ (3, 5)
420 __inline_mathcodeNP (tan, __x, \
421 register long double __value; \
422 register long double __value2 __attribute__ ((__unused__)); \
423 __asm__ __volatile__ \
425 : "=t" (__value2), "=u" (__value) : "0" (__x)); \
428 #endif /* __FAST_MATH__ */
431 #if __GNUC_PREREQ (3, 4)
432 __inline_mathcodeNP2_ (long double, __atan2l, __y, __x,
433 return __builtin_atan2l (__y, __x))
435 # define __atan2_code \
436 register long double __value; \
437 __asm__ __volatile__ \
439 : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
441 # ifdef __FAST_MATH__
442 __inline_mathcodeNP2 (atan2, __y, __x, __atan2_code)
444 __inline_mathcodeNP2_ (long double, __atan2l, __y, __x, __atan2_code)
448 #if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
449 __inline_mathcodeNP2 (fmod, __x, __y, \
450 register long double __value; \
451 __asm__ __volatile__ \
456 : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); \
462 # if !__GNUC_PREREQ (3,3)
463 __inline_mathopNP (sqrt, "fsqrt")
464 __inline_mathopNP_ (long double, __sqrtl, "fsqrt")
465 # define __libc_sqrtl(n) __sqrtl (n)
467 # define __libc_sqrtl(n) __builtin_sqrtl (n)
471 #if __GNUC_PREREQ (2, 8)
472 __inline_mathcodeNP_ (double, fabs, __x, return __builtin_fabs (__x))
473 # if defined __USE_MISC || defined __USE_ISOC99
474 __inline_mathcodeNP_ (float, fabsf, __x, return __builtin_fabsf (__x))
475 __inline_mathcodeNP_ (long double, fabsl, __x, return __builtin_fabsl (__x))
477 __inline_mathcodeNP_ (long double, __fabsl, __x, return __builtin_fabsl (__x))
479 __inline_mathop (fabs, "fabs")
480 __inline_mathop_ (long double, __fabsl, "fabs")
484 # if !__GNUC_PREREQ (3, 4)
485 /* The argument range of this inline version is reduced. */
486 __inline_mathopNP (sin, "fsin")
487 /* The argument range of this inline version is reduced. */
488 __inline_mathopNP (cos, "fcos")
490 __inline_mathop_declNP (log, "fldln2; fxch; fyl2x", "0" (__x) : "st(1)")
493 # if !__GNUC_PREREQ (3, 5)
494 __inline_mathop_declNP (log10, "fldlg2; fxch; fyl2x", "0" (__x) : "st(1)")
496 __inline_mathcodeNP (asin, __x, return __atan2l (__x, __libc_sqrtl (1.0 - __x * __x)))
497 __inline_mathcodeNP (acos, __x, return __atan2l (__libc_sqrtl (1.0 - __x * __x), __x))
500 # if !__GNUC_PREREQ (3, 4)
501 __inline_mathop_declNP (atan, "fld1; fpatan", "0" (__x) : "st(1)")
503 #endif /* __FAST_MATH__ */
505 __inline_mathcode_ (long double, __sgn1l, __x, \
506 __extension__ union { long double __xld; unsigned int __xi[3]; } __n = \
508 __n.__xi[2] = (__n.__xi[2] & 0x8000) | 0x3fff; \
509 __n.__xi[1] = 0x80000000; \
515 /* The argument range of the inline version of sinhl is slightly reduced. */
516 __inline_mathcodeNP (sinh, __x, \
517 register long double __exm1 = __expm1l (__fabsl (__x)); \
518 return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1l (__x))
520 __inline_mathcodeNP (cosh, __x, \
521 register long double __ex = __expl (__x); \
522 return 0.5 * (__ex + 1.0 / __ex))
524 __inline_mathcodeNP (tanh, __x, \
525 register long double __exm1 = __expm1l (-__fabsl (__x + __x)); \
526 return __exm1 / (__exm1 + 2.0) * __sgn1l (-__x))
529 __inline_mathcodeNP (floor, __x, \
530 register long double __value; \
531 __volatile__ unsigned short int __cw; \
532 __volatile__ unsigned short int __cwtmp; \
533 __asm__ __volatile__ ("fnstcw %0" : "=m" (__cw)); \
534 __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ \
535 __asm__ __volatile__ ("fldcw %0" : : "m" (__cwtmp)); \
536 __asm__ __volatile__ ("frndint" : "=t" (__value) : "0" (__x)); \
537 __asm__ __volatile__ ("fldcw %0" : : "m" (__cw)); \
540 __inline_mathcodeNP (ceil, __x, \
541 register long double __value; \
542 __volatile__ unsigned short int __cw; \
543 __volatile__ unsigned short int __cwtmp; \
544 __asm__ __volatile__ ("fnstcw %0" : "=m" (__cw)); \
545 __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ \
546 __asm__ __volatile__ ("fldcw %0" : : "m" (__cwtmp)); \
547 __asm__ __volatile__ ("frndint" : "=t" (__value) : "0" (__x)); \
548 __asm__ __volatile__ ("fldcw %0" : : "m" (__cw)); \
552 # define __ldexp_code \
553 register long double __value; \
554 __asm__ __volatile__ \
556 : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
560 __NTH (ldexp (double __x, int __y))
567 /* Optimized versions for some non-standardized functions. */
568 #if defined __USE_ISOC99 || defined __USE_MISC
570 # ifdef __FAST_MATH__
571 __inline_mathcodeNP (expm1, __x, __expm1_code)
573 /* We cannot rely on M_SQRT being defined. So we do it for ourself
575 # define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
577 # if !__GNUC_PREREQ (3, 5)
578 __inline_mathcodeNP (log1p, __x, \
579 register long double __value; \
580 if (__fabsl (__x) >= 1.0 - 0.5 * __M_SQRT2) \
581 __value = logl (1.0 + __x); \
583 __asm__ __volatile__ \
587 : "=t" (__value) : "0" (__x) : "st(1)"); \
592 /* The argument range of the inline version of asinhl is slightly reduced. */
593 __inline_mathcodeNP (asinh, __x, \
594 register long double __y = __fabsl (__x); \
595 return (log1pl (__y * __y / (__libc_sqrtl (__y * __y + 1.0) + 1.0) + __y) \
598 __inline_mathcodeNP (acosh, __x, \
599 return logl (__x + __libc_sqrtl (__x - 1.0) * __libc_sqrtl (__x + 1.0)))
601 __inline_mathcodeNP (atanh, __x, \
602 register long double __y = __fabsl (__x); \
603 return -0.5 * log1pl (-(__y + __y) / (1.0 + __y)) * __sgn1l (__x))
605 /* The argument range of the inline version of hypotl is slightly reduced. */
606 __inline_mathcodeNP2 (hypot, __x, __y,
607 return __libc_sqrtl (__x * __x + __y * __y))
609 # if !__GNUC_PREREQ (3, 5)
610 __inline_mathcodeNP(logb, __x, \
611 register long double __value; \
612 register long double __junk; \
613 __asm__ __volatile__ \
615 : "=t" (__junk), "=u" (__value) : "0" (__x)); \
623 # ifdef __FAST_MATH__
625 # if !__GNUC_PREREQ (3, 5)
626 __inline_mathop_declNP (log2, "fld1; fxch; fyl2x", "0" (__x) : "st(1)")
630 __NTH (ldexpf (float __x, int __y))
635 __MATH_INLINE long double
636 __NTH (ldexpl (long double __x, int __y))
641 __inline_mathcodeNP3 (fma, __x, __y, __z, return (__x * __y) + __z)
643 __inline_mathopNP (rint, "frndint")
644 # endif /* __FAST_MATH__ */
646 # define __lrint_code \
647 long int __lrintres; \
648 __asm__ __volatile__ \
650 : "=m" (__lrintres) : "t" (__x) : "st"); \
652 __MATH_INLINE long int
653 __NTH (lrintf (float __x))
657 __MATH_INLINE long int
658 __NTH (lrint (double __x))
662 __MATH_INLINE long int
663 __NTH (lrintl (long double __x))
669 # define __llrint_code \
670 long long int __llrintres; \
671 __asm__ __volatile__ \
673 : "=m" (__llrintres) : "t" (__x) : "st"); \
675 __MATH_INLINE long long int
676 __NTH (llrintf (float __x))
680 __MATH_INLINE long long int
681 __NTH (llrint (double __x))
685 __MATH_INLINE long long int
686 __NTH (llrintl (long double __x))
690 # undef __llrint_code
697 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
698 __inline_mathcodeNP2 (drem, __x, __y, \
699 register double __value; \
700 register int __clobbered; \
701 __asm__ __volatile__ \
706 : "=t" (__value), "=&a" (__clobbered) : "0" (__x), "u" (__y) : "cc"); \
711 /* This function is used in the `isfinite' macro. */
713 __NTH (__finite (double __x))
715 union { double __d; int __i[2]; } u;
717 /* Finite numbers have at least one zero bit in exponent. */
718 /* All other numbers will result in 0xffffffff after OR: */
719 return (u.__i[1] | 0x800fffff) != 0xffffffff;
723 __NTH (__finitef (float __x))
725 union { float __d; int __i; } u;
727 return (u.__i | 0x807fffff) != 0xffffffff;
731 /* Miscellaneous functions */
732 # ifdef __FAST_MATH__
733 __inline_mathcode (__coshm1, __x, \
734 register long double __exm1 = __expm1l (__fabsl (__x)); \
735 return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1)
737 __inline_mathcode (__acosh1p, __x, \
738 return log1pl (__x + __libc_sqrtl (__x) * __libc_sqrtl (__x + 2.0)))
740 # endif /* __FAST_MATH__ */
741 #endif /* __USE_MISC */
743 /* Undefine some of the large macros which are not used anymore. */
748 # undef __sincos_code
749 #endif /* __FAST_MATH__ */
751 #endif /* __NO_MATH_INLINES */
754 /* This code is used internally in the GNU libc. */
755 #ifdef __LIBC_INTERNAL_MATH_INLINES
756 __inline_mathop (__ieee754_sqrt, "fsqrt")
757 __inline_mathcode2 (__ieee754_atan2, __y, __x,
758 register long double __value;
759 __asm__ __volatile__ ("fpatan\n\t"
761 : "0" (__x), "u" (__y) : "st(1)");
765 #endif /* __GNUC__ */