]>
Commit | Line | Data |
---|---|---|
d876f532 | 1 | /* Software floating-point emulation. Common operations. |
568035b7 | 2 | Copyright (C) 1997-2013 Free Software Foundation, Inc. |
d876f532 UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Richard Henderson (rth@cygnus.com), | |
5 | Jakub Jelinek (jj@ultra.linux.cz), | |
6 | David S. Miller (davem@redhat.com) and | |
7 | Peter Maydell (pmaydell@chiark.greenend.org.uk). | |
8 | ||
9 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
10 | modify it under the terms of the GNU Lesser General Public |
11 | License as published by the Free Software Foundation; either | |
12 | version 2.1 of the License, or (at your option) any later version. | |
d876f532 | 13 | |
638a783c RM |
14 | In addition to the permissions in the GNU Lesser General Public |
15 | License, the Free Software Foundation gives you unlimited | |
16 | permission to link the compiled version of this file into | |
17 | combinations with other programs, and to distribute those | |
18 | combinations without any restriction coming from the use of this | |
19 | file. (The Lesser General Public License restrictions do apply in | |
20 | other respects; for example, they cover modification of the file, | |
21 | and distribution when not linked into a combine executable.) | |
22 | ||
d876f532 UD |
23 | The GNU C Library is distributed in the hope that it will be useful, |
24 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 26 | Lesser General Public License for more details. |
d876f532 | 27 | |
41bdb6e2 | 28 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
29 | License along with the GNU C Library; if not, see |
30 | <http://www.gnu.org/licenses/>. */ | |
d876f532 | 31 | |
a0d7066a JM |
32 | #define _FP_DECL(wc, X) \ |
33 | _FP_I_TYPE X##_c __attribute__((unused)); \ | |
34 | _FP_I_TYPE X##_s __attribute__((unused)); \ | |
35 | _FP_I_TYPE X##_e; \ | |
d876f532 UD |
36 | _FP_FRAC_DECL_##wc(X) |
37 | ||
2848b105 MR |
38 | /* Test whether the qNaN bit denotes a signaling NaN. */ |
39 | #define _FP_FRAC_SNANP(fs, X) \ | |
40 | ((_FP_QNANNEGATEDP) \ | |
41 | ? (_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ | |
42 | : !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) | |
43 | #define _FP_FRAC_SNANP_SEMIRAW(fs, X) \ | |
44 | ((_FP_QNANNEGATEDP) \ | |
45 | ? (_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs) \ | |
46 | : !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) | |
47 | ||
d876f532 | 48 | /* |
5b60c59d | 49 | * Finish truly unpacking a native fp value by classifying the kind |
d876f532 UD |
50 | * of fp value and normalizing both the exponent and the fraction. |
51 | */ | |
52 | ||
53 | #define _FP_UNPACK_CANONICAL(fs, wc, X) \ | |
54 | do { \ | |
55 | switch (X##_e) \ | |
56 | { \ | |
57 | default: \ | |
58 | _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ | |
59 | _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ | |
60 | X##_e -= _FP_EXPBIAS_##fs; \ | |
61 | X##_c = FP_CLS_NORMAL; \ | |
62 | break; \ | |
63 | \ | |
64 | case 0: \ | |
65 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
66 | X##_c = FP_CLS_ZERO; \ | |
67 | else \ | |
68 | { \ | |
69 | /* a denormalized number */ \ | |
70 | _FP_I_TYPE _shift; \ | |
71 | _FP_FRAC_CLZ_##wc(_shift, X); \ | |
72 | _shift -= _FP_FRACXBITS_##fs; \ | |
73 | _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ | |
74 | X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ | |
75 | X##_c = FP_CLS_NORMAL; \ | |
76 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
77 | } \ | |
78 | break; \ | |
79 | \ | |
80 | case _FP_EXPMAX_##fs: \ | |
81 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
82 | X##_c = FP_CLS_INF; \ | |
83 | else \ | |
84 | { \ | |
85 | X##_c = FP_CLS_NAN; \ | |
86 | /* Check for signaling NaN */ \ | |
2848b105 | 87 | if (_FP_FRAC_SNANP(fs, X)) \ |
d876f532 UD |
88 | FP_SET_EXCEPTION(FP_EX_INVALID); \ |
89 | } \ | |
90 | break; \ | |
91 | } \ | |
92 | } while (0) | |
93 | ||
fe0b1e85 RM |
94 | /* Finish unpacking an fp value in semi-raw mode: the mantissa is |
95 | shifted by _FP_WORKBITS but the implicit MSB is not inserted and | |
96 | other classification is not done. */ | |
97 | #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) | |
98 | ||
99 | /* A semi-raw value has overflowed to infinity. Adjust the mantissa | |
100 | and exponent appropriately. */ | |
101 | #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ | |
102 | do { \ | |
103 | if (FP_ROUNDMODE == FP_RND_NEAREST \ | |
104 | || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ | |
105 | || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ | |
106 | { \ | |
107 | X##_e = _FP_EXPMAX_##fs; \ | |
108 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
109 | } \ | |
110 | else \ | |
111 | { \ | |
112 | X##_e = _FP_EXPMAX_##fs - 1; \ | |
fe0b1e85 RM |
113 | _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ |
114 | } \ | |
d68f5d2c JJ |
115 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
116 | FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ | |
fe0b1e85 RM |
117 | } while (0) |
118 | ||
119 | /* Check for a semi-raw value being a signaling NaN and raise the | |
120 | invalid exception if so. */ | |
121 | #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ | |
122 | do { \ | |
123 | if (X##_e == _FP_EXPMAX_##fs \ | |
124 | && !_FP_FRAC_ZEROP_##wc(X) \ | |
2848b105 | 125 | && _FP_FRAC_SNANP_SEMIRAW(fs, X)) \ |
fe0b1e85 RM |
126 | FP_SET_EXCEPTION(FP_EX_INVALID); \ |
127 | } while (0) | |
128 | ||
129 | /* Choose a NaN result from an operation on two semi-raw NaN | |
130 | values. */ | |
131 | #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ | |
132 | do { \ | |
133 | /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ | |
134 | _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ | |
135 | _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ | |
136 | _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ | |
137 | _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ | |
138 | } while (0) | |
139 | ||
2848b105 MR |
140 | /* Make the fractional part a quiet NaN, preserving the payload |
141 | if possible, otherwise make it the canonical quiet NaN and set | |
142 | the sign bit accordingly. */ | |
143 | #define _FP_SETQNAN(fs, wc, X) \ | |
144 | do { \ | |
145 | if (_FP_QNANNEGATEDP) \ | |
146 | { \ | |
147 | _FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \ | |
148 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
149 | { \ | |
150 | X##_s = _FP_NANSIGN_##fs; \ | |
151 | _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ | |
152 | } \ | |
153 | } \ | |
154 | else \ | |
155 | _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ | |
156 | } while (0) | |
157 | #define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ | |
158 | do { \ | |
159 | if (_FP_QNANNEGATEDP) \ | |
160 | { \ | |
161 | _FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \ | |
162 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
163 | { \ | |
164 | X##_s = _FP_NANSIGN_##fs; \ | |
165 | _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ | |
166 | _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ | |
167 | } \ | |
168 | } \ | |
169 | else \ | |
170 | _FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \ | |
171 | } while (0) | |
172 | ||
fe0b1e85 RM |
173 | /* Test whether a biased exponent is normal (not zero or maximum). */ |
174 | #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) | |
175 | ||
176 | /* Prepare to pack an fp value in semi-raw mode: the mantissa is | |
177 | rounded and shifted right, with the rounding possibly increasing | |
178 | the exponent (including changing a finite value to infinity). */ | |
179 | #define _FP_PACK_SEMIRAW(fs, wc, X) \ | |
180 | do { \ | |
181 | _FP_ROUND(wc, X); \ | |
47594329 MS |
182 | if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \ |
183 | { \ | |
184 | if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ | |
185 | || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ | |
186 | FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ | |
187 | } \ | |
fe0b1e85 RM |
188 | if (_FP_FRAC_HIGH_##fs(X) \ |
189 | & (_FP_OVERFLOW_##fs >> 1)) \ | |
190 | { \ | |
191 | _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ | |
192 | X##_e++; \ | |
193 | if (X##_e == _FP_EXPMAX_##fs) \ | |
194 | _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ | |
195 | } \ | |
196 | _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ | |
47594329 | 197 | if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ |
fe0b1e85 | 198 | { \ |
47594329 | 199 | if (!_FP_KEEPNANFRACP) \ |
ae251b0b | 200 | { \ |
47594329 MS |
201 | _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ |
202 | X##_s = _FP_NANSIGN_##fs; \ | |
ae251b0b | 203 | } \ |
fe0b1e85 | 204 | else \ |
2848b105 | 205 | _FP_SETQNAN(fs, wc, X); \ |
fe0b1e85 RM |
206 | } \ |
207 | } while (0) | |
208 | ||
d876f532 UD |
209 | /* |
210 | * Before packing the bits back into the native fp result, take care | |
211 | * of such mundane things as rounding and overflow. Also, for some | |
212 | * kinds of fp values, the original parts may not have been fully | |
213 | * extracted -- but that is ok, we can regenerate them now. | |
214 | */ | |
215 | ||
216 | #define _FP_PACK_CANONICAL(fs, wc, X) \ | |
217 | do { \ | |
218 | switch (X##_c) \ | |
219 | { \ | |
220 | case FP_CLS_NORMAL: \ | |
221 | X##_e += _FP_EXPBIAS_##fs; \ | |
222 | if (X##_e > 0) \ | |
223 | { \ | |
224 | _FP_ROUND(wc, X); \ | |
225 | if (_FP_FRAC_OVERP_##wc(fs, X)) \ | |
226 | { \ | |
cf299341 | 227 | _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ |
d876f532 UD |
228 | X##_e++; \ |
229 | } \ | |
cf299341 | 230 | _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ |
d876f532 UD |
231 | if (X##_e >= _FP_EXPMAX_##fs) \ |
232 | { \ | |
233 | /* overflow */ \ | |
234 | switch (FP_ROUNDMODE) \ | |
235 | { \ | |
236 | case FP_RND_NEAREST: \ | |
237 | X##_c = FP_CLS_INF; \ | |
238 | break; \ | |
239 | case FP_RND_PINF: \ | |
240 | if (!X##_s) X##_c = FP_CLS_INF; \ | |
241 | break; \ | |
242 | case FP_RND_MINF: \ | |
243 | if (X##_s) X##_c = FP_CLS_INF; \ | |
244 | break; \ | |
245 | } \ | |
246 | if (X##_c == FP_CLS_INF) \ | |
247 | { \ | |
248 | /* Overflow to infinity */ \ | |
249 | X##_e = _FP_EXPMAX_##fs; \ | |
250 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
251 | } \ | |
252 | else \ | |
253 | { \ | |
254 | /* Overflow to maximum normal */ \ | |
255 | X##_e = _FP_EXPMAX_##fs - 1; \ | |
256 | _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ | |
257 | } \ | |
258 | FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ | |
259 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
260 | } \ | |
261 | } \ | |
262 | else \ | |
263 | { \ | |
264 | /* we've got a denormalized number */ \ | |
265 | X##_e = -X##_e + 1; \ | |
266 | if (X##_e <= _FP_WFRACBITS_##fs) \ | |
267 | { \ | |
268 | _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ | |
269 | _FP_ROUND(wc, X); \ | |
270 | if (_FP_FRAC_HIGH_##fs(X) \ | |
271 | & (_FP_OVERFLOW_##fs >> 1)) \ | |
272 | { \ | |
273 | X##_e = 1; \ | |
274 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
ae251b0b | 275 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ |
d876f532 UD |
276 | } \ |
277 | else \ | |
278 | { \ | |
279 | X##_e = 0; \ | |
280 | _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ | |
d876f532 | 281 | } \ |
ae251b0b DM |
282 | if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ |
283 | || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ | |
284 | FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ | |
d876f532 UD |
285 | } \ |
286 | else \ | |
287 | { \ | |
288 | /* underflow to zero */ \ | |
289 | X##_e = 0; \ | |
290 | if (!_FP_FRAC_ZEROP_##wc(X)) \ | |
291 | { \ | |
292 | _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ | |
293 | _FP_ROUND(wc, X); \ | |
294 | _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ | |
295 | } \ | |
296 | FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ | |
297 | } \ | |
298 | } \ | |
299 | break; \ | |
300 | \ | |
301 | case FP_CLS_ZERO: \ | |
302 | X##_e = 0; \ | |
303 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
304 | break; \ | |
305 | \ | |
306 | case FP_CLS_INF: \ | |
307 | X##_e = _FP_EXPMAX_##fs; \ | |
308 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
309 | break; \ | |
310 | \ | |
311 | case FP_CLS_NAN: \ | |
312 | X##_e = _FP_EXPMAX_##fs; \ | |
313 | if (!_FP_KEEPNANFRACP) \ | |
314 | { \ | |
315 | _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ | |
316 | X##_s = _FP_NANSIGN_##fs; \ | |
317 | } \ | |
318 | else \ | |
2848b105 | 319 | _FP_SETQNAN(fs, wc, X); \ |
d876f532 UD |
320 | break; \ |
321 | } \ | |
322 | } while (0) | |
323 | ||
324 | /* This one accepts raw argument and not cooked, returns | |
325 | * 1 if X is a signaling NaN. | |
326 | */ | |
327 | #define _FP_ISSIGNAN(fs, wc, X) \ | |
328 | ({ \ | |
329 | int __ret = 0; \ | |
330 | if (X##_e == _FP_EXPMAX_##fs) \ | |
331 | { \ | |
332 | if (!_FP_FRAC_ZEROP_##wc(X) \ | |
2848b105 | 333 | && _FP_FRAC_SNANP(fs, X)) \ |
d876f532 UD |
334 | __ret = 1; \ |
335 | } \ | |
336 | __ret; \ | |
337 | }) | |
338 | ||
339 | ||
340 | ||
341 | ||
342 | ||
fe0b1e85 RM |
343 | /* Addition on semi-raw values. */ |
344 | #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ | |
345 | do { \ | |
346 | if (X##_s == Y##_s) \ | |
347 | { \ | |
348 | /* Addition. */ \ | |
349 | R##_s = X##_s; \ | |
350 | int ediff = X##_e - Y##_e; \ | |
351 | if (ediff > 0) \ | |
352 | { \ | |
353 | R##_e = X##_e; \ | |
354 | if (Y##_e == 0) \ | |
355 | { \ | |
356 | /* Y is zero or denormalized. */ \ | |
357 | if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
358 | { \ | |
359 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
360 | _FP_FRAC_COPY_##wc(R, X); \ | |
361 | goto add_done; \ | |
362 | } \ | |
363 | else \ | |
364 | { \ | |
365 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
366 | ediff--; \ | |
367 | if (ediff == 0) \ | |
368 | { \ | |
369 | _FP_FRAC_ADD_##wc(R, X, Y); \ | |
370 | goto add3; \ | |
371 | } \ | |
372 | if (X##_e == _FP_EXPMAX_##fs) \ | |
373 | { \ | |
374 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
375 | _FP_FRAC_COPY_##wc(R, X); \ | |
376 | goto add_done; \ | |
377 | } \ | |
378 | goto add1; \ | |
379 | } \ | |
380 | } \ | |
381 | else if (X##_e == _FP_EXPMAX_##fs) \ | |
382 | { \ | |
383 | /* X is NaN or Inf, Y is normal. */ \ | |
384 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
385 | _FP_FRAC_COPY_##wc(R, X); \ | |
386 | goto add_done; \ | |
387 | } \ | |
388 | \ | |
389 | /* Insert implicit MSB of Y. */ \ | |
390 | _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ | |
391 | \ | |
392 | add1: \ | |
393 | /* Shift the mantissa of Y to the right EDIFF steps; \ | |
394 | remember to account later for the implicit MSB of X. */ \ | |
395 | if (ediff <= _FP_WFRACBITS_##fs) \ | |
396 | _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ | |
397 | else if (!_FP_FRAC_ZEROP_##wc(Y)) \ | |
398 | _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ | |
399 | _FP_FRAC_ADD_##wc(R, X, Y); \ | |
400 | } \ | |
401 | else if (ediff < 0) \ | |
402 | { \ | |
403 | ediff = -ediff; \ | |
404 | R##_e = Y##_e; \ | |
405 | if (X##_e == 0) \ | |
406 | { \ | |
407 | /* X is zero or denormalized. */ \ | |
408 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
409 | { \ | |
410 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
411 | _FP_FRAC_COPY_##wc(R, Y); \ | |
412 | goto add_done; \ | |
413 | } \ | |
414 | else \ | |
415 | { \ | |
416 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
417 | ediff--; \ | |
418 | if (ediff == 0) \ | |
419 | { \ | |
420 | _FP_FRAC_ADD_##wc(R, Y, X); \ | |
421 | goto add3; \ | |
422 | } \ | |
423 | if (Y##_e == _FP_EXPMAX_##fs) \ | |
424 | { \ | |
425 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
426 | _FP_FRAC_COPY_##wc(R, Y); \ | |
427 | goto add_done; \ | |
428 | } \ | |
429 | goto add2; \ | |
430 | } \ | |
431 | } \ | |
432 | else if (Y##_e == _FP_EXPMAX_##fs) \ | |
433 | { \ | |
434 | /* Y is NaN or Inf, X is normal. */ \ | |
435 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
436 | _FP_FRAC_COPY_##wc(R, Y); \ | |
437 | goto add_done; \ | |
438 | } \ | |
439 | \ | |
440 | /* Insert implicit MSB of X. */ \ | |
441 | _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ | |
442 | \ | |
443 | add2: \ | |
444 | /* Shift the mantissa of X to the right EDIFF steps; \ | |
445 | remember to account later for the implicit MSB of Y. */ \ | |
446 | if (ediff <= _FP_WFRACBITS_##fs) \ | |
447 | _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ | |
448 | else if (!_FP_FRAC_ZEROP_##wc(X)) \ | |
449 | _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ | |
450 | _FP_FRAC_ADD_##wc(R, Y, X); \ | |
451 | } \ | |
452 | else \ | |
453 | { \ | |
454 | /* ediff == 0. */ \ | |
455 | if (!_FP_EXP_NORMAL(fs, wc, X)) \ | |
456 | { \ | |
457 | if (X##_e == 0) \ | |
458 | { \ | |
459 | /* X and Y are zero or denormalized. */ \ | |
460 | R##_e = 0; \ | |
461 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
462 | { \ | |
463 | if (!_FP_FRAC_ZEROP_##wc(Y)) \ | |
464 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
465 | _FP_FRAC_COPY_##wc(R, Y); \ | |
466 | goto add_done; \ | |
467 | } \ | |
468 | else if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
469 | { \ | |
470 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
471 | _FP_FRAC_COPY_##wc(R, X); \ | |
472 | goto add_done; \ | |
473 | } \ | |
474 | else \ | |
475 | { \ | |
476 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
477 | _FP_FRAC_ADD_##wc(R, X, Y); \ | |
478 | if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ | |
479 | { \ | |
480 | /* Normalized result. */ \ | |
481 | _FP_FRAC_HIGH_##fs(R) \ | |
482 | &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ | |
483 | R##_e = 1; \ | |
484 | } \ | |
485 | goto add_done; \ | |
486 | } \ | |
487 | } \ | |
488 | else \ | |
489 | { \ | |
490 | /* X and Y are NaN or Inf. */ \ | |
491 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
492 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
493 | R##_e = _FP_EXPMAX_##fs; \ | |
494 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
495 | _FP_FRAC_COPY_##wc(R, Y); \ | |
496 | else if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
497 | _FP_FRAC_COPY_##wc(R, X); \ | |
498 | else \ | |
499 | _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ | |
500 | goto add_done; \ | |
501 | } \ | |
502 | } \ | |
503 | /* The exponents of X and Y, both normal, are equal. The \ | |
504 | implicit MSBs will always add to increase the \ | |
505 | exponent. */ \ | |
506 | _FP_FRAC_ADD_##wc(R, X, Y); \ | |
507 | R##_e = X##_e + 1; \ | |
508 | _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ | |
509 | if (R##_e == _FP_EXPMAX_##fs) \ | |
510 | /* Overflow to infinity (depending on rounding mode). */ \ | |
511 | _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ | |
512 | goto add_done; \ | |
513 | } \ | |
514 | add3: \ | |
515 | if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ | |
516 | { \ | |
517 | /* Overflow. */ \ | |
518 | _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ | |
519 | R##_e++; \ | |
520 | _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ | |
521 | if (R##_e == _FP_EXPMAX_##fs) \ | |
522 | /* Overflow to infinity (depending on rounding mode). */ \ | |
523 | _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ | |
524 | } \ | |
525 | add_done: ; \ | |
526 | } \ | |
527 | else \ | |
528 | { \ | |
529 | /* Subtraction. */ \ | |
530 | int ediff = X##_e - Y##_e; \ | |
531 | if (ediff > 0) \ | |
532 | { \ | |
533 | R##_e = X##_e; \ | |
534 | R##_s = X##_s; \ | |
535 | if (Y##_e == 0) \ | |
536 | { \ | |
537 | /* Y is zero or denormalized. */ \ | |
538 | if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
539 | { \ | |
540 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
541 | _FP_FRAC_COPY_##wc(R, X); \ | |
542 | goto sub_done; \ | |
543 | } \ | |
544 | else \ | |
545 | { \ | |
546 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
547 | ediff--; \ | |
548 | if (ediff == 0) \ | |
549 | { \ | |
550 | _FP_FRAC_SUB_##wc(R, X, Y); \ | |
551 | goto sub3; \ | |
552 | } \ | |
553 | if (X##_e == _FP_EXPMAX_##fs) \ | |
554 | { \ | |
555 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
556 | _FP_FRAC_COPY_##wc(R, X); \ | |
557 | goto sub_done; \ | |
558 | } \ | |
559 | goto sub1; \ | |
560 | } \ | |
561 | } \ | |
562 | else if (X##_e == _FP_EXPMAX_##fs) \ | |
563 | { \ | |
564 | /* X is NaN or Inf, Y is normal. */ \ | |
565 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
566 | _FP_FRAC_COPY_##wc(R, X); \ | |
567 | goto sub_done; \ | |
568 | } \ | |
569 | \ | |
570 | /* Insert implicit MSB of Y. */ \ | |
571 | _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ | |
572 | \ | |
573 | sub1: \ | |
574 | /* Shift the mantissa of Y to the right EDIFF steps; \ | |
575 | remember to account later for the implicit MSB of X. */ \ | |
576 | if (ediff <= _FP_WFRACBITS_##fs) \ | |
577 | _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ | |
578 | else if (!_FP_FRAC_ZEROP_##wc(Y)) \ | |
579 | _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ | |
580 | _FP_FRAC_SUB_##wc(R, X, Y); \ | |
581 | } \ | |
582 | else if (ediff < 0) \ | |
583 | { \ | |
584 | ediff = -ediff; \ | |
585 | R##_e = Y##_e; \ | |
586 | R##_s = Y##_s; \ | |
587 | if (X##_e == 0) \ | |
588 | { \ | |
589 | /* X is zero or denormalized. */ \ | |
590 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
591 | { \ | |
592 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
593 | _FP_FRAC_COPY_##wc(R, Y); \ | |
594 | goto sub_done; \ | |
595 | } \ | |
596 | else \ | |
597 | { \ | |
598 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
599 | ediff--; \ | |
600 | if (ediff == 0) \ | |
601 | { \ | |
602 | _FP_FRAC_SUB_##wc(R, Y, X); \ | |
603 | goto sub3; \ | |
604 | } \ | |
605 | if (Y##_e == _FP_EXPMAX_##fs) \ | |
606 | { \ | |
607 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
608 | _FP_FRAC_COPY_##wc(R, Y); \ | |
609 | goto sub_done; \ | |
610 | } \ | |
611 | goto sub2; \ | |
612 | } \ | |
613 | } \ | |
614 | else if (Y##_e == _FP_EXPMAX_##fs) \ | |
615 | { \ | |
616 | /* Y is NaN or Inf, X is normal. */ \ | |
617 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
618 | _FP_FRAC_COPY_##wc(R, Y); \ | |
619 | goto sub_done; \ | |
620 | } \ | |
621 | \ | |
622 | /* Insert implicit MSB of X. */ \ | |
623 | _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ | |
624 | \ | |
625 | sub2: \ | |
626 | /* Shift the mantissa of X to the right EDIFF steps; \ | |
627 | remember to account later for the implicit MSB of Y. */ \ | |
628 | if (ediff <= _FP_WFRACBITS_##fs) \ | |
629 | _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ | |
630 | else if (!_FP_FRAC_ZEROP_##wc(X)) \ | |
631 | _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ | |
632 | _FP_FRAC_SUB_##wc(R, Y, X); \ | |
633 | } \ | |
634 | else \ | |
635 | { \ | |
636 | /* ediff == 0. */ \ | |
637 | if (!_FP_EXP_NORMAL(fs, wc, X)) \ | |
638 | { \ | |
639 | if (X##_e == 0) \ | |
640 | { \ | |
641 | /* X and Y are zero or denormalized. */ \ | |
642 | R##_e = 0; \ | |
643 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
644 | { \ | |
645 | _FP_FRAC_COPY_##wc(R, Y); \ | |
646 | if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
647 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ | |
648 | else \ | |
649 | { \ | |
650 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
651 | R##_s = Y##_s; \ | |
652 | } \ | |
653 | goto sub_done; \ | |
654 | } \ | |
655 | else if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
656 | { \ | |
657 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
658 | _FP_FRAC_COPY_##wc(R, X); \ | |
659 | R##_s = X##_s; \ | |
660 | goto sub_done; \ | |
661 | } \ | |
662 | else \ | |
663 | { \ | |
664 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
665 | _FP_FRAC_SUB_##wc(R, X, Y); \ | |
666 | R##_s = X##_s; \ | |
667 | if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ | |
668 | { \ | |
669 | /* |X| < |Y|, negate result. */ \ | |
670 | _FP_FRAC_SUB_##wc(R, Y, X); \ | |
671 | R##_s = Y##_s; \ | |
672 | } \ | |
673 | else if (_FP_FRAC_ZEROP_##wc(R)) \ | |
674 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ | |
675 | goto sub_done; \ | |
676 | } \ | |
677 | } \ | |
678 | else \ | |
679 | { \ | |
680 | /* X and Y are NaN or Inf, of opposite signs. */ \ | |
681 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ | |
682 | _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ | |
683 | R##_e = _FP_EXPMAX_##fs; \ | |
684 | if (_FP_FRAC_ZEROP_##wc(X)) \ | |
685 | { \ | |
686 | if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
687 | { \ | |
688 | /* Inf - Inf. */ \ | |
689 | R##_s = _FP_NANSIGN_##fs; \ | |
690 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
691 | _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ | |
692 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
693 | } \ | |
694 | else \ | |
695 | { \ | |
696 | /* Inf - NaN. */ \ | |
697 | R##_s = Y##_s; \ | |
698 | _FP_FRAC_COPY_##wc(R, Y); \ | |
699 | } \ | |
700 | } \ | |
701 | else \ | |
702 | { \ | |
703 | if (_FP_FRAC_ZEROP_##wc(Y)) \ | |
704 | { \ | |
705 | /* NaN - Inf. */ \ | |
706 | R##_s = X##_s; \ | |
707 | _FP_FRAC_COPY_##wc(R, X); \ | |
708 | } \ | |
709 | else \ | |
710 | { \ | |
711 | /* NaN - NaN. */ \ | |
712 | _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ | |
713 | } \ | |
714 | } \ | |
715 | goto sub_done; \ | |
716 | } \ | |
717 | } \ | |
718 | /* The exponents of X and Y, both normal, are equal. The \ | |
719 | implicit MSBs cancel. */ \ | |
720 | R##_e = X##_e; \ | |
721 | _FP_FRAC_SUB_##wc(R, X, Y); \ | |
722 | R##_s = X##_s; \ | |
723 | if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ | |
724 | { \ | |
725 | /* |X| < |Y|, negate result. */ \ | |
726 | _FP_FRAC_SUB_##wc(R, Y, X); \ | |
727 | R##_s = Y##_s; \ | |
728 | } \ | |
729 | else if (_FP_FRAC_ZEROP_##wc(R)) \ | |
730 | { \ | |
731 | R##_e = 0; \ | |
732 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ | |
733 | goto sub_done; \ | |
734 | } \ | |
735 | goto norm; \ | |
736 | } \ | |
737 | sub3: \ | |
738 | if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ | |
739 | { \ | |
740 | int diff; \ | |
741 | /* Carry into most significant bit of larger one of X and Y, \ | |
742 | canceling it; renormalize. */ \ | |
743 | _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ | |
744 | norm: \ | |
745 | _FP_FRAC_CLZ_##wc(diff, R); \ | |
746 | diff -= _FP_WFRACXBITS_##fs; \ | |
747 | _FP_FRAC_SLL_##wc(R, diff); \ | |
748 | if (R##_e <= diff) \ | |
749 | { \ | |
750 | /* R is denormalized. */ \ | |
751 | diff = diff - R##_e + 1; \ | |
752 | _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ | |
753 | R##_e = 0; \ | |
754 | } \ | |
755 | else \ | |
756 | { \ | |
757 | R##_e -= diff; \ | |
758 | _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ | |
759 | } \ | |
760 | } \ | |
761 | sub_done: ; \ | |
762 | } \ | |
d876f532 UD |
763 | } while (0) |
764 | ||
765 | #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') | |
fe0b1e85 RM |
766 | #define _FP_SUB(fs, wc, R, X, Y) \ |
767 | do { \ | |
768 | if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ | |
769 | _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ | |
d876f532 UD |
770 | } while (0) |
771 | ||
772 | ||
773 | /* | |
774 | * Main negation routine. FIXME -- when we care about setting exception | |
775 | * bits reliably, this will not do. We should examine all of the fp classes. | |
776 | */ | |
777 | ||
778 | #define _FP_NEG(fs, wc, R, X) \ | |
779 | do { \ | |
780 | _FP_FRAC_COPY_##wc(R, X); \ | |
781 | R##_c = X##_c; \ | |
782 | R##_e = X##_e; \ | |
783 | R##_s = 1 ^ X##_s; \ | |
784 | } while (0) | |
785 | ||
786 | ||
787 | /* | |
788 | * Main multiplication routine. The input values should be cooked. | |
789 | */ | |
790 | ||
791 | #define _FP_MUL(fs, wc, R, X, Y) \ | |
792 | do { \ | |
793 | R##_s = X##_s ^ Y##_s; \ | |
573cd484 | 794 | R##_e = X##_e + Y##_e + 1; \ |
d876f532 UD |
795 | switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ |
796 | { \ | |
797 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ | |
798 | R##_c = FP_CLS_NORMAL; \ | |
d876f532 UD |
799 | \ |
800 | _FP_MUL_MEAT_##fs(R,X,Y); \ | |
801 | \ | |
802 | if (_FP_FRAC_OVERP_##wc(fs, R)) \ | |
803 | _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ | |
804 | else \ | |
805 | R##_e--; \ | |
806 | break; \ | |
807 | \ | |
808 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ | |
809 | _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ | |
810 | break; \ | |
811 | \ | |
812 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ | |
813 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ | |
814 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ | |
815 | R##_s = X##_s; \ | |
816 | \ | |
817 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ | |
818 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ | |
819 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ | |
820 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ | |
821 | _FP_FRAC_COPY_##wc(R, X); \ | |
822 | R##_c = X##_c; \ | |
823 | break; \ | |
824 | \ | |
825 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ | |
826 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ | |
827 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ | |
828 | R##_s = Y##_s; \ | |
829 | \ | |
830 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ | |
831 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ | |
832 | _FP_FRAC_COPY_##wc(R, Y); \ | |
833 | R##_c = Y##_c; \ | |
834 | break; \ | |
835 | \ | |
836 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ | |
837 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ | |
838 | R##_s = _FP_NANSIGN_##fs; \ | |
839 | R##_c = FP_CLS_NAN; \ | |
840 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
841 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
842 | break; \ | |
843 | \ | |
844 | default: \ | |
845 | abort(); \ | |
846 | } \ | |
77f01ab5 JM |
847 | } while (0) |
848 | ||
849 | ||
850 | /* Fused multiply-add. The input values should be cooked. */ | |
851 | ||
852 | #define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \ | |
853 | do { \ | |
854 | FP_DECL_##fs(T); \ | |
855 | T##_s = X##_s ^ Y##_s; \ | |
856 | T##_e = X##_e + Y##_e + 1; \ | |
857 | switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ | |
858 | { \ | |
859 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ | |
860 | switch (Z##_c) \ | |
861 | { \ | |
862 | case FP_CLS_INF: \ | |
863 | case FP_CLS_NAN: \ | |
864 | R##_s = Z##_s; \ | |
865 | _FP_FRAC_COPY_##wc(R, Z); \ | |
866 | R##_c = Z##_c; \ | |
867 | break; \ | |
868 | \ | |
869 | case FP_CLS_ZERO: \ | |
870 | R##_c = FP_CLS_NORMAL; \ | |
871 | R##_s = T##_s; \ | |
872 | R##_e = T##_e; \ | |
873 | \ | |
874 | _FP_MUL_MEAT_##fs(R, X, Y); \ | |
875 | \ | |
876 | if (_FP_FRAC_OVERP_##wc(fs, R)) \ | |
877 | _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ | |
878 | else \ | |
879 | R##_e--; \ | |
880 | break; \ | |
881 | \ | |
882 | case FP_CLS_NORMAL:; \ | |
883 | _FP_FRAC_DECL_##dwc(TD); \ | |
884 | _FP_FRAC_DECL_##dwc(ZD); \ | |
885 | _FP_FRAC_DECL_##dwc(RD); \ | |
886 | _FP_MUL_MEAT_DW_##fs(TD, X, Y); \ | |
887 | R##_e = T##_e; \ | |
888 | int tsh = _FP_FRAC_HIGHBIT_DW_##dwc(fs, TD) == 0; \ | |
889 | T##_e -= tsh; \ | |
890 | int ediff = T##_e - Z##_e; \ | |
891 | if (ediff >= 0) \ | |
892 | { \ | |
893 | int shift = _FP_WFRACBITS_##fs - tsh - ediff; \ | |
894 | if (shift <= -_FP_WFRACBITS_##fs) \ | |
895 | _FP_FRAC_SET_##dwc(ZD, _FP_MINFRAC_##dwc); \ | |
896 | else \ | |
897 | { \ | |
898 | _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ | |
899 | if (shift < 0) \ | |
900 | _FP_FRAC_SRS_##dwc(ZD, -shift, \ | |
901 | _FP_WFRACBITS_DW_##fs); \ | |
902 | else if (shift > 0) \ | |
903 | _FP_FRAC_SLL_##dwc(ZD, shift); \ | |
904 | } \ | |
905 | R##_s = T##_s; \ | |
906 | if (T##_s == Z##_s) \ | |
907 | _FP_FRAC_ADD_##dwc(RD, TD, ZD); \ | |
908 | else \ | |
909 | { \ | |
910 | _FP_FRAC_SUB_##dwc(RD, TD, ZD); \ | |
911 | if (_FP_FRAC_NEGP_##dwc(RD)) \ | |
912 | { \ | |
913 | R##_s = Z##_s; \ | |
914 | _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ | |
915 | } \ | |
916 | } \ | |
917 | } \ | |
918 | else \ | |
919 | { \ | |
920 | R##_e = Z##_e; \ | |
921 | R##_s = Z##_s; \ | |
922 | _FP_FRAC_COPY_##dwc##_##wc(ZD, Z); \ | |
923 | _FP_FRAC_SLL_##dwc(ZD, _FP_WFRACBITS_##fs); \ | |
924 | int shift = -ediff - tsh; \ | |
925 | if (shift >= _FP_WFRACBITS_DW_##fs) \ | |
926 | _FP_FRAC_SET_##dwc(TD, _FP_MINFRAC_##dwc); \ | |
927 | else if (shift > 0) \ | |
928 | _FP_FRAC_SRS_##dwc(TD, shift, \ | |
929 | _FP_WFRACBITS_DW_##fs); \ | |
930 | if (Z##_s == T##_s) \ | |
931 | _FP_FRAC_ADD_##dwc(RD, ZD, TD); \ | |
932 | else \ | |
933 | _FP_FRAC_SUB_##dwc(RD, ZD, TD); \ | |
934 | } \ | |
935 | if (_FP_FRAC_ZEROP_##dwc(RD)) \ | |
936 | { \ | |
937 | if (T##_s == Z##_s) \ | |
938 | R##_s = Z##_s; \ | |
939 | else \ | |
940 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ | |
941 | _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ | |
942 | R##_c = FP_CLS_ZERO; \ | |
943 | } \ | |
944 | else \ | |
945 | { \ | |
946 | int rlz; \ | |
947 | _FP_FRAC_CLZ_##dwc(rlz, RD); \ | |
948 | rlz -= _FP_WFRACXBITS_DW_##fs; \ | |
949 | R##_e -= rlz; \ | |
950 | int shift = _FP_WFRACBITS_##fs - rlz; \ | |
951 | if (shift > 0) \ | |
952 | _FP_FRAC_SRS_##dwc(RD, shift, \ | |
953 | _FP_WFRACBITS_DW_##fs); \ | |
954 | else if (shift < 0) \ | |
955 | _FP_FRAC_SLL_##dwc(RD, -shift); \ | |
956 | _FP_FRAC_COPY_##wc##_##dwc(R, RD); \ | |
957 | R##_c = FP_CLS_NORMAL; \ | |
958 | } \ | |
959 | break; \ | |
960 | } \ | |
961 | goto done_fma; \ | |
962 | \ | |
963 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ | |
964 | _FP_CHOOSENAN(fs, wc, T, X, Y, '*'); \ | |
965 | break; \ | |
966 | \ | |
967 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ | |
968 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ | |
969 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ | |
970 | T##_s = X##_s; \ | |
971 | \ | |
972 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ | |
973 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ | |
974 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ | |
975 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ | |
976 | _FP_FRAC_COPY_##wc(T, X); \ | |
977 | T##_c = X##_c; \ | |
978 | break; \ | |
979 | \ | |
980 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ | |
981 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ | |
982 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ | |
983 | T##_s = Y##_s; \ | |
984 | \ | |
985 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ | |
986 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ | |
987 | _FP_FRAC_COPY_##wc(T, Y); \ | |
988 | T##_c = Y##_c; \ | |
989 | break; \ | |
990 | \ | |
991 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ | |
992 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ | |
993 | T##_s = _FP_NANSIGN_##fs; \ | |
994 | T##_c = FP_CLS_NAN; \ | |
995 | _FP_FRAC_SET_##wc(T, _FP_NANFRAC_##fs); \ | |
996 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
997 | break; \ | |
998 | \ | |
999 | default: \ | |
1000 | abort(); \ | |
1001 | } \ | |
1002 | \ | |
1003 | /* T = X * Y is zero, infinity or NaN. */ \ | |
1004 | switch (_FP_CLS_COMBINE(T##_c, Z##_c)) \ | |
1005 | { \ | |
1006 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ | |
1007 | _FP_CHOOSENAN(fs, wc, R, T, Z, '+'); \ | |
1008 | break; \ | |
1009 | \ | |
1010 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ | |
1011 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ | |
1012 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ | |
1013 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ | |
1014 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ | |
1015 | R##_s = T##_s; \ | |
1016 | _FP_FRAC_COPY_##wc(R, T); \ | |
1017 | R##_c = T##_c; \ | |
1018 | break; \ | |
1019 | \ | |
1020 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ | |
1021 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ | |
1022 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ | |
1023 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ | |
1024 | R##_s = Z##_s; \ | |
1025 | _FP_FRAC_COPY_##wc(R, Z); \ | |
1026 | R##_c = Z##_c; \ | |
1027 | break; \ | |
1028 | \ | |
1029 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ | |
1030 | if (T##_s == Z##_s) \ | |
1031 | { \ | |
1032 | R##_s = Z##_s; \ | |
1033 | _FP_FRAC_COPY_##wc(R, Z); \ | |
1034 | R##_c = Z##_c; \ | |
1035 | } \ | |
1036 | else \ | |
1037 | { \ | |
1038 | R##_s = _FP_NANSIGN_##fs; \ | |
1039 | R##_c = FP_CLS_NAN; \ | |
1040 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
1041 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
1042 | } \ | |
1043 | break; \ | |
1044 | \ | |
1045 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ | |
1046 | if (T##_s == Z##_s) \ | |
1047 | R##_s = Z##_s; \ | |
1048 | else \ | |
1049 | R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ | |
1050 | _FP_FRAC_COPY_##wc(R, Z); \ | |
1051 | R##_c = Z##_c; \ | |
1052 | break; \ | |
1053 | \ | |
1054 | default: \ | |
1055 | abort(); \ | |
1056 | } \ | |
1057 | done_fma: ; \ | |
d876f532 UD |
1058 | } while (0) |
1059 | ||
1060 | ||
1061 | /* | |
1062 | * Main division routine. The input values should be cooked. | |
1063 | */ | |
1064 | ||
1065 | #define _FP_DIV(fs, wc, R, X, Y) \ | |
1066 | do { \ | |
1067 | R##_s = X##_s ^ Y##_s; \ | |
573cd484 | 1068 | R##_e = X##_e - Y##_e; \ |
d876f532 UD |
1069 | switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ |
1070 | { \ | |
1071 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ | |
1072 | R##_c = FP_CLS_NORMAL; \ | |
d876f532 UD |
1073 | \ |
1074 | _FP_DIV_MEAT_##fs(R,X,Y); \ | |
1075 | break; \ | |
1076 | \ | |
1077 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ | |
1078 | _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ | |
1079 | break; \ | |
1080 | \ | |
1081 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ | |
1082 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ | |
1083 | case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ | |
1084 | R##_s = X##_s; \ | |
1085 | _FP_FRAC_COPY_##wc(R, X); \ | |
1086 | R##_c = X##_c; \ | |
1087 | break; \ | |
1088 | \ | |
1089 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ | |
1090 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ | |
1091 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ | |
1092 | R##_s = Y##_s; \ | |
1093 | _FP_FRAC_COPY_##wc(R, Y); \ | |
1094 | R##_c = Y##_c; \ | |
1095 | break; \ | |
1096 | \ | |
1097 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ | |
1098 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ | |
1099 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ | |
1100 | R##_c = FP_CLS_ZERO; \ | |
1101 | break; \ | |
1102 | \ | |
1103 | case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ | |
1104 | FP_SET_EXCEPTION(FP_EX_DIVZERO); \ | |
1105 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ | |
1106 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ | |
1107 | R##_c = FP_CLS_INF; \ | |
1108 | break; \ | |
1109 | \ | |
1110 | case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ | |
1111 | case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ | |
1112 | R##_s = _FP_NANSIGN_##fs; \ | |
1113 | R##_c = FP_CLS_NAN; \ | |
1114 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
1115 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
1116 | break; \ | |
1117 | \ | |
1118 | default: \ | |
1119 | abort(); \ | |
1120 | } \ | |
1121 | } while (0) | |
1122 | ||
1123 | ||
1124 | /* | |
1125 | * Main differential comparison routine. The inputs should be raw not | |
1126 | * cooked. The return is -1,0,1 for normal values, 2 otherwise. | |
1127 | */ | |
1128 | ||
1129 | #define _FP_CMP(fs, wc, ret, X, Y, un) \ | |
1130 | do { \ | |
1131 | /* NANs are unordered */ \ | |
1132 | if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ | |
1133 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ | |
1134 | { \ | |
1135 | ret = un; \ | |
1136 | } \ | |
1137 | else \ | |
1138 | { \ | |
1139 | int __is_zero_x; \ | |
1140 | int __is_zero_y; \ | |
1141 | \ | |
1142 | __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ | |
1143 | __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ | |
1144 | \ | |
1145 | if (__is_zero_x && __is_zero_y) \ | |
1146 | ret = 0; \ | |
1147 | else if (__is_zero_x) \ | |
1148 | ret = Y##_s ? 1 : -1; \ | |
1149 | else if (__is_zero_y) \ | |
1150 | ret = X##_s ? -1 : 1; \ | |
1151 | else if (X##_s != Y##_s) \ | |
1152 | ret = X##_s ? -1 : 1; \ | |
1153 | else if (X##_e > Y##_e) \ | |
1154 | ret = X##_s ? -1 : 1; \ | |
1155 | else if (X##_e < Y##_e) \ | |
1156 | ret = X##_s ? 1 : -1; \ | |
1157 | else if (_FP_FRAC_GT_##wc(X, Y)) \ | |
1158 | ret = X##_s ? -1 : 1; \ | |
1159 | else if (_FP_FRAC_GT_##wc(Y, X)) \ | |
1160 | ret = X##_s ? 1 : -1; \ | |
1161 | else \ | |
1162 | ret = 0; \ | |
1163 | } \ | |
1164 | } while (0) | |
1165 | ||
1166 | ||
1167 | /* Simplification for strict equality. */ | |
1168 | ||
fe0b1e85 RM |
1169 | #define _FP_CMP_EQ(fs, wc, ret, X, Y) \ |
1170 | do { \ | |
1171 | /* NANs are unordered */ \ | |
1172 | if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ | |
1173 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ | |
1174 | { \ | |
1175 | ret = 1; \ | |
1176 | } \ | |
1177 | else \ | |
1178 | { \ | |
1179 | ret = !(X##_e == Y##_e \ | |
1180 | && _FP_FRAC_EQ_##wc(X, Y) \ | |
1181 | && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ | |
1182 | } \ | |
d876f532 UD |
1183 | } while (0) |
1184 | ||
e7b8c7bc RM |
1185 | /* Version to test unordered. */ |
1186 | ||
1187 | #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ | |
1188 | do { \ | |
1189 | ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ | |
1190 | || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ | |
1191 | } while (0) | |
1192 | ||
d876f532 UD |
1193 | /* |
1194 | * Main square root routine. The input value should be cooked. | |
1195 | */ | |
1196 | ||
1197 | #define _FP_SQRT(fs, wc, R, X) \ | |
1198 | do { \ | |
1199 | _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ | |
1200 | _FP_W_TYPE q; \ | |
1201 | switch (X##_c) \ | |
1202 | { \ | |
1203 | case FP_CLS_NAN: \ | |
1204 | _FP_FRAC_COPY_##wc(R, X); \ | |
1205 | R##_s = X##_s; \ | |
350635a5 OB |
1206 | R##_c = FP_CLS_NAN; \ |
1207 | break; \ | |
d876f532 | 1208 | case FP_CLS_INF: \ |
350635a5 OB |
1209 | if (X##_s) \ |
1210 | { \ | |
1211 | R##_s = _FP_NANSIGN_##fs; \ | |
d876f532 UD |
1212 | R##_c = FP_CLS_NAN; /* NAN */ \ |
1213 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
1214 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
350635a5 OB |
1215 | } \ |
1216 | else \ | |
1217 | { \ | |
1218 | R##_s = 0; \ | |
1219 | R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ | |
1220 | } \ | |
1221 | break; \ | |
d876f532 UD |
1222 | case FP_CLS_ZERO: \ |
1223 | R##_s = X##_s; \ | |
1224 | R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ | |
1225 | break; \ | |
1226 | case FP_CLS_NORMAL: \ | |
350635a5 | 1227 | R##_s = 0; \ |
d876f532 UD |
1228 | if (X##_s) \ |
1229 | { \ | |
93fd48c5 | 1230 | R##_c = FP_CLS_NAN; /* NAN */ \ |
d876f532 UD |
1231 | R##_s = _FP_NANSIGN_##fs; \ |
1232 | _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ | |
1233 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
1234 | break; \ | |
1235 | } \ | |
350635a5 | 1236 | R##_c = FP_CLS_NORMAL; \ |
d876f532 UD |
1237 | if (X##_e & 1) \ |
1238 | _FP_FRAC_SLL_##wc(X, 1); \ | |
1239 | R##_e = X##_e >> 1; \ | |
1240 | _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ | |
1241 | _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ | |
1242 | q = _FP_OVERFLOW_##fs >> 1; \ | |
1243 | _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ | |
1244 | } \ | |
1245 | } while (0) | |
1246 | ||
1247 | /* | |
fe0b1e85 | 1248 | * Convert from FP to integer. Input is raw. |
d876f532 UD |
1249 | */ |
1250 | ||
1251 | /* RSIGNED can have following values: | |
1252 | * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus | |
fe0b1e85 RM |
1253 | * the result is either 0 or (2^rsize)-1 depending on the sign in such |
1254 | * case. | |
1255 | * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, | |
1256 | * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 | |
1257 | * depending on the sign in such case. | |
d876f532 | 1258 | * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is |
fe0b1e85 RM |
1259 | * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 |
1260 | * depending on the sign in such case. | |
d876f532 | 1261 | */ |
fe0b1e85 RM |
1262 | #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ |
1263 | do { \ | |
1264 | if (X##_e < _FP_EXPBIAS_##fs) \ | |
1265 | { \ | |
1266 | r = 0; \ | |
1267 | if (X##_e == 0) \ | |
1268 | { \ | |
1269 | if (!_FP_FRAC_ZEROP_##wc(X)) \ | |
1270 | { \ | |
1271 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
1272 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
1273 | } \ | |
1274 | } \ | |
1275 | else \ | |
1276 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
1277 | } \ | |
1278 | else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ | |
1279 | || (!rsigned && X##_s)) \ | |
1280 | { \ | |
1281 | /* Overflow or converting to the most negative integer. */ \ | |
1282 | if (rsigned) \ | |
1283 | { \ | |
1284 | r = 1; \ | |
1285 | r <<= rsize - 1; \ | |
1286 | r -= 1 - X##_s; \ | |
1287 | } else { \ | |
1288 | r = 0; \ | |
1289 | if (X##_s) \ | |
1290 | r = ~r; \ | |
1291 | } \ | |
a334319f | 1292 | \ |
fe0b1e85 RM |
1293 | if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ |
1294 | { \ | |
1295 | /* Possibly converting to most negative integer; check the \ | |
1296 | mantissa. */ \ | |
1297 | int inexact = 0; \ | |
1298 | (void)((_FP_FRACBITS_##fs > rsize) \ | |
1299 | ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ | |
1300 | _FP_FRACBITS_##fs - rsize, \ | |
1301 | _FP_FRACBITS_##fs); 0; }) \ | |
1302 | : 0); \ | |
1303 | if (!_FP_FRAC_ZEROP_##wc(X)) \ | |
1304 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
1305 | else if (inexact) \ | |
1306 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
1307 | } \ | |
1308 | else \ | |
1309 | FP_SET_EXCEPTION(FP_EX_INVALID); \ | |
1310 | } \ | |
1311 | else \ | |
1312 | { \ | |
1313 | _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ | |
1314 | if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ | |
1315 | { \ | |
1316 | _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ | |
1317 | r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ | |
1318 | } \ | |
1319 | else \ | |
1320 | { \ | |
1321 | int inexact; \ | |
1322 | _FP_FRAC_SRST_##wc(X, inexact, \ | |
1323 | (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ | |
1324 | - X##_e), \ | |
1325 | _FP_FRACBITS_##fs); \ | |
1326 | if (inexact) \ | |
1327 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
1328 | _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ | |
1329 | } \ | |
1330 | if (rsigned && X##_s) \ | |
1331 | r = -r; \ | |
1332 | } \ | |
1333 | } while (0) | |
1334 | ||
1335 | /* Convert integer to fp. Output is raw. RTYPE is unsigned even if | |
1336 | input is signed. */ | |
1337 | #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ | |
1338 | do { \ | |
1339 | if (r) \ | |
1340 | { \ | |
1341 | rtype ur_; \ | |
1342 | \ | |
1343 | if ((X##_s = (r < 0))) \ | |
1344 | r = -(rtype)r; \ | |
1345 | \ | |
1346 | ur_ = (rtype) r; \ | |
1347 | (void)((rsize <= _FP_W_TYPE_SIZE) \ | |
1348 | ? ({ \ | |
1349 | int lz_; \ | |
1350 | __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ | |
1351 | X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ | |
1352 | }) \ | |
1353 | : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ | |
1354 | ? ({ \ | |
1355 | int lz_; \ | |
1356 | __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ | |
1357 | (_FP_W_TYPE)ur_); \ | |
1358 | X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ | |
1359 | - lz_); \ | |
1360 | }) \ | |
1361 | : (abort(), 0))); \ | |
1362 | \ | |
1363 | if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ | |
1364 | && X##_e >= _FP_EXPMAX_##fs) \ | |
1365 | { \ | |
1366 | /* Exponent too big; overflow to infinity. (May also \ | |
1367 | happen after rounding below.) */ \ | |
1368 | _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ | |
1369 | goto pack_semiraw; \ | |
1370 | } \ | |
1371 | \ | |
1372 | if (rsize <= _FP_FRACBITS_##fs \ | |
1373 | || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ | |
1374 | { \ | |
1375 | /* Exactly representable; shift left. */ \ | |
1376 | _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ | |
8fdda7af JM |
1377 | if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ |
1378 | _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ | |
1379 | + _FP_FRACBITS_##fs - 1 - X##_e)); \ | |
fe0b1e85 RM |
1380 | } \ |
1381 | else \ | |
1382 | { \ | |
1383 | /* More bits in integer than in floating type; need to \ | |
1384 | round. */ \ | |
1385 | if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ | |
1386 | ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ | |
1387 | - _FP_WFRACBITS_##fs + 1)) \ | |
1388 | | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ | |
1389 | - _FP_WFRACBITS_##fs + 1))) \ | |
1390 | != 0)); \ | |
1391 | _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ | |
1392 | if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ | |
1393 | _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ | |
1394 | + _FP_WFRACBITS_##fs - 1 - X##_e)); \ | |
1395 | _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ | |
1396 | pack_semiraw: \ | |
1397 | _FP_PACK_SEMIRAW(fs, wc, X); \ | |
1398 | } \ | |
1399 | } \ | |
1400 | else \ | |
1401 | { \ | |
1402 | X##_s = 0; \ | |
1403 | X##_e = 0; \ | |
1404 | _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ | |
1405 | } \ | |
a334319f | 1406 | } while (0) |
d876f532 | 1407 | |
0ecb606c | 1408 | |
fe0b1e85 RM |
1409 | /* Extend from a narrower floating-point format to a wider one. Input |
1410 | and output are raw. */ | |
1411 | #define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ | |
1412 | do { \ | |
1413 | if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ | |
1414 | || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ | |
1415 | < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ | |
37002cbc JJ |
1416 | || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ |
1417 | && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ | |
fe0b1e85 RM |
1418 | abort(); \ |
1419 | D##_s = S##_s; \ | |
1420 | _FP_FRAC_COPY_##dwc##_##swc(D, S); \ | |
1421 | if (_FP_EXP_NORMAL(sfs, swc, S)) \ | |
1422 | { \ | |
1423 | D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ | |
1424 | _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ | |
1425 | } \ | |
1426 | else \ | |
1427 | { \ | |
1428 | if (S##_e == 0) \ | |
1429 | { \ | |
1430 | if (_FP_FRAC_ZEROP_##swc(S)) \ | |
1431 | D##_e = 0; \ | |
37002cbc JJ |
1432 | else if (_FP_EXPBIAS_##dfs \ |
1433 | < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ | |
1434 | { \ | |
1435 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
1436 | _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ | |
1437 | - _FP_FRACBITS_##sfs)); \ | |
1438 | D##_e = 0; \ | |
1439 | } \ | |
fe0b1e85 RM |
1440 | else \ |
1441 | { \ | |
1442 | int _lz; \ | |
1443 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
1444 | _FP_FRAC_CLZ_##swc(_lz, S); \ | |
1445 | _FP_FRAC_SLL_##dwc(D, \ | |
1446 | _lz + _FP_FRACBITS_##dfs \ | |
1447 | - _FP_FRACTBITS_##sfs); \ | |
1448 | D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ | |
1449 | + _FP_FRACXBITS_##sfs - _lz); \ | |
1450 | } \ | |
1451 | } \ | |
1452 | else \ | |
1453 | { \ | |
1454 | D##_e = _FP_EXPMAX_##dfs; \ | |
1455 | if (!_FP_FRAC_ZEROP_##swc(S)) \ | |
1456 | { \ | |
2848b105 | 1457 | if (_FP_FRAC_SNANP(sfs, S)) \ |
fe0b1e85 RM |
1458 | FP_SET_EXCEPTION(FP_EX_INVALID); \ |
1459 | _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ | |
1460 | - _FP_FRACBITS_##sfs)); \ | |
1461 | } \ | |
1462 | } \ | |
1463 | } \ | |
1464 | } while (0) | |
1465 | ||
1466 | /* Truncate from a wider floating-point format to a narrower one. | |
1467 | Input and output are semi-raw. */ | |
1468 | #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ | |
1469 | do { \ | |
1470 | if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ | |
37002cbc JJ |
1471 | || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ |
1472 | && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ | |
fe0b1e85 RM |
1473 | abort(); \ |
1474 | D##_s = S##_s; \ | |
1475 | if (_FP_EXP_NORMAL(sfs, swc, S)) \ | |
1476 | { \ | |
1477 | D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ | |
1478 | if (D##_e >= _FP_EXPMAX_##dfs) \ | |
1479 | _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ | |
1480 | else \ | |
1481 | { \ | |
1482 | if (D##_e <= 0) \ | |
1483 | { \ | |
002f0b0b JJ |
1484 | if (D##_e < 1 - _FP_FRACBITS_##dfs) \ |
1485 | { \ | |
1486 | _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ | |
1487 | _FP_FRAC_LOW_##swc(S) |= 1; \ | |
1488 | } \ | |
fe0b1e85 RM |
1489 | else \ |
1490 | { \ | |
1491 | _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ | |
1492 | _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ | |
1493 | - _FP_WFRACBITS_##dfs + 1 - D##_e), \ | |
1494 | _FP_WFRACBITS_##sfs); \ | |
1495 | } \ | |
1496 | D##_e = 0; \ | |
1497 | } \ | |
1498 | else \ | |
1499 | _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ | |
1500 | - _FP_WFRACBITS_##dfs), \ | |
1501 | _FP_WFRACBITS_##sfs); \ | |
1502 | _FP_FRAC_COPY_##dwc##_##swc(D, S); \ | |
1503 | } \ | |
1504 | } \ | |
1505 | else \ | |
1506 | { \ | |
1507 | if (S##_e == 0) \ | |
1508 | { \ | |
1509 | D##_e = 0; \ | |
37002cbc JJ |
1510 | if (_FP_FRAC_ZEROP_##swc(S)) \ |
1511 | _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ | |
1512 | else \ | |
fe0b1e85 RM |
1513 | { \ |
1514 | FP_SET_EXCEPTION(FP_EX_DENORM); \ | |
37002cbc JJ |
1515 | if (_FP_EXPBIAS_##sfs \ |
1516 | < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ | |
1517 | { \ | |
1518 | _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ | |
1519 | - _FP_WFRACBITS_##dfs), \ | |
1520 | _FP_WFRACBITS_##sfs); \ | |
1521 | _FP_FRAC_COPY_##dwc##_##swc(D, S); \ | |
1522 | } \ | |
1523 | else \ | |
1524 | { \ | |
1525 | _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ | |
1526 | _FP_FRAC_LOW_##dwc(D) |= 1; \ | |
1527 | } \ | |
fe0b1e85 RM |
1528 | } \ |
1529 | } \ | |
1530 | else \ | |
1531 | { \ | |
1532 | D##_e = _FP_EXPMAX_##dfs; \ | |
1533 | if (_FP_FRAC_ZEROP_##swc(S)) \ | |
1534 | _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ | |
1535 | else \ | |
1536 | { \ | |
1537 | _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ | |
1538 | _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ | |
1539 | - _FP_WFRACBITS_##dfs)); \ | |
1540 | _FP_FRAC_COPY_##dwc##_##swc(D, S); \ | |
d68f5d2c JJ |
1541 | /* Semi-raw NaN must have all workbits cleared. */ \ |
1542 | _FP_FRAC_LOW_##dwc(D) \ | |
1543 | &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ | |
2848b105 | 1544 | _FP_SETQNAN_SEMIRAW(dfs, dwc, D); \ |
fe0b1e85 RM |
1545 | } \ |
1546 | } \ | |
1547 | } \ | |
1548 | } while (0) | |
d876f532 UD |
1549 | |
1550 | /* | |
1551 | * Helper primitives. | |
1552 | */ | |
1553 | ||
1554 | /* Count leading zeros in a word. */ | |
1555 | ||
1556 | #ifndef __FP_CLZ | |
0d86378f RM |
1557 | /* GCC 3.4 and later provide the builtins for us. */ |
1558 | #define __FP_CLZ(r, x) \ | |
1559 | do { \ | |
1560 | if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ | |
1561 | r = __builtin_clz (x); \ | |
1562 | else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ | |
1563 | r = __builtin_clzl (x); \ | |
1564 | else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ | |
1565 | r = __builtin_clzll (x); \ | |
1566 | else \ | |
1567 | abort (); \ | |
d876f532 | 1568 | } while (0) |
d876f532 UD |
1569 | #endif /* ndef __FP_CLZ */ |
1570 | ||
1571 | #define _FP_DIV_HELP_imm(q, r, n, d) \ | |
1572 | do { \ | |
1573 | q = n / d, r = n % d; \ | |
1574 | } while (0) | |
1575 | ||
1a8aaf91 UD |
1576 | |
1577 | /* A restoring bit-by-bit division primitive. */ | |
1578 | ||
1579 | #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ | |
1580 | do { \ | |
1581 | int count = _FP_WFRACBITS_##fs; \ | |
1582 | _FP_FRAC_DECL_##wc (u); \ | |
1583 | _FP_FRAC_DECL_##wc (v); \ | |
1584 | _FP_FRAC_COPY_##wc (u, X); \ | |
1585 | _FP_FRAC_COPY_##wc (v, Y); \ | |
1586 | _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ | |
1587 | /* Normalize U and V. */ \ | |
1588 | _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ | |
1589 | _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ | |
1590 | /* First round. Since the operands are normalized, either the \ | |
1591 | first or second bit will be set in the fraction. Produce a \ | |
1592 | normalized result by checking which and adjusting the loop \ | |
1593 | count and exponent accordingly. */ \ | |
1594 | if (_FP_FRAC_GE_1 (u, v)) \ | |
1595 | { \ | |
1596 | _FP_FRAC_SUB_##wc (u, u, v); \ | |
1597 | _FP_FRAC_LOW_##wc (R) |= 1; \ | |
1598 | count--; \ | |
1599 | } \ | |
1600 | else \ | |
1601 | R##_e--; \ | |
1602 | /* Subsequent rounds. */ \ | |
1603 | do { \ | |
1604 | int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ | |
1605 | _FP_FRAC_SLL_##wc (u, 1); \ | |
1606 | _FP_FRAC_SLL_##wc (R, 1); \ | |
1607 | if (msb || _FP_FRAC_GE_1 (u, v)) \ | |
1608 | { \ | |
1609 | _FP_FRAC_SUB_##wc (u, u, v); \ | |
1610 | _FP_FRAC_LOW_##wc (R) |= 1; \ | |
1611 | } \ | |
1612 | } while (--count > 0); \ | |
1613 | /* If there's anything left in U, the result is inexact. */ \ | |
1614 | _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ | |
1615 | } while (0) | |
1616 | ||
1617 | #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) | |
1618 | #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) | |
1619 | #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y) |