]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/x86_64/fpu/bits/mathinline.h
Relax asm requirements for recently added x86-64 math interfaces
[thirdparty/glibc.git] / sysdeps / x86_64 / fpu / bits / mathinline.h
CommitLineData
9359218f 1/* Inline math functions for x86-64.
cd205654 2 Copyright (C) 2002-2004, 2007, 2009, 2011 Free Software Foundation, Inc.
9359218f 3 This file is part of the GNU C Library.
9359218f
AJ
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
24044103
JJ
24#include <bits/wordsize.h>
25
cd205654 26#ifndef __extern_always_inline
9359218f
AJ
27# define __MATH_INLINE __inline
28#else
cd205654 29# define __MATH_INLINE __extern_always_inline
9359218f
AJ
30#endif
31
32
ed22dcf6
UD
33/* The gcc, version 2.7 or below, has problems with all this inlining
34 code. So disable it for this version of the compiler. */
35#if __GNUC_PREREQ (2, 8) && defined __USE_ISOC99
ad0f5cad 36__BEGIN_NAMESPACE_C99
ea493b56
UD
37
38/* Test for negative number. Used in the signbit() macro. */
39__MATH_INLINE int
f377d022 40__NTH (__signbitf (float __x))
ea493b56 41{
ed22dcf6 42# if __WORDSIZE == 32
24044103
JJ
43 __extension__ union { float __f; int __i; } __u = { __f: __x };
44 return __u.__i < 0;
ed22dcf6 45# else
ef72d5f1 46 int __m;
c2735e95 47 __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
ef72d5f1 48 return __m & 0x8;
ed22dcf6 49# endif
ea493b56
UD
50}
51__MATH_INLINE int
f377d022 52__NTH (__signbit (double __x))
ea493b56 53{
ed22dcf6 54# if __WORDSIZE == 32
24044103
JJ
55 __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
56 return __u.__i[1] < 0;
ed22dcf6 57# else
ef72d5f1 58 int __m;
c2735e95 59 __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x));
ef72d5f1 60 return __m & 0x80;
ed22dcf6 61# endif
ea493b56
UD
62}
63__MATH_INLINE int
f377d022 64__NTH (__signbitl (long double __x))
ea493b56
UD
65{
66 __extension__ union { long double __l; int __i[3]; } __u = { __l: __x };
67 return (__u.__i[2] & 0x8000) != 0;
68}
cd205654 69
ed22dcf6
UD
70__END_NAMESPACE_C99
71#endif
72
73
74#if (__GNUC_PREREQ (2, 8) && !defined __NO_MATH_INLINES \
75 && defined __OPTIMIZE__)
76
77# ifdef __USE_ISOC99
78__BEGIN_NAMESPACE_C99
79
cd205654 80/* Round to nearest integer. */
4c1a1f71 81# if __WORDSIZE == 64 || defined __SSE_MATH__
cd205654
UD
82__MATH_INLINE long int
83__NTH (lrintf (float __x))
84{
85 long int __res;
bf972c9d 86 __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
cd205654
UD
87 return __res;
88}
4c1a1f71
UD
89# endif
90# if __WORDSIZE == 64 || defined __SSE2_MATH__
cd205654
UD
91__MATH_INLINE long int
92__NTH (lrint (double __x))
93{
94 long int __res;
bf972c9d 95 __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
cd205654
UD
96 return __res;
97}
4c1a1f71
UD
98# endif
99# if __WORDSIZE == 64
cd205654
UD
100__MATH_INLINE long long int
101__NTH (llrintf (float __x))
102{
103 long long int __res;
bf972c9d 104 __asm ("cvtss2si %1, %0" : "=r" (__res) : "xm" (__x));
cd205654
UD
105 return __res;
106}
107__MATH_INLINE long long int
108__NTH (llrint (double __x))
109{
110 long long int __res;
bf972c9d 111 __asm ("cvtsd2si %1, %0" : "=r" (__res) : "xm" (__x));
cd205654
UD
112 return __res;
113}
4c1a1f71
UD
114# endif
115
0ac5ae23
UD
116# if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0 \
117 && (__WORDSIZE == 64 || defined __SSE2_MATH__)
4c1a1f71
UD
118/* Determine maximum of two values. */
119__MATH_INLINE float
120__NTH (fmaxf (float __x, float __y))
121{
bf972c9d 122 __asm ("maxss %1, %0" : "+x" (__x) : "xm" (__y));
4c1a1f71
UD
123 return __x;
124}
125__MATH_INLINE double
126__NTH (fmax (double __x, double __y))
127{
bf972c9d 128 __asm ("maxsd %1, %0" : "+x" (__x) : "xm" (__y));
4c1a1f71
UD
129 return __x;
130}
131
132/* Determine minimum of two values. */
133__MATH_INLINE float
134__NTH (fminf (float __x, float __y))
135{
bf972c9d 136 __asm ("minss %1, %0" : "+x" (__x) : "xm" (__y));
4c1a1f71
UD
137 return __x;
138}
139__MATH_INLINE double
140__NTH (fmin (double __x, double __y))
141{
bf972c9d 142 __asm ("minsd %1, %0" : "+x" (__x) : "xm" (__y));
4c1a1f71
UD
143 return __x;
144}
145# endif
146
147__END_NAMESPACE_C99
cd205654
UD
148# endif
149
ad0f5cad
UD
150# if defined __SSE4_1__ && (__WORDSIZE == 64 || defined __SSE2_MATH__)
151# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
152__BEGIN_NAMESPACE_C99
153
154/* Round to nearest integer. */
155__MATH_INLINE double
156__NTH (rint (double __x))
157{
158 double __res;
228a984d 159 __asm ("roundsd $4, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
160 return __res;
161}
162__MATH_INLINE float
163__NTH (rintf (float __x))
164{
165 float __res;
228a984d 166 __asm ("roundss $4, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
167 return __res;
168}
169
170__END_NAMESPACE_C99
171# endif
172
173__BEGIN_NAMESPACE_STD
174/* Smallest integral value not less than X. */
175__MATH_INLINE double
176__NTH (ceil (double __x))
177{
178 double __res;
228a984d 179 __asm ("roundsd $2, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
180 return __res;
181}
182__END_NAMESPACE_STD
183
184__BEGIN_NAMESPACE_C99
185__MATH_INLINE float
186__NTH (ceilf (float __x))
187{
188 float __res;
228a984d 189 __asm ("roundss $2, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
190 return __res;
191}
192__END_NAMESPACE_C99
193
194__BEGIN_NAMESPACE_STD
195/* Largest integer not greater than X. */
196__MATH_INLINE double
b171c137 197__NTH (floor (double __x))
ad0f5cad
UD
198{
199 double __res;
228a984d 200 __asm ("roundsd $1, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
201 return __res;
202}
203__END_NAMESPACE_STD
204
205__BEGIN_NAMESPACE_C99
206__MATH_INLINE float
b171c137 207__NTH (floorf (float __x))
ad0f5cad
UD
208{
209 float __res;
228a984d 210 __asm ("roundss $1, %1, %0" : "=x" (__res) : "xm" (__x));
ad0f5cad
UD
211 return __res;
212}
213__END_NAMESPACE_C99
214# endif
215
9359218f 216#endif