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 EXTRACT_WORDS64(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__
52extern __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
64extern __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
76extern __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
88extern __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