]>
git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/x86/fpu/bits/mathinline.h
1 /* Inline math functions for i387 and SSE.
2 Copyright (C) 1995-2017 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
29 /* The gcc, version 2.7 or below, has problems with all this inlining
30 code. So disable it for this version of the compiler. */
31 # if __GNUC_PREREQ (2, 8)
33 /* Test for negative number. Used in the signbit() macro. */
35 __NTH (__signbitf (float __x
))
39 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
40 return (__m
& 0x8) != 0;
42 __extension__
union { float __f
; int __i
; } __u
= { __f
: __x
};
47 __NTH (__signbit (double __x
))
51 __asm ("pmovmskb %1, %0" : "=r" (__m
) : "x" (__x
));
52 return (__m
& 0x80) != 0;
54 __extension__
union { double __d
; int __i
[2]; } __u
= { __d
: __x
};
55 return __u
.__i
[1] < 0;
59 __NTH (__signbitl (long double __x
))
61 __extension__
union { long double __l
; int __i
[3]; } __u
= { __l
: __x
};
62 return (__u
.__i
[2] & 0x8000) != 0;
67 /* The gcc, version 2.7 or below, has problems with all this inlining
68 code. So disable it for this version of the compiler. */
69 #if __GNUC_PREREQ (2, 8)
70 # if !__GNUC_PREREQ (3, 4) && !defined __NO_MATH_INLINES \
71 && defined __OPTIMIZE__
72 /* GCC 3.4 introduced builtins for all functions below, so
73 there's no need to define any of these inline functions. */
77 /* Round to nearest integer. */
79 __MATH_INLINE
long int
80 __NTH (lrintf (float __x
))
83 /* Mark as volatile since the result is dependent on the state of
84 the SSE control register (the rounding mode). Otherwise GCC might
85 remove these assembler instructions since it does not know about
86 the rounding mode change and cannot currently be told. */
87 __asm
__volatile__ ("cvtss2si %1, %0" : "=r" (__res
) : "xm" (__x
));
92 __MATH_INLINE
long int
93 __NTH (lrint (double __x
))
96 /* Mark as volatile since the result is dependent on the state of
97 the SSE control register (the rounding mode). Otherwise GCC might
98 remove these assembler instructions since it does not know about
99 the rounding mode change and cannot currently be told. */
100 __asm
__volatile__ ("cvtsd2si %1, %0" : "=r" (__res
) : "xm" (__x
));
106 __MATH_INLINE
long long int
107 __NTH (llrintf (float __x
))
110 /* Mark as volatile since the result is dependent on the state of
111 the SSE control register (the rounding mode). Otherwise GCC might
112 remove these assembler instructions since it does not know about
113 the rounding mode change and cannot currently be told. */
114 __asm
__volatile__ ("cvtss2si %1, %0" : "=r" (__res
) : "xm" (__x
));
118 __MATH_INLINE
long long int
119 __NTH (llrint (double __x
))
122 /* Mark as volatile since the result is dependent on the state of
123 the SSE control register (the rounding mode). Otherwise GCC might
124 remove these assembler instructions since it does not know about
125 the rounding mode change and cannot currently be told. */
126 __asm
__volatile__ ("cvtsd2si %1, %0" : "=r" (__res
) : "xm" (__x
));
131 # if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
132 && defined __SSE2_MATH__
133 /* Determine maximum of two values. */
135 __NTH (fmaxf (float __x
, float __y
))
139 __asm ("vmaxss %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
142 __asm ("maxss %1, %0" : "+x" (__x
) : "xm" (__y
));
147 __NTH (fmax (double __x
, double __y
))
151 __asm ("vmaxsd %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
154 __asm ("maxsd %1, %0" : "+x" (__x
) : "xm" (__y
));
159 /* Determine minimum of two values. */
161 __NTH (fminf (float __x
, float __y
))
165 __asm ("vminss %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
168 __asm ("minss %1, %0" : "+x" (__x
) : "xm" (__y
));
173 __NTH (fmin (double __x
, double __y
))
177 __asm ("vminsd %2, %1, %0" : "=x" (__res
) : "x" (x
), "xm" (__y
));
180 __asm ("minsd %1, %0" : "+x" (__x
) : "xm" (__y
));
188 # if defined __SSE4_1__ && defined __SSE2_MATH__
189 # if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
191 /* Round to nearest integer. */
193 __NTH (rint (double __x
))
196 /* Mark as volatile since the result is dependent on the state of
197 the SSE control register (the rounding mode). Otherwise GCC might
198 remove these assembler instructions since it does not know about
199 the rounding mode change and cannot currently be told. */
200 __asm
__volatile__ ("roundsd $4, %1, %0" : "=x" (__res
) : "xm" (__x
));
204 __NTH (rintf (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__ ("roundss $4, %1, %0" : "=x" (__res
) : "xm" (__x
));
216 /* Round to nearest integer without raising inexact exception. */
218 __NTH (nearbyint (double __x
))
221 /* Mark as volatile since the result is dependent on the state of
222 the SSE control register (the rounding mode). Otherwise GCC might
223 remove these assembler instructions since it does not know about
224 the rounding mode change and cannot currently be told. */
225 __asm
__volatile__ ("roundsd $0xc, %1, %0" : "=x" (__res
) : "xm" (__x
));
229 __NTH (nearbyintf (float __x
))
232 /* Mark as volatile since the result is dependent on the state of
233 the SSE control register (the rounding mode). Otherwise GCC might
234 remove these assembler instructions since it does not know about
235 the rounding mode change and cannot currently be told. */
236 __asm
__volatile__ ("roundss $0xc, %1, %0" : "=x" (__res
) : "xm" (__x
));
243 /* Smallest integral value not less than X. */
245 __NTH (ceil (double __x
))
248 __asm ("roundsd $2, %1, %0" : "=x" (__res
) : "xm" (__x
));
253 __NTH (ceilf (float __x
))
256 __asm ("roundss $2, %1, %0" : "=x" (__res
) : "xm" (__x
));
260 /* Largest integer not greater than X. */
262 __NTH (floor (double __x
))
265 __asm ("roundsd $1, %1, %0" : "=x" (__res
) : "xm" (__x
));
270 __NTH (floorf (float __x
))
273 __asm ("roundss $1, %1, %0" : "=x" (__res
) : "xm" (__x
));
280 /* Disable x87 inlines when -fpmath=sse is passed and also when we're building
281 on x86_64. Older gcc (gcc-3.2 for example) does not define __SSE2_MATH__
283 #if !defined __SSE2_MATH__ && !defined __x86_64__
284 # if ((!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) \
285 && defined __OPTIMIZE__)
287 /* The inline functions do not set errno or raise necessarily the
288 correct exceptions. */
289 # undef math_errhandling
291 /* A macro to define float, double, and long double versions of various
292 math functions for the ix87 FPU. FUNC is the function name (which will
293 be suffixed with f and l for the float and long double version,
294 respectively). OP is the name of the FPU operation.
295 We define two sets of macros. The set with the additional NP
296 doesn't add a prototype declaration. */
299 # define __inline_mathop(func, op) \
300 __inline_mathop_ (double, func, op) \
301 __inline_mathop_ (float, __CONCAT(func,f), op) \
302 __inline_mathop_ (long double, __CONCAT(func,l), op)
303 # define __inline_mathopNP(func, op) \
304 __inline_mathopNP_ (double, func, op) \
305 __inline_mathopNP_ (float, __CONCAT(func,f), op) \
306 __inline_mathopNP_ (long double, __CONCAT(func,l), op)
308 # define __inline_mathop(func, op) \
309 __inline_mathop_ (double, func, op)
310 # define __inline_mathopNP(func, op) \
311 __inline_mathopNP_ (double, func, op)
314 # define __inline_mathop_(float_type, func, op) \
315 __inline_mathop_decl_ (float_type, func, op, "0" (__x))
316 # define __inline_mathopNP_(float_type, func, op) \
317 __inline_mathop_declNP_ (float_type, func, op, "0" (__x))
321 # define __inline_mathop_decl(func, op, params...) \
322 __inline_mathop_decl_ (double, func, op, params) \
323 __inline_mathop_decl_ (float, __CONCAT(func,f), op, params) \
324 __inline_mathop_decl_ (long double, __CONCAT(func,l), op, params)
325 # define __inline_mathop_declNP(func, op, params...) \
326 __inline_mathop_declNP_ (double, func, op, params) \
327 __inline_mathop_declNP_ (float, __CONCAT(func,f), op, params) \
328 __inline_mathop_declNP_ (long double, __CONCAT(func,l), op, params)
330 # define __inline_mathop_decl(func, op, params...) \
331 __inline_mathop_decl_ (double, func, op, params)
332 # define __inline_mathop_declNP(func, op, params...) \
333 __inline_mathop_declNP_ (double, func, op, params)
336 # define __inline_mathop_decl_(float_type, func, op, params...) \
337 __MATH_INLINE float_type func (float_type) __THROW; \
338 __inline_mathop_declNP_ (float_type, func, op, params)
340 # define __inline_mathop_declNP_(float_type, func, op, params...) \
341 __MATH_INLINE float_type __NTH (func (float_type __x)) \
343 register float_type __result; \
344 __asm __volatile__ (op : "=t" (__result) : params); \
350 # define __inline_mathcode(func, arg, code) \
351 __inline_mathcode_ (double, func, arg, code) \
352 __inline_mathcode_ (float, __CONCAT(func,f), arg, code) \
353 __inline_mathcode_ (long double, __CONCAT(func,l), arg, code)
354 # define __inline_mathcodeNP(func, arg, code) \
355 __inline_mathcodeNP_ (double, func, arg, code) \
356 __inline_mathcodeNP_ (float, __CONCAT(func,f), arg, code) \
357 __inline_mathcodeNP_ (long double, __CONCAT(func,l), arg, code)
358 # define __inline_mathcode2(func, arg1, arg2, code) \
359 __inline_mathcode2_ (double, func, arg1, arg2, code) \
360 __inline_mathcode2_ (float, __CONCAT(func,f), arg1, arg2, code) \
361 __inline_mathcode2_ (long double, __CONCAT(func,l), arg1, arg2, code)
362 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
363 __inline_mathcodeNP2_ (double, func, arg1, arg2, code) \
364 __inline_mathcodeNP2_ (float, __CONCAT(func,f), arg1, arg2, code) \
365 __inline_mathcodeNP2_ (long double, __CONCAT(func,l), arg1, arg2, code)
366 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
367 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code) \
368 __inline_mathcode3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
369 __inline_mathcode3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
370 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
371 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code) \
372 __inline_mathcodeNP3_ (float, __CONCAT(func,f), arg1, arg2, arg3, code) \
373 __inline_mathcodeNP3_ (long double, __CONCAT(func,l), arg1, arg2, arg3, code)
375 # define __inline_mathcode(func, arg, code) \
376 __inline_mathcode_ (double, func, (arg), code)
377 # define __inline_mathcodeNP(func, arg, code) \
378 __inline_mathcodeNP_ (double, func, (arg), code)
379 # define __inline_mathcode2(func, arg1, arg2, code) \
380 __inline_mathcode2_ (double, func, arg1, arg2, code)
381 # define __inline_mathcodeNP2(func, arg1, arg2, code) \
382 __inline_mathcodeNP2_ (double, func, arg1, arg2, code)
383 # define __inline_mathcode3(func, arg1, arg2, arg3, code) \
384 __inline_mathcode3_ (double, func, arg1, arg2, arg3, code)
385 # define __inline_mathcodeNP3(func, arg1, arg2, arg3, code) \
386 __inline_mathcodeNP3_ (double, func, arg1, arg2, arg3, code)
389 # define __inline_mathcode_(float_type, func, arg, code) \
390 __MATH_INLINE float_type func (float_type) __THROW; \
391 __inline_mathcodeNP_(float_type, func, arg, code)
393 # define __inline_mathcodeNP_(float_type, func, arg, code) \
394 __MATH_INLINE float_type __NTH (func (float_type arg)) \
400 # define __inline_mathcode2_(float_type, func, arg1, arg2, code) \
401 __MATH_INLINE float_type func (float_type, float_type) __THROW; \
402 __inline_mathcodeNP2_ (float_type, func, arg1, arg2, code)
404 # define __inline_mathcodeNP2_(float_type, func, arg1, arg2, code) \
405 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2)) \
410 # define __inline_mathcode3_(float_type, func, arg1, arg2, arg3, code) \
411 __MATH_INLINE float_type func (float_type, float_type, float_type) __THROW; \
412 __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code)
414 # define __inline_mathcodeNP3_(float_type, func, arg1, arg2, arg3, code) \
415 __MATH_INLINE float_type __NTH (func (float_type arg1, float_type arg2, \
423 # if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
424 /* Miscellaneous functions */
426 /* __FAST_MATH__ is defined by gcc -ffast-math. */
427 # ifdef __FAST_MATH__
429 # define __sincos_code \
430 register long double __cosr; \
431 register long double __sinr; \
432 register unsigned int __swtmp; \
436 "testl $0x400, %2\n\t" \
443 "testl $0x400, %2\n\t" \
448 : "=t" (__cosr), "=u" (__sinr), "=a" (__swtmp) : "0" (__x)); \
453 __NTH (__sincos (double __x
, double *__sinx
, double *__cosx
))
459 __NTH (__sincosf (float __x
, float *__sinx
, float *__cosx
))
465 __NTH (__sincosl (long double __x
, long double *__sinx
, long double *__cosx
))
472 /* Optimized inline implementation, sometimes with reduced precision
473 and/or argument range. */
475 # if __GNUC_PREREQ (3, 5)
476 # define __expm1_code \
477 register long double __temp; \
478 __temp = __builtin_expm1l (__x); \
479 return __temp ? __temp : __x
481 # define __expm1_code \
482 register long double __value; \
483 register long double __exponent; \
484 register long double __temp; \
486 ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" \
487 "fmul %%st(1) # x * log2(e)\n\t" \
489 "frndint # int(x * log2(e))\n\t" \
491 "fsub %%st(1) # fract(x * log2(e))\n\t" \
492 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
493 "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" \
494 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
496 ("fscale # 2^int(x * log2(e))\n\t" \
497 : "=t" (__temp) : "0" (1.0), "u" (__exponent)); \
500 return __temp ? __temp : __x
502 __inline_mathcodeNP_ (long double, __expm1l
, __x
, __expm1_code
)
504 # if __GNUC_PREREQ (3, 4)
505 __inline_mathcodeNP_ (long double, __expl
, __x
, return __builtin_expl (__x
))
507 # define __exp_code \
508 register long double __value; \
509 register long double __exponent; \
511 ("fldl2e # e^x = 2^(x * log2(e))\n\t" \
512 "fmul %%st(1) # x * log2(e)\n\t" \
514 "frndint # int(x * log2(e))\n\t" \
516 "fsub %%st(1) # fract(x * log2(e))\n\t" \
517 "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" \
518 : "=t" (__value), "=u" (__exponent) : "0" (__x)); \
522 : "=t" (__value) : "0" (__value), "u" (__exponent)); \
524 __inline_mathcodeNP (exp
, __x
, __exp_code
)
525 __inline_mathcodeNP_ (long double, __expl
, __x
, __exp_code
)
529 # if !__GNUC_PREREQ (3, 5)
530 __inline_mathcodeNP (tan
, __x
, \
531 register long double __value
; \
532 register long double __value2
__attribute__ ((__unused__
)); \
535 : "=t" (__value2
), "=u" (__value
) : "0" (__x
)); \
538 # endif /* __FAST_MATH__ */
541 # if __GNUC_PREREQ (3, 4)
542 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
,
543 return __builtin_atan2l (__y
, __x
))
545 # define __atan2_code \
546 register long double __value; \
549 : "=t" (__value) : "0" (__x), "u" (__y) : "st(1)"); \
551 # ifdef __FAST_MATH__
552 __inline_mathcodeNP2 (atan2
, __y
, __x
, __atan2_code
)
554 __inline_mathcodeNP2_ (long double, __atan2l
, __y
, __x
, __atan2_code
)
558 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
559 __inline_mathcodeNP2 (fmod
, __x
, __y
, \
560 register long double __value
; \
566 : "=t" (__value
) : "0" (__x
), "u" (__y
) : "ax", "cc"); \
571 # ifdef __FAST_MATH__
572 # if !__GNUC_PREREQ (3,3)
573 __inline_mathopNP (sqrt
, "fsqrt")
574 __inline_mathopNP_ (long double, __sqrtl
, "fsqrt")
575 # define __libc_sqrtl(n) __sqrtl (n)
577 # define __libc_sqrtl(n) __builtin_sqrtl (n)
581 # if __GNUC_PREREQ (2, 8)
582 __inline_mathcodeNP_ (double, fabs
, __x
, return __builtin_fabs (__x
))
584 __inline_mathcodeNP_ (float, fabsf
, __x
, return __builtin_fabsf (__x
))
585 __inline_mathcodeNP_ (long double, fabsl
, __x
, return __builtin_fabsl (__x
))
587 __inline_mathcodeNP_ (long double, __fabsl
, __x
, return __builtin_fabsl (__x
))
589 __inline_mathop (fabs
, "fabs")
590 __inline_mathop_ (long double, __fabsl
, "fabs")
593 # ifdef __FAST_MATH__
594 # if !__GNUC_PREREQ (3, 4)
595 /* The argument range of this inline version is reduced. */
596 __inline_mathopNP (sin
, "fsin")
597 /* The argument range of this inline version is reduced. */
598 __inline_mathopNP (cos
, "fcos")
600 __inline_mathop_declNP (log
, "fldln2; fxch; fyl2x", "0" (__x
) : "st(1)")
603 # if !__GNUC_PREREQ (3, 5)
604 __inline_mathop_declNP (log10
, "fldlg2; fxch; fyl2x", "0" (__x
) : "st(1)")
606 __inline_mathcodeNP (asin
, __x
, return __atan2l (__x
, __libc_sqrtl (1.0 - __x
* __x
)))
607 __inline_mathcodeNP (acos
, __x
, return __atan2l (__libc_sqrtl (1.0 - __x
* __x
), __x
))
610 # if !__GNUC_PREREQ (3, 4)
611 __inline_mathop_declNP (atan
, "fld1; fpatan", "0" (__x
) : "st(1)")
613 # endif /* __FAST_MATH__ */
615 __inline_mathcode_ (long double, __sgn1l
, __x
, \
616 __extension__
union { long double __xld
; unsigned int __xi
[3]; } __n
= \
618 __n
.__xi
[2] = (__n
.__xi
[2] & 0x8000) | 0x3fff; \
619 __n
.__xi
[1] = 0x80000000; \
624 # ifdef __FAST_MATH__
625 /* The argument range of the inline version of sinhl is slightly reduced. */
626 __inline_mathcodeNP (sinh
, __x
, \
627 register long double __exm1
= __expm1l (__fabsl (__x
)); \
628 return 0.5 * (__exm1
/ (__exm1
+ 1.0) + __exm1
) * __sgn1l (__x
))
630 __inline_mathcodeNP (cosh
, __x
, \
631 register long double __ex
= __expl (__x
); \
632 return 0.5 * (__ex
+ 1.0 / __ex
))
634 __inline_mathcodeNP (tanh
, __x
, \
635 register long double __exm1
= __expm1l (-__fabsl (__x
+ __x
)); \
636 return __exm1
/ (__exm1
+ 2.0) * __sgn1l (-__x
))
639 __inline_mathcodeNP (floor
, __x
, \
640 register long double __value
; \
641 register int __ignore
; \
642 unsigned short int __cw
; \
643 unsigned short int __cwtmp
; \
644 __asm
__volatile ("fnstcw %3\n\t" \
645 "movzwl %3, %1\n\t" \
646 "andl $0xf3ff, %1\n\t" \
647 "orl $0x0400, %1\n\t" /* rounding down */ \
652 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
657 __inline_mathcodeNP (ceil
, __x
, \
658 register long double __value
; \
659 register int __ignore
; \
660 unsigned short int __cw
; \
661 unsigned short int __cwtmp
; \
662 __asm
__volatile ("fnstcw %3\n\t" \
663 "movzwl %3, %1\n\t" \
664 "andl $0xf3ff, %1\n\t" \
665 "orl $0x0800, %1\n\t" /* rounding up */ \
670 : "=t" (__value
), "=&q" (__ignore
), "=m" (__cwtmp
), \
675 # ifdef __FAST_MATH__
676 # define __ldexp_code \
677 register long double __value; \
680 : "=t" (__value) : "0" (__x), "u" ((long double) __y)); \
684 __NTH (ldexp (double __x
, int __y
))
691 /* Optimized versions for some non-standardized functions. */
694 # ifdef __FAST_MATH__
695 __inline_mathcodeNP (expm1
, __x
, __expm1_code
)
697 /* We cannot rely on M_SQRT being defined. So we do it for ourself
699 # define __M_SQRT2 1.41421356237309504880L /* sqrt(2) */
701 # if !__GNUC_PREREQ (3, 5)
702 __inline_mathcodeNP (log1p
, __x
, \
703 register long double __value
; \
704 if (__fabsl (__x
) >= 1.0 - 0.5 * __M_SQRT2
) \
705 __value
= logl (1.0 + __x
); \
711 : "=t" (__value
) : "0" (__x
) : "st(1)"); \
716 /* The argument range of the inline version of asinhl is slightly reduced. */
717 __inline_mathcodeNP (asinh
, __x
, \
718 register long double __y
= __fabsl (__x
); \
719 return (log1pl (__y
* __y
/ (__libc_sqrtl (__y
* __y
+ 1.0) + 1.0) + __y
) \
722 __inline_mathcodeNP (acosh
, __x
, \
723 return logl (__x
+ __libc_sqrtl (__x
- 1.0) * __libc_sqrtl (__x
+ 1.0)))
725 __inline_mathcodeNP (atanh
, __x
, \
726 register long double __y
= __fabsl (__x
); \
727 return -0.5 * log1pl (-(__y
+ __y
) / (1.0 + __y
)) * __sgn1l (__x
))
729 /* The argument range of the inline version of hypotl is slightly reduced. */
730 __inline_mathcodeNP2 (hypot
, __x
, __y
,
731 return __libc_sqrtl (__x
* __x
+ __y
* __y
))
733 # if !__GNUC_PREREQ (3, 5)
734 __inline_mathcodeNP(logb
, __x
, \
735 register long double __value
; \
736 register long double __junk
; \
739 : "=t" (__junk
), "=u" (__value
) : "0" (__x
)); \
747 # ifdef __FAST_MATH__
749 # if !__GNUC_PREREQ (3, 5)
750 __inline_mathop_declNP (log2
, "fld1; fxch; fyl2x", "0" (__x
) : "st(1)")
754 __NTH (ldexpf (float __x
, int __y
))
759 __MATH_INLINE
long double
760 __NTH (ldexpl (long double __x
, int __y
))
765 __inline_mathopNP (rint
, "frndint")
766 # endif /* __FAST_MATH__ */
768 # define __lrint_code \
769 long int __lrintres; \
770 __asm__ __volatile__ \
772 : "=m" (__lrintres) : "t" (__x) : "st"); \
774 __MATH_INLINE
long int
775 __NTH (lrintf (float __x
))
779 __MATH_INLINE
long int
780 __NTH (lrint (double __x
))
784 __MATH_INLINE
long int
785 __NTH (lrintl (long double __x
))
791 # define __llrint_code \
792 long long int __llrintres; \
793 __asm__ __volatile__ \
795 : "=m" (__llrintres) : "t" (__x) : "st"); \
798 __MATH_INLINE
long long int
799 __NTH (llrintf (float __x
))
804 __MATH_INLINE
long long int
805 __NTH (llrint (double __x
))
810 __MATH_INLINE
long long int
811 __NTH (llrintl (long double __x
))
815 # undef __llrint_code
822 # if defined __FAST_MATH__ && !__GNUC_PREREQ (3, 5)
823 __inline_mathcodeNP2 (drem
, __x
, __y
, \
824 register double __value
; \
825 register int __clobbered
; \
831 : "=t" (__value
), "=&a" (__clobbered
) : "0" (__x
), "u" (__y
) : "cc"); \
836 /* This function is used in the `isfinite' macro. */
838 __NTH (__finite (double __x
))
840 return (__extension__
841 (((((union { double __d
; int __i
[2]; }) {__d
: __x
}).__i
[1]
842 | 0x800fffffu
) + 1) >> 31));
845 # endif /* __USE_MISC */
847 /* Undefine some of the large macros which are not used anymore. */
849 # ifdef __FAST_MATH__
852 # undef __sincos_code
853 # endif /* __FAST_MATH__ */
855 # endif /* __NO_MATH_INLINES */
858 /* This code is used internally in the GNU libc. */
859 # ifdef __LIBC_INTERNAL_MATH_INLINES
860 __inline_mathop (__ieee754_sqrt
, "fsqrt")
861 __inline_mathcode2_ (long double, __ieee754_atan2l
, __y
, __x
,
862 register long double __value
;
863 __asm
__volatile__ ("fpatan\n\t"
865 : "0" (__x
), "u" (__y
) : "st(1)");
869 #endif /* !__SSE2_MATH__ && !__x86_64__ */