]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/powerpc/fpu/math_private.h
powerpc: Avoid putting floating point values in memory [BZ #22189]
[thirdparty/glibc.git] / sysdeps / powerpc / fpu / math_private.h
1 /* Private inline math functions for powerpc.
2 Copyright (C) 2006-2017 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, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifndef _PPC_MATH_PRIVATE_H_
20 #define _PPC_MATH_PRIVATE_H_
21
22 #include <sysdep.h>
23 #include <ldsodefs.h>
24 #include <dl-procinfo.h>
25 #include <fenv_private.h>
26
27 /* Avoid putting floating point values in memory. */
28 # define math_opt_barrier(x) \
29 ({ __typeof (x) __x = (x); __asm ("" : "+dwa" (__x)); __x; })
30 # define math_force_eval(x) \
31 ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "dwa" (__x)); })
32
33 #include_next <math_private.h>
34
35 #if defined _ARCH_PWR9 && __HAVE_DISTINCT_FLOAT128
36 extern __always_inline _Float128
37 __ieee754_sqrtf128 (_Float128 __x)
38 {
39 _Float128 __z;
40 asm ("xssqrtqp %0,%1" : "=v" (__z) : "v" (__x));
41 return __z;
42 }
43 #endif
44
45 extern double __slow_ieee754_sqrt (double);
46 extern __always_inline double
47 __ieee754_sqrt (double __x)
48 {
49 double __z;
50
51 #ifdef _ARCH_PPCSQ
52 asm ("fsqrt %0,%1" : "=f" (__z) : "f" (__x));
53 #else
54 __z = __slow_ieee754_sqrt(__x);
55 #endif
56
57 return __z;
58 }
59
60 extern float __slow_ieee754_sqrtf (float);
61 extern __always_inline float
62 __ieee754_sqrtf (float __x)
63 {
64 float __z;
65
66 #ifdef _ARCH_PPCSQ
67 asm ("fsqrts %0,%1" : "=f" (__z) : "f" (__x));
68 #else
69 __z = __slow_ieee754_sqrtf(__x);
70 #endif
71
72 return __z;
73 }
74
75 #if defined _ARCH_PWR5X
76
77 # ifndef __round
78 # define __round(x) \
79 ({ double __z; \
80 __asm __volatile ( \
81 " frin %0,%1\n" \
82 : "=f" (__z) \
83 : "f" (x)); \
84 __z; })
85 # endif
86 # ifndef __roundf
87 # define __roundf(x) \
88 ({ float __z; \
89 __asm __volatile ( \
90 " frin %0,%1\n" \
91 " frsp %0,%0\n" \
92 : "=f" (__z) \
93 : "f" (x)); \
94 __z; })
95 # endif
96
97 # ifndef __trunc
98 # define __trunc(x) \
99 ({ double __z; \
100 __asm __volatile ( \
101 " friz %0,%1\n" \
102 : "=f" (__z) \
103 : "f" (x)); \
104 __z; })
105 # endif
106 # ifndef __truncf
107 # define __truncf(x) \
108 ({ float __z; \
109 __asm __volatile ( \
110 " friz %0,%1\n" \
111 " frsp %0,%0\n" \
112 : "=f" (__z) \
113 : "f" (x)); \
114 __z; })
115 # endif
116
117 # ifndef __ceil
118 # define __ceil(x) \
119 ({ double __z; \
120 __asm __volatile ( \
121 " frip %0,%1\n" \
122 : "=f" (__z) \
123 : "f" (x)); \
124 __z; })
125 # endif
126 # ifndef __ceilf
127 # define __ceilf(x) \
128 ({ float __z; \
129 __asm __volatile ( \
130 " frip %0,%1\n" \
131 " frsp %0,%0\n" \
132 : "=f" (__z) \
133 : "f" (x)); \
134 __z; })
135 # endif
136
137 # ifndef __floor
138 # define __floor(x) \
139 ({ double __z; \
140 __asm __volatile ( \
141 " frim %0,%1\n" \
142 : "=f" (__z) \
143 : "f" (x)); \
144 __z; })
145 # endif
146 # ifndef __floorf
147 # define __floorf(x) \
148 ({ float __z; \
149 __asm __volatile ( \
150 " frim %0,%1\n" \
151 " frsp %0,%0\n" \
152 : "=f" (__z) \
153 : "f" (x)); \
154 __z; })
155 # endif
156
157 #endif /* defined _ARCH_PWR5X */
158
159 #endif /* _PPC_MATH_PRIVATE_H_ */