]>
Commit | Line | Data |
---|---|---|
f7eac6eb RM |
1 | /* |
2 | * ==================================================== | |
3 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |
4 | * | |
5 | * Developed at SunPro, a Sun Microsystems, Inc. business. | |
6 | * Permission to use, copy, modify, and distribute this | |
7 | * software is freely granted, provided that this notice | |
8 | * is preserved. | |
9 | * ==================================================== | |
10 | */ | |
11 | ||
12 | /* | |
13 | * from: @(#)fdlibm.h 5.1 93/09/24 | |
f7eac6eb RM |
14 | */ |
15 | ||
16 | #ifndef _MATH_PRIVATE_H_ | |
17 | #define _MATH_PRIVATE_H_ | |
18 | ||
abfbdde1 | 19 | #include <endian.h> |
cf00cc00 | 20 | #include <stdint.h> |
f7eac6eb RM |
21 | #include <sys/types.h> |
22 | ||
23 | /* The original fdlibm code used statements like: | |
24 | n0 = ((*(int*)&one)>>29)^1; * index of high word * | |
25 | ix0 = *(n0+(int*)&x); * high word of x * | |
26 | ix1 = *((1-n0)+(int*)&x); * low word of x * | |
27 | to dig two 32 bit words out of the 64 bit IEEE floating point | |
28 | value. That is non-ANSI, and, moreover, the gcc instruction | |
29 | scheduler gets it wrong. We instead use the following macros. | |
30 | Unlike the original code, we determine the endianness at compile | |
31 | time, not at run time; I don't see much benefit to selecting | |
32 | endianness at run time. */ | |
33 | ||
34 | /* A union which permits us to convert between a double and two 32 bit | |
35 | ints. */ | |
36 | ||
48252123 | 37 | #if __FLOAT_WORD_ORDER == BIG_ENDIAN |
f7eac6eb RM |
38 | |
39 | typedef union | |
40 | { | |
41 | double value; | |
42 | struct | |
43 | { | |
44 | u_int32_t msw; | |
45 | u_int32_t lsw; | |
46 | } parts; | |
cf00cc00 | 47 | uint64_t word; |
f7eac6eb RM |
48 | } ieee_double_shape_type; |
49 | ||
50 | #endif | |
51 | ||
48252123 | 52 | #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN |
f7eac6eb RM |
53 | |
54 | typedef union | |
55 | { | |
56 | double value; | |
57 | struct | |
58 | { | |
59 | u_int32_t lsw; | |
60 | u_int32_t msw; | |
61 | } parts; | |
cf00cc00 | 62 | uint64_t word; |
f7eac6eb RM |
63 | } ieee_double_shape_type; |
64 | ||
65 | #endif | |
66 | ||
67 | /* Get two 32 bit ints from a double. */ | |
68 | ||
69 | #define EXTRACT_WORDS(ix0,ix1,d) \ | |
70 | do { \ | |
71 | ieee_double_shape_type ew_u; \ | |
72 | ew_u.value = (d); \ | |
73 | (ix0) = ew_u.parts.msw; \ | |
74 | (ix1) = ew_u.parts.lsw; \ | |
75 | } while (0) | |
76 | ||
77 | /* Get the more significant 32 bit int from a double. */ | |
78 | ||
79 | #define GET_HIGH_WORD(i,d) \ | |
80 | do { \ | |
81 | ieee_double_shape_type gh_u; \ | |
82 | gh_u.value = (d); \ | |
83 | (i) = gh_u.parts.msw; \ | |
84 | } while (0) | |
85 | ||
86 | /* Get the less significant 32 bit int from a double. */ | |
87 | ||
88 | #define GET_LOW_WORD(i,d) \ | |
89 | do { \ | |
90 | ieee_double_shape_type gl_u; \ | |
91 | gl_u.value = (d); \ | |
92 | (i) = gl_u.parts.lsw; \ | |
93 | } while (0) | |
94 | ||
cf00cc00 UD |
95 | /* Get all in one, efficient on 64-bit machines. */ |
96 | #define EXTRACT_WORDS64(i,d) \ | |
97 | do { \ | |
98 | ieee_double_shape_type gh_u; \ | |
99 | gh_u.value = (d); \ | |
100 | (i) = gh_u.word; \ | |
101 | } while (0) | |
102 | ||
f7eac6eb RM |
103 | /* Set a double from two 32 bit ints. */ |
104 | ||
105 | #define INSERT_WORDS(d,ix0,ix1) \ | |
106 | do { \ | |
107 | ieee_double_shape_type iw_u; \ | |
108 | iw_u.parts.msw = (ix0); \ | |
109 | iw_u.parts.lsw = (ix1); \ | |
110 | (d) = iw_u.value; \ | |
111 | } while (0) | |
112 | ||
cf00cc00 | 113 | /* Get all in one, efficient on 64-bit machines. */ |
2e9337f5 | 114 | #define INSERT_WORDS64(d,i) \ |
cf00cc00 UD |
115 | do { \ |
116 | ieee_double_shape_type iw_u; \ | |
117 | iw_u.word = (i); \ | |
118 | (d) = iw_u.value; \ | |
119 | } while (0) | |
120 | ||
f7eac6eb RM |
121 | /* Set the more significant 32 bits of a double from an int. */ |
122 | ||
123 | #define SET_HIGH_WORD(d,v) \ | |
124 | do { \ | |
125 | ieee_double_shape_type sh_u; \ | |
126 | sh_u.value = (d); \ | |
127 | sh_u.parts.msw = (v); \ | |
128 | (d) = sh_u.value; \ | |
129 | } while (0) | |
130 | ||
131 | /* Set the less significant 32 bits of a double from an int. */ | |
132 | ||
133 | #define SET_LOW_WORD(d,v) \ | |
134 | do { \ | |
135 | ieee_double_shape_type sl_u; \ | |
136 | sl_u.value = (d); \ | |
137 | sl_u.parts.lsw = (v); \ | |
138 | (d) = sl_u.value; \ | |
139 | } while (0) | |
140 | ||
141 | /* A union which permits us to convert between a float and a 32 bit | |
142 | int. */ | |
143 | ||
144 | typedef union | |
145 | { | |
146 | float value; | |
147 | u_int32_t word; | |
148 | } ieee_float_shape_type; | |
149 | ||
150 | /* Get a 32 bit int from a float. */ | |
151 | ||
152 | #define GET_FLOAT_WORD(i,d) \ | |
153 | do { \ | |
154 | ieee_float_shape_type gf_u; \ | |
155 | gf_u.value = (d); \ | |
156 | (i) = gf_u.word; \ | |
157 | } while (0) | |
158 | ||
159 | /* Set a float from a 32 bit int. */ | |
160 | ||
161 | #define SET_FLOAT_WORD(d,i) \ | |
162 | do { \ | |
163 | ieee_float_shape_type sf_u; \ | |
164 | sf_u.word = (i); \ | |
165 | (d) = sf_u.value; \ | |
166 | } while (0) | |
167 | ||
abfbdde1 UD |
168 | /* Get long double macros from a separate header. */ |
169 | #include <math_ldbl.h> | |
76060ec0 | 170 | |
f7eac6eb | 171 | /* ieee style elementary functions */ |
c1422e5b UD |
172 | extern double __ieee754_sqrt (double); |
173 | extern double __ieee754_acos (double); | |
174 | extern double __ieee754_acosh (double); | |
175 | extern double __ieee754_log (double); | |
176 | extern double __ieee754_atanh (double); | |
177 | extern double __ieee754_asin (double); | |
178 | extern double __ieee754_atan2 (double,double); | |
179 | extern double __ieee754_exp (double); | |
180 | extern double __ieee754_exp2 (double); | |
181 | extern double __ieee754_exp10 (double); | |
182 | extern double __ieee754_cosh (double); | |
183 | extern double __ieee754_fmod (double,double); | |
184 | extern double __ieee754_pow (double,double); | |
185 | extern double __ieee754_lgamma_r (double,int *); | |
186 | extern double __ieee754_gamma_r (double,int *); | |
187 | extern double __ieee754_lgamma (double); | |
188 | extern double __ieee754_gamma (double); | |
189 | extern double __ieee754_log10 (double); | |
601d2942 | 190 | extern double __ieee754_log2 (double); |
c1422e5b UD |
191 | extern double __ieee754_sinh (double); |
192 | extern double __ieee754_hypot (double,double); | |
193 | extern double __ieee754_j0 (double); | |
194 | extern double __ieee754_j1 (double); | |
195 | extern double __ieee754_y0 (double); | |
196 | extern double __ieee754_y1 (double); | |
197 | extern double __ieee754_jn (int,double); | |
198 | extern double __ieee754_yn (int,double); | |
199 | extern double __ieee754_remainder (double,double); | |
200 | extern int32_t __ieee754_rem_pio2 (double,double*); | |
201 | extern double __ieee754_scalb (double,double); | |
f7eac6eb RM |
202 | |
203 | /* fdlibm kernel function */ | |
c1422e5b | 204 | extern double __kernel_standard (double,double,int); |
0ac5ae23 | 205 | extern float __kernel_standard_f (float,float,int); |
c1422e5b UD |
206 | extern double __kernel_sin (double,double,int); |
207 | extern double __kernel_cos (double,double); | |
208 | extern double __kernel_tan (double,double,int); | |
209 | extern int __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*); | |
f7eac6eb | 210 | |
e859d1d9 AJ |
211 | /* internal functions. */ |
212 | extern double __copysign (double x, double __y); | |
213 | ||
bc82059d RH |
214 | #if __GNUC_PREREQ (4, 0) |
215 | extern inline double __copysign (double x, double y) | |
216 | { return __builtin_copysign (x, y); } | |
217 | #endif | |
f7eac6eb RM |
218 | |
219 | /* ieee style elementary float functions */ | |
c1422e5b UD |
220 | extern float __ieee754_sqrtf (float); |
221 | extern float __ieee754_acosf (float); | |
222 | extern float __ieee754_acoshf (float); | |
223 | extern float __ieee754_logf (float); | |
224 | extern float __ieee754_atanhf (float); | |
225 | extern float __ieee754_asinf (float); | |
226 | extern float __ieee754_atan2f (float,float); | |
227 | extern float __ieee754_expf (float); | |
228 | extern float __ieee754_exp2f (float); | |
229 | extern float __ieee754_exp10f (float); | |
230 | extern float __ieee754_coshf (float); | |
231 | extern float __ieee754_fmodf (float,float); | |
232 | extern float __ieee754_powf (float,float); | |
233 | extern float __ieee754_lgammaf_r (float,int *); | |
234 | extern float __ieee754_gammaf_r (float,int *); | |
235 | extern float __ieee754_lgammaf (float); | |
236 | extern float __ieee754_gammaf (float); | |
237 | extern float __ieee754_log10f (float); | |
601d2942 | 238 | extern float __ieee754_log2f (float); |
c1422e5b UD |
239 | extern float __ieee754_sinhf (float); |
240 | extern float __ieee754_hypotf (float,float); | |
241 | extern float __ieee754_j0f (float); | |
242 | extern float __ieee754_j1f (float); | |
243 | extern float __ieee754_y0f (float); | |
244 | extern float __ieee754_y1f (float); | |
245 | extern float __ieee754_jnf (int,float); | |
246 | extern float __ieee754_ynf (int,float); | |
247 | extern float __ieee754_remainderf (float,float); | |
248 | extern int32_t __ieee754_rem_pio2f (float,float*); | |
249 | extern float __ieee754_scalbf (float,float); | |
f7eac6eb | 250 | |
e859d1d9 | 251 | |
f7eac6eb | 252 | /* float versions of fdlibm kernel functions */ |
c1422e5b UD |
253 | extern float __kernel_sinf (float,float,int); |
254 | extern float __kernel_cosf (float,float); | |
255 | extern float __kernel_tanf (float,float,int); | |
256 | extern int __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*); | |
f7eac6eb | 257 | |
abcb00da UD |
258 | /* internal functions. */ |
259 | extern float __copysignf (float x, float __y); | |
260 | ||
bc82059d RH |
261 | #if __GNUC_PREREQ (4, 0) |
262 | extern inline float __copysignf (float x, float y) | |
263 | { return __builtin_copysignf (x, y); } | |
264 | #endif | |
76060ec0 RM |
265 | |
266 | /* ieee style elementary long double functions */ | |
c1422e5b UD |
267 | extern long double __ieee754_sqrtl (long double); |
268 | extern long double __ieee754_acosl (long double); | |
269 | extern long double __ieee754_acoshl (long double); | |
270 | extern long double __ieee754_logl (long double); | |
271 | extern long double __ieee754_atanhl (long double); | |
272 | extern long double __ieee754_asinl (long double); | |
273 | extern long double __ieee754_atan2l (long double,long double); | |
274 | extern long double __ieee754_expl (long double); | |
275 | extern long double __ieee754_exp2l (long double); | |
276 | extern long double __ieee754_exp10l (long double); | |
277 | extern long double __ieee754_coshl (long double); | |
278 | extern long double __ieee754_fmodl (long double,long double); | |
279 | extern long double __ieee754_powl (long double,long double); | |
280 | extern long double __ieee754_lgammal_r (long double,int *); | |
281 | extern long double __ieee754_gammal_r (long double,int *); | |
282 | extern long double __ieee754_lgammal (long double); | |
283 | extern long double __ieee754_gammal (long double); | |
284 | extern long double __ieee754_log10l (long double); | |
601d2942 | 285 | extern long double __ieee754_log2l (long double); |
c1422e5b UD |
286 | extern long double __ieee754_sinhl (long double); |
287 | extern long double __ieee754_hypotl (long double,long double); | |
288 | extern long double __ieee754_j0l (long double); | |
289 | extern long double __ieee754_j1l (long double); | |
290 | extern long double __ieee754_y0l (long double); | |
291 | extern long double __ieee754_y1l (long double); | |
292 | extern long double __ieee754_jnl (int,long double); | |
293 | extern long double __ieee754_ynl (int,long double); | |
294 | extern long double __ieee754_remainderl (long double,long double); | |
295 | extern int __ieee754_rem_pio2l (long double,long double*); | |
296 | extern long double __ieee754_scalbl (long double,long double); | |
76060ec0 RM |
297 | |
298 | /* long double versions of fdlibm kernel functions */ | |
c1422e5b UD |
299 | extern long double __kernel_sinl (long double,long double,int); |
300 | extern long double __kernel_cosl (long double,long double); | |
301 | extern long double __kernel_tanl (long double,long double,int); | |
302 | extern void __kernel_sincosl (long double,long double, | |
303 | long double *,long double *, int); | |
304 | extern int __kernel_rem_pio2l (long double*,long double*,int,int, | |
305 | int,const int*); | |
76060ec0 | 306 | |
f3acd97a | 307 | #ifndef NO_LONG_DOUBLE |
09bf6406 UD |
308 | /* prototypes required to compile the ldbl-96 support without warnings */ |
309 | extern int __finitel (long double); | |
f3acd97a | 310 | extern int __ilogbl (long double); |
09bf6406 | 311 | extern int __isinfl (long double); |
f3acd97a | 312 | extern int __isnanl (long double); |
09bf6406 | 313 | extern long double __atanl (long double); |
f3acd97a | 314 | extern long double __copysignl (long double, long double); |
09bf6406 | 315 | extern long double __expm1l (long double); |
f3acd97a UD |
316 | extern long double __floorl (long double); |
317 | extern long double __frexpl (long double, int *); | |
318 | extern long double __ldexpl (long double, int); | |
09bf6406 UD |
319 | extern long double __log1pl (long double); |
320 | extern long double __nanl (const char *); | |
f3acd97a | 321 | extern long double __rintl (long double); |
09bf6406 | 322 | extern long double __scalbnl (long double, int); |
f3acd97a UD |
323 | extern long double __sqrtl (long double x); |
324 | extern long double fabsl (long double x); | |
09bf6406 | 325 | extern void __sincosl (long double, long double *, long double *); |
8101ca20 AJ |
326 | extern long double __logbl (long double x); |
327 | extern long double __significandl (long double x); | |
bc82059d RH |
328 | |
329 | #if __GNUC_PREREQ (4, 0) | |
330 | extern inline long double __copysignl (long double x, long double y) | |
331 | { return __builtin_copysignl (x, y); } | |
332 | #endif | |
333 | ||
f3acd97a | 334 | #endif |
09bf6406 | 335 | |
15b3c029 AJ |
336 | /* Prototypes for functions of the IBM Accurate Mathematical Library. */ |
337 | extern double __exp1 (double __x, double __xx, double __error); | |
338 | extern double __sin (double __x); | |
339 | extern double __cos (double __x); | |
340 | extern int __branred (double __x, double *__a, double *__aa); | |
341 | extern void __doasin (double __x, double __dx, double __v[]); | |
342 | extern void __dubsin (double __x, double __dx, double __v[]); | |
343 | extern void __dubcos (double __x, double __dx, double __v[]); | |
344 | extern double __halfulp (double __x, double __y); | |
345 | extern double __sin32 (double __x, double __res, double __res1); | |
346 | extern double __cos32 (double __x, double __res, double __res1); | |
347 | extern double __mpsin (double __x, double __dx); | |
348 | extern double __mpcos (double __x, double __dx); | |
349 | extern double __mpsin1 (double __x); | |
350 | extern double __mpcos1 (double __x); | |
351 | extern double __slowexp (double __x); | |
352 | extern double __slowpow (double __x, double __y, double __z); | |
353 | extern void __docos (double __x, double __dx, double __v[]); | |
354 | ||
3e336a87 | 355 | #ifndef math_opt_barrier |
a784e502 | 356 | # define math_opt_barrier(x) \ |
f6ce9294 | 357 | ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; }) |
a784e502 UD |
358 | # define math_force_eval(x) \ |
359 | ({ __typeof (x) __x = (x); __asm __volatile__ ("" : : "m" (__x)); }) | |
3e336a87 UD |
360 | #endif |
361 | ||
d38f1dba UD |
362 | |
363 | /* The standards only specify one variant of the fenv.h interfaces. | |
364 | But at least for some architectures we can be more efficient if we | |
365 | know what operations are going to be performed. Therefore we | |
366 | define additional interfaces. By default they refer to the normal | |
367 | interfaces. */ | |
368 | #define libc_fegetround() fegetround () | |
369 | #define libc_fegetroundf() fegetround () | |
370 | #define libc_fegetroundl() fegetround () | |
371 | ||
372 | #define libc_fesetround(r) (void) fesetround (r) | |
373 | #define libc_fesetroundf(r) (void) fesetround (r) | |
374 | #define libc_fesetroundl(r) (void) fesetround (r) | |
375 | ||
376 | #define libc_feholdexcept(e) (void) feholdexcept (e) | |
377 | #define libc_feholdexceptf(e) (void) feholdexcept (e) | |
378 | #define libc_feholdexceptl(e) (void) feholdexcept (e) | |
379 | ||
4855e3dd UD |
380 | #define libc_feholdexcept_setround(e, r) \ |
381 | do { feholdexcept (e); fesetround (r); } while (0) | |
382 | #define libc_feholdexcept_setroundf(e, r) \ | |
383 | do { feholdexcept (e); fesetround (r); } while (0) | |
384 | #define libc_feholdexcept_setroundl(e, r) \ | |
385 | do { feholdexcept (e); fesetround (r); } while (0) | |
386 | ||
d9a8d0ab UD |
387 | #define libc_fetestexcept(e) fetestexcept (e) |
388 | #define libc_fetestexceptf(e) fetestexcept (e) | |
389 | #define libc_fetestexceptl(e) fetestexcept (e) | |
390 | ||
d38f1dba UD |
391 | #define libc_fesetenv(e) (void) fesetenv (e) |
392 | #define libc_fesetenvf(e) (void) fesetenv (e) | |
393 | #define libc_fesetenvl(e) (void) fesetenv (e) | |
394 | ||
d9a8d0ab UD |
395 | #define libc_feupdateenv(e) (void) feupdateenv (e) |
396 | #define libc_feupdateenvf(e) (void) feupdateenv (e) | |
397 | #define libc_feupdateenvl(e) (void) feupdateenv (e) | |
398 | ||
bc62c2fb UD |
399 | #define __nan(str) \ |
400 | (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) | |
401 | #define __nanf(str) \ | |
402 | (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) | |
403 | #define __nanl(str) \ | |
404 | (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) | |
405 | ||
f7eac6eb | 406 | #endif /* _MATH_PRIVATE_H_ */ |