]>
Commit | Line | Data |
---|---|---|
d876f532 UD |
1 | /* Software floating-point emulation. |
2 | Definitions for IEEE Double Precision | |
d4697bc9 | 3 | Copyright (C) 1997-2014 Free Software Foundation, Inc. |
d876f532 UD |
4 | This file is part of the GNU C Library. |
5 | Contributed by Richard Henderson (rth@cygnus.com), | |
6 | Jakub Jelinek (jj@ultra.linux.cz), | |
7 | David S. Miller (davem@redhat.com) and | |
8 | Peter Maydell (pmaydell@chiark.greenend.org.uk). | |
9 | ||
10 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
11 | modify it under the terms of the GNU Lesser General Public |
12 | License as published by the Free Software Foundation; either | |
13 | version 2.1 of the License, or (at your option) any later version. | |
d876f532 | 14 | |
638a783c RM |
15 | In addition to the permissions in the GNU Lesser General Public |
16 | License, the Free Software Foundation gives you unlimited | |
17 | permission to link the compiled version of this file into | |
18 | combinations with other programs, and to distribute those | |
19 | combinations without any restriction coming from the use of this | |
20 | file. (The Lesser General Public License restrictions do apply in | |
21 | other respects; for example, they cover modification of the file, | |
22 | and distribution when not linked into a combine executable.) | |
23 | ||
d876f532 UD |
24 | The GNU C Library is distributed in the hope that it will be useful, |
25 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 27 | Lesser General Public License for more details. |
d876f532 | 28 | |
41bdb6e2 | 29 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
30 | License along with the GNU C Library; if not, see |
31 | <http://www.gnu.org/licenses/>. */ | |
d876f532 UD |
32 | |
33 | #if _FP_W_TYPE_SIZE < 32 | |
71b4dea7 | 34 | # error "Here's a nickel kid. Go buy yourself a real computer." |
d876f532 UD |
35 | #endif |
36 | ||
37 | #if _FP_W_TYPE_SIZE < 64 | |
71b4dea7 JM |
38 | # define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) |
39 | # define _FP_FRACTBITS_DW_D (4 * _FP_W_TYPE_SIZE) | |
d876f532 | 40 | #else |
71b4dea7 JM |
41 | # define _FP_FRACTBITS_D _FP_W_TYPE_SIZE |
42 | # define _FP_FRACTBITS_DW_D (2 * _FP_W_TYPE_SIZE) | |
d876f532 UD |
43 | #endif |
44 | ||
45 | #define _FP_FRACBITS_D 53 | |
46 | #define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D) | |
47 | #define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D) | |
48 | #define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D) | |
49 | #define _FP_EXPBITS_D 11 | |
50 | #define _FP_EXPBIAS_D 1023 | |
51 | #define _FP_EXPMAX_D 2047 | |
52 | ||
53 | #define _FP_QNANBIT_D \ | |
51ca9e29 | 54 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) |
fe0b1e85 | 55 | #define _FP_QNANBIT_SH_D \ |
51ca9e29 | 56 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
d876f532 | 57 | #define _FP_IMPLBIT_D \ |
51ca9e29 | 58 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) |
fe0b1e85 | 59 | #define _FP_IMPLBIT_SH_D \ |
51ca9e29 | 60 | ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) |
d876f532 | 61 | #define _FP_OVERFLOW_D \ |
51ca9e29 | 62 | ((_FP_W_TYPE) 1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) |
d876f532 | 63 | |
77f01ab5 JM |
64 | #define _FP_WFRACBITS_DW_D (2 * _FP_WFRACBITS_D) |
65 | #define _FP_WFRACXBITS_DW_D (_FP_FRACTBITS_DW_D - _FP_WFRACBITS_DW_D) | |
66 | #define _FP_HIGHBIT_DW_D \ | |
51ca9e29 | 67 | ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_D - 1) % _FP_W_TYPE_SIZE) |
77f01ab5 | 68 | |
51ca9e29 | 69 | typedef float DFtype __attribute__ ((mode (DF))); |
fe0b1e85 | 70 | |
d876f532 UD |
71 | #if _FP_W_TYPE_SIZE < 64 |
72 | ||
73 | union _FP_UNION_D | |
74 | { | |
fe0b1e85 | 75 | DFtype flt; |
1e145589 JM |
76 | struct _FP_STRUCT_LAYOUT |
77 | { | |
71b4dea7 | 78 | # if __BYTE_ORDER == __BIG_ENDIAN |
d876f532 UD |
79 | unsigned sign : 1; |
80 | unsigned exp : _FP_EXPBITS_D; | |
81 | unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; | |
82 | unsigned frac0 : _FP_W_TYPE_SIZE; | |
71b4dea7 | 83 | # else |
d876f532 UD |
84 | unsigned frac0 : _FP_W_TYPE_SIZE; |
85 | unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; | |
86 | unsigned exp : _FP_EXPBITS_D; | |
87 | unsigned sign : 1; | |
71b4dea7 | 88 | # endif |
51ca9e29 | 89 | } bits __attribute__ ((packed)); |
d876f532 UD |
90 | }; |
91 | ||
51ca9e29 JM |
92 | # define FP_DECL_D(X) _FP_DECL (2, X) |
93 | # define FP_UNPACK_RAW_D(X, val) _FP_UNPACK_RAW_2 (D, X, val) | |
94 | # define FP_UNPACK_RAW_DP(X, val) _FP_UNPACK_RAW_2_P (D, X, val) | |
95 | # define FP_PACK_RAW_D(val, X) _FP_PACK_RAW_2 (D, val, X) | |
96 | # define FP_PACK_RAW_DP(val, X) \ | |
1e145589 JM |
97 | do \ |
98 | { \ | |
99 | if (!FP_INHIBIT_RESULTS) \ | |
51ca9e29 | 100 | _FP_PACK_RAW_2_P (D, val, X); \ |
1e145589 JM |
101 | } \ |
102 | while (0) | |
103 | ||
51ca9e29 | 104 | # define FP_UNPACK_D(X, val) \ |
1e145589 JM |
105 | do \ |
106 | { \ | |
51ca9e29 JM |
107 | _FP_UNPACK_RAW_2 (D, X, val); \ |
108 | _FP_UNPACK_CANONICAL (D, 2, X); \ | |
1e145589 JM |
109 | } \ |
110 | while (0) | |
111 | ||
51ca9e29 | 112 | # define FP_UNPACK_DP(X, val) \ |
1e145589 JM |
113 | do \ |
114 | { \ | |
51ca9e29 JM |
115 | _FP_UNPACK_RAW_2_P (D, X, val); \ |
116 | _FP_UNPACK_CANONICAL (D, 2, X); \ | |
1e145589 JM |
117 | } \ |
118 | while (0) | |
119 | ||
51ca9e29 | 120 | # define FP_UNPACK_SEMIRAW_D(X, val) \ |
1e145589 JM |
121 | do \ |
122 | { \ | |
51ca9e29 JM |
123 | _FP_UNPACK_RAW_2 (D, X, val); \ |
124 | _FP_UNPACK_SEMIRAW (D, 2, X); \ | |
1e145589 JM |
125 | } \ |
126 | while (0) | |
127 | ||
51ca9e29 | 128 | # define FP_UNPACK_SEMIRAW_DP(X, val) \ |
1e145589 JM |
129 | do \ |
130 | { \ | |
51ca9e29 JM |
131 | _FP_UNPACK_RAW_2_P (D, X, val); \ |
132 | _FP_UNPACK_SEMIRAW (D, 2, X); \ | |
1e145589 JM |
133 | } \ |
134 | while (0) | |
135 | ||
51ca9e29 | 136 | # define FP_PACK_D(val, X) \ |
1e145589 JM |
137 | do \ |
138 | { \ | |
51ca9e29 JM |
139 | _FP_PACK_CANONICAL (D, 2, X); \ |
140 | _FP_PACK_RAW_2 (D, val, X); \ | |
1e145589 JM |
141 | } \ |
142 | while (0) | |
143 | ||
51ca9e29 | 144 | # define FP_PACK_DP(val, X) \ |
1e145589 JM |
145 | do \ |
146 | { \ | |
51ca9e29 | 147 | _FP_PACK_CANONICAL (D, 2, X); \ |
1e145589 | 148 | if (!FP_INHIBIT_RESULTS) \ |
51ca9e29 | 149 | _FP_PACK_RAW_2_P (D, val, X); \ |
1e145589 JM |
150 | } \ |
151 | while (0) | |
152 | ||
51ca9e29 | 153 | # define FP_PACK_SEMIRAW_D(val, X) \ |
1e145589 JM |
154 | do \ |
155 | { \ | |
51ca9e29 JM |
156 | _FP_PACK_SEMIRAW (D, 2, X); \ |
157 | _FP_PACK_RAW_2 (D, val, X); \ | |
1e145589 JM |
158 | } \ |
159 | while (0) | |
160 | ||
51ca9e29 | 161 | # define FP_PACK_SEMIRAW_DP(val, X) \ |
1e145589 JM |
162 | do \ |
163 | { \ | |
51ca9e29 | 164 | _FP_PACK_SEMIRAW (D, 2, X); \ |
1e145589 | 165 | if (!FP_INHIBIT_RESULTS) \ |
51ca9e29 | 166 | _FP_PACK_RAW_2_P (D, val, X); \ |
1e145589 JM |
167 | } \ |
168 | while (0) | |
fe0b1e85 | 169 | |
51ca9e29 JM |
170 | # define FP_ISSIGNAN_D(X) _FP_ISSIGNAN (D, 2, X) |
171 | # define FP_NEG_D(R, X) _FP_NEG (D, 2, R, X) | |
172 | # define FP_ADD_D(R, X, Y) _FP_ADD (D, 2, R, X, Y) | |
173 | # define FP_SUB_D(R, X, Y) _FP_SUB (D, 2, R, X, Y) | |
174 | # define FP_MUL_D(R, X, Y) _FP_MUL (D, 2, R, X, Y) | |
175 | # define FP_DIV_D(R, X, Y) _FP_DIV (D, 2, R, X, Y) | |
176 | # define FP_SQRT_D(R, X) _FP_SQRT (D, 2, R, X) | |
177 | # define _FP_SQRT_MEAT_D(R, S, T, X, Q) _FP_SQRT_MEAT_2 (R, S, T, X, Q) | |
178 | # define FP_FMA_D(R, X, Y, Z) _FP_FMA (D, 2, 4, R, X, Y, Z) | |
d876f532 | 179 | |
51ca9e29 JM |
180 | # define FP_CMP_D(r, X, Y, un) _FP_CMP (D, 2, r, X, Y, un) |
181 | # define FP_CMP_EQ_D(r, X, Y) _FP_CMP_EQ (D, 2, r, X, Y) | |
182 | # define FP_CMP_UNORD_D(r, X, Y) _FP_CMP_UNORD (D, 2, r, X, Y) | |
d876f532 | 183 | |
51ca9e29 JM |
184 | # define FP_TO_INT_D(r, X, rsz, rsg) _FP_TO_INT (D, 2, r, X, rsz, rsg) |
185 | # define FP_FROM_INT_D(X, r, rs, rt) _FP_FROM_INT (D, 2, X, r, rs, rt) | |
d876f532 | 186 | |
51ca9e29 JM |
187 | # define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2 (X) |
188 | # define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2 (X) | |
d876f532 | 189 | |
51ca9e29 | 190 | # define _FP_FRAC_HIGH_DW_D(X) _FP_FRAC_HIGH_4 (X) |
77f01ab5 | 191 | |
d876f532 UD |
192 | #else |
193 | ||
194 | union _FP_UNION_D | |
195 | { | |
fe0b1e85 | 196 | DFtype flt; |
1e145589 JM |
197 | struct _FP_STRUCT_LAYOUT |
198 | { | |
71b4dea7 | 199 | # if __BYTE_ORDER == __BIG_ENDIAN |
06029c20 JJ |
200 | unsigned sign : 1; |
201 | unsigned exp : _FP_EXPBITS_D; | |
202 | _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); | |
71b4dea7 | 203 | # else |
06029c20 JJ |
204 | _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); |
205 | unsigned exp : _FP_EXPBITS_D; | |
206 | unsigned sign : 1; | |
71b4dea7 | 207 | # endif |
51ca9e29 | 208 | } bits __attribute__ ((packed)); |
d876f532 UD |
209 | }; |
210 | ||
51ca9e29 JM |
211 | # define FP_DECL_D(X) _FP_DECL (1, X) |
212 | # define FP_UNPACK_RAW_D(X, val) _FP_UNPACK_RAW_1 (D, X, val) | |
213 | # define FP_UNPACK_RAW_DP(X, val) _FP_UNPACK_RAW_1_P (D, X, val) | |
214 | # define FP_PACK_RAW_D(val, X) _FP_PACK_RAW_1 (D, val, X) | |
215 | # define FP_PACK_RAW_DP(val, X) \ | |
1e145589 JM |
216 | do \ |
217 | { \ | |
218 | if (!FP_INHIBIT_RESULTS) \ | |
51ca9e29 | 219 | _FP_PACK_RAW_1_P (D, val, X); \ |
1e145589 JM |
220 | } \ |
221 | while (0) | |
222 | ||
51ca9e29 | 223 | # define FP_UNPACK_D(X, val) \ |
1e145589 JM |
224 | do \ |
225 | { \ | |
51ca9e29 JM |
226 | _FP_UNPACK_RAW_1 (D, X, val); \ |
227 | _FP_UNPACK_CANONICAL (D, 1, X); \ | |
1e145589 JM |
228 | } \ |
229 | while (0) | |
230 | ||
51ca9e29 | 231 | # define FP_UNPACK_DP(X, val) \ |
1e145589 JM |
232 | do \ |
233 | { \ | |
51ca9e29 JM |
234 | _FP_UNPACK_RAW_1_P (D, X, val); \ |
235 | _FP_UNPACK_CANONICAL (D, 1, X); \ | |
1e145589 JM |
236 | } \ |
237 | while (0) | |
238 | ||
51ca9e29 | 239 | # define FP_UNPACK_SEMIRAW_D(X, val) \ |
1e145589 JM |
240 | do \ |
241 | { \ | |
51ca9e29 JM |
242 | _FP_UNPACK_RAW_1 (D, X, val); \ |
243 | _FP_UNPACK_SEMIRAW (D, 1, X); \ | |
1e145589 JM |
244 | } \ |
245 | while (0) | |
246 | ||
51ca9e29 | 247 | # define FP_UNPACK_SEMIRAW_DP(X, val) \ |
1e145589 JM |
248 | do \ |
249 | { \ | |
51ca9e29 JM |
250 | _FP_UNPACK_RAW_1_P (D, X, val); \ |
251 | _FP_UNPACK_SEMIRAW (D, 1, X); \ | |
1e145589 JM |
252 | } \ |
253 | while (0) | |
254 | ||
51ca9e29 | 255 | # define FP_PACK_D(val, X) \ |
1e145589 JM |
256 | do \ |
257 | { \ | |
51ca9e29 JM |
258 | _FP_PACK_CANONICAL (D, 1, X); \ |
259 | _FP_PACK_RAW_1 (D, val, X); \ | |
1e145589 JM |
260 | } \ |
261 | while (0) | |
262 | ||
51ca9e29 | 263 | # define FP_PACK_DP(val, X) \ |
1e145589 JM |
264 | do \ |
265 | { \ | |
51ca9e29 | 266 | _FP_PACK_CANONICAL (D, 1, X); \ |
1e145589 | 267 | if (!FP_INHIBIT_RESULTS) \ |
51ca9e29 | 268 | _FP_PACK_RAW_1_P (D, val, X); \ |
1e145589 JM |
269 | } \ |
270 | while (0) | |
271 | ||
51ca9e29 | 272 | # define FP_PACK_SEMIRAW_D(val, X) \ |
1e145589 JM |
273 | do \ |
274 | { \ | |
51ca9e29 JM |
275 | _FP_PACK_SEMIRAW (D, 1, X); \ |
276 | _FP_PACK_RAW_1 (D, val, X); \ | |
1e145589 JM |
277 | } \ |
278 | while (0) | |
279 | ||
51ca9e29 | 280 | # define FP_PACK_SEMIRAW_DP(val, X) \ |
1e145589 JM |
281 | do \ |
282 | { \ | |
51ca9e29 | 283 | _FP_PACK_SEMIRAW (D, 1, X); \ |
1e145589 | 284 | if (!FP_INHIBIT_RESULTS) \ |
51ca9e29 | 285 | _FP_PACK_RAW_1_P (D, val, X); \ |
1e145589 JM |
286 | } \ |
287 | while (0) | |
fe0b1e85 | 288 | |
51ca9e29 JM |
289 | # define FP_ISSIGNAN_D(X) _FP_ISSIGNAN (D, 1, X) |
290 | # define FP_NEG_D(R, X) _FP_NEG (D, 1, R, X) | |
291 | # define FP_ADD_D(R, X, Y) _FP_ADD (D, 1, R, X, Y) | |
292 | # define FP_SUB_D(R, X, Y) _FP_SUB (D, 1, R, X, Y) | |
293 | # define FP_MUL_D(R, X, Y) _FP_MUL (D, 1, R, X, Y) | |
294 | # define FP_DIV_D(R, X, Y) _FP_DIV (D, 1, R, X, Y) | |
295 | # define FP_SQRT_D(R, X) _FP_SQRT (D, 1, R, X) | |
296 | # define _FP_SQRT_MEAT_D(R, S, T, X, Q) _FP_SQRT_MEAT_1 (R, S, T, X, Q) | |
297 | # define FP_FMA_D(R, X, Y, Z) _FP_FMA (D, 1, 2, R, X, Y, Z) | |
d876f532 UD |
298 | |
299 | /* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by | |
300 | the target machine. */ | |
301 | ||
51ca9e29 JM |
302 | # define FP_CMP_D(r, X, Y, un) _FP_CMP (D, 1, r, X, Y, un) |
303 | # define FP_CMP_EQ_D(r, X, Y) _FP_CMP_EQ (D, 1, r, X, Y) | |
304 | # define FP_CMP_UNORD_D(r, X, Y) _FP_CMP_UNORD (D, 1, r, X, Y) | |
d876f532 | 305 | |
51ca9e29 JM |
306 | # define FP_TO_INT_D(r, X, rsz, rsg) _FP_TO_INT (D, 1, r, X, rsz, rsg) |
307 | # define FP_FROM_INT_D(X, r, rs, rt) _FP_FROM_INT (D, 1, X, r, rs, rt) | |
d876f532 | 308 | |
51ca9e29 JM |
309 | # define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1 (X) |
310 | # define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1 (X) | |
d876f532 | 311 | |
51ca9e29 | 312 | # define _FP_FRAC_HIGH_DW_D(X) _FP_FRAC_HIGH_2 (X) |
77f01ab5 | 313 | |
d876f532 | 314 | #endif /* W_TYPE_SIZE < 64 */ |