Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/sparc/src/libm_inlines.h
+++ new/usr/src/lib/libm/sparc/src/libm_inlines.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21
22 22 /*
23 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright 2011, Richard Lowe.
29 29 */
30 30
31 -/* Functions in this file are duplicated in libm.m4. Keep them in sync */
31 +/* Functions in this file are duplicated in locallibm.il. Keep them in sync */
32 32
33 33 #ifndef _LIBM_INLINES_H
34 34 #define _LIBM_INLINES_H
35 35
36 36 #ifdef __GNUC__
37 37
38 38 #include <sys/types.h>
39 39 #include <sys/ieeefp.h>
40 40
41 41 #ifdef __cplusplus
42 42 extern "C" {
43 43 #endif
44 44
45 45 extern __inline__ double
46 46 __inline_sqrt(double d)
47 47 {
48 48 double ret;
49 49
50 - __asm__ __volatile__("fsqrtd %0,%0\n\t" : "=e" (ret) : "0" (d));
50 + __asm__ __volatile__("fsqrtd %1,%0\n\t" : "=e" (ret) : "e" (d));
51 51 return (ret);
52 52 }
53 53
54 54 extern __inline__ float
55 55 __inline_sqrtf(float f)
56 56 {
57 57 float ret;
58 58
59 - __asm__ __volatile__("fsqrts %0,%0\n\t" : "=f" (ret) : "0" (f));
59 + __asm__ __volatile__("fsqrts %1,%0\n\t" : "=f" (ret) : "f" (f));
60 60 return (ret);
61 61 }
62 62
63 63 extern __inline__ enum fp_class_type
64 64 fp_classf(float f)
65 65 {
66 66 enum fp_class_type ret;
67 + uint32_t tmp;
67 68
69 + /* XXX: Separate input and output */
68 70 __asm__ __volatile__(
69 - "sethi %%hi(0x80000000),%%o2\n\t"
70 - "andncc %0,%%o2,%0\n\t"
71 + "sethi %%hi(0x80000000),%1\n\t"
72 + "andncc %3,%1,%0\n\t"
71 73 "bne 1f\n\t"
72 74 "nop\n\t"
73 75 "mov 0,%0\n\t"
74 - "ba 2f\n\t" /* x is 0 */
76 + "ba 2f\n\t" /* x is 0 */
75 77 "nop\n\t"
76 78 "1:\n\t"
77 - "sethi %%hi(0x7f800000),%%o2\n\t"
78 - "andcc %0,%%o2,%%g0\n\t"
79 + "sethi %%hi(0x7f800000),%1\n\t"
80 + "andcc %0,%1,%%g0\n\t"
79 81 "bne 1f\n\t"
80 82 "nop\n\t"
81 83 "mov 1,%0\n\t"
82 - "ba 2f\n\t" /* x is subnormal */
84 + "ba 2f\n\t" /* x is subnormal */
83 85 "nop\n\t"
84 86 "1:\n\t"
85 - "cmp %0,%%o2\n\t"
87 + "cmp %0,%1\n\t"
86 88 "bge 1f\n\t"
87 89 "nop\n\t"
88 90 "mov 2,%0\n\t"
89 - "ba 2f\n\t" /* x is normal */
91 + "ba 2f\n\t" /* x is normal */
90 92 "nop\n\t"
91 93 "1:\n\t"
92 94 "bg 1f\n\t"
93 95 "nop\n\t"
94 96 "mov 3,%0\n\t"
95 - "ba 2f\n\t" /* x is __infinity */
97 + "ba 2f\n\t" /* x is __infinity */
96 98 "nop\n\t"
97 99 "1:\n\t"
98 - "sethi %%hi(0x00400000),%%o2\n\t"
99 - "andcc %0,%%o2,%%g0\n\t"
100 - "mov 4,%0\n\t" /* x is quiet NaN */
100 + "sethi %%hi(0x00400000),%1\n\t"
101 + "andcc %0,%1,%%g0\n\t"
102 + "mov 4,%0\n\t" /* x is quiet NaN */
101 103 "bne 2f\n\t"
102 104 "nop\n\t"
103 - "mov 5,%0\n\t" /* x is signaling NaN */
105 + "mov 5,%0\n\t" /* x is signaling NaN */
104 106 "2:\n\t"
105 - : "=r" (ret)
106 - : "0" (f)
107 - : "o2");
107 + : "+r" (ret), "=&r" (tmp)
108 + : "r" (f)
109 + : "cc");
108 110 return (ret);
109 111 }
110 112
111 113 #define _HI_WORD(x) ((uint32_t *)&x)[0]
112 114 #define _LO_WORD(x) ((uint32_t *)&x)[1]
113 115
114 116 extern __inline__ enum fp_class_type
115 117 fp_class(double d)
116 118 {
117 119 enum fp_class_type ret;
120 + uint32_t tmp;
118 121
119 122 __asm__ __volatile__(
120 - "sethi %%hi(0x80000000),%%o2\n\t" /* o2 gets 80000000 */
121 - "andn %0,%%o2,%0\n\t" /* o0-o1 gets abs(x) */
122 - "orcc %0,%2,%%g0\n\t" /* set cc as x is zero/nonzero */
123 - "bne 1f\n\t" /* branch if x is nonzero */
123 + "sethi %%hi(0x80000000),%1\n\t" /* %1 gets 80000000 */
124 + "andn %2,%1,%0\n\t" /* %2-%0 gets abs(x) */
125 + "orcc %0,%3,%%g0\n\t" /* set cc as x is zero/nonzero */
126 + "bne 1f\n\t" /* branch if x is nonzero */
124 127 "nop\n\t"
125 128 "mov 0,%0\n\t"
126 - "ba 2f\n\t" /* x is 0 */
129 + "ba 2f\n\t" /* x is 0 */
127 130 "nop\n\t"
128 131 "1:\n\t"
129 - "sethi %%hi(0x7ff00000),%%o2\n\t" /* o2 gets 7ff00000 */
130 - "andcc %0,%%o2,%%g0\n\t" /* cc set by __exp field of x */
131 - "bne 1f\n\t" /* branch if normal or max __exp */
132 + "sethi %%hi(0x7ff00000),%1\n\t" /* %1 gets 7ff00000 */
133 + "andcc %0,%1,%%g0\n\t" /* cc set by __exp field of x */
134 + "bne 1f\n\t" /* branch if normal or max __exp */
132 135 "nop\n\t"
133 136 "mov 1,%0\n\t"
134 - "ba 2f\n\t" /* x is subnormal */
137 + "ba 2f\n\t" /* x is subnormal */
135 138 "nop\n\t"
136 139 "1:\n\t"
137 - "cmp %0,%%o2\n\t"
138 - "bge 1f\n\t" /* branch if x is max __exp */
140 + "cmp %0,%1\n\t"
141 + "bge 1f\n\t" /* branch if x is max __exp */
139 142 "nop\n\t"
140 143 "mov 2,%0\n\t"
141 - "ba 2f\n\t" /* x is normal */
144 + "ba 2f\n\t" /* x is normal */
142 145 "nop\n\t"
143 146 "1:\n\t"
144 - "andn %0,%%o2,%0\n\t" /* o0 gets msw __significand field */
145 - "orcc %0,%2,%%g0\n\t" /* set cc by OR __significand */
146 - "bne 1f\n\t" /* Branch if __nan */
147 + "andn %0,%1,%0\n\t" /* o0 gets msw __significand field */
148 + "orcc %0,%3,%%g0\n\t" /* set cc by OR __significand */
149 + "bne 1f\n\t" /* Branch if __nan */
147 150 "nop\n\t"
148 151 "mov 3,%0\n\t"
149 - "ba 2f\n\t" /* x is __infinity */
152 + "ba 2f\n\t" /* x is __infinity */
150 153 "nop\n\t"
151 154 "1:\n\t"
152 - "sethi %%hi(0x00080000),%%o2\n\t"
153 - "andcc %0,%%o2,%%g0\n\t" /* set cc by quiet/sig bit */
154 - "be 1f\n\t" /* Branch if signaling */
155 + "sethi %%hi(0x00080000),%1\n\t"
156 + "andcc %0,%1,%%g0\n\t" /* set cc by quiet/sig bit */
157 + "be 1f\n\t" /* Branch if signaling */
155 158 "nop\n\t"
156 - "mov 4,%0\n\t" /* x is quiet NaN */
159 + "mov 4,%0\n\t" /* x is quiet NaN */
157 160 "ba 2f\n\t"
158 161 "nop\n\t"
159 162 "1:\n\t"
160 - "mov 5,%0\n\t" /* x is signaling NaN */
163 + "mov 5,%0\n\t" /* x is signaling NaN */
161 164 "2:\n\t"
162 - : "=r" (ret)
163 - : "0" (_HI_WORD(d)), "r" (_LO_WORD(d))
164 - : "o2");
165 + : "=&r" (ret), "=&r" (tmp)
166 + : "r" (_HI_WORD(d)), "r" (_LO_WORD(d))
167 + : "cc");
165 168
166 169 return (ret);
167 170 }
168 171
169 172 extern __inline__ int
170 173 __swapEX(int i)
171 174 {
172 175 int ret;
173 176 uint32_t fsr;
177 + uint32_t tmp1, tmp2;
174 178
175 179 __asm__ __volatile__(
176 - "and %0,0x1f,%%o1\n\t"
177 - "sll %%o1,5,%%o1\n\t" /* input to aexc bit location */
180 + "and %4,0x1f,%3\n\t"
181 + "sll %3,5,%3\n\t" /* shift input to aexc bit location */
178 182 ".volatile\n\t"
179 - "st %%fsr,%2\n\t"
180 - "ld %2,%0\n\t" /* = fsr */
181 - "andn %0,0x3e0,%%o2\n\t"
182 - "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */
183 - "st %%o1,%2\n\t"
184 - "ld %2,%%fsr\n\t"
183 + "st %%fsr,%1\n\t"
184 + "ld %1,%0\n\t" /* %0 = fsr */
185 + "andn %0,0x3e0,%4\n\t"
186 + "or %3,%4,%3\n\t" /* %3 = new fsr */
187 + "st %3,%1\n\t"
188 + "ld %1,%%fsr\n\t"
185 189 "srl %0,5,%0\n\t"
186 190 "and %0,0x1f,%0\n\t"
187 191 ".nonvolatile\n\t"
188 - : "=r" (ret)
189 - : "0" (i), "m" (fsr)
190 - : "o1", "o2");
192 + : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2)
193 + : "r" (i)
194 + : "cc");
191 195
192 196 return (ret);
193 197 }
194 198
195 199 /*
196 200 * On the SPARC, __swapRP is a no-op; always return 0 for backward
197 201 * compatibility
198 202 */
199 203 /* ARGSUSED */
200 204 extern __inline__ enum fp_precision_type
201 205 __swapRP(enum fp_precision_type i)
202 206 {
203 207 return (0);
204 208 }
205 209
206 210 extern __inline__ enum fp_direction_type
207 211 __swapRD(enum fp_direction_type d)
208 212 {
209 213 enum fp_direction_type ret;
210 214 uint32_t fsr;
215 + uint32_t tmp1, tmp2, tmp3;
211 216
212 217 __asm__ __volatile__(
213 - "and %0,0x3,%0\n\t"
214 - "sll %0,30,%%o1\n\t" /* input to RD bit location */
218 + "and %5,0x3,%0\n\t"
219 + "sll %0,30,%2\n\t" /* shift input to RD bit location */
215 220 ".volatile\n\t"
216 - "st %%fsr,%2\n\t"
217 - "ld %2,%0\n\t" /* o0 = fsr */
218 - "set 0xc0000000,%%o4\n\t" /* mask of rounding direction bits */
219 - "andn %0,%%o4,%%o2\n\t"
220 - "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */
221 - "st %%o1,%2\n\t"
222 - "ld %2,%%fsr\n\t"
221 + "st %%fsr,%1\n\t"
222 + "ld %1,%0\n\t" /* %0 = fsr */
223 + "set 0xc0000000,%4\n\t" /* mask of rounding direction bits */
224 + "andn %0,%4,%3\n\t"
225 + "or %2,%3,%2\n\t" /* %2 = new fsr */
226 + "st %2,%1\n\t"
227 + "ld %1,%%fsr\n\t"
223 228 "srl %0,30,%0\n\t"
224 229 "and %0,0x3,%0\n\t"
225 230 ".nonvolatile\n\t"
226 - : "=r" (ret)
227 - : "0" (d), "m" (fsr)
228 - : "o1", "o2", "o4");
231 + : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
232 + : "r" (d)
233 + : "cc");
229 234
230 235 return (ret);
231 236 }
232 237
233 238 extern __inline__ int
234 239 __swapTE(int i)
235 240 {
236 241 int ret;
237 - uint32_t fsr;
238 -
242 + uint32_t fsr, tmp1, tmp2;
243 +
239 244 __asm__ __volatile__(
240 - "and %0,0x1f,%0\n\t"
241 - "sll %0,23,%%o1\n\t" /* input to TEM bit location */
245 + "and %4,0x1f,%0\n\t"
246 + "sll %0,23,%2\n\t" /* shift input to TEM bit location */
242 247 ".volatile\n\t"
243 - "st %%fsr,%2\n\t"
244 - "ld %2,%0\n\t" /* o0 = fsr */
245 - "set 0x0f800000,%%o4\n\t" /* mask of TEM (Trap Enable Mode bits) */
246 - "andn %0,%%o4,%%o2\n\t"
247 - "or %%o1,%%o2,%%o1\n\t" /* o1 = new fsr */
248 - "st %%o1,%2\n\t"
249 - "ld %2,%%fsr\n\t"
248 + "st %%fsr,%1\n\t"
249 + "ld %1,%0\n\t" /* %0 = fsr */
250 + "set 0x0f800000,%%o4\n\t" /* mask of TEM (Trap Enable Mode bits) */
251 + "andn %0,%%o4,%3\n\t"
252 + "or %2,%3,%2\n\t" /* %2 = new fsr */
253 + "st %2,%1\n\t"
254 + "ld %1,%%fsr\n\t"
250 255 "srl %0,23,%0\n\t"
251 256 "and %0,0x1f,%0\n\t"
252 257 ".nonvolatile\n\t"
253 - : "=r" (ret)
254 - : "0" (i), "m" (fsr)
255 - : "o1", "o2", "o4");
258 + : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2)
259 + : "r" (i)
260 + : "cc");
256 261
257 262 return (ret);
258 263 }
259 264
260 265 extern __inline__ double
261 266 sqrt(double d)
262 267 {
263 - double ret;
264 -
265 - __asm__ __volatile__("fsqrtd %0,%0\n\t" : "=f" (ret) : "0" (d));
266 - return (ret);
268 + return (__inline_sqrt(d));
267 269 }
268 270
269 271 extern __inline__ float
270 272 sqrtf(float f)
271 273 {
272 - float ret;
273 -
274 - __asm__ __volatile__("fsqrts %0,%0\n\t" : "=f" (ret) : "0" (f));
275 - return (ret);
274 + return (__inline_sqrtf(f));
276 275 }
277 276
278 277 extern __inline__ double
279 278 fabs(double d)
280 279 {
281 - double ret;
280 + double ret;
282 281
283 - __asm__ __volatile__("fabsd %0,%0\n\t" : "=e" (ret) : "0" (d));
284 - return (ret);
282 + __asm__ __volatile__("fabsd %1,%0\n\t" : "=e" (ret) : "e" (d));
283 + return (ret);
285 284 }
286 285
287 286 extern __inline__ float
288 287 fabsf(float f)
289 288 {
290 - float ret;
289 + float ret;
291 290
292 - __asm__ __volatile__("fabss %0,%0\n\t" : "=f" (ret) : "0" (f));
293 - return (ret);
291 + __asm__ __volatile__("fabss %1,%0\n\t" : "=f" (ret) : "f" (f));
292 + return (ret);
294 293 }
295 294
296 295 #ifdef __cplusplus
297 296 }
298 297 #endif
299 298
300 299 #endif /* __GNUC */
301 300
302 301 #endif /* _LIBM_INLINES_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX