Annotation of src/lib/libm/src/math_private.h, Revision 1.18
1.1 jtc 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
1.8 simonb 7: * software is freely granted, provided that this notice
1.1 jtc 8: * is preserved.
9: * ====================================================
10: */
11:
12: /*
13: * from: @(#)fdlibm.h 5.1 93/09/24
1.18 ! christos 14: * $NetBSD: math_private.h,v 1.17 2012/05/05 17:54:14 christos Exp $
1.1 jtc 15: */
16:
17: #ifndef _MATH_PRIVATE_H_
18: #define _MATH_PRIVATE_H_
19:
1.2 jtc 20: #include <sys/types.h>
1.1 jtc 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:
1.4 mark 36: /*
1.11 bjh21 37: * The ARM ports are little endian except for the FPA word order which is
1.4 mark 38: * big endian.
39: */
40:
1.11 bjh21 41: #if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
1.1 jtc 42:
1.8 simonb 43: typedef union
1.1 jtc 44: {
45: double value;
1.8 simonb 46: struct
1.1 jtc 47: {
1.2 jtc 48: u_int32_t msw;
49: u_int32_t lsw;
1.1 jtc 50: } parts;
1.18 ! christos 51: struct {
! 52: u_int64_t w;
! 53: } xparts;
1.1 jtc 54: } ieee_double_shape_type;
55:
56: #endif
57:
1.11 bjh21 58: #if (BYTE_ORDER == LITTLE_ENDIAN) && \
59: !(defined(__arm__) && !defined(__VFP_FP__))
1.1 jtc 60:
1.8 simonb 61: typedef union
1.1 jtc 62: {
63: double value;
1.8 simonb 64: struct
1.1 jtc 65: {
1.2 jtc 66: u_int32_t lsw;
67: u_int32_t msw;
1.1 jtc 68: } parts;
1.18 ! christos 69: struct {
! 70: u_int64_t w;
! 71: } xparts;
1.1 jtc 72: } ieee_double_shape_type;
73:
74: #endif
75:
76: /* Get two 32 bit ints from a double. */
77:
78: #define EXTRACT_WORDS(ix0,ix1,d) \
79: do { \
80: ieee_double_shape_type ew_u; \
81: ew_u.value = (d); \
82: (ix0) = ew_u.parts.msw; \
83: (ix1) = ew_u.parts.lsw; \
1.13 christos 84: } while (/*CONSTCOND*/0)
1.1 jtc 85:
1.18 ! christos 86: /* Get a 64-bit int from a double. */
! 87: #define EXTRACT_WORD64(ix,d) \
! 88: do { \
! 89: ieee_double_shape_type ew_u; \
! 90: ew_u.value = (d); \
! 91: (ix) = ew_u.xparts.w; \
! 92: } while (/*CONSTCOND*/0)
! 93:
! 94:
1.1 jtc 95: /* Get the more significant 32 bit int from a double. */
96:
97: #define GET_HIGH_WORD(i,d) \
98: do { \
99: ieee_double_shape_type gh_u; \
100: gh_u.value = (d); \
101: (i) = gh_u.parts.msw; \
1.13 christos 102: } while (/*CONSTCOND*/0)
1.1 jtc 103:
104: /* Get the less significant 32 bit int from a double. */
105:
106: #define GET_LOW_WORD(i,d) \
107: do { \
108: ieee_double_shape_type gl_u; \
109: gl_u.value = (d); \
110: (i) = gl_u.parts.lsw; \
1.13 christos 111: } while (/*CONSTCOND*/0)
1.1 jtc 112:
113: /* Set a double from two 32 bit ints. */
114:
115: #define INSERT_WORDS(d,ix0,ix1) \
116: do { \
117: ieee_double_shape_type iw_u; \
118: iw_u.parts.msw = (ix0); \
119: iw_u.parts.lsw = (ix1); \
120: (d) = iw_u.value; \
1.13 christos 121: } while (/*CONSTCOND*/0)
1.1 jtc 122:
1.18 ! christos 123: /* Set a double from a 64-bit int. */
! 124: #define INSERT_WORD64(d,ix) \
! 125: do { \
! 126: ieee_double_shape_type iw_u; \
! 127: iw_u.xparts.w = (ix); \
! 128: (d) = iw_u.value; \
! 129: } while (/*CONSTCOND*/0)
! 130:
! 131:
1.1 jtc 132: /* Set the more significant 32 bits of a double from an int. */
133:
134: #define SET_HIGH_WORD(d,v) \
135: do { \
136: ieee_double_shape_type sh_u; \
137: sh_u.value = (d); \
138: sh_u.parts.msw = (v); \
139: (d) = sh_u.value; \
1.13 christos 140: } while (/*CONSTCOND*/0)
1.1 jtc 141:
142: /* Set the less significant 32 bits of a double from an int. */
143:
144: #define SET_LOW_WORD(d,v) \
145: do { \
146: ieee_double_shape_type sl_u; \
147: sl_u.value = (d); \
148: sl_u.parts.lsw = (v); \
149: (d) = sl_u.value; \
1.13 christos 150: } while (/*CONSTCOND*/0)
1.1 jtc 151:
152: /* A union which permits us to convert between a float and a 32 bit
153: int. */
154:
155: typedef union
156: {
157: float value;
1.3 jtc 158: u_int32_t word;
1.1 jtc 159: } ieee_float_shape_type;
160:
161: /* Get a 32 bit int from a float. */
162:
163: #define GET_FLOAT_WORD(i,d) \
164: do { \
165: ieee_float_shape_type gf_u; \
166: gf_u.value = (d); \
167: (i) = gf_u.word; \
1.13 christos 168: } while (/*CONSTCOND*/0)
1.1 jtc 169:
170: /* Set a float from a 32 bit int. */
171:
172: #define SET_FLOAT_WORD(d,i) \
173: do { \
174: ieee_float_shape_type sf_u; \
175: sf_u.word = (i); \
176: (d) = sf_u.value; \
1.13 christos 177: } while (/*CONSTCOND*/0)
1.1 jtc 178:
1.14 christos 179: /*
180: * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
181: */
182: #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
183: #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
184: #else
185: #define STRICT_ASSIGN(type, lval, rval) do { \
186: volatile type __lval; \
187: \
188: if (sizeof(type) >= sizeof(double)) \
189: (lval) = (rval); \
190: else { \
191: __lval = (rval); \
192: (lval) = __lval; \
193: } \
194: } while (/*CONSTCOND*/0)
195: #endif
196:
1.15 christos 197: #ifdef _COMPLEX_H
198:
199: /*
200: * Quoting from ISO/IEC 9899:TC2:
201: *
202: * 6.2.5.13 Types
203: * Each complex type has the same representation and alignment requirements as
204: * an array type containing exactly two elements of the corresponding real type;
205: * the first element is equal to the real part, and the second element to the
206: * imaginary part, of the complex number.
207: */
208: typedef union {
209: float complex z;
210: float parts[2];
211: } float_complex;
212:
213: typedef union {
214: double complex z;
215: double parts[2];
216: } double_complex;
217:
218: typedef union {
219: long double complex z;
1.16 drochner 220: long double parts[2];
1.15 christos 221: } long_double_complex;
222:
223: #define REAL_PART(z) ((z).parts[0])
224: #define IMAG_PART(z) ((z).parts[1])
225:
226: #endif /* _COMPLEX_H */
227:
1.1 jtc 228: /* ieee style elementary functions */
1.8 simonb 229: extern double __ieee754_sqrt __P((double));
230: extern double __ieee754_acos __P((double));
231: extern double __ieee754_acosh __P((double));
232: extern double __ieee754_log __P((double));
233: extern double __ieee754_atanh __P((double));
234: extern double __ieee754_asin __P((double));
235: extern double __ieee754_atan2 __P((double,double));
1.1 jtc 236: extern double __ieee754_exp __P((double));
237: extern double __ieee754_cosh __P((double));
238: extern double __ieee754_fmod __P((double,double));
239: extern double __ieee754_pow __P((double,double));
240: extern double __ieee754_lgamma_r __P((double,int *));
241: extern double __ieee754_gamma_r __P((double,int *));
242: extern double __ieee754_lgamma __P((double));
243: extern double __ieee754_gamma __P((double));
244: extern double __ieee754_log10 __P((double));
1.12 christos 245: extern double __ieee754_log2 __P((double));
1.1 jtc 246: extern double __ieee754_sinh __P((double));
247: extern double __ieee754_hypot __P((double,double));
248: extern double __ieee754_j0 __P((double));
249: extern double __ieee754_j1 __P((double));
250: extern double __ieee754_y0 __P((double));
251: extern double __ieee754_y1 __P((double));
252: extern double __ieee754_jn __P((int,double));
253: extern double __ieee754_yn __P((int,double));
254: extern double __ieee754_remainder __P((double,double));
255: extern int __ieee754_rem_pio2 __P((double,double*));
256: extern double __ieee754_scalb __P((double,double));
257:
258: /* fdlibm kernel function */
1.8 simonb 259: extern double __kernel_standard __P((double,double,int));
1.1 jtc 260: extern double __kernel_sin __P((double,double,int));
261: extern double __kernel_cos __P((double,double));
262: extern double __kernel_tan __P((double,double,int));
263: extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));
264:
265:
266: /* ieee style elementary float functions */
1.8 simonb 267: extern float __ieee754_sqrtf __P((float));
268: extern float __ieee754_acosf __P((float));
269: extern float __ieee754_acoshf __P((float));
270: extern float __ieee754_logf __P((float));
271: extern float __ieee754_atanhf __P((float));
272: extern float __ieee754_asinf __P((float));
273: extern float __ieee754_atan2f __P((float,float));
1.1 jtc 274: extern float __ieee754_expf __P((float));
275: extern float __ieee754_coshf __P((float));
276: extern float __ieee754_fmodf __P((float,float));
277: extern float __ieee754_powf __P((float,float));
278: extern float __ieee754_lgammaf_r __P((float,int *));
279: extern float __ieee754_gammaf_r __P((float,int *));
280: extern float __ieee754_lgammaf __P((float));
281: extern float __ieee754_gammaf __P((float));
282: extern float __ieee754_log10f __P((float));
1.12 christos 283: extern float __ieee754_log2f __P((float));
1.1 jtc 284: extern float __ieee754_sinhf __P((float));
285: extern float __ieee754_hypotf __P((float,float));
286: extern float __ieee754_j0f __P((float));
287: extern float __ieee754_j1f __P((float));
288: extern float __ieee754_y0f __P((float));
289: extern float __ieee754_y1f __P((float));
290: extern float __ieee754_jnf __P((int,float));
291: extern float __ieee754_ynf __P((int,float));
292: extern float __ieee754_remainderf __P((float,float));
293: extern int __ieee754_rem_pio2f __P((float,float*));
294: extern float __ieee754_scalbf __P((float,float));
295:
296: /* float versions of fdlibm kernel functions */
297: extern float __kernel_sinf __P((float,float,int));
298: extern float __kernel_cosf __P((float,float));
299: extern float __kernel_tanf __P((float,float,int));
300: extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*));
301:
1.17 christos 302: /*
303: * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an
304: * IEEE double variable to zero. It must be expression-like for syntactic
305: * reasons, and we implement this expression using an inline function
306: * instead of a pure macro to avoid depending on the gcc feature of
307: * statement-expressions.
308: */
309: #define TRUNC(d) (_b_trunc(&(d)))
310:
311: static __inline void
312: _b_trunc(volatile double *_dp)
313: {
314: uint32_t _lw;
315:
316: GET_LOW_WORD(_lw, *_dp);
317: SET_LOW_WORD(*_dp, _lw & 0xf8000000);
318: }
319:
320: struct Double {
321: double a;
322: double b;
323: };
324:
325: /*
326: * Functions internal to the math package, yet not static.
327: */
328: double __exp__D(double, double);
329: struct Double __log__D(double);
330:
1.1 jtc 331: #endif /* _MATH_PRIVATE_H_ */
CVSweb <webmaster@jp.NetBSD.org>