]>
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> |
f7eac6eb RM |
20 | #include <sys/types.h> |
21 | ||
22 | /* The original fdlibm code used statements like: | |
23 | n0 = ((*(int*)&one)>>29)^1; * index of high word * | |
24 | ix0 = *(n0+(int*)&x); * high word of x * | |
25 | ix1 = *((1-n0)+(int*)&x); * low word of x * | |
26 | to dig two 32 bit words out of the 64 bit IEEE floating point | |
27 | value. That is non-ANSI, and, moreover, the gcc instruction | |
28 | scheduler gets it wrong. We instead use the following macros. | |
29 | Unlike the original code, we determine the endianness at compile | |
30 | time, not at run time; I don't see much benefit to selecting | |
31 | endianness at run time. */ | |
32 | ||
33 | /* A union which permits us to convert between a double and two 32 bit | |
34 | ints. */ | |
35 | ||
48252123 | 36 | #if __FLOAT_WORD_ORDER == BIG_ENDIAN |
f7eac6eb RM |
37 | |
38 | typedef union | |
39 | { | |
40 | double value; | |
41 | struct | |
42 | { | |
43 | u_int32_t msw; | |
44 | u_int32_t lsw; | |
45 | } parts; | |
46 | } ieee_double_shape_type; | |
47 | ||
48 | #endif | |
49 | ||
48252123 | 50 | #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN |
f7eac6eb RM |
51 | |
52 | typedef union | |
53 | { | |
54 | double value; | |
55 | struct | |
56 | { | |
57 | u_int32_t lsw; | |
58 | u_int32_t msw; | |
59 | } parts; | |
60 | } ieee_double_shape_type; | |
61 | ||
62 | #endif | |
63 | ||
64 | /* Get two 32 bit ints from a double. */ | |
65 | ||
66 | #define EXTRACT_WORDS(ix0,ix1,d) \ | |
67 | do { \ | |
68 | ieee_double_shape_type ew_u; \ | |
69 | ew_u.value = (d); \ | |
70 | (ix0) = ew_u.parts.msw; \ | |
71 | (ix1) = ew_u.parts.lsw; \ | |
72 | } while (0) | |
73 | ||
74 | /* Get the more significant 32 bit int from a double. */ | |
75 | ||
76 | #define GET_HIGH_WORD(i,d) \ | |
77 | do { \ | |
78 | ieee_double_shape_type gh_u; \ | |
79 | gh_u.value = (d); \ | |
80 | (i) = gh_u.parts.msw; \ | |
81 | } while (0) | |
82 | ||
83 | /* Get the less significant 32 bit int from a double. */ | |
84 | ||
85 | #define GET_LOW_WORD(i,d) \ | |
86 | do { \ | |
87 | ieee_double_shape_type gl_u; \ | |
88 | gl_u.value = (d); \ | |
89 | (i) = gl_u.parts.lsw; \ | |
90 | } while (0) | |
91 | ||
92 | /* Set a double from two 32 bit ints. */ | |
93 | ||
94 | #define INSERT_WORDS(d,ix0,ix1) \ | |
95 | do { \ | |
96 | ieee_double_shape_type iw_u; \ | |
97 | iw_u.parts.msw = (ix0); \ | |
98 | iw_u.parts.lsw = (ix1); \ | |
99 | (d) = iw_u.value; \ | |
100 | } while (0) | |
101 | ||
102 | /* Set the more significant 32 bits of a double from an int. */ | |
103 | ||
104 | #define SET_HIGH_WORD(d,v) \ | |
105 | do { \ | |
106 | ieee_double_shape_type sh_u; \ | |
107 | sh_u.value = (d); \ | |
108 | sh_u.parts.msw = (v); \ | |
109 | (d) = sh_u.value; \ | |
110 | } while (0) | |
111 | ||
112 | /* Set the less significant 32 bits of a double from an int. */ | |
113 | ||
114 | #define SET_LOW_WORD(d,v) \ | |
115 | do { \ | |
116 | ieee_double_shape_type sl_u; \ | |
117 | sl_u.value = (d); \ | |
118 | sl_u.parts.lsw = (v); \ | |
119 | (d) = sl_u.value; \ | |
120 | } while (0) | |
121 | ||
122 | /* A union which permits us to convert between a float and a 32 bit | |
123 | int. */ | |
124 | ||
125 | typedef union | |
126 | { | |
127 | float value; | |
128 | u_int32_t word; | |
129 | } ieee_float_shape_type; | |
130 | ||
131 | /* Get a 32 bit int from a float. */ | |
132 | ||
133 | #define GET_FLOAT_WORD(i,d) \ | |
134 | do { \ | |
135 | ieee_float_shape_type gf_u; \ | |
136 | gf_u.value = (d); \ | |
137 | (i) = gf_u.word; \ | |
138 | } while (0) | |
139 | ||
140 | /* Set a float from a 32 bit int. */ | |
141 | ||
142 | #define SET_FLOAT_WORD(d,i) \ | |
143 | do { \ | |
144 | ieee_float_shape_type sf_u; \ | |
145 | sf_u.word = (i); \ | |
146 | (d) = sf_u.value; \ | |
147 | } while (0) | |
148 | ||
abfbdde1 UD |
149 | /* Get long double macros from a separate header. */ |
150 | #include <math_ldbl.h> | |
76060ec0 | 151 | |
f7eac6eb | 152 | /* ieee style elementary functions */ |
c1422e5b UD |
153 | extern double __ieee754_sqrt (double); |
154 | extern double __ieee754_acos (double); | |
155 | extern double __ieee754_acosh (double); | |
156 | extern double __ieee754_log (double); | |
157 | extern double __ieee754_atanh (double); | |
158 | extern double __ieee754_asin (double); | |
159 | extern double __ieee754_atan2 (double,double); | |
160 | extern double __ieee754_exp (double); | |
161 | extern double __ieee754_exp2 (double); | |
162 | extern double __ieee754_exp10 (double); | |
163 | extern double __ieee754_cosh (double); | |
164 | extern double __ieee754_fmod (double,double); | |
165 | extern double __ieee754_pow (double,double); | |
166 | extern double __ieee754_lgamma_r (double,int *); | |
167 | extern double __ieee754_gamma_r (double,int *); | |
168 | extern double __ieee754_lgamma (double); | |
169 | extern double __ieee754_gamma (double); | |
170 | extern double __ieee754_log10 (double); | |
601d2942 | 171 | extern double __ieee754_log2 (double); |
c1422e5b UD |
172 | extern double __ieee754_sinh (double); |
173 | extern double __ieee754_hypot (double,double); | |
174 | extern double __ieee754_j0 (double); | |
175 | extern double __ieee754_j1 (double); | |
176 | extern double __ieee754_y0 (double); | |
177 | extern double __ieee754_y1 (double); | |
178 | extern double __ieee754_jn (int,double); | |
179 | extern double __ieee754_yn (int,double); | |
180 | extern double __ieee754_remainder (double,double); | |
181 | extern int32_t __ieee754_rem_pio2 (double,double*); | |
182 | extern double __ieee754_scalb (double,double); | |
f7eac6eb RM |
183 | |
184 | /* fdlibm kernel function */ | |
c1422e5b UD |
185 | extern double __kernel_standard (double,double,int); |
186 | extern double __kernel_sin (double,double,int); | |
187 | extern double __kernel_cos (double,double); | |
188 | extern double __kernel_tan (double,double,int); | |
189 | extern int __kernel_rem_pio2 (double*,double*,int,int,int, const int32_t*); | |
f7eac6eb | 190 | |
e859d1d9 AJ |
191 | /* internal functions. */ |
192 | extern double __copysign (double x, double __y); | |
193 | ||
bc82059d RH |
194 | #if __GNUC_PREREQ (4, 0) |
195 | extern inline double __copysign (double x, double y) | |
196 | { return __builtin_copysign (x, y); } | |
197 | #endif | |
f7eac6eb RM |
198 | |
199 | /* ieee style elementary float functions */ | |
c1422e5b UD |
200 | extern float __ieee754_sqrtf (float); |
201 | extern float __ieee754_acosf (float); | |
202 | extern float __ieee754_acoshf (float); | |
203 | extern float __ieee754_logf (float); | |
204 | extern float __ieee754_atanhf (float); | |
205 | extern float __ieee754_asinf (float); | |
206 | extern float __ieee754_atan2f (float,float); | |
207 | extern float __ieee754_expf (float); | |
208 | extern float __ieee754_exp2f (float); | |
209 | extern float __ieee754_exp10f (float); | |
210 | extern float __ieee754_coshf (float); | |
211 | extern float __ieee754_fmodf (float,float); | |
212 | extern float __ieee754_powf (float,float); | |
213 | extern float __ieee754_lgammaf_r (float,int *); | |
214 | extern float __ieee754_gammaf_r (float,int *); | |
215 | extern float __ieee754_lgammaf (float); | |
216 | extern float __ieee754_gammaf (float); | |
217 | extern float __ieee754_log10f (float); | |
601d2942 | 218 | extern float __ieee754_log2f (float); |
c1422e5b UD |
219 | extern float __ieee754_sinhf (float); |
220 | extern float __ieee754_hypotf (float,float); | |
221 | extern float __ieee754_j0f (float); | |
222 | extern float __ieee754_j1f (float); | |
223 | extern float __ieee754_y0f (float); | |
224 | extern float __ieee754_y1f (float); | |
225 | extern float __ieee754_jnf (int,float); | |
226 | extern float __ieee754_ynf (int,float); | |
227 | extern float __ieee754_remainderf (float,float); | |
228 | extern int32_t __ieee754_rem_pio2f (float,float*); | |
229 | extern float __ieee754_scalbf (float,float); | |
f7eac6eb | 230 | |
e859d1d9 | 231 | |
f7eac6eb | 232 | /* float versions of fdlibm kernel functions */ |
c1422e5b UD |
233 | extern float __kernel_sinf (float,float,int); |
234 | extern float __kernel_cosf (float,float); | |
235 | extern float __kernel_tanf (float,float,int); | |
236 | extern int __kernel_rem_pio2f (float*,float*,int,int,int, const int32_t*); | |
f7eac6eb | 237 | |
abcb00da UD |
238 | /* internal functions. */ |
239 | extern float __copysignf (float x, float __y); | |
240 | ||
bc82059d RH |
241 | #if __GNUC_PREREQ (4, 0) |
242 | extern inline float __copysignf (float x, float y) | |
243 | { return __builtin_copysignf (x, y); } | |
244 | #endif | |
76060ec0 RM |
245 | |
246 | /* ieee style elementary long double functions */ | |
c1422e5b UD |
247 | extern long double __ieee754_sqrtl (long double); |
248 | extern long double __ieee754_acosl (long double); | |
249 | extern long double __ieee754_acoshl (long double); | |
250 | extern long double __ieee754_logl (long double); | |
251 | extern long double __ieee754_atanhl (long double); | |
252 | extern long double __ieee754_asinl (long double); | |
253 | extern long double __ieee754_atan2l (long double,long double); | |
254 | extern long double __ieee754_expl (long double); | |
255 | extern long double __ieee754_exp2l (long double); | |
256 | extern long double __ieee754_exp10l (long double); | |
257 | extern long double __ieee754_coshl (long double); | |
258 | extern long double __ieee754_fmodl (long double,long double); | |
259 | extern long double __ieee754_powl (long double,long double); | |
260 | extern long double __ieee754_lgammal_r (long double,int *); | |
261 | extern long double __ieee754_gammal_r (long double,int *); | |
262 | extern long double __ieee754_lgammal (long double); | |
263 | extern long double __ieee754_gammal (long double); | |
264 | extern long double __ieee754_log10l (long double); | |
601d2942 | 265 | extern long double __ieee754_log2l (long double); |
c1422e5b UD |
266 | extern long double __ieee754_sinhl (long double); |
267 | extern long double __ieee754_hypotl (long double,long double); | |
268 | extern long double __ieee754_j0l (long double); | |
269 | extern long double __ieee754_j1l (long double); | |
270 | extern long double __ieee754_y0l (long double); | |
271 | extern long double __ieee754_y1l (long double); | |
272 | extern long double __ieee754_jnl (int,long double); | |
273 | extern long double __ieee754_ynl (int,long double); | |
274 | extern long double __ieee754_remainderl (long double,long double); | |
275 | extern int __ieee754_rem_pio2l (long double,long double*); | |
276 | extern long double __ieee754_scalbl (long double,long double); | |
76060ec0 RM |
277 | |
278 | /* long double versions of fdlibm kernel functions */ | |
c1422e5b UD |
279 | extern long double __kernel_sinl (long double,long double,int); |
280 | extern long double __kernel_cosl (long double,long double); | |
281 | extern long double __kernel_tanl (long double,long double,int); | |
282 | extern void __kernel_sincosl (long double,long double, | |
283 | long double *,long double *, int); | |
284 | extern int __kernel_rem_pio2l (long double*,long double*,int,int, | |
285 | int,const int*); | |
76060ec0 | 286 | |
f3acd97a | 287 | #ifndef NO_LONG_DOUBLE |
09bf6406 UD |
288 | /* prototypes required to compile the ldbl-96 support without warnings */ |
289 | extern int __finitel (long double); | |
f3acd97a | 290 | extern int __ilogbl (long double); |
09bf6406 | 291 | extern int __isinfl (long double); |
f3acd97a | 292 | extern int __isnanl (long double); |
09bf6406 | 293 | extern long double __atanl (long double); |
f3acd97a | 294 | extern long double __copysignl (long double, long double); |
09bf6406 | 295 | extern long double __expm1l (long double); |
f3acd97a UD |
296 | extern long double __floorl (long double); |
297 | extern long double __frexpl (long double, int *); | |
298 | extern long double __ldexpl (long double, int); | |
09bf6406 UD |
299 | extern long double __log1pl (long double); |
300 | extern long double __nanl (const char *); | |
f3acd97a | 301 | extern long double __rintl (long double); |
09bf6406 | 302 | extern long double __scalbnl (long double, int); |
f3acd97a UD |
303 | extern long double __sqrtl (long double x); |
304 | extern long double fabsl (long double x); | |
09bf6406 | 305 | extern void __sincosl (long double, long double *, long double *); |
8101ca20 AJ |
306 | extern long double __logbl (long double x); |
307 | extern long double __significandl (long double x); | |
bc82059d RH |
308 | |
309 | #if __GNUC_PREREQ (4, 0) | |
310 | extern inline long double __copysignl (long double x, long double y) | |
311 | { return __builtin_copysignl (x, y); } | |
312 | #endif | |
313 | ||
f3acd97a | 314 | #endif |
09bf6406 | 315 | |
15b3c029 AJ |
316 | /* Prototypes for functions of the IBM Accurate Mathematical Library. */ |
317 | extern double __exp1 (double __x, double __xx, double __error); | |
318 | extern double __sin (double __x); | |
319 | extern double __cos (double __x); | |
320 | extern int __branred (double __x, double *__a, double *__aa); | |
321 | extern void __doasin (double __x, double __dx, double __v[]); | |
322 | extern void __dubsin (double __x, double __dx, double __v[]); | |
323 | extern void __dubcos (double __x, double __dx, double __v[]); | |
324 | extern double __halfulp (double __x, double __y); | |
325 | extern double __sin32 (double __x, double __res, double __res1); | |
326 | extern double __cos32 (double __x, double __res, double __res1); | |
327 | extern double __mpsin (double __x, double __dx); | |
328 | extern double __mpcos (double __x, double __dx); | |
329 | extern double __mpsin1 (double __x); | |
330 | extern double __mpcos1 (double __x); | |
331 | extern double __slowexp (double __x); | |
332 | extern double __slowpow (double __x, double __y, double __z); | |
333 | extern void __docos (double __x, double __dx, double __v[]); | |
334 | ||
32c075e1 JJ |
335 | #ifndef math_opt_barrier |
336 | #define math_opt_barrier(x) \ | |
337 | ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; }) | |
338 | #define math_force_eval(x) __asm __volatile ("" : : "m" (x)) | |
339 | #endif | |
340 | ||
f7eac6eb | 341 | #endif /* _MATH_PRIVATE_H_ */ |