Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/i386/src/libm_inlines.h
+++ new/usr/src/lib/libm/i386/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 #ifdef __cplusplus
39 39 extern "C" {
40 40 #endif
41 41
42 42 #include <sys/types.h>
43 43 #include <sys/ieeefp.h>
44 44
45 45 #define _LO_WORD(x) ((uint32_t *)&x)[0]
46 46 #define _HI_WORD(x) ((uint32_t *)&x)[1]
47 47 #define _HIER_WORD(x) ((uint32_t *)&x)[2]
48 48
49 49 extern __inline__ double
50 -__ieee754_sqrt(double a)
51 -{
52 - double ret;
53 -
54 - __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a));
55 - return (ret);
56 -}
57 -
58 -extern __inline__ double
59 50 __inline_sqrt(double a)
60 51 {
61 52 double ret;
62 53
63 - __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a));
54 + __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a) : "cc");
64 55 return (ret);
65 56 }
66 57
67 58 extern __inline__ double
68 -__d_sqrt_(double *a)
59 +__ieee754_sqrt(double a)
69 60 {
70 - double ret;
71 -
72 - __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (*a));
73 - return (ret);
61 + return (__inline_sqrt(a));
74 62 }
75 63
76 64 extern __inline__ float
77 65 __inline_sqrtf(float a)
78 66 {
79 67 float ret;
80 68
81 - __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a));
69 + __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a) : "cc");
82 70 return (ret);
83 71 }
84 72
85 73 extern __inline__ double
86 74 __inline_rint(double a)
87 75 {
88 - double ret;
89 -
90 76 __asm__ __volatile__(
91 - "andl $0x7fffffff,%2\n\t"
92 - "cmpl $0x43300000,%2\n\t"
93 - "jae 1f\n\t"
94 - "frndint\n\t"
95 - "1: fwait\n\t"
96 - : "=t" (ret)
97 - : "0" (a), "r" (_HI_WORD(a)));
98 -
99 - return (ret);
100 -}
101 -
102 -extern __inline__ short
103 -__inline_fstsw(void)
104 -{
105 - short ret;
77 + "andl $0x7fffffff,%1\n\t"
78 + "cmpl $0x43300000,%1\n\t"
79 + "jae 1f\n\t"
80 + "frndint\n\t"
81 + "1: fwait\n\t"
82 + : "+t" (a), "+&r" (_HI_WORD(a))
83 + :
84 + : "cc");
106 85
107 - __asm__ __volatile__("fstsw %0\n\t" : "=r" (ret));
108 - return (ret);
86 + return (a);
109 87 }
110 88
111 89 /*
112 90 * 00 - 24 bits
113 91 * 01 - reserved
114 92 * 10 - 53 bits
115 93 * 11 - 64 bits
116 94 */
117 95 extern __inline__ int
118 96 __swapRP(int i)
119 97 {
120 98 int ret;
121 99 uint16_t cw;
122 100
123 101 __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
124 102
125 103 ret = (cw >> 8) & 0x3;
126 104 cw = (cw & 0xfcff) | ((i & 0x3) << 8);
127 105
128 106 __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
129 107
130 108 return (ret);
131 109 }
132 110
133 111 /*
134 112 * 00 - Round to nearest, with even preferred
135 113 * 01 - Round down
136 114 * 10 - Round up
137 115 * 11 - Chop
138 116 */
139 117 extern __inline__ enum fp_direction_type
140 118 __swap87RD(enum fp_direction_type i)
141 119 {
142 120 int ret;
143 121 uint16_t cw;
144 122
145 123 __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
146 124
147 125 ret = (cw >> 10) & 0x3;
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
148 126 cw = (cw & 0xf3ff) | ((i & 0x3) << 10);
149 127
150 128 __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
151 129
152 130 return (ret);
153 131 }
154 132
155 133 extern __inline__ double
156 134 ceil(double d)
157 135 {
158 - double ret;
159 136 short rd = __swap87RD(fp_positive);
160 137
161 - __asm__ __volatile__("frndint" : "=t" (ret) : "0" (d));
138 + __asm__ __volatile__("frndint" : "+t" (d), "+r" (rd) : : "cc");
162 139 __swap87RD(rd);
163 140
164 - return (ret);
141 + return (d);
165 142 }
166 143
167 144 extern __inline__ double
168 145 copysign(double d1, double d2)
169 146 {
170 147 __asm__ __volatile__(
171 - "andl $0x7fffffff,%0\n\t" /* %0 <-- hi_32(abs(d)) */
172 - "andl $0x80000000,%1\n\t" /* %1[31] <-- sign_bit(d2) */
173 - "orl %1,%0\n\t" /* %0 <-- hi_32(copysign(x,y)) */
174 - : "+r" (_HI_WORD(d1))
175 - : "r" (_HI_WORD(d2)));
148 + "andl $0x7fffffff,%0\n\t" /* %0 <-- hi_32(abs(d)) */
149 + "andl $0x80000000,%1\n\t" /* %1[31] <-- sign_bit(d2) */
150 + "orl %1,%0\n\t" /* %0 <-- hi_32(copysign(x,y)) */
151 + : "+&r" (_HI_WORD(d1)), "+r" (_HI_WORD(d2))
152 + :
153 + : "cc");
176 154
177 155 return (d1);
178 156 }
179 157
180 158 extern __inline__ double
181 159 fabs(double d)
182 160 {
183 - double ret;
184 -
185 - __asm__ __volatile__("fabs\n\t" : "=t" (ret) : "0" (d));
186 - return (ret);
161 + __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
162 + return (d);
187 163 }
188 164
189 165 extern __inline__ float
190 166 fabsf(float d)
191 167 {
192 - float ret;
193 -
194 - __asm__ __volatile__("fabs\n\t" : "=t" (ret) : "0" (d));
195 - return (ret);
168 + __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
169 + return (d);
196 170 }
197 171
198 172 extern __inline__ long double
199 173 fabsl(long double d)
200 174 {
201 - long double ret;
202 -
203 - __asm__ __volatile__("fabs\n\t" : "=t" (ret) : "0" (d));
204 - return (ret);
175 + __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
176 + return (d);
205 177 }
206 178
207 179 extern __inline__ int
208 180 finite(double d)
209 181 {
210 - int ret;
182 + int ret = _HI_WORD(d);
211 183
212 184 __asm__ __volatile__(
213 - "notl %1\n\t"
214 - "andl $0x7ff00000,%1\n\t"
215 - "negl %1\n\t"
216 - "shrl $31,%1\n\t"
217 - : "=r" (ret)
218 - : "0" (_HI_WORD(d)));
185 + "notl %0\n\t"
186 + "andl $0x7ff00000,%0\n\t"
187 + "negl %0\n\t"
188 + "shrl $31,%0\n\t"
189 + : "+r" (ret)
190 + :
191 + : "cc");
219 192 return (ret);
220 193 }
221 194
222 195 extern __inline__ double
223 196 floor(double d)
224 197 {
225 - double ret;
226 198 short rd = __swap87RD(fp_negative);
227 199
228 - __asm__ __volatile__("frndint" : "=t" (ret) : "0" (d));
200 + __asm__ __volatile__("frndint" : "+t" (d), "+r" (rd) : : "cc");
229 201 __swap87RD(rd);
230 202
231 - return (ret);
232 -}
233 -
234 -/*
235 - * branchless __isnan
236 - * ((0x7ff00000-[((lx|-lx)>>31)&1]|ahx)>>31)&1 = 1 iff x is NaN
237 - */
238 -extern __inline__ int
239 -isnan(double d)
240 -{
241 - int ret;
242 -
243 - __asm__ __volatile__(
244 - "movl %1,%%ecx\n\t"
245 - "negl %%ecx\n\t" /* ecx <-- -lo_32(x) */
246 - "orl %%ecx,%1\n\t"
247 - "shrl $31,%1\n\t" /* 1 iff lx != 0 */
248 - "andl $0x7fffffff,%2\n\t" /* ecx <-- hi_32(abs(x)) */
249 - "orl %2,%1\n\t"
250 - "subl $0x7ff00000,%1\n\t"
251 - "negl %1\n\t"
252 - "shrl $31,%1\n\t"
253 - : "=r" (ret)
254 - : "0" (_HI_WORD(d)), "r" (_LO_WORD(d))
255 - : "ecx");
256 -
257 - return (ret);
203 + return (d);
258 204 }
259 205
260 206 extern __inline__ int
261 207 isnanf(float f)
262 208 {
263 - int ret;
264 -
265 209 __asm__ __volatile__(
266 210 "andl $0x7fffffff,%0\n\t"
267 211 "negl %0\n\t"
268 212 "addl $0x7f800000,%0\n\t"
269 213 "shrl $31,%0\n\t"
270 - : "=r" (ret)
271 - : "0" (f));
214 + : "+r" (f)
215 + :
216 + : "cc");
272 217
273 - return (ret);
274 -}
275 -
276 -extern __inline__ int
277 -isinf(double d)
278 -{
279 - int ret;
280 -
281 - __asm__ __volatile__(
282 - "andl $0x7fffffff,%1\n\t" /* set first bit to 0 */
283 - "cmpl $0x7ff00000,%1\n\t"
284 - "pushfl\n\t"
285 - "popl %0\n\t"
286 - "cmpl $0,%2\n\t" /* is lo_32(x) = 0? */
287 - "pushfl\n\t"
288 - "popl %2\n\t" /* bit 6 of ecx <-- lo_32(x) == 0 */
289 - "andl %2,%0\n\t"
290 - "andl $0x40,%0\n\t"
291 - "shrl $6,%0\n\t"
292 - : "=r" (ret)
293 - : "0" (_HI_WORD(d)), "r" (_LO_WORD(d)));
294 -
295 - return (ret);
218 + return (f);
296 219 }
297 220
298 221 extern __inline__ double
299 222 rint(double a) {
300 - double ret;
301 -
302 - __asm__ __volatile__(
303 - "andl $0x7fffffff,%2\n\t"
304 - "cmpl $0x43300000,%2\n\t"
305 - "jae 1f\n\t"
306 - "frndint\n\t"
307 - "1: fwait\n\t"
308 - : "=t" (ret)
309 - : "0" (a), "r" (_HI_WORD(a)));
310 -
311 - return (ret);
223 + return (__inline_rint(a));
312 224 }
313 225
314 226 extern __inline__ double
315 227 scalbn(double d, int n)
316 228 {
317 - double ret, dummy;
229 + double dummy;
318 230
319 231 __asm__ __volatile__(
320 - "fildl %3\n\t" /* Convert N to extended */
232 + "fildl %2\n\t" /* Convert N to extended */
321 233 "fxch\n\t"
322 234 "fscale\n\t"
323 - : "=t" (ret), "=u" (dummy)
324 - : "0" (d), "m" (n));
235 + : "+t" (d), "=u" (dummy)
236 + : "m" (n)
237 + : "cc");
325 238
326 - return (ret);
239 + return (d);
327 240 }
328 241
329 242 extern __inline__ int
330 243 signbit(double d)
331 244 {
332 245 return (_HI_WORD(d) >> 31);
333 246 }
334 247
335 248 extern __inline__ int
336 249 signbitf(float f)
337 250 {
338 251 return ((*(uint32_t *)&f) >> 31);
339 252 }
340 253
341 254 extern __inline__ double
342 255 sqrt(double d)
343 256 {
344 - double ret;
345 - __asm__ __volatile__("fsqrt" : "=t" (ret) : "0" (d));
346 - return (ret);
257 + return (__inline_sqrt(d));
347 258 }
348 259
349 260 extern __inline__ float
350 261 sqrtf(float f)
351 262 {
352 - float ret;
353 - __asm__ __volatile__("fsqrt" : "=t" (ret) : "0" (f));
354 - return (ret);
263 + return (__inline_sqrtf(f));
355 264 }
356 265
357 266 extern __inline__ long double
358 267 sqrtl(long double ld)
359 268 {
360 - long double ret;
361 - __asm__ __volatile__("fsqrt" : "=t" (ret) : "0" (ld));
362 - return (ret);
269 + __asm__ __volatile__("fsqrt" : "+t" (ld) : : "cc");
270 + return (ld);
363 271 }
364 272
365 273 extern __inline__ int
366 274 isnanl(long double ld)
367 275 {
368 - int ret;
276 + int ret = _HIER_WORD(ld);
369 277
370 - __asm__ __volatile__(
371 - "andl $0x00007fff,%1\n\t"
372 - "jz 1f\n\t" /* jump if __exp is all 0 */
373 - "xorl $0x00007fff,%1\n\t"
374 - "jz 2f\n\t" /* jump if __exp is all 1 */
375 - "testl $0x80000000,%2\n\t"
376 - "jz 3f\n\t" /* jump if leading bit is 0 */
377 - "movl $0,%1\n\t"
278 + __asm__ __volatile__(
279 + "andl $0x00007fff,%0\n\t"
280 + "jz 1f\n\t" /* jump if exp is all 0 */
281 + "xorl $0x00007fff,%0\n\t"
282 + "jz 2f\n\t" /* jump if exp is all 1 */
283 + "testl $0x80000000,%1\n\t"
284 + "jz 3f\n\t" /* jump if leading bit is 0 */
285 + "movl $0,%0\n\t"
378 286 "jmp 1f\n\t"
379 - "2:\n\t" /* note that %eax = 0 from before */
380 - "cmpl $0x80000000,%2\n\t" /* what is first half of __significand? */
381 - "jnz 3f\n\t" /* jump if not equal to 0x80000000 */
382 - "testl $0xffffffff,%3\n\t" /* is second half of __significand 0? */
383 - "jnz 3f\n\t" /* jump if not equal to 0 */
287 + "2:\n\t" /* note that %0 = 0 from before */
288 + "cmpl $0x80000000,%1\n\t" /* what is first half of significand? */
289 + "jnz 3f\n\t" /* jump if not equal to 0x80000000 */
290 + "testl $0xffffffff,%2\n\t" /* is second half of significand 0? */
291 + "jnz 3f\n\t" /* jump if not equal to 0 */
384 292 "jmp 1f\n\t"
385 - "3:\n\t"
386 - "movl $1,%1\n\t"
387 - "1:\n\t"
388 - : "=r" (ret)
389 - : "0" (_HIER_WORD(ld)), "r" (_HI_WORD(ld)), "r" (_LO_WORD(ld)));
293 + "3:\n\t"
294 + "movl $1,%0\n\t"
295 + "1:\n\t"
296 + : "+&r" (ret)
297 + : "r" (_HI_WORD(ld)), "r" (_LO_WORD(ld))
298 + : "cc");
390 299
391 - return (ret);
300 + return (ret);
392 301 }
393 302
394 303 #ifdef __cplusplus
395 304 }
396 305 #endif
397 306
398 307 #endif /* __GNUC__ */
399 308
400 309 #endif /* _LIBM_INLINES_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX