2 * ====================================================
3 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
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
9 * ====================================================
13 * from: @(#)fdlibm.h 5.1 93/09/24
16 #ifndef _MATH_PRIVATE_H_
17 #define _MATH_PRIVATE_H_
20 #include <sys/types.h>
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. */
33 /* A union which permits us to convert between a double and two 32 bit
36 #if __FLOAT_WORD_ORDER == BIG_ENDIAN
46 } ieee_double_shape_type
;
50 #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
60 } ieee_double_shape_type
;
64 /* Get two 32 bit ints from a double. */
66 #define EXTRACT_WORDS(ix0,ix1,d) \
68 ieee_double_shape_type ew_u; \
70 (ix0) = ew_u.parts.msw; \
71 (ix1) = ew_u.parts.lsw; \
74 /* Get the more significant 32 bit int from a double. */
76 #define GET_HIGH_WORD(i,d) \
78 ieee_double_shape_type gh_u; \
80 (i) = gh_u.parts.msw; \
83 /* Get the less significant 32 bit int from a double. */
85 #define GET_LOW_WORD(i,d) \
87 ieee_double_shape_type gl_u; \
89 (i) = gl_u.parts.lsw; \
92 /* Set a double from two 32 bit ints. */
94 #define INSERT_WORDS(d,ix0,ix1) \
96 ieee_double_shape_type iw_u; \
97 iw_u.parts.msw = (ix0); \
98 iw_u.parts.lsw = (ix1); \
102 /* Set the more significant 32 bits of a double from an int. */
104 #define SET_HIGH_WORD(d,v) \
106 ieee_double_shape_type sh_u; \
108 sh_u.parts.msw = (v); \
112 /* Set the less significant 32 bits of a double from an int. */
114 #define SET_LOW_WORD(d,v) \
116 ieee_double_shape_type sl_u; \
118 sl_u.parts.lsw = (v); \
122 /* A union which permits us to convert between a float and a 32 bit
129 } ieee_float_shape_type
;
131 /* Get a 32 bit int from a float. */
133 #define GET_FLOAT_WORD(i,d) \
135 ieee_float_shape_type gf_u; \
140 /* Set a float from a 32 bit int. */
142 #define SET_FLOAT_WORD(d,i) \
144 ieee_float_shape_type sf_u; \
149 /* Get long double macros from a separate header. */
150 #include <math_ldbl.h>
152 /* ieee style elementary functions */
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);
171 extern double __ieee754_log2 (double);
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);
184 /* fdlibm kernel function */
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*);
191 /* internal functions. */
192 extern double __copysign (double x
, double __y
);
194 #if __GNUC_PREREQ (4, 0)
195 extern inline double __copysign (double x
, double y
)
196 { return __builtin_copysign (x
, y
); }
199 /* ieee style elementary float functions */
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);
218 extern float __ieee754_log2f (float);
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);
232 /* float versions of fdlibm kernel functions */
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*);
238 /* internal functions. */
239 extern float __copysignf (float x
, float __y
);
241 #if __GNUC_PREREQ (4, 0)
242 extern inline float __copysignf (float x
, float y
)
243 { return __builtin_copysignf (x
, y
); }
246 /* ieee style elementary long double functions */
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);
265 extern long double __ieee754_log2l (long double);
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);
278 /* long double versions of fdlibm kernel functions */
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,
287 #ifndef NO_LONG_DOUBLE
288 /* prototypes required to compile the ldbl-96 support without warnings */
289 extern int __finitel (long double);
290 extern int __ilogbl (long double);
291 extern int __isinfl (long double);
292 extern int __isnanl (long double);
293 extern long double __atanl (long double);
294 extern long double __copysignl (long double, long double);
295 extern long double __expm1l (long double);
296 extern long double __floorl (long double);
297 extern long double __frexpl (long double, int *);
298 extern long double __ldexpl (long double, int);
299 extern long double __log1pl (long double);
300 extern long double __nanl (const char *);
301 extern long double __rintl (long double);
302 extern long double __scalbnl (long double, int);
303 extern long double __sqrtl (long double x
);
304 extern long double fabsl (long double x
);
305 extern void __sincosl (long double, long double *, long double *);
306 extern long double __logbl (long double x
);
307 extern long double __significandl (long double x
);
309 #if __GNUC_PREREQ (4, 0)
310 extern inline long double __copysignl (long double x
, long double y
)
311 { return __builtin_copysignl (x
, y
); }
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
[]);
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))
341 #endif /* _MATH_PRIVATE_H_ */