1 | #ifndef X86_64_MATH_PRIVATE_H |
2 | #define X86_64_MATH_PRIVATE_H 1 |
3 | |
4 | /* We can do a few things better on x86-64. */ |
5 | |
6 | #if defined __AVX__ || defined SSE2AVX |
7 | # define MOVD "vmovd" |
8 | # define MOVQ "vmovq" |
9 | #else |
10 | # define MOVD "movd" |
11 | # define MOVQ "movq" |
12 | #endif |
13 | |
14 | /* Direct movement of float into integer register. */ |
15 | #define (i, d) \ |
16 | do { \ |
17 | int64_t i_; \ |
18 | asm (MOVQ " %1, %0" : "=rm" (i_) : "x" ((double) (d))); \ |
19 | (i) = i_; \ |
20 | } while (0) |
21 | |
22 | /* And the reverse. */ |
23 | #define INSERT_WORDS64(d, i) \ |
24 | do { \ |
25 | int64_t i_ = i; \ |
26 | double d__; \ |
27 | asm (MOVQ " %1, %0" : "=x" (d__) : "rm" (i_)); \ |
28 | d = d__; \ |
29 | } while (0) |
30 | |
31 | /* Direct movement of float into integer register. */ |
32 | #define GET_FLOAT_WORD(i, d) \ |
33 | do { \ |
34 | int i_; \ |
35 | asm (MOVD " %1, %0" : "=rm" (i_) : "x" ((float) (d))); \ |
36 | (i) = i_; \ |
37 | } while (0) |
38 | |
39 | /* And the reverse. */ |
40 | #define SET_FLOAT_WORD(f, i) \ |
41 | do { \ |
42 | int i_ = i; \ |
43 | float f__; \ |
44 | asm (MOVD " %1, %0" : "=x" (f__) : "rm" (i_)); \ |
45 | f = f__; \ |
46 | } while (0) |
47 | |
48 | #include <sysdeps/i386/fpu/fenv_private.h> |
49 | #include_next <math_private.h> |
50 | |
51 | #ifdef __SSE4_1__ |
52 | extern __always_inline double |
53 | __rint (double d) |
54 | { |
55 | double res; |
56 | # if defined __AVX__ || defined SSE2AVX |
57 | asm ("vroundsd $4, %1, %0, %0" : "=x" (res) : "xm" (d)); |
58 | # else |
59 | asm ("roundsd $4, %1, %0" : "=x" (res) : "xm" (d)); |
60 | # endif |
61 | return res; |
62 | } |
63 | |
64 | extern __always_inline float |
65 | __rintf (float d) |
66 | { |
67 | float res; |
68 | # if defined __AVX__ || defined SSE2AVX |
69 | asm ("vroundss $4, %1, %0, %0" : "=x" (res) : "xm" (d)); |
70 | # else |
71 | asm ("roundss $4, %1, %0" : "=x" (res) : "xm" (d)); |
72 | # endif |
73 | return res; |
74 | } |
75 | |
76 | extern __always_inline double |
77 | __floor (double d) |
78 | { |
79 | double res; |
80 | # if defined __AVX__ || defined SSE2AVX |
81 | asm ("vroundsd $1, %1, %0, %0" : "=x" (res) : "xm" (d)); |
82 | # else |
83 | asm ("roundsd $1, %1, %0" : "=x" (res) : "xm" (d)); |
84 | # endif |
85 | return res; |
86 | } |
87 | |
88 | extern __always_inline float |
89 | __floorf (float d) |
90 | { |
91 | float res; |
92 | # if defined __AVX__ || defined SSE2AVX |
93 | asm ("vroundss $1, %1, %0, %0" : "=x" (res) : "xm" (d)); |
94 | # else |
95 | asm ("roundss $1, %1, %0" : "=x" (res) : "xm" (d)); |
96 | # endif |
97 | return res; |
98 | } |
99 | #endif /* __SSE4_1__ */ |
100 | |
101 | #endif /* X86_64_MATH_PRIVATE_H */ |
102 | |