1 /* Inline math functions for i387 and SSE.
2 Copyright (C) 1995-2012 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
20 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
23 #define __NTH(fct) __attribute__ ((__nothrow__)) fct
25 #ifndef __extern_always_inline
26 # define __MATH_INLINE __inline
28 # define __MATH_INLINE __extern_always_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 __BEGIN_NAMESPACE_C99
127 /* Test for negative number. Used in the signbit() macro. */
129 __signbitf (float __x
)
131 # ifdef __SSE2_MATH__
133 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
134 return (__m
& 0x8) != 0;
136 __extension__
union { float __f
; int __i
; } __u
= { __f
: __x
};
141 __signbit (double __x
)
143 # ifdef __SSE2_MATH__
145 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
146 return (__m
& 0x80) != 0;
148 __extension__
union { double __d
; int __i
[2]; } __u
= { __d
: __x
};
149 return __u
.__i
[1] < 0;
153 __signbitl (long double __x
)
155 __extension__
union { long double __l
; int __i
[3]; } __u
= { __l
: __x
};
156 return (__u
.__i
[2] & 0x8000) != 0;
164 /* The gcc, version 2.7 or below, has problems with all this inlining
165 code. So disable it for this version of the compiler. */
166 #if __GNUC_PREREQ (2, 8)
167 # if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \
168 && defined __OPTIMIZE__
169 /* GCC 3.4 introduced builtins for all functions below, so
170 there's no need to define any of these inline functions. */
173 __BEGIN_NAMESPACE_C99
175 /* Round to nearest integer. */
177 __MATH_INLINE
long int
178 __NTH (lrintf (float __x
))
181 /* Mark as volatile since the result is dependent on the state of
182 the SSE control register (the rounding mode). Otherwise GCC might
183 remove these assembler instructions since it does not know about
184 the rounding mode change and cannot currently be told. */
185 __asm
__volatile__ ("cvtss2si %1, %0" : "=r" (__res
) : "xm" (__x
));
189 # ifdef __SSE2_MATH__
190 __MATH_INLINE
long int
191 __NTH (lrint (double __x
))
194 /* Mark as volatile since the result is dependent on the state of
195 the SSE control register (the rounding mode). Otherwise GCC might
196 remove these assembler instructions since it does not know about
197 the rounding mode change and cannot currently be told. */
198 __asm
__volatile__ ("cvtsd2si %1, %0" : "=r" (__res
) : "xm" (__x
));
203 __MATH_INLINE
long long int
204 __NTH (llrintf (float __x
))
207 /* Mark as volatile since the result is dependent on the state of
208 the SSE control register (the rounding mode). Otherwise GCC might
209 remove these assembler instructions since it does not know about
210 the rounding mode change and cannot currently be told. */
211 __asm
__volatile__ ("cvtss2si %1, %0" : "=r" (__res
) : "xm" (__x
));
214 __MATH_INLINE
long long int
215 __NTH (llrint (double __x
))
218 /* Mark as volatile since the result is dependent on the state of
219 the SSE control register (the rounding mode). Otherwise GCC might
220 remove these assembler instructions since it does not know about
221 the rounding mode change and cannot currently be told. */
222 __asm
__volatile__ ("cvtsd2si %1, %0" : "=r" (__res
) : "xm" (__x
));
227 # if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
228 && defined __SSE2_MATH__
229 /* Determine maximum of two values. */
231 __NTH (fmaxf (float __x
, float __y
))
235 __asm ("vmaxss %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
238 __asm ("maxss %1, %0" : "+x" (__x
) : "xm" (__y
));
243 __NTH (fmax (double __x
, double __y
))
247 __asm ("vmaxsd %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
250 __asm ("maxsd %1, %0" : "+x" (__x
) : "xm" (__y
));
255 /* Determine minimum of two values. */
257 __NTH (fminf (float __x
, float __y
))
261 __asm ("vminss %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
264 __asm ("minss %1, %0" : "+x" (__x
) : "xm" (__y
));
269 __NTH (fmin (double __x
, double __y
))
273 __asm ("vminsd %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
276 __asm ("minsd %1, %0" : "+x" (__x
) : "xm" (__y
));
285 # if defined __SSE4_1__ && defined __SSE2_MATH__
286 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
287 __BEGIN_NAMESPACE_C99
289 /* Round to nearest integer. */
291 __NTH (rint (double __x
))
294 /* Mark as volatile since the result is dependent on the state of
295 the SSE control register (the rounding mode). Otherwise GCC might
296 remove these assembler instructions since it does not know about
297 the rounding mode change and cannot currently be told. */
298 __asm
__volatile__ ("roundsd $4, %1, %0" : "=x" (__res
) : "xm" (__x
));
302 __NTH (rintf (float __x
))
305 /* Mark as volatile since the result is dependent on the state of
306 the SSE control register (the rounding mode). Otherwise GCC might
307 remove these assembler instructions since it does not know about
308 the rounding mode change and cannot currently be told. */
309 __asm
__volatile__ ("roundss $4, %1, %0" : "=x" (__res
) : "xm" (__x
));
314 /* Round to nearest integer without raising inexact exception. */
316 __NTH (nearbyint (double __x
))
319 /* Mark as volatile since the result is dependent on the state of
320 the SSE control register (the rounding mode). Otherwise GCC might
321 remove these assembler instructions since it does not know about
322 the rounding mode change and cannot currently be told. */
323 __asm
__volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res
) : "xm" (__x
));
327 __NTH (nearbyintf (float __x
))
330 /* Mark as volatile since the result is dependent on the state of
331 the SSE control register (the rounding mode). Otherwise GCC might
332 remove these assembler instructions since it does not know about
333 the rounding mode change and cannot currently be told. */
334 __asm
__volatile__ ("roundss $0xc, %1, %0" : "=x" (__res
) : "xm" (__x
));
342 __BEGIN_NAMESPACE_STD
343 /* Smallest integral value not less than X. */
345 __NTH (ceil (double __x
))
348 __asm ("roundsd $2, %1, %0" : "=x" (__res
) : "xm" (__x
));
353 __BEGIN_NAMESPACE_C99
355 __NTH (ceilf (float __x
))
358 __asm ("roundss $2, %1, %0" : "=x" (__res
) : "xm" (__x
));
363 __BEGIN_NAMESPACE_STD
364 /* Largest integer not greater than X. */
366 __NTH (floor (double __x
))
369 __asm ("roundsd $1, %1, %0" : "=x" (__res
) : "xm" (__x
));
374 __BEGIN_NAMESPACE_C99
376 __NTH (floorf (float __x
))
379 __asm ("roundss $1, %1, %0" : "=x" (__res
) : "xm" (__x
));
388 # if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
389 && defined __OPTIMIZE__)
391 /* The inline functions do not set errno or raise necessarily the
392 correct exceptions. */
393 # undef math_errhandling
395 /* A macro to define float, double, and long double versions of various
396 math functions for the ix87 FPU. FUNC is the function name (which will
397 be suffixed with f and l for the float and long double version,
398 respectively). OP is the name of the FPU operation.
399 We define two sets of macros. The set with the additional NP
400 doesn't add a prototype declaration. */
402 # if defined __USE_MISC || defined __USE_ISOC99
403 # define __inline_mathop(func, op) \
404 __inline_mathop_ (double, func, op) \
405 __inline_mathop_ (float, __CONCAT(func,f), op) \
406 __inline_mathop_ (long double, __CONCAT(func,l), op)
407 # define __inline_mathopNP(func, op) \
408 __inline_mathopNP_ (double, func, op) \
409 __inline_mathopNP_ (float, __CONCAT(func,f), op) \
410 __inline_mathopNP_ (long double, __CONCAT(func,l), op)
412 # define __inline_mathop(func, op) \
413 __inline_mathop_ (double, func, op)
414 # define __inline_mathopNP(func, op) \
415 __inline_mathopNP_ (double, func, op)
418 # define __inline_mathop_(float_type, func, op) \
419 __inline_mathop_decl_ (float_type, func, op, "0" (__x))
420 # define __inline_mathopNP_(float_type, func, op) \
421 __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
424 # if defined __USE_MISC || defined __USE_ISOC99
425 # define __inline_mathop_decl(func, op, params...) \
426 __inline_mathop_decl_ (double, func, op, params) \
427 __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
428 __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
429 # define __inline_mathop_declNP(func, op, params...) \
430 __inline_mathop_declNP_ (double, func, op, params) \
431 __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
432 __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
434 # define __inline_mathop_decl(func, op, params...) \
435 __inline_mathop_decl_ (double, func, op, params)
436 # define __inline_mathop_declNP(func, op, params...) \
437 __inline_mathop_declNP_ (double, func, op, params)
440 # define __inline_mathop_decl_(float_type, func, op, params...) \
441 __MATH_INLINE float_type func (float_type) __THROW; \
442 __inline_mathop_declNP_ (float_type, func, op, params)
444 # define __inline_mathop_declNP_(float_type, func, op, params...) \
445 __MATH_INLINE float_type __NTH (func (float_type __x)) \
447 register float_type __result; \
448 __asm __volatile__ (op : "=t" (__result) : params); \
453 # if defined __USE_MISC || defined __USE_ISOC99
454 # define __inline_mathcode(func, arg, code) \
455 __inline_mathcode_ (double, func, arg, code) \
456 __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
457 __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
458 # define __inline_mathcodeNP(func, arg, code) \
459 __inline_mathcodeNP_ (double, func, arg, code) \
460 __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
461 __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
462 # define __inline_mathcode2(func, arg1, arg2, code) \
463 __inline_mathcode2_ (double, func, arg1, arg2, code) \
464 __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
465 __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
466 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
467 __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
468 __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
469 __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
470 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
471 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
472 __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
473 __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
474 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
475 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
476 __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
477 __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
479 # define __inline_mathcode(func, arg, code) \
480 __inline_mathcode_ (double, func, (arg), code)
481 # define __inline_mathcodeNP(func, arg, code) \
482 __inline_mathcodeNP_ (double, func, (arg), code)
483 # define __inline_mathcode2(func, arg1, arg2, code) \
484 __inline_mathcode2_ (double, func, arg1, arg2, code)
485 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
486 __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
487 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
488 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
489 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
490 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
493 # define __inline_mathcode_(float_type, func, arg, code) \
494 __MATH_INLINE float_type func (float_type) __THROW; \
495 __inline_mathcodeNP_(float_type, func, arg, code)
497 # define __inline_mathcodeNP_(float_type, func, arg, code) \
498 __MATH_INLINE float_type __NTH (func (float_type arg)) \
504 # define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
505 __MATH_INLINE float_type func (float_type, float_type) __THROW; \
506 __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
508 # define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
509 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
514 # define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
515 __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
516 __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
518 # define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
519 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
527 # if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
528 /* Miscellaneous functions */
530 /* __FAST_MATH__ is defined by gcc -ffast-math. */
531 # ifdef __FAST_MATH__
533 # define __sincos_code \
534 register long double __cosr; \
535 register long double __sinr; \
536 register unsigned int __swtmp; \
540 "testl $0x400, %2\n\t" \
547 "testl $0x400, %2\n\t" \
552 : "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x)); \
557 __NTH (__sincos (double __x
, double *__sinx
, double *__cosx
))
563 __NTH (__sincosf (float __x
, float *__sinx
, float *__cosx
))
569 __NTH (__sincosl (long double __x
, long double *__sinx
, long double *__cosx
))
576 /* Optimized inline implementation, sometimes with reduced precision
577 and/or argument range. */
579 # if __GNUC_PREREQ (3, 5)
580 # define __expm1_code \
581 register long double __temp; \
582 __temp = __builtin_expm1l (__x); \
583 return __temp ? __temp : __x
585 # define __expm1_code \
586 register long double __value; \
587 register long double __exponent; \
588 register long double __temp; \
590 ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
591 "fmul %%st(1) # x * log2(e)\n\t" \
593 "frndint # int(x * log2(e))\n\t" \
595 "fsub %%st(1) # fract(x * log2(e))\n\t" \
596 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
597 "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
598 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
600 ("fscale # 2^int(x * log2(e))\n\t" \
601 : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
604 return __temp ? __temp : __x
606 __inline_mathcodeNP_ (long double, __expm1l
, __x
, __expm1_code
)
608 # if __GNUC_PREREQ (3, 4)
609 __inline_mathcodeNP_ (long double, __expl
, __x
, return __builtin_expl (__x
))
611 # define __exp_code \
612 register long double __value; \
613 register long double __exponent; \
615 ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
616 "fmul %%st(1) # x * log2(e)\n\t" \
618 "frndint # int(x * log2(e))\n\t" \
620 "fsub %%st(1) # fract(x * log2(e))\n\t" \
621 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
622 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
626 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
628 __inline_mathcodeNP (exp
, __x
, __exp_code
)
629 __inline_mathcodeNP_ (long double, __expl
, __x
, __exp_code
)
633 # if !__GNUC_PREREQ (3, 5)
634 __inline_mathcodeNP (tan
, __x
, \
635 register long double __value
; \
636 register long double __value2
__attribute__ ((__unused__
)); \
639 : "=t" (__value2
), "=u" (__value
) : "0" (__x
)); \
642 # endif /* __FAST_MATH__ */
645 # if __GNUC_PREREQ (3, 4)
646 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
,
647 return __builtin_atan2l (__y
, __x
))
649 # define __atan2_code \
650 register long double __value; \
653 : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
655 # ifdef __FAST_MATH__
656 __inline_mathcodeNP2 (atan2
, __y
, __x
, __atan2_code
)
658 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
, __atan2_code
)
662 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
663 __inline_mathcodeNP2 (fmod
, __x
, __y
, \
664 register long double __value
; \
670 : "=t" (__value
) : "0" (__x
), "u" (__y
) : "ax", "cc"); \
675 # ifdef __FAST_MATH__
676 # if !__GNUC_PREREQ (3,3)
677 __inline_mathopNP (sqrt
, "fsqrt")
678 __inline_mathopNP_ (long double, __sqrtl
, "fsqrt")
679 # define __libc_sqrtl(n) __sqrtl (n)
681 # define __libc_sqrtl(n) __builtin_sqrtl (n)
685 # if __GNUC_PREREQ (2, 8)
686 __inline_mathcodeNP_ (double, fabs
, __x
, return __builtin_fabs (__x
))
687 # if defined __USE_MISC || defined __USE_ISOC99
688 __inline_mathcodeNP_ (float, fabsf
, __x
, return __builtin_fabsf (__x
))
689 __inline_mathcodeNP_ (long double, fabsl
, __x
, return __builtin_fabsl (__x
))
691 __inline_mathcodeNP_ (long double, __fabsl
, __x
, return __builtin_fabsl (__x
))
693 __inline_mathop (fabs
, "fabs")
694 __inline_mathop_ (long double, __fabsl
, "fabs")
697 # ifdef __FAST_MATH__
698 # if !__GNUC_PREREQ (3, 4)
699 /* The argument range of this inline version is reduced. */
700 __inline_mathopNP (sin
, "fsin")
701 /* The argument range of this inline version is reduced. */
702 __inline_mathopNP (cos
, "fcos")
704 __inline_mathop_declNP (log
, "fldln2; fxch; fyl2x", "0" (__x
) : "st(1)")
707 # if !__GNUC_PREREQ (3, 5)
708 __inline_mathop_declNP (log10
, "fldlg2; fxch; fyl2x", "0" (__x
) : "st(1)")
710 __inline_mathcodeNP (asin
, __x
, return __atan2l (__x
, __libc_sqrtl (1.0 - __x
* __x
)))
711 __inline_mathcodeNP (acos
, __x
, return __atan2l (__libc_sqrtl (1.0 - __x
* __x
), __x
))
714 # if !__GNUC_PREREQ (3, 4)
715 __inline_mathop_declNP (atan
, "fld1; fpatan", "0" (__x
) : "st(1)")
717 # endif /* __FAST_MATH__ */
719 __inline_mathcode_ (long double, __sgn1l
, __x
, \
720 __extension__
union { long double __xld
; unsigned int __xi
[3]; } __n
= \
722 __n
.__xi
[2] = (__n
.__xi
[2] & 0x8000) | 0x3fff; \
723 __n
.__xi
[1] = 0x80000000; \
728 # ifdef __FAST_MATH__
729 /* The argument range of the inline version of sinhl is slightly reduced. */
730 __inline_mathcodeNP (sinh
, __x
, \
731 register long double __exm1
= __expm1l (__fabsl (__x
)); \
732 return 0.5 * (__exm1
/ (__exm1
+ 1.0) + __exm1
) * __sgn1l (__x
))
734 __inline_mathcodeNP (cosh
, __x
, \
735 register long double __ex
= __expl (__x
); \
736 return 0.5 * (__ex
+ 1.0 / __ex
))
738 __inline_mathcodeNP (tanh
, __x
, \
739 register long double __exm1
= __expm1l (-__fabsl (__x
+ __x
)); \
740 return __exm1
/ (__exm1
+ 2.0) * __sgn1l (-__x
))
743 __inline_mathcodeNP (floor
, __x
, \
744 register long double __value
; \
745 register int __ignore
; \
746 unsigned short int __cw
; \
747 unsigned short int __cwtmp
; \
748 __asm
__volatile ("fnstcw %3\n\t" \
749 "movzwl %3, %1\n\t" \
750 "andl $0xf3ff, %1\n\t" \
751 "orl $0x0400, %1\n\t" /* rounding down */ \
756 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
761 __inline_mathcodeNP (ceil
, __x
, \
762 register long double __value
; \
763 register int __ignore
; \
764 unsigned short int __cw
; \
765 unsigned short int __cwtmp
; \
766 __asm
__volatile ("fnstcw %3\n\t" \
767 "movzwl %3, %1\n\t" \
768 "andl $0xf3ff, %1\n\t" \
769 "orl $0x0800, %1\n\t" /* rounding up */ \
774 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
779 # ifdef __FAST_MATH__
780 # define __ldexp_code \
781 register long double __value; \
784 : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
788 __NTH (ldexp (double __x
, int __y
))
795 /* Optimized versions for some non-standardized functions. */
796 # if defined __USE_ISOC99 || defined __USE_MISC
798 # ifdef __FAST_MATH__
799 __inline_mathcodeNP (expm1
, __x
, __expm1_code
)
801 /* We cannot rely on M_SQRT being defined. So we do it for ourself
803 # define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
805 # if !__GNUC_PREREQ (3, 5)
806 __inline_mathcodeNP (log1p
, __x
, \
807 register long double __value
; \
808 if (__fabsl (__x
) >= 1.0 - 0.5 * __M_SQRT2
) \
809 __value
= logl (1.0 + __x
); \
815 : "=t" (__value
) : "0" (__x
) : "st(1)"); \
820 /* The argument range of the inline version of asinhl is slightly reduced. */
821 __inline_mathcodeNP (asinh
, __x
, \
822 register long double __y
= __fabsl (__x
); \
823 return (log1pl (__y
* __y
/ (__libc_sqrtl (__y
* __y
+ 1.0) + 1.0) + __y
) \
826 __inline_mathcodeNP (acosh
, __x
, \
827 return logl (__x
+ __libc_sqrtl (__x
- 1.0) * __libc_sqrtl (__x
+ 1.0)))
829 __inline_mathcodeNP (atanh
, __x
, \
830 register long double __y
= __fabsl (__x
); \
831 return -0.5 * log1pl (-(__y
+ __y
) / (1.0 + __y
)) * __sgn1l (__x
))
833 /* The argument range of the inline version of hypotl is slightly reduced. */
834 __inline_mathcodeNP2 (hypot
, __x
, __y
,
835 return __libc_sqrtl (__x
* __x
+ __y
* __y
))
837 # if !__GNUC_PREREQ (3, 5)
838 __inline_mathcodeNP(logb
, __x
, \
839 register long double __value
; \
840 register long double __junk
; \
843 : "=t" (__junk
), "=u" (__value
) : "0" (__x
)); \
851 # ifdef __FAST_MATH__
853 # if !__GNUC_PREREQ (3, 5)
854 __inline_mathop_declNP (log2
, "fld1; fxch; fyl2x", "0" (__x
) : "st(1)")
858 __NTH (ldexpf (float __x
, int __y
))
863 __MATH_INLINE
long double
864 __NTH (ldexpl (long double __x
, int __y
))
869 __inline_mathopNP (rint
, "frndint")
870 # endif /* __FAST_MATH__ */
872 # define __lrint_code \
873 long int __lrintres; \
874 __asm__ __volatile__ \
876 : "=m" (__lrintres) : "t" (__x) : "st"); \
878 __MATH_INLINE
long int
879 __NTH (lrintf (float __x
))
883 __MATH_INLINE
long int
884 __NTH (lrint (double __x
))
888 __MATH_INLINE
long int
889 __NTH (lrintl (long double __x
))
895 # define __llrint_code \
896 long long int __llrintres; \
897 __asm__ __volatile__ \
899 : "=m" (__llrintres) : "t" (__x) : "st"); \
901 __MATH_INLINE
long long int
902 __NTH (llrintf (float __x
))
906 __MATH_INLINE
long long int
907 __NTH (llrint (double __x
))
911 __MATH_INLINE
long long int
912 __NTH (llrintl (long double __x
))
916 # undef __llrint_code
923 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
924 __inline_mathcodeNP2 (drem
, __x
, __y
, \
925 register double __value
; \
926 register int __clobbered
; \
932 : "=t" (__value
), "=&a" (__clobbered
) : "0" (__x
), "u" (__y
) : "cc"); \
937 /* This function is used in the `isfinite' macro. */
939 __NTH (__finite (double __x
))
941 return (__extension__
942 (((((union { double __d
; int __i
[2]; }) {__d
: __x
}).__i
[1]
943 | 0x800fffffu
) + 1) >> 31));
946 # endif /* __USE_MISC */
948 /* Undefine some of the large macros which are not used anymore. */
950 # ifdef __FAST_MATH__
953 # undef __sincos_code
954 # endif /* __FAST_MATH__ */
956 # endif /* __NO_MATH_INLINES */
959 /* This code is used internally in the GNU libc. */
960 # ifdef __LIBC_INTERNAL_MATH_INLINES
961 __inline_mathop (__ieee754_sqrt
, "fsqrt")
962 __inline_mathcode2 (__ieee754_atan2
, __y
, __x
,
963 register long double __value
;
964 __asm
__volatile__ ("fpatan\n\t"
966 : "0" (__x
), "u" (__y
) : "st(1)");
970 #endif /* !__x86_64__ */