diff options
Diffstat (limited to 'baseline/source/fmref/math_private.h')
-rw-r--r-- | baseline/source/fmref/math_private.h | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/baseline/source/fmref/math_private.h b/baseline/source/fmref/math_private.h new file mode 100644 index 0000000..58d4354 --- /dev/null +++ b/baseline/source/fmref/math_private.h | |||
@@ -0,0 +1,178 @@ | |||
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 | ||
14 | */ | ||
15 | |||
16 | #ifndef _MATH_PRIVATE_H_ | ||
17 | #define _MATH_PRIVATE_H_ | ||
18 | |||
19 | #include "wcclibm.h" | ||
20 | |||
21 | //#include <endian.h> | ||
22 | //#include <sys/types.h> | ||
23 | |||
24 | /* A representation of a double as a union. */ | ||
25 | union ieee754_double | ||
26 | { | ||
27 | double d; | ||
28 | |||
29 | /* This is the IEEE 754 double-precision format. */ | ||
30 | struct { | ||
31 | /* Together these comprise the mantissa. */ | ||
32 | unsigned int mantissa1:32; | ||
33 | unsigned int mantissa0:20; | ||
34 | unsigned int exponent:11; | ||
35 | unsigned int negative:1; | ||
36 | } ieee; | ||
37 | |||
38 | /* This format makes it easier to see if a NaN is a signalling NaN. */ | ||
39 | struct { | ||
40 | /* Together these comprise the mantissa. */ | ||
41 | unsigned int mantissa1:32; | ||
42 | unsigned int mantissa0:19; | ||
43 | unsigned int quiet_nan:1; | ||
44 | unsigned int exponent:11; | ||
45 | unsigned int negative:1; | ||
46 | } ieee_nan; | ||
47 | }; | ||
48 | |||
49 | /* The original fdlibm code used statements like: | ||
50 | n0 = ((*(int*)&one)>>29)^1; * index of high word * | ||
51 | ix0 = *(n0+(int*)&x); * high word of x * | ||
52 | ix1 = *((1-n0)+(int*)&x); * low word of x * | ||
53 | to dig two 32 bit words out of the 64 bit IEEE floating point | ||
54 | value. That is non-ANSI, and, moreover, the gcc instruction | ||
55 | scheduler gets it wrong. We instead use the following macros. | ||
56 | Unlike the original code, we determine the endianness at compile | ||
57 | time, not at run time; I don't see much benefit to selecting | ||
58 | endianness at run time. */ | ||
59 | |||
60 | /* A union which permits us to convert between a double and two 32 bit | ||
61 | ints. */ | ||
62 | |||
63 | /* #if __FLOAT_WORD_ORDER == BIG_ENDIAN */ | ||
64 | /* #warning USING Big Endian float word order */ | ||
65 | /* typedef union */ | ||
66 | /* { */ | ||
67 | /* double value; */ | ||
68 | /* struct */ | ||
69 | /* { */ | ||
70 | /* u_int16_t msw; */ | ||
71 | /* u_int16_t lsw; */ | ||
72 | /* } parts; */ | ||
73 | /* } ieeeDoubleShapeType; */ | ||
74 | |||
75 | /* #endif */ | ||
76 | |||
77 | /* #if __FLOAT_WORD_ORDER == LITTLE_ENDIAN */ | ||
78 | /* #warning USING Little Endian float word order */ | ||
79 | |||
80 | typedef union | ||
81 | { | ||
82 | double value; | ||
83 | struct | ||
84 | { | ||
85 | u_int16_t lsw; | ||
86 | u_int16_t msw; | ||
87 | } parts; | ||
88 | } ieeeDoubleShapeType; | ||
89 | |||
90 | /* #endif */ | ||
91 | |||
92 | /* Get two 32 bit ints from a double. */ | ||
93 | |||
94 | #define EXTRACT_WORDS(ix0,ix1,d) \ | ||
95 | { \ | ||
96 | ieeeDoubleShapeType ew_u; \ | ||
97 | ew_u.value = (d); \ | ||
98 | (ix0) = ew_u.parts.msw; \ | ||
99 | (ix1) = ew_u.parts.lsw; \ | ||
100 | } | ||
101 | |||
102 | /* Get the more significant 32 bit int from a double. */ | ||
103 | |||
104 | #define GET_HIGH_WORD(i,d) \ | ||
105 | { \ | ||
106 | ieeeDoubleShapeType gh_u; \ | ||
107 | gh_u.value = (d); \ | ||
108 | (i) = gh_u.parts.msw; \ | ||
109 | } | ||
110 | |||
111 | /* Get the less significant 32 bit int from a double. */ | ||
112 | |||
113 | #define GET_LOW_WORD(i,d) \ | ||
114 | { \ | ||
115 | ieeeDoubleShapeType gl_u; \ | ||
116 | gl_u.value = (d); \ | ||
117 | (i) = gl_u.parts.lsw; \ | ||
118 | } | ||
119 | |||
120 | /* Set a double from two 32 bit ints. */ | ||
121 | |||
122 | #define INSERT_WORDS(d,ix0,ix1) \ | ||
123 | { \ | ||
124 | ieeeDoubleShapeType iw_u; \ | ||
125 | iw_u.parts.msw = (ix0); \ | ||
126 | iw_u.parts.lsw = (ix1); \ | ||
127 | (d) = iw_u.value; \ | ||
128 | } | ||
129 | |||
130 | /* Set the more significant 32 bits of a double from an int. */ | ||
131 | |||
132 | #define SET_HIGH_WORD(d,v) \ | ||
133 | { \ | ||
134 | ieeeDoubleShapeType sh_u; \ | ||
135 | sh_u.value = (d); \ | ||
136 | sh_u.parts.msw = (v); \ | ||
137 | (d) = sh_u.value; \ | ||
138 | } | ||
139 | |||
140 | /* Set the less significant 32 bits of a double from an int. */ | ||
141 | |||
142 | #define SET_LOW_WORD(d,v) \ | ||
143 | { \ | ||
144 | ieeeDoubleShapeType sl_u; \ | ||
145 | sl_u.value = (d); \ | ||
146 | sl_u.parts.lsw = (v); \ | ||
147 | (d) = sl_u.value; \ | ||
148 | } | ||
149 | |||
150 | /* A union which permits us to convert between a float and a 32 bit | ||
151 | int. */ | ||
152 | |||
153 | typedef union | ||
154 | { | ||
155 | float value; | ||
156 | u_int32_t word; | ||
157 | } ieee_float_shape_type; | ||
158 | |||
159 | /* Get a 32 bit int from a float. */ | ||
160 | |||
161 | #define GET_FLOAT_WORD(i,d) \ | ||
162 | { \ | ||
163 | ieee_float_shape_type gf_u; \ | ||
164 | gf_u.value = (d); \ | ||
165 | (i) = gf_u.word; \ | ||
166 | } | ||
167 | |||
168 | /* Set a float from a 32 bit int. */ | ||
169 | |||
170 | #define SET_FLOAT_WORD(d,i) \ | ||
171 | { \ | ||
172 | ieee_float_shape_type sf_u; \ | ||
173 | sf_u.word = (i); \ | ||
174 | (d) = sf_u.value; \ | ||
175 | } | ||
176 | |||
177 | |||
178 | #endif /* _MATH_PRIVATE_H_ */ | ||