1 /* Inline math functions for i387 and SSE.
2 Copyright (C) 1995-2015 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 #ifndef __extern_always_inline
24 # define __MATH_INLINE __inline
26 # define __MATH_INLINE __extern_always_inline
30 #if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
31 /* GCC 2.97 and up have builtins that actually can be used. */
32 # if !__GNUC_PREREQ (2,97)
33 /* ISO C99 defines some macros to perform unordered comparisons. The
34 ix87 FPU supports this with special opcodes and we should use them.
35 These must not be inline functions since we have to be able to handle
36 all floating-point types. */
38 # undef isgreaterequal
44 /* For the PentiumPro and more recent processors we can provide
46 # define isgreater(x, y) \
47 ({ register char __result; \
48 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
49 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
51 # define isgreaterequal(x, y) \
52 ({ register char __result; \
53 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
54 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
57 # define isless(x, y) \
58 ({ register char __result; \
59 __asm__ ("fucomip %%st(1), %%st; seta %%al" \
60 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
63 # define islessequal(x, y) \
64 ({ register char __result; \
65 __asm__ ("fucomip %%st(1), %%st; setae %%al" \
66 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st"); \
69 # define islessgreater(x, y) \
70 ({ register char __result; \
71 __asm__ ("fucomip %%st(1), %%st; setne %%al" \
72 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
75 # define isunordered(x, y) \
76 ({ register char __result; \
77 __asm__ ("fucomip %%st(1), %%st; setp %%al" \
78 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); \
81 /* This is the dumb, portable code for i386 and above. */
82 # define isgreater(x, y) \
83 ({ register char __result; \
84 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
85 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
88 # define isgreaterequal(x, y) \
89 ({ register char __result; \
90 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
91 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
94 # define isless(x, y) \
95 ({ register char __result; \
96 __asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al" \
97 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
100 # define islessequal(x, y) \
101 ({ register char __result; \
102 __asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al" \
103 : "=a" (__result) : "u" (x), "t" (y) : "cc", "st", "st(1)"); \
106 # define islessgreater(x, y) \
107 ({ register char __result; \
108 __asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al" \
109 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
112 # define isunordered(x, y) \
113 ({ register char __result; \
114 __asm__ ("fucompp; fnstsw; sahf; setp %%al" \
115 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
117 # endif /* __i686__ */
118 # endif /* GCC 2.97 */
120 /* The gcc, version 2.7 or below, has problems with all this inlining
121 code. So disable it for this version of the compiler. */
122 # if __GNUC_PREREQ (2, 8)
123 __BEGIN_NAMESPACE_C99
125 /* Test for negative number. Used in the signbit() macro. */
127 __NTH (__signbitf (float __x
))
129 # ifdef __SSE2_MATH__
131 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
132 return (__m
& 0x8) != 0;
134 __extension__
union { float __f
; int __i
; } __u
= { __f
: __x
};
139 __NTH (__signbit (double __x
))
141 # ifdef __SSE2_MATH__
143 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
144 return (__m
& 0x80) != 0;
146 __extension__
union { double __d
; int __i
[2]; } __u
= { __d
: __x
};
147 return __u
.__i
[1] < 0;
151 __NTH (__signbitl (long double __x
))
153 __extension__
union { long double __l
; int __i
[3]; } __u
= { __l
: __x
};
154 return (__u
.__i
[2] & 0x8000) != 0;
162 /* The gcc, version 2.7 or below, has problems with all this inlining
163 code. So disable it for this version of the compiler. */
164 #if __GNUC_PREREQ (2, 8)
165 # if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \
166 && defined __OPTIMIZE__
167 /* GCC 3.4 introduced builtins for all functions below, so
168 there's no need to define any of these inline functions. */
171 __BEGIN_NAMESPACE_C99
173 /* Round to nearest integer. */
175 __MATH_INLINE
long int
176 __NTH (lrintf (float __x
))
179 /* Mark as volatile since the result is dependent on the state of
180 the SSE control register (the rounding mode). Otherwise GCC might
181 remove these assembler instructions since it does not know about
182 the rounding mode change and cannot currently be told. */
183 __asm
__volatile__ ("cvtss2si %1, %0" : "=r" (__res
) : "xm" (__x
));
187 # ifdef __SSE2_MATH__
188 __MATH_INLINE
long int
189 __NTH (lrint (double __x
))
192 /* Mark as volatile since the result is dependent on the state of
193 the SSE control register (the rounding mode). Otherwise GCC might
194 remove these assembler instructions since it does not know about
195 the rounding mode change and cannot currently be told. */
196 __asm
__volatile__ ("cvtsd2si %1, %0" : "=r" (__res
) : "xm" (__x
));
202 __MATH_INLINE
long long int
203 __NTH (llrintf (float __x
))
206 /* Mark as volatile since the result is dependent on the state of
207 the SSE control register (the rounding mode). Otherwise GCC might
208 remove these assembler instructions since it does not know about
209 the rounding mode change and cannot currently be told. */
210 __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_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
));
387 /* Disable x87 inlines when -fpmath=sse is passed and also when we're building
388 on x86_64. Older gcc (gcc-3.2 for example) does not define __SSE2_MATH__
390 #if !defined __SSE2_MATH__ && !defined __x86_64__
391 # if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
392 && defined __OPTIMIZE__)
394 /* The inline functions do not set errno or raise necessarily the
395 correct exceptions. */
396 # undef math_errhandling
398 /* A macro to define float, double, and long double versions of various
399 math functions for the ix87 FPU. FUNC is the function name (which will
400 be suffixed with f and l for the float and long double version,
401 respectively). OP is the name of the FPU operation.
402 We define two sets of macros. The set with the additional NP
403 doesn't add a prototype declaration. */
406 # define __inline_mathop(func, op) \
407 __inline_mathop_ (double, func, op) \
408 __inline_mathop_ (float, __CONCAT(func,f), op) \
409 __inline_mathop_ (long double, __CONCAT(func,l), op)
410 # define __inline_mathopNP(func, op) \
411 __inline_mathopNP_ (double, func, op) \
412 __inline_mathopNP_ (float, __CONCAT(func,f), op) \
413 __inline_mathopNP_ (long double, __CONCAT(func,l), op)
415 # define __inline_mathop(func, op) \
416 __inline_mathop_ (double, func, op)
417 # define __inline_mathopNP(func, op) \
418 __inline_mathopNP_ (double, func, op)
421 # define __inline_mathop_(float_type, func, op) \
422 __inline_mathop_decl_ (float_type, func, op, "0" (__x))
423 # define __inline_mathopNP_(float_type, func, op) \
424 __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
428 # define __inline_mathop_decl(func, op, params...) \
429 __inline_mathop_decl_ (double, func, op, params) \
430 __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
431 __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
432 # define __inline_mathop_declNP(func, op, params...) \
433 __inline_mathop_declNP_ (double, func, op, params) \
434 __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
435 __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
437 # define __inline_mathop_decl(func, op, params...) \
438 __inline_mathop_decl_ (double, func, op, params)
439 # define __inline_mathop_declNP(func, op, params...) \
440 __inline_mathop_declNP_ (double, func, op, params)
443 # define __inline_mathop_decl_(float_type, func, op, params...) \
444 __MATH_INLINE float_type func (float_type) __THROW; \
445 __inline_mathop_declNP_ (float_type, func, op, params)
447 # define __inline_mathop_declNP_(float_type, func, op, params...) \
448 __MATH_INLINE float_type __NTH (func (float_type __x)) \
450 register float_type __result; \
451 __asm __volatile__ (op : "=t" (__result) : params); \
457 # define __inline_mathcode(func, arg, code) \
458 __inline_mathcode_ (double, func, arg, code) \
459 __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
460 __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
461 # define __inline_mathcodeNP(func, arg, code) \
462 __inline_mathcodeNP_ (double, func, arg, code) \
463 __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
464 __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
465 # define __inline_mathcode2(func, arg1, arg2, code) \
466 __inline_mathcode2_ (double, func, arg1, arg2, code) \
467 __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
468 __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
469 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
470 __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
471 __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
472 __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
473 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
474 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
475 __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
476 __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
477 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
478 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
479 __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
480 __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
482 # define __inline_mathcode(func, arg, code) \
483 __inline_mathcode_ (double, func, (arg), code)
484 # define __inline_mathcodeNP(func, arg, code) \
485 __inline_mathcodeNP_ (double, func, (arg), code)
486 # define __inline_mathcode2(func, arg1, arg2, code) \
487 __inline_mathcode2_ (double, func, arg1, arg2, code)
488 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
489 __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
490 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
491 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
492 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
493 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
496 # define __inline_mathcode_(float_type, func, arg, code) \
497 __MATH_INLINE float_type func (float_type) __THROW; \
498 __inline_mathcodeNP_(float_type, func, arg, code)
500 # define __inline_mathcodeNP_(float_type, func, arg, code) \
501 __MATH_INLINE float_type __NTH (func (float_type arg)) \
507 # define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
508 __MATH_INLINE float_type func (float_type, float_type) __THROW; \
509 __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
511 # define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
512 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
517 # define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
518 __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
519 __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
521 # define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
522 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
530 # if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
531 /* Miscellaneous functions */
533 /* __FAST_MATH__ is defined by gcc -ffast-math. */
534 # ifdef __FAST_MATH__
536 # define __sincos_code \
537 register long double __cosr; \
538 register long double __sinr; \
539 register unsigned int __swtmp; \
543 "testl $0x400, %2\n\t" \
550 "testl $0x400, %2\n\t" \
555 : "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x)); \
560 __NTH (__sincos (double __x
, double *__sinx
, double *__cosx
))
566 __NTH (__sincosf (float __x
, float *__sinx
, float *__cosx
))
572 __NTH (__sincosl (long double __x
, long double *__sinx
, long double *__cosx
))
579 /* Optimized inline implementation, sometimes with reduced precision
580 and/or argument range. */
582 # if __GNUC_PREREQ (3, 5)
583 # define __expm1_code \
584 register long double __temp; \
585 __temp = __builtin_expm1l (__x); \
586 return __temp ? __temp : __x
588 # define __expm1_code \
589 register long double __value; \
590 register long double __exponent; \
591 register long double __temp; \
593 ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
594 "fmul %%st(1) # x * log2(e)\n\t" \
596 "frndint # int(x * log2(e))\n\t" \
598 "fsub %%st(1) # fract(x * log2(e))\n\t" \
599 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
600 "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
601 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
603 ("fscale # 2^int(x * log2(e))\n\t" \
604 : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
607 return __temp ? __temp : __x
609 __inline_mathcodeNP_ (long double, __expm1l
, __x
, __expm1_code
)
611 # if __GNUC_PREREQ (3, 4)
612 __inline_mathcodeNP_ (long double, __expl
, __x
, return __builtin_expl (__x
))
614 # define __exp_code \
615 register long double __value; \
616 register long double __exponent; \
618 ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
619 "fmul %%st(1) # x * log2(e)\n\t" \
621 "frndint # int(x * log2(e))\n\t" \
623 "fsub %%st(1) # fract(x * log2(e))\n\t" \
624 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
625 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
629 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
631 __inline_mathcodeNP (exp
, __x
, __exp_code
)
632 __inline_mathcodeNP_ (long double, __expl
, __x
, __exp_code
)
636 # if !__GNUC_PREREQ (3, 5)
637 __inline_mathcodeNP (tan
, __x
, \
638 register long double __value
; \
639 register long double __value2
__attribute__ ((__unused__
)); \
642 : "=t" (__value2
), "=u" (__value
) : "0" (__x
)); \
645 # endif /* __FAST_MATH__ */
648 # if __GNUC_PREREQ (3, 4)
649 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
,
650 return __builtin_atan2l (__y
, __x
))
652 # define __atan2_code \
653 register long double __value; \
656 : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
658 # ifdef __FAST_MATH__
659 __inline_mathcodeNP2 (atan2
, __y
, __x
, __atan2_code
)
661 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
, __atan2_code
)
665 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
666 __inline_mathcodeNP2 (fmod
, __x
, __y
, \
667 register long double __value
; \
673 : "=t" (__value
) : "0" (__x
), "u" (__y
) : "ax", "cc"); \
678 # ifdef __FAST_MATH__
679 # if !__GNUC_PREREQ (3,3)
680 __inline_mathopNP (sqrt
, "fsqrt")
681 __inline_mathopNP_ (long double, __sqrtl
, "fsqrt")
682 # define __libc_sqrtl(n) __sqrtl (n)
684 # define __libc_sqrtl(n) __builtin_sqrtl (n)
688 # if __GNUC_PREREQ (2, 8)
689 __inline_mathcodeNP_ (double, fabs
, __x
, return __builtin_fabs (__x
))
691 __inline_mathcodeNP_ (float, fabsf
, __x
, return __builtin_fabsf (__x
))
692 __inline_mathcodeNP_ (long double, fabsl
, __x
, return __builtin_fabsl (__x
))
694 __inline_mathcodeNP_ (long double, __fabsl
, __x
, return __builtin_fabsl (__x
))
696 __inline_mathop (fabs
, "fabs")
697 __inline_mathop_ (long double, __fabsl
, "fabs")
700 # ifdef __FAST_MATH__
701 # if !__GNUC_PREREQ (3, 4)
702 /* The argument range of this inline version is reduced. */
703 __inline_mathopNP (sin
, "fsin")
704 /* The argument range of this inline version is reduced. */
705 __inline_mathopNP (cos
, "fcos")
707 __inline_mathop_declNP (log
, "fldln2; fxch; fyl2x", "0" (__x
) : "st(1)")
710 # if !__GNUC_PREREQ (3, 5)
711 __inline_mathop_declNP (log10
, "fldlg2; fxch; fyl2x", "0" (__x
) : "st(1)")
713 __inline_mathcodeNP (asin
, __x
, return __atan2l (__x
, __libc_sqrtl (1.0 - __x
* __x
)))
714 __inline_mathcodeNP (acos
, __x
, return __atan2l (__libc_sqrtl (1.0 - __x
* __x
), __x
))
717 # if !__GNUC_PREREQ (3, 4)
718 __inline_mathop_declNP (atan
, "fld1; fpatan", "0" (__x
) : "st(1)")
720 # endif /* __FAST_MATH__ */
722 __inline_mathcode_ (long double, __sgn1l
, __x
, \
723 __extension__
union { long double __xld
; unsigned int __xi
[3]; } __n
= \
725 __n
.__xi
[2] = (__n
.__xi
[2] & 0x8000) | 0x3fff; \
726 __n
.__xi
[1] = 0x80000000; \
731 # ifdef __FAST_MATH__
732 /* The argument range of the inline version of sinhl is slightly reduced. */
733 __inline_mathcodeNP (sinh
, __x
, \
734 register long double __exm1
= __expm1l (__fabsl (__x
)); \
735 return 0.5 * (__exm1
/ (__exm1
+ 1.0) + __exm1
) * __sgn1l (__x
))
737 __inline_mathcodeNP (cosh
, __x
, \
738 register long double __ex
= __expl (__x
); \
739 return 0.5 * (__ex
+ 1.0 / __ex
))
741 __inline_mathcodeNP (tanh
, __x
, \
742 register long double __exm1
= __expm1l (-__fabsl (__x
+ __x
)); \
743 return __exm1
/ (__exm1
+ 2.0) * __sgn1l (-__x
))
746 __inline_mathcodeNP (floor
, __x
, \
747 register long double __value
; \
748 register int __ignore
; \
749 unsigned short int __cw
; \
750 unsigned short int __cwtmp
; \
751 __asm
__volatile ("fnstcw %3\n\t" \
752 "movzwl %3, %1\n\t" \
753 "andl $0xf3ff, %1\n\t" \
754 "orl $0x0400, %1\n\t" /* rounding down */ \
759 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
764 __inline_mathcodeNP (ceil
, __x
, \
765 register long double __value
; \
766 register int __ignore
; \
767 unsigned short int __cw
; \
768 unsigned short int __cwtmp
; \
769 __asm
__volatile ("fnstcw %3\n\t" \
770 "movzwl %3, %1\n\t" \
771 "andl $0xf3ff, %1\n\t" \
772 "orl $0x0800, %1\n\t" /* rounding up */ \
777 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
782 # ifdef __FAST_MATH__
783 # define __ldexp_code \
784 register long double __value; \
787 : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
791 __NTH (ldexp (double __x
, int __y
))
798 /* Optimized versions for some non-standardized functions. */
801 # ifdef __FAST_MATH__
802 __inline_mathcodeNP (expm1
, __x
, __expm1_code
)
804 /* We cannot rely on M_SQRT being defined. So we do it for ourself
806 # define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
808 # if !__GNUC_PREREQ (3, 5)
809 __inline_mathcodeNP (log1p
, __x
, \
810 register long double __value
; \
811 if (__fabsl (__x
) >= 1.0 - 0.5 * __M_SQRT2
) \
812 __value
= logl (1.0 + __x
); \
818 : "=t" (__value
) : "0" (__x
) : "st(1)"); \
823 /* The argument range of the inline version of asinhl is slightly reduced. */
824 __inline_mathcodeNP (asinh
, __x
, \
825 register long double __y
= __fabsl (__x
); \
826 return (log1pl (__y
* __y
/ (__libc_sqrtl (__y
* __y
+ 1.0) + 1.0) + __y
) \
829 __inline_mathcodeNP (acosh
, __x
, \
830 return logl (__x
+ __libc_sqrtl (__x
- 1.0) * __libc_sqrtl (__x
+ 1.0)))
832 __inline_mathcodeNP (atanh
, __x
, \
833 register long double __y
= __fabsl (__x
); \
834 return -0.5 * log1pl (-(__y
+ __y
) / (1.0 + __y
)) * __sgn1l (__x
))
836 /* The argument range of the inline version of hypotl is slightly reduced. */
837 __inline_mathcodeNP2 (hypot
, __x
, __y
,
838 return __libc_sqrtl (__x
* __x
+ __y
* __y
))
840 # if !__GNUC_PREREQ (3, 5)
841 __inline_mathcodeNP(logb
, __x
, \
842 register long double __value
; \
843 register long double __junk
; \
846 : "=t" (__junk
), "=u" (__value
) : "0" (__x
)); \
854 # ifdef __FAST_MATH__
856 # if !__GNUC_PREREQ (3, 5)
857 __inline_mathop_declNP (log2
, "fld1; fxch; fyl2x", "0" (__x
) : "st(1)")
861 __NTH (ldexpf (float __x
, int __y
))
866 __MATH_INLINE
long double
867 __NTH (ldexpl (long double __x
, int __y
))
872 __inline_mathopNP (rint
, "frndint")
873 # endif /* __FAST_MATH__ */
875 # define __lrint_code \
876 long int __lrintres; \
877 __asm__ __volatile__ \
879 : "=m" (__lrintres) : "t" (__x) : "st"); \
881 __MATH_INLINE
long int
882 __NTH (lrintf (float __x
))
886 __MATH_INLINE
long int
887 __NTH (lrint (double __x
))
891 __MATH_INLINE
long int
892 __NTH (lrintl (long double __x
))
898 # define __llrint_code \
899 long long int __llrintres; \
900 __asm__ __volatile__ \
902 : "=m" (__llrintres) : "t" (__x) : "st"); \
905 __MATH_INLINE
long long int
906 __NTH (llrintf (float __x
))
911 __MATH_INLINE
long long int
912 __NTH (llrint (double __x
))
917 __MATH_INLINE
long long int
918 __NTH (llrintl (long double __x
))
922 # undef __llrint_code
929 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
930 __inline_mathcodeNP2 (drem
, __x
, __y
, \
931 register double __value
; \
932 register int __clobbered
; \
938 : "=t" (__value
), "=&a" (__clobbered
) : "0" (__x
), "u" (__y
) : "cc"); \
943 /* This function is used in the `isfinite' macro. */
945 __NTH (__finite (double __x
))
947 return (__extension__
948 (((((union { double __d
; int __i
[2]; }) {__d
: __x
}).__i
[1]
949 | 0x800fffffu
) + 1) >> 31));
952 # endif /* __USE_MISC */
954 /* Undefine some of the large macros which are not used anymore. */
956 # ifdef __FAST_MATH__
959 # undef __sincos_code
960 # endif /* __FAST_MATH__ */
962 # endif /* __NO_MATH_INLINES */
965 /* This code is used internally in the GNU libc. */
966 # ifdef __LIBC_INTERNAL_MATH_INLINES
967 __inline_mathop (__ieee754_sqrt
, "fsqrt")
968 __inline_mathcode2_ (long double, __ieee754_atan2l
, __y
, __x
,
969 register long double __value
;
970 __asm
__volatile__ ("fpatan\n\t"
972 : "0" (__x
), "u" (__y
) : "st(1)");
976 #endif /* !__SSE2_MATH__ && !__x86_64__ */