]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/x86_64/fpu/math_private.h
Fix PLT use for feraiseexcept on x86_64
[thirdparty/glibc.git] / sysdeps / x86_64 / fpu / math_private.h
CommitLineData
3e336a87
UD
1#ifndef _MATH_PRIVATE_H
2
3#define math_opt_barrier(x) \
4({ __typeof(x) __x; \
5 if (sizeof (x) <= sizeof (double)) \
6 __asm ("" : "=x" (__x) : "0" (x)); \
7 else \
8 __asm ("" : "=t" (__x) : "0" (x)); \
9 __x; })
10#define math_force_eval(x) \
11do \
12 { \
13 if (sizeof (x) <= sizeof (double)) \
14 __asm __volatile ("" : : "x" (x)); \
15 else \
16 __asm __volatile ("" : : "f" (x)); \
17 } \
18while (0)
19
20#include <math/math_private.h>
9a1ea152
UD
21
22/* We can do a few things better on x86-64. */
23
cf00cc00
UD
24/* Direct movement of float into integer register. */
25#undef EXTRACT_WORDS64
26#define EXTRACT_WORDS64(i,d) \
27do { \
28 long int i_; \
29 asm ("movd %1, %0" : "=rm" (i_) : "x" (d)); \
30 (i) = i_; \
31} while (0)
32
33/* And the reverse. */
34#undef INSERT_WORDS64
35#define INSERT_WORDS64(d,i) \
36do { \
37 long int i_ = i; \
38 asm ("movd %1, %0" : "=x" (d) : "rm" (i_)); \
39} while (0)
40
9a1ea152
UD
41/* Direct movement of float into integer register. */
42#undef GET_FLOAT_WORD
43#define GET_FLOAT_WORD(i,d) \
44do { \
45 int i_; \
46 asm ("movd %1, %0" : "=rm" (i_) : "x" (d)); \
47 (i) = i_; \
48} while (0)
49
50/* And the reverse. */
51#undef SET_FLOAT_WORD
52#define SET_FLOAT_WORD(d,i) \
53do { \
54 int i_ = i; \
55 asm ("movd %1, %0" : "=x" (d) : "rm" (i_)); \
56} while (0)
57
3e336a87 58#endif
7edb55ce
UD
59
60#define __isnan(d) \
c8553a6a 61 ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \
7edb55ce
UD
62 (__di & 0x7fffffffffffffffl) > 0x7ff0000000000000l; })
63#define __isnanf(d) \
0ac5ae23 64 ({ int __di; GET_FLOAT_WORD (__di, (float) d); \
7edb55ce
UD
65 (__di & 0x7fffffff) > 0x7f800000; })
66
67#define __isinf_ns(d) \
c8553a6a 68 ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \
7edb55ce
UD
69 (__di & 0x7fffffffffffffffl) == 0x7ff0000000000000l; })
70#define __isinf_nsf(d) \
0ac5ae23 71 ({ int __di; GET_FLOAT_WORD (__di, (float) d); \
7edb55ce
UD
72 (__di & 0x7fffffff) == 0x7f800000; })
73
74#define __finite(d) \
c8553a6a 75 ({ long int __di; EXTRACT_WORDS64 (__di, (double) (d)); \
7edb55ce
UD
76 (__di & 0x7fffffffffffffffl) < 0x7ff0000000000000l; })
77#define __finitef(d) \
0ac5ae23 78 ({ int __di; GET_FLOAT_WORD (__di, (float) d); \
7edb55ce 79 (__di & 0x7fffffff) < 0x7f800000; })
0ac5ae23
UD
80
81#define __ieee754_sqrt(d) \
82 ({ double __res; \
c8553a6a 83 asm ("sqrtsd %1, %0" : "=x" (__res) : "xm" ((double) (d))); \
0ac5ae23
UD
84 __res; })
85#define __ieee754_sqrtf(d) \
86 ({ float __res; \
c8553a6a 87 asm ("sqrtss %1, %0" : "=x" (__res) : "xm" ((float) (d))); \
0ac5ae23
UD
88 __res; })
89#define __ieee754_sqrtl(d) \
90 ({ long double __res; \
c8553a6a 91 asm ("fsqrt" : "=t" (__res) : "0" ((long double) (d))); \
0ac5ae23 92 __res; })
ed22dcf6
UD
93
94#ifdef __SSE4_1__
95# ifndef __rint
96# define __rint(d) \
97 ({ double __res; \
228a984d 98 asm ("roundsd $4, %1, %0" : "=x" (__res) : "xm" ((double) (d))); \
ed22dcf6
UD
99 __res; })
100# endif
101# ifndef __rintf
102# define __rintf(d) \
103 ({ float __res; \
228a984d 104 asm ("roundss $4, %1, %0" : "=x" (__res) : "xm" ((float) (d))); \
ed22dcf6
UD
105 __res; })
106# endif
107
108# ifndef __floor
109# define __floor(d) \
110 ({ double __res; \
228a984d 111 asm ("roundsd $1, %1, %0" : "=x" (__res) : "xm" ((double) (d))); \
ed22dcf6
UD
112 __res; })
113# endif
114# ifndef __floorf
115# define __floorf(d) \
116 ({ float __res; \
228a984d 117 asm ("roundss $1, %1, %0" : "=x" (__res) : "xm" ((float) (d))); \
ed22dcf6
UD
118 __res; })
119# endif
120#endif
d38f1dba
UD
121
122
123/* Specialized variants of the <fenv.h> interfaces which only handle
124 either the FPU or the SSE unit. */
125#undef libc_fegetround
126#define libc_fegetround() \
127 ({ \
128 unsigned int mxcsr; \
129 asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
130 (mxcsr & 0x6000) >> 3; \
131 })
d9a8d0ab
UD
132#undef libc_fegetroundf
133#define libc_fegetroundf() libc_fegetround ()
d38f1dba
UD
134// #define libc_fegetroundl() fegetround ()
135
136#undef libc_fesetround
137#define libc_fesetround(r) \
138 do { \
139 unsigned int mxcsr; \
140 asm ("stmxcsr %0" : "=m" (*&mxcsr)); \
141 mxcsr = (mxcsr & ~0x6000) | ((r) << 3); \
142 asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
143 } while (0)
d9a8d0ab
UD
144#undef libc_fesetroundf
145#define libc_fesetroundf(r) libc_fesetround (r)
d38f1dba
UD
146// #define libc_fesetroundl(r) (void) fesetround (r)
147
148#undef libc_feholdexcept
149#define libc_feholdexcept(e) \
4855e3dd 150 do { \
d38f1dba
UD
151 unsigned int mxcsr; \
152 asm ("stmxcsr %0" : "=m" (*&mxcsr)); \
153 (e)->__mxcsr = mxcsr; \
154 mxcsr = (mxcsr | 0x1f80) & ~0x3f; \
155 asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
156 } while (0)
d9a8d0ab
UD
157#undef libc_feholdexceptf
158#define libc_feholdexceptf(e) libc_feholdexcept (e)
d38f1dba
UD
159// #define libc_feholdexceptl(e) (void) feholdexcept (e)
160
4855e3dd
UD
161#undef libc_feholdexcept_setround
162#define libc_feholdexcept_setround(e, r) \
163 do { \
164 unsigned int mxcsr; \
165 asm ("stmxcsr %0" : "=m" (*&mxcsr)); \
166 (e)->__mxcsr = mxcsr; \
167 mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3); \
168 asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
169 } while (0)
d9a8d0ab
UD
170#undef libc_feholdexcept_setroundf
171#define libc_feholdexcept_setroundf(e, r) libc_feholdexcept_setround (e, r)
4855e3dd
UD
172// #define libc_feholdexcept_setroundl(e, r) ...
173
d9a8d0ab
UD
174#undef libc_fetestexcept
175#define libc_fetestexcept(e) \
176 ({ unsigned int mxcsr; asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
177 mxcsr & (e) & FE_ALL_EXCEPT; })
178#undef libc_fetestexceptf
179#define libc_fetestexceptf(e) libc_fetestexcept (e)
180// #define libc_fetestexceptl(e) fetestexcept (e)
181
d38f1dba
UD
182#undef libc_fesetenv
183#define libc_fesetenv(e) \
184 asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr))
d9a8d0ab
UD
185#undef libc_fesetenvf
186#define libc_fesetenvf(e) libc_fesetenv (e)
d38f1dba 187// #define libc_fesetenvl(e) (void) fesetenv (e)
d9a8d0ab
UD
188
189#undef libc_feupdateenv
190#define libc_feupdateenv(e) \
191 do { \
192 unsigned int mxcsr; \
193 asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
194 asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr)); \
8f3b1ffe 195 __feraiseexcept (mxcsr & FE_ALL_EXCEPT); \
d9a8d0ab
UD
196 } while (0)
197#undef libc_feupdateenvf
198#define libc_feupdateenvf(e) libc_feupdateenv (e)
199// #define libc_feupdateenvl(e) (void) feupdateenv (e)