diff options
Diffstat (limited to 'include/math-emu/extended.h')
-rw-r--r-- | include/math-emu/extended.h | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/include/math-emu/extended.h b/include/math-emu/extended.h new file mode 100644 index 000000000000..84770fceb53e --- /dev/null +++ b/include/math-emu/extended.h | |||
@@ -0,0 +1,396 @@ | |||
1 | /* Software floating-point emulation. | ||
2 | Definitions for IEEE Extended Precision. | ||
3 | Copyright (C) 1999 Free Software Foundation, Inc. | ||
4 | This file is part of the GNU C Library. | ||
5 | Contributed by Jakub Jelinek (jj@ultra.linux.cz). | ||
6 | |||
7 | The GNU C Library is free software; you can redistribute it and/or | ||
8 | modify it under the terms of the GNU Library General Public License as | ||
9 | published by the Free Software Foundation; either version 2 of the | ||
10 | License, or (at your option) any later version. | ||
11 | |||
12 | The GNU C Library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Library General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU Library General Public | ||
18 | License along with the GNU C Library; see the file COPYING.LIB. If | ||
19 | not, write to the Free Software Foundation, Inc., | ||
20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
21 | |||
22 | |||
23 | #ifndef __MATH_EMU_EXTENDED_H__ | ||
24 | #define __MATH_EMU_EXTENDED_H__ | ||
25 | |||
26 | #if _FP_W_TYPE_SIZE < 32 | ||
27 | #error "Here's a nickel, kid. Go buy yourself a real computer." | ||
28 | #endif | ||
29 | |||
30 | #if _FP_W_TYPE_SIZE < 64 | ||
31 | #define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) | ||
32 | #else | ||
33 | #define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) | ||
34 | #endif | ||
35 | |||
36 | #define _FP_FRACBITS_E 64 | ||
37 | #define _FP_FRACXBITS_E (_FP_FRACTBITS_E - _FP_FRACBITS_E) | ||
38 | #define _FP_WFRACBITS_E (_FP_WORKBITS + _FP_FRACBITS_E) | ||
39 | #define _FP_WFRACXBITS_E (_FP_FRACTBITS_E - _FP_WFRACBITS_E) | ||
40 | #define _FP_EXPBITS_E 15 | ||
41 | #define _FP_EXPBIAS_E 16383 | ||
42 | #define _FP_EXPMAX_E 32767 | ||
43 | |||
44 | #define _FP_QNANBIT_E \ | ||
45 | ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) | ||
46 | #define _FP_IMPLBIT_E \ | ||
47 | ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) | ||
48 | #define _FP_OVERFLOW_E \ | ||
49 | ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) | ||
50 | |||
51 | #if _FP_W_TYPE_SIZE < 64 | ||
52 | |||
53 | union _FP_UNION_E | ||
54 | { | ||
55 | long double flt; | ||
56 | struct | ||
57 | { | ||
58 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
59 | unsigned long pad1 : _FP_W_TYPE_SIZE; | ||
60 | unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); | ||
61 | unsigned long sign : 1; | ||
62 | unsigned long exp : _FP_EXPBITS_E; | ||
63 | unsigned long frac1 : _FP_W_TYPE_SIZE; | ||
64 | unsigned long frac0 : _FP_W_TYPE_SIZE; | ||
65 | #else | ||
66 | unsigned long frac0 : _FP_W_TYPE_SIZE; | ||
67 | unsigned long frac1 : _FP_W_TYPE_SIZE; | ||
68 | unsigned exp : _FP_EXPBITS_E; | ||
69 | unsigned sign : 1; | ||
70 | #endif /* not bigendian */ | ||
71 | } bits __attribute__((packed)); | ||
72 | }; | ||
73 | |||
74 | |||
75 | #define FP_DECL_E(X) _FP_DECL(4,X) | ||
76 | |||
77 | #define FP_UNPACK_RAW_E(X, val) \ | ||
78 | do { \ | ||
79 | union _FP_UNION_E _flo; _flo.flt = (val); \ | ||
80 | \ | ||
81 | X##_f[2] = 0; X##_f[3] = 0; \ | ||
82 | X##_f[0] = _flo.bits.frac0; \ | ||
83 | X##_f[1] = _flo.bits.frac1; \ | ||
84 | X##_e = _flo.bits.exp; \ | ||
85 | X##_s = _flo.bits.sign; \ | ||
86 | if (!X##_e && (X##_f[1] || X##_f[0]) \ | ||
87 | && !(X##_f[1] & _FP_IMPLBIT_E)) \ | ||
88 | { \ | ||
89 | X##_e++; \ | ||
90 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | ||
91 | } \ | ||
92 | } while (0) | ||
93 | |||
94 | #define FP_UNPACK_RAW_EP(X, val) \ | ||
95 | do { \ | ||
96 | union _FP_UNION_E *_flo = \ | ||
97 | (union _FP_UNION_E *)(val); \ | ||
98 | \ | ||
99 | X##_f[2] = 0; X##_f[3] = 0; \ | ||
100 | X##_f[0] = _flo->bits.frac0; \ | ||
101 | X##_f[1] = _flo->bits.frac1; \ | ||
102 | X##_e = _flo->bits.exp; \ | ||
103 | X##_s = _flo->bits.sign; \ | ||
104 | if (!X##_e && (X##_f[1] || X##_f[0]) \ | ||
105 | && !(X##_f[1] & _FP_IMPLBIT_E)) \ | ||
106 | { \ | ||
107 | X##_e++; \ | ||
108 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | ||
109 | } \ | ||
110 | } while (0) | ||
111 | |||
112 | #define FP_PACK_RAW_E(val, X) \ | ||
113 | do { \ | ||
114 | union _FP_UNION_E _flo; \ | ||
115 | \ | ||
116 | if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ | ||
117 | else X##_f[1] &= ~(_FP_IMPLBIT_E); \ | ||
118 | _flo.bits.frac0 = X##_f[0]; \ | ||
119 | _flo.bits.frac1 = X##_f[1]; \ | ||
120 | _flo.bits.exp = X##_e; \ | ||
121 | _flo.bits.sign = X##_s; \ | ||
122 | \ | ||
123 | (val) = _flo.flt; \ | ||
124 | } while (0) | ||
125 | |||
126 | #define FP_PACK_RAW_EP(val, X) \ | ||
127 | do { \ | ||
128 | if (!FP_INHIBIT_RESULTS) \ | ||
129 | { \ | ||
130 | union _FP_UNION_E *_flo = \ | ||
131 | (union _FP_UNION_E *)(val); \ | ||
132 | \ | ||
133 | if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ | ||
134 | else X##_f[1] &= ~(_FP_IMPLBIT_E); \ | ||
135 | _flo->bits.frac0 = X##_f[0]; \ | ||
136 | _flo->bits.frac1 = X##_f[1]; \ | ||
137 | _flo->bits.exp = X##_e; \ | ||
138 | _flo->bits.sign = X##_s; \ | ||
139 | } \ | ||
140 | } while (0) | ||
141 | |||
142 | #define FP_UNPACK_E(X,val) \ | ||
143 | do { \ | ||
144 | FP_UNPACK_RAW_E(X,val); \ | ||
145 | _FP_UNPACK_CANONICAL(E,4,X); \ | ||
146 | } while (0) | ||
147 | |||
148 | #define FP_UNPACK_EP(X,val) \ | ||
149 | do { \ | ||
150 | FP_UNPACK_RAW_2_P(X,val); \ | ||
151 | _FP_UNPACK_CANONICAL(E,4,X); \ | ||
152 | } while (0) | ||
153 | |||
154 | #define FP_PACK_E(val,X) \ | ||
155 | do { \ | ||
156 | _FP_PACK_CANONICAL(E,4,X); \ | ||
157 | FP_PACK_RAW_E(val,X); \ | ||
158 | } while (0) | ||
159 | |||
160 | #define FP_PACK_EP(val,X) \ | ||
161 | do { \ | ||
162 | _FP_PACK_CANONICAL(E,4,X); \ | ||
163 | FP_PACK_RAW_EP(val,X); \ | ||
164 | } while (0) | ||
165 | |||
166 | #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) | ||
167 | #define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) | ||
168 | #define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) | ||
169 | #define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) | ||
170 | #define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) | ||
171 | #define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) | ||
172 | #define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) | ||
173 | |||
174 | /* | ||
175 | * Square root algorithms: | ||
176 | * We have just one right now, maybe Newton approximation | ||
177 | * should be added for those machines where division is fast. | ||
178 | * This has special _E version because standard _4 square | ||
179 | * root would not work (it has to start normally with the | ||
180 | * second word and not the first), but as we have to do it | ||
181 | * anyway, we optimize it by doing most of the calculations | ||
182 | * in two UWtype registers instead of four. | ||
183 | */ | ||
184 | |||
185 | #define _FP_SQRT_MEAT_E(R, S, T, X, q) \ | ||
186 | do { \ | ||
187 | q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ | ||
188 | _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ | ||
189 | while (q) \ | ||
190 | { \ | ||
191 | T##_f[1] = S##_f[1] + q; \ | ||
192 | if (T##_f[1] <= X##_f[1]) \ | ||
193 | { \ | ||
194 | S##_f[1] = T##_f[1] + q; \ | ||
195 | X##_f[1] -= T##_f[1]; \ | ||
196 | R##_f[1] += q; \ | ||
197 | } \ | ||
198 | _FP_FRAC_SLL_2(X, 1); \ | ||
199 | q >>= 1; \ | ||
200 | } \ | ||
201 | q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ | ||
202 | while (q) \ | ||
203 | { \ | ||
204 | T##_f[0] = S##_f[0] + q; \ | ||
205 | T##_f[1] = S##_f[1]; \ | ||
206 | if (T##_f[1] < X##_f[1] || \ | ||
207 | (T##_f[1] == X##_f[1] && \ | ||
208 | T##_f[0] <= X##_f[0])) \ | ||
209 | { \ | ||
210 | S##_f[0] = T##_f[0] + q; \ | ||
211 | S##_f[1] += (T##_f[0] > S##_f[0]); \ | ||
212 | _FP_FRAC_DEC_2(X, T); \ | ||
213 | R##_f[0] += q; \ | ||
214 | } \ | ||
215 | _FP_FRAC_SLL_2(X, 1); \ | ||
216 | q >>= 1; \ | ||
217 | } \ | ||
218 | _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ | ||
219 | if (X##_f[0] | X##_f[1]) \ | ||
220 | { \ | ||
221 | if (S##_f[1] < X##_f[1] || \ | ||
222 | (S##_f[1] == X##_f[1] && \ | ||
223 | S##_f[0] < X##_f[0])) \ | ||
224 | R##_f[0] |= _FP_WORK_ROUND; \ | ||
225 | R##_f[0] |= _FP_WORK_STICKY; \ | ||
226 | } \ | ||
227 | } while (0) | ||
228 | |||
229 | #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) | ||
230 | #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) | ||
231 | |||
232 | #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) | ||
233 | #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,4,r,X,rsz,rsg) | ||
234 | #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) | ||
235 | |||
236 | #define _FP_FRAC_HIGH_E(X) (X##_f[2]) | ||
237 | #define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) | ||
238 | |||
239 | #else /* not _FP_W_TYPE_SIZE < 64 */ | ||
240 | union _FP_UNION_E | ||
241 | { | ||
242 | long double flt /* __attribute__((mode(TF))) */ ; | ||
243 | struct { | ||
244 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
245 | unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); | ||
246 | unsigned sign : 1; | ||
247 | unsigned exp : _FP_EXPBITS_E; | ||
248 | unsigned long frac : _FP_W_TYPE_SIZE; | ||
249 | #else | ||
250 | unsigned long frac : _FP_W_TYPE_SIZE; | ||
251 | unsigned exp : _FP_EXPBITS_E; | ||
252 | unsigned sign : 1; | ||
253 | #endif | ||
254 | } bits; | ||
255 | }; | ||
256 | |||
257 | #define FP_DECL_E(X) _FP_DECL(2,X) | ||
258 | |||
259 | #define FP_UNPACK_RAW_E(X, val) \ | ||
260 | do { \ | ||
261 | union _FP_UNION_E _flo; _flo.flt = (val); \ | ||
262 | \ | ||
263 | X##_f0 = _flo.bits.frac; \ | ||
264 | X##_f1 = 0; \ | ||
265 | X##_e = _flo.bits.exp; \ | ||
266 | X##_s = _flo.bits.sign; \ | ||
267 | if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ | ||
268 | { \ | ||
269 | X##_e++; \ | ||
270 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | ||
271 | } \ | ||
272 | } while (0) | ||
273 | |||
274 | #define FP_UNPACK_RAW_EP(X, val) \ | ||
275 | do { \ | ||
276 | union _FP_UNION_E *_flo = \ | ||
277 | (union _FP_UNION_E *)(val); \ | ||
278 | \ | ||
279 | X##_f0 = _flo->bits.frac; \ | ||
280 | X##_f1 = 0; \ | ||
281 | X##_e = _flo->bits.exp; \ | ||
282 | X##_s = _flo->bits.sign; \ | ||
283 | if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E)) \ | ||
284 | { \ | ||
285 | X##_e++; \ | ||
286 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | ||
287 | } \ | ||
288 | } while (0) | ||
289 | |||
290 | #define FP_PACK_RAW_E(val, X) \ | ||
291 | do { \ | ||
292 | union _FP_UNION_E _flo; \ | ||
293 | \ | ||
294 | if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ | ||
295 | else X##_f0 &= ~(_FP_IMPLBIT_E); \ | ||
296 | _flo.bits.frac = X##_f0; \ | ||
297 | _flo.bits.exp = X##_e; \ | ||
298 | _flo.bits.sign = X##_s; \ | ||
299 | \ | ||
300 | (val) = _flo.flt; \ | ||
301 | } while (0) | ||
302 | |||
303 | #define FP_PACK_RAW_EP(fs, val, X) \ | ||
304 | do { \ | ||
305 | if (!FP_INHIBIT_RESULTS) \ | ||
306 | { \ | ||
307 | union _FP_UNION_E *_flo = \ | ||
308 | (union _FP_UNION_E *)(val); \ | ||
309 | \ | ||
310 | if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ | ||
311 | else X##_f0 &= ~(_FP_IMPLBIT_E); \ | ||
312 | _flo->bits.frac = X##_f0; \ | ||
313 | _flo->bits.exp = X##_e; \ | ||
314 | _flo->bits.sign = X##_s; \ | ||
315 | } \ | ||
316 | } while (0) | ||
317 | |||
318 | |||
319 | #define FP_UNPACK_E(X,val) \ | ||
320 | do { \ | ||
321 | FP_UNPACK_RAW_E(X,val); \ | ||
322 | _FP_UNPACK_CANONICAL(E,2,X); \ | ||
323 | } while (0) | ||
324 | |||
325 | #define FP_UNPACK_EP(X,val) \ | ||
326 | do { \ | ||
327 | FP_UNPACK_RAW_EP(X,val); \ | ||
328 | _FP_UNPACK_CANONICAL(E,2,X); \ | ||
329 | } while (0) | ||
330 | |||
331 | #define FP_PACK_E(val,X) \ | ||
332 | do { \ | ||
333 | _FP_PACK_CANONICAL(E,2,X); \ | ||
334 | FP_PACK_RAW_E(val,X); \ | ||
335 | } while (0) | ||
336 | |||
337 | #define FP_PACK_EP(val,X) \ | ||
338 | do { \ | ||
339 | _FP_PACK_CANONICAL(E,2,X); \ | ||
340 | FP_PACK_RAW_EP(val,X); \ | ||
341 | } while (0) | ||
342 | |||
343 | #define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) | ||
344 | #define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) | ||
345 | #define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) | ||
346 | #define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) | ||
347 | #define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) | ||
348 | #define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) | ||
349 | #define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) | ||
350 | |||
351 | /* | ||
352 | * Square root algorithms: | ||
353 | * We have just one right now, maybe Newton approximation | ||
354 | * should be added for those machines where division is fast. | ||
355 | * We optimize it by doing most of the calculations | ||
356 | * in one UWtype registers instead of two, although we don't | ||
357 | * have to. | ||
358 | */ | ||
359 | #define _FP_SQRT_MEAT_E(R, S, T, X, q) \ | ||
360 | do { \ | ||
361 | q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ | ||
362 | _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ | ||
363 | while (q) \ | ||
364 | { \ | ||
365 | T##_f0 = S##_f0 + q; \ | ||
366 | if (T##_f0 <= X##_f0) \ | ||
367 | { \ | ||
368 | S##_f0 = T##_f0 + q; \ | ||
369 | X##_f0 -= T##_f0; \ | ||
370 | R##_f0 += q; \ | ||
371 | } \ | ||
372 | _FP_FRAC_SLL_1(X, 1); \ | ||
373 | q >>= 1; \ | ||
374 | } \ | ||
375 | _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ | ||
376 | if (X##_f0) \ | ||
377 | { \ | ||
378 | if (S##_f0 < X##_f0) \ | ||
379 | R##_f0 |= _FP_WORK_ROUND; \ | ||
380 | R##_f0 |= _FP_WORK_STICKY; \ | ||
381 | } \ | ||
382 | } while (0) | ||
383 | |||
384 | #define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) | ||
385 | #define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) | ||
386 | |||
387 | #define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) | ||
388 | #define FP_TO_INT_ROUND_E(r,X,rsz,rsg) _FP_TO_INT_ROUND(E,2,r,X,rsz,rsg) | ||
389 | #define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) | ||
390 | |||
391 | #define _FP_FRAC_HIGH_E(X) (X##_f1) | ||
392 | #define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) | ||
393 | |||
394 | #endif /* not _FP_W_TYPE_SIZE < 64 */ | ||
395 | |||
396 | #endif /* __MATH_EMU_EXTENDED_H__ */ | ||