]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/x86_64/fpu/bits/mathinline.h
Optimize libm
[thirdparty/glibc.git] / sysdeps / x86_64 / fpu / bits / mathinline.h
1 /* Inline math functions for x86-64.
2 Copyright (C) 2002-2004, 2007, 2009, 2011 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #ifndef _MATH_H
21 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
22 #endif
23
24 #include <bits/wordsize.h>
25
26 #ifndef __extern_always_inline
27 # define __MATH_INLINE __inline
28 #else
29 # define __MATH_INLINE __extern_always_inline
30 #endif
31
32
33 #if defined __USE_ISOC99 && defined __GNUC__ && __GNUC__ >= 2
34
35 /* Test for negative number. Used in the signbit() macro. */
36 __MATH_INLINE int
37 __NTH (__signbitf (float __x))
38 {
39 # if __WORDSIZE == 32
40 __extension__ union { float __f; int __i; } __u = { __f: __x };
41 return __u.__i < 0;
42 # else
43 int __m;
44 __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
45 return __m & 0x8;
46 # endif
47 }
48 __MATH_INLINE int
49 __NTH (__signbit (double __x))
50 {
51 # if __WORDSIZE == 32
52 __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
53 return __u.__i[1] < 0;
54 # else
55 int __m;
56 __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
57 return __m & 0x80;
58 # endif
59 }
60 __MATH_INLINE int
61 __NTH (__signbitl (long double __x))
62 {
63 __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
64 return (__u.__i[2] & 0x8000) != 0;
65 }
66
67 #ifdef __USE_ISOC99
68 __BEGIN_NAMESPACE_C99
69
70 /* Round to nearest integer. */
71 # if __WORDSIZE == 64 || defined __SSE_MATH__
72 __MATH_INLINE long int
73 __NTH (lrintf (float __x))
74 {
75 long int __res;
76 __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
77 return __res;
78 }
79 # endif
80 # if __WORDSIZE == 64 || defined __SSE2_MATH__
81 __MATH_INLINE long int
82 __NTH (lrint (double __x))
83 {
84 long int __res;
85 __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
86 return __res;
87 }
88 # endif
89 # if __WORDSIZE == 64
90 __MATH_INLINE long long int
91 __NTH (llrintf (float __x))
92 {
93 long long int __res;
94 __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
95 return __res;
96 }
97 __MATH_INLINE long long int
98 __NTH (llrint (double __x))
99 {
100 long long int __res;
101 __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
102 return __res;
103 }
104 # endif
105
106 # if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
107 && (__WORDSIZE == 64 || defined __SSE2_MATH__)
108 /* Determine maximum of two values. */
109 __MATH_INLINE float
110 __NTH (fmaxf (float __x, float __y))
111 {
112 __asm ("maxss %1, %0" : "+x" (__x) : "xm" (__y));
113 return __x;
114 }
115 __MATH_INLINE double
116 __NTH (fmax (double __x, double __y))
117 {
118 __asm ("maxsd %1, %0" : "+x" (__x) : "xm" (__y));
119 return __x;
120 }
121
122 /* Determine minimum of two values. */
123 __MATH_INLINE float
124 __NTH (fminf (float __x, float __y))
125 {
126 __asm ("minss %1, %0" : "+x" (__x) : "xm" (__y));
127 return __x;
128 }
129 __MATH_INLINE double
130 __NTH (fmin (double __x, double __y))
131 {
132 __asm ("minsd %1, %0" : "+x" (__x) : "xm" (__y));
133 return __x;
134 }
135 # endif
136
137 __END_NAMESPACE_C99
138 # endif
139
140 #endif