Print this page
6648 illumos build should be explicit about C standards
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 */
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 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
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
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 -extern __inline__ double
49 +extern __GNU_INLINE double
50 50 __inline_sqrt(double a)
51 51 {
52 52 double ret;
53 53
54 54 __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a) : "cc");
55 55 return (ret);
56 56 }
57 57
58 -extern __inline__ double
58 +extern __GNU_INLINE double
59 59 __ieee754_sqrt(double a)
60 60 {
61 61 return (__inline_sqrt(a));
62 62 }
63 63
64 -extern __inline__ float
64 +extern __GNU_INLINE float
65 65 __inline_sqrtf(float a)
66 66 {
67 67 float ret;
68 68
69 69 __asm__ __volatile__("fsqrt\n\t" : "=t" (ret) : "0" (a) : "cc");
70 70 return (ret);
71 71 }
72 72
73 -extern __inline__ double
73 +extern __GNU_INLINE double
74 74 __inline_rint(double a)
75 75 {
76 76 __asm__ __volatile__(
77 77 "andl $0x7fffffff,%1\n\t"
78 78 "cmpl $0x43300000,%1\n\t"
79 79 "jae 1f\n\t"
80 80 "frndint\n\t"
81 81 "1: fwait\n\t"
82 82 : "+t" (a), "+&r" (_HI_WORD(a))
83 83 :
84 84 : "cc");
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
85 85
86 86 return (a);
87 87 }
88 88
89 89 /*
90 90 * 00 - 24 bits
91 91 * 01 - reserved
92 92 * 10 - 53 bits
93 93 * 11 - 64 bits
94 94 */
95 -extern __inline__ int
95 +extern __GNU_INLINE int
96 96 __swapRP(int i)
97 97 {
98 98 int ret;
99 99 uint16_t cw;
100 100
101 101 __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
102 102
103 103 ret = (cw >> 8) & 0x3;
104 104 cw = (cw & 0xfcff) | ((i & 0x3) << 8);
105 105
106 106 __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
107 107
108 108 return (ret);
109 109 }
110 110
111 111 /*
112 112 * 00 - Round to nearest, with even preferred
113 113 * 01 - Round down
114 114 * 10 - Round up
115 115 * 11 - Chop
116 116 */
117 -extern __inline__ enum fp_direction_type
117 +extern __GNU_INLINE enum fp_direction_type
118 118 __swap87RD(enum fp_direction_type i)
119 119 {
120 120 int ret;
121 121 uint16_t cw;
122 122
123 123 __asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
124 124
125 125 ret = (cw >> 10) & 0x3;
126 126 cw = (cw & 0xf3ff) | ((i & 0x3) << 10);
127 127
128 128 __asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
129 129
130 130 return (ret);
131 131 }
132 132
133 -extern __inline__ double
133 +extern __GNU_INLINE double
134 134 ceil(double d)
135 135 {
136 136 /*
137 137 * Let's set a Rounding Control (RC) bits from x87 FPU Control Word
138 138 * to fp_positive and save old bits in rd.
139 139 */
140 140 short rd = __swap87RD(fp_positive);
141 141
142 142 /*
143 143 * The FRNDINT instruction returns a floating-point value that is the
144 144 * integral value closest to the source value in the direction of the
145 145 * rounding mode specified in the RC field of the x87 FPU control word.
146 146 *
147 147 * Rounds the source value in the ST(0) register to the nearest
148 148 * integral value, depending on the current rounding mode
149 149 * (setting of the RC field of the FPU control word),
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
150 150 * and stores the result in ST(0).
151 151 */
152 152 __asm__ __volatile__("frndint" : "+t" (d) : : "cc");
153 153
154 154 /* restore old RC bits */
155 155 __swap87RD(rd);
156 156
157 157 return (d);
158 158 }
159 159
160 -extern __inline__ double
160 +extern __GNU_INLINE double
161 161 copysign(double d1, double d2)
162 162 {
163 163 __asm__ __volatile__(
164 164 "andl $0x7fffffff,%0\n\t" /* %0 <-- hi_32(abs(d)) */
165 165 "andl $0x80000000,%1\n\t" /* %1[31] <-- sign_bit(d2) */
166 166 "orl %1,%0\n\t" /* %0 <-- hi_32(copysign(x,y)) */
167 167 : "+&r" (_HI_WORD(d1)), "+r" (_HI_WORD(d2))
168 168 :
169 169 : "cc");
170 170
171 171 return (d1);
172 172 }
173 173
174 -extern __inline__ double
174 +extern __GNU_INLINE double
175 175 fabs(double d)
176 176 {
177 177 __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
178 178 return (d);
179 179 }
180 180
181 -extern __inline__ float
181 +extern __GNU_INLINE float
182 182 fabsf(float d)
183 183 {
184 184 __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
185 185 return (d);
186 186 }
187 187
188 -extern __inline__ long double
188 +extern __GNU_INLINE long double
189 189 fabsl(long double d)
190 190 {
191 191 __asm__ __volatile__("fabs\n\t" : "+t" (d) : : "cc");
192 192 return (d);
193 193 }
194 194
195 -extern __inline__ int
195 +extern __GNU_INLINE int
196 196 finite(double d)
197 197 {
198 198 int ret = _HI_WORD(d);
199 199
200 200 __asm__ __volatile__(
201 201 "notl %0\n\t"
202 202 "andl $0x7ff00000,%0\n\t"
203 203 "negl %0\n\t"
204 204 "shrl $31,%0\n\t"
205 205 : "+r" (ret)
206 206 :
207 207 : "cc");
208 208 return (ret);
209 209 }
210 210
211 -extern __inline__ double
211 +extern __GNU_INLINE double
212 212 floor(double d)
213 213 {
214 214 short rd = __swap87RD(fp_negative);
215 215
216 216 __asm__ __volatile__("frndint" : "+t" (d), "+r" (rd) : : "cc");
217 217 __swap87RD(rd);
218 218
219 219 return (d);
220 220 }
221 221
222 222 /*
223 223 * branchless __isnan
224 224 * ((0x7ff00000-[((lx|-lx)>>31)&1]|ahx)>>31)&1 = 1 iff x is NaN
225 225 */
226 -extern __inline__ int
226 +extern __GNU_INLINE int
227 227 isnan(double d)
228 228 {
229 229 int ret;
230 230
231 231 __asm__ __volatile__(
232 - "movl %1,%%ecx\n\t"
233 - "negl %%ecx\n\t" /* ecx <-- -lo_32(x) */
234 - "orl %%ecx,%1\n\t"
235 - "shrl $31,%1\n\t" /* 1 iff lx != 0 */
236 - "andl $0x7fffffff,%2\n\t" /* ecx <-- hi_32(abs(x)) */
237 - "orl %2,%1\n\t"
238 - "subl $0x7ff00000,%1\n\t"
239 - "negl %1\n\t"
240 - "shrl $31,%1\n\t"
241 - : "=r" (ret)
242 - : "0" (_HI_WORD(d)), "r" (_LO_WORD(d))
243 - : "ecx");
232 + "movl %1,%%ecx\n\t"
233 + "negl %%ecx\n\t" /* ecx <-- -lo_32(x) */
234 + "orl %%ecx,%1\n\t"
235 + "shrl $31,%1\n\t" /* 1 iff lx != 0 */
236 + "andl $0x7fffffff,%2\n\t" /* ecx <-- hi_32(abs(x)) */
237 + "orl %2,%1\n\t"
238 + "subl $0x7ff00000,%1\n\t"
239 + "negl %1\n\t"
240 + "shrl $31,%1\n\t"
241 + : "=r" (ret)
242 + : "0" (_HI_WORD(d)), "r" (_LO_WORD(d))
243 + : "ecx");
244 244
245 245 return (ret);
246 246 }
247 247
248 -extern __inline__ int
248 +extern __GNU_INLINE int
249 249 isnanf(float f)
250 250 {
251 251 __asm__ __volatile__(
252 252 "andl $0x7fffffff,%0\n\t"
253 253 "negl %0\n\t"
254 254 "addl $0x7f800000,%0\n\t"
255 255 "shrl $31,%0\n\t"
256 256 : "+r" (f)
257 257 :
258 258 : "cc");
259 259
260 260 return (f);
261 261 }
262 262
263 -extern __inline__ double
263 +extern __GNU_INLINE double
264 264 rint(double a) {
265 265 return (__inline_rint(a));
266 266 }
267 267
268 -extern __inline__ double
268 +extern __GNU_INLINE double
269 269 scalbn(double d, int n)
270 270 {
271 271 double dummy;
272 272
273 273 __asm__ __volatile__(
274 274 "fildl %2\n\t" /* Convert N to extended */
275 275 "fxch\n\t"
276 276 "fscale\n\t"
277 277 : "+t" (d), "=u" (dummy)
278 278 : "m" (n)
279 279 : "cc");
280 280
281 281 return (d);
282 282 }
283 283
284 -extern __inline__ int
284 +extern __GNU_INLINE int
285 285 signbit(double d)
286 286 {
287 287 return (_HI_WORD(d) >> 31);
288 288 }
289 289
290 -extern __inline__ int
290 +extern __GNU_INLINE int
291 291 signbitf(float f)
292 292 {
293 293 return ((*(uint32_t *)&f) >> 31);
294 294 }
295 295
296 -extern __inline__ double
296 +extern __GNU_INLINE double
297 297 sqrt(double d)
298 298 {
299 299 return (__inline_sqrt(d));
300 300 }
301 301
302 -extern __inline__ float
302 +extern __GNU_INLINE float
303 303 sqrtf(float f)
304 304 {
305 305 return (__inline_sqrtf(f));
306 306 }
307 307
308 -extern __inline__ long double
308 +extern __GNU_INLINE long double
309 309 sqrtl(long double ld)
310 310 {
311 311 __asm__ __volatile__("fsqrt" : "+t" (ld) : : "cc");
312 312 return (ld);
313 313 }
314 314
315 -extern __inline__ int
315 +extern __GNU_INLINE int
316 316 isnanl(long double ld)
317 317 {
318 318 int ret = _HIER_WORD(ld);
319 319
320 320 __asm__ __volatile__(
321 321 "andl $0x00007fff,%0\n\t"
322 322 "jz 1f\n\t" /* jump if exp is all 0 */
323 323 "xorl $0x00007fff,%0\n\t"
324 324 "jz 2f\n\t" /* jump if exp is all 1 */
325 325 "testl $0x80000000,%1\n\t"
326 326 "jz 3f\n\t" /* jump if leading bit is 0 */
327 327 "xorl %0,%0\n\t"
328 328 "jmp 1f\n\t"
329 329 "2:\n\t" /* note that %0 = 0 from before */
330 330 "cmpl $0x80000000,%1\n\t" /* what is first half of significand? */
331 331 "jnz 3f\n\t" /* jump if not equal to 0x80000000 */
332 332 "testl $0xffffffff,%2\n\t" /* is second half of significand 0? */
333 333 "jnz 3f\n\t" /* jump if not equal to 0 */
334 334 "jmp 1f\n\t"
335 335 "3:\n\t"
336 336 "movl $1,%0\n\t"
337 337 "1:\n\t"
338 338 : "+&r" (ret)
339 339 : "r" (_HI_WORD(ld)), "r" (_LO_WORD(ld))
340 340 : "cc");
341 341
342 342 return (ret);
343 343 }
344 344
345 345 #ifdef __cplusplus
346 346 }
347 347 #endif
348 348
349 349 #endif /* __GNUC__ */
350 350
351 351 #endif /* _LIBM_INLINES_H */
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX