Update Changelog and NEWS
[glibc.git] / soft-fp / op-common.h
blobbed1e21fd4d14d95ab0727d168d275042c4ae6c4
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997-2013 Free Software Foundation, Inc.
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).
9 The GNU C Library is free software; you can redistribute it and/or
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.
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.)
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
26 Lesser General Public License for more details.
28 You should have received a copy of the GNU Lesser General Public
29 License along with the GNU C Library; if not, see
30 <http://www.gnu.org/licenses/>. */
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; \
36 _FP_FRAC_DECL_##wc(X)
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))
49 * Finish truely unpacking a native fp value by classifying the kind
50 * of fp value and normalizing both the exponent and the fraction.
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; \
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; \
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 */ \
87 if (_FP_FRAC_SNANP(fs, X)) \
88 FP_SET_EXCEPTION(FP_EX_INVALID); \
89 } \
90 break; \
91 } \
92 } while (0)
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)
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)) \
107 X##_e = _FP_EXPMAX_##fs; \
108 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
110 else \
112 X##_e = _FP_EXPMAX_##fs - 1; \
113 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
115 FP_SET_EXCEPTION(FP_EX_INEXACT); \
116 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
117 } while (0)
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) \
125 && _FP_FRAC_SNANP_SEMIRAW(fs, X)) \
126 FP_SET_EXCEPTION(FP_EX_INVALID); \
127 } while (0)
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)
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) \
147 _FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \
148 if (_FP_FRAC_ZEROP_##wc(X)) \
150 X##_s = _FP_NANSIGN_##fs; \
151 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
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) \
161 _FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \
162 if (_FP_FRAC_ZEROP_##wc(X)) \
164 X##_s = _FP_NANSIGN_##fs; \
165 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
166 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
169 else \
170 _FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \
171 } while (0)
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)
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); \
182 if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \
184 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
185 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
186 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
188 if (_FP_FRAC_HIGH_##fs(X) \
189 & (_FP_OVERFLOW_##fs >> 1)) \
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); \
196 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
197 if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
199 if (!_FP_KEEPNANFRACP) \
201 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
202 X##_s = _FP_NANSIGN_##fs; \
204 else \
205 _FP_SETQNAN(fs, wc, X); \
207 } while (0)
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.
216 #define _FP_PACK_CANONICAL(fs, wc, X) \
217 do { \
218 switch (X##_c) \
220 case FP_CLS_NORMAL: \
221 X##_e += _FP_EXPBIAS_##fs; \
222 if (X##_e > 0) \
224 _FP_ROUND(wc, X); \
225 if (_FP_FRAC_OVERP_##wc(fs, X)) \
227 _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
228 X##_e++; \
230 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
231 if (X##_e >= _FP_EXPMAX_##fs) \
233 /* overflow */ \
234 switch (FP_ROUNDMODE) \
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; \
246 if (X##_c == FP_CLS_INF) \
248 /* Overflow to infinity */ \
249 X##_e = _FP_EXPMAX_##fs; \
250 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
252 else \
254 /* Overflow to maximum normal */ \
255 X##_e = _FP_EXPMAX_##fs - 1; \
256 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
258 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
259 FP_SET_EXCEPTION(FP_EX_INEXACT); \
262 else \
264 /* we've got a denormalized number */ \
265 X##_e = -X##_e + 1; \
266 if (X##_e <= _FP_WFRACBITS_##fs) \
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)) \
273 X##_e = 1; \
274 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
275 FP_SET_EXCEPTION(FP_EX_INEXACT); \
277 else \
279 X##_e = 0; \
280 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
282 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
283 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
284 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
286 else \
288 /* underflow to zero */ \
289 X##_e = 0; \
290 if (!_FP_FRAC_ZEROP_##wc(X)) \
292 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
293 _FP_ROUND(wc, X); \
294 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
296 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
299 break; \
301 case FP_CLS_ZERO: \
302 X##_e = 0; \
303 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
304 break; \
306 case FP_CLS_INF: \
307 X##_e = _FP_EXPMAX_##fs; \
308 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
309 break; \
311 case FP_CLS_NAN: \
312 X##_e = _FP_EXPMAX_##fs; \
313 if (!_FP_KEEPNANFRACP) \
315 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
316 X##_s = _FP_NANSIGN_##fs; \
318 else \
319 _FP_SETQNAN(fs, wc, X); \
320 break; \
322 } while (0)
324 /* This one accepts raw argument and not cooked, returns
325 * 1 if X is a signaling NaN.
327 #define _FP_ISSIGNAN(fs, wc, X) \
328 ({ \
329 int __ret = 0; \
330 if (X##_e == _FP_EXPMAX_##fs) \
332 if (!_FP_FRAC_ZEROP_##wc(X) \
333 && _FP_FRAC_SNANP(fs, X)) \
334 __ret = 1; \
336 __ret; \
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) \
348 /* Addition. */ \
349 R##_s = X##_s; \
350 int ediff = X##_e - Y##_e; \
351 if (ediff > 0) \
353 R##_e = X##_e; \
354 if (Y##_e == 0) \
356 /* Y is zero or denormalized. */ \
357 if (_FP_FRAC_ZEROP_##wc(Y)) \
359 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
360 _FP_FRAC_COPY_##wc(R, X); \
361 goto add_done; \
363 else \
365 FP_SET_EXCEPTION(FP_EX_DENORM); \
366 ediff--; \
367 if (ediff == 0) \
369 _FP_FRAC_ADD_##wc(R, X, Y); \
370 goto add3; \
372 if (X##_e == _FP_EXPMAX_##fs) \
374 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
375 _FP_FRAC_COPY_##wc(R, X); \
376 goto add_done; \
378 goto add1; \
381 else if (X##_e == _FP_EXPMAX_##fs) \
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; \
389 /* Insert implicit MSB of Y. */ \
390 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
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); \
401 else if (ediff < 0) \
403 ediff = -ediff; \
404 R##_e = Y##_e; \
405 if (X##_e == 0) \
407 /* X is zero or denormalized. */ \
408 if (_FP_FRAC_ZEROP_##wc(X)) \
410 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
411 _FP_FRAC_COPY_##wc(R, Y); \
412 goto add_done; \
414 else \
416 FP_SET_EXCEPTION(FP_EX_DENORM); \
417 ediff--; \
418 if (ediff == 0) \
420 _FP_FRAC_ADD_##wc(R, Y, X); \
421 goto add3; \
423 if (Y##_e == _FP_EXPMAX_##fs) \
425 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
426 _FP_FRAC_COPY_##wc(R, Y); \
427 goto add_done; \
429 goto add2; \
432 else if (Y##_e == _FP_EXPMAX_##fs) \
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; \
440 /* Insert implicit MSB of X. */ \
441 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
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); \
452 else \
454 /* ediff == 0. */ \
455 if (!_FP_EXP_NORMAL(fs, wc, X)) \
457 if (X##_e == 0) \
459 /* X and Y are zero or denormalized. */ \
460 R##_e = 0; \
461 if (_FP_FRAC_ZEROP_##wc(X)) \
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; \
468 else if (_FP_FRAC_ZEROP_##wc(Y)) \
470 FP_SET_EXCEPTION(FP_EX_DENORM); \
471 _FP_FRAC_COPY_##wc(R, X); \
472 goto add_done; \
474 else \
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) \
480 /* Normalized result. */ \
481 _FP_FRAC_HIGH_##fs(R) \
482 &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
483 R##_e = 1; \
485 goto add_done; \
488 else \
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; \
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; \
514 add3: \
515 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
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); \
525 add_done: ; \
527 else \
529 /* Subtraction. */ \
530 int ediff = X##_e - Y##_e; \
531 if (ediff > 0) \
533 R##_e = X##_e; \
534 R##_s = X##_s; \
535 if (Y##_e == 0) \
537 /* Y is zero or denormalized. */ \
538 if (_FP_FRAC_ZEROP_##wc(Y)) \
540 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
541 _FP_FRAC_COPY_##wc(R, X); \
542 goto sub_done; \
544 else \
546 FP_SET_EXCEPTION(FP_EX_DENORM); \
547 ediff--; \
548 if (ediff == 0) \
550 _FP_FRAC_SUB_##wc(R, X, Y); \
551 goto sub3; \
553 if (X##_e == _FP_EXPMAX_##fs) \
555 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
556 _FP_FRAC_COPY_##wc(R, X); \
557 goto sub_done; \
559 goto sub1; \
562 else if (X##_e == _FP_EXPMAX_##fs) \
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; \
570 /* Insert implicit MSB of Y. */ \
571 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
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); \
582 else if (ediff < 0) \
584 ediff = -ediff; \
585 R##_e = Y##_e; \
586 R##_s = Y##_s; \
587 if (X##_e == 0) \
589 /* X is zero or denormalized. */ \
590 if (_FP_FRAC_ZEROP_##wc(X)) \
592 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
593 _FP_FRAC_COPY_##wc(R, Y); \
594 goto sub_done; \
596 else \
598 FP_SET_EXCEPTION(FP_EX_DENORM); \
599 ediff--; \
600 if (ediff == 0) \
602 _FP_FRAC_SUB_##wc(R, Y, X); \
603 goto sub3; \
605 if (Y##_e == _FP_EXPMAX_##fs) \
607 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
608 _FP_FRAC_COPY_##wc(R, Y); \
609 goto sub_done; \
611 goto sub2; \
614 else if (Y##_e == _FP_EXPMAX_##fs) \
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; \
622 /* Insert implicit MSB of X. */ \
623 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
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); \
634 else \
636 /* ediff == 0. */ \
637 if (!_FP_EXP_NORMAL(fs, wc, X)) \
639 if (X##_e == 0) \
641 /* X and Y are zero or denormalized. */ \
642 R##_e = 0; \
643 if (_FP_FRAC_ZEROP_##wc(X)) \
645 _FP_FRAC_COPY_##wc(R, Y); \
646 if (_FP_FRAC_ZEROP_##wc(Y)) \
647 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
648 else \
650 FP_SET_EXCEPTION(FP_EX_DENORM); \
651 R##_s = Y##_s; \
653 goto sub_done; \
655 else if (_FP_FRAC_ZEROP_##wc(Y)) \
657 FP_SET_EXCEPTION(FP_EX_DENORM); \
658 _FP_FRAC_COPY_##wc(R, X); \
659 R##_s = X##_s; \
660 goto sub_done; \
662 else \
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) \
669 /* |X| < |Y|, negate result. */ \
670 _FP_FRAC_SUB_##wc(R, Y, X); \
671 R##_s = Y##_s; \
673 else if (_FP_FRAC_ZEROP_##wc(R)) \
674 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
675 goto sub_done; \
678 else \
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)) \
686 if (_FP_FRAC_ZEROP_##wc(Y)) \
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); \
694 else \
696 /* Inf - NaN. */ \
697 R##_s = Y##_s; \
698 _FP_FRAC_COPY_##wc(R, Y); \
701 else \
703 if (_FP_FRAC_ZEROP_##wc(Y)) \
705 /* NaN - Inf. */ \
706 R##_s = X##_s; \
707 _FP_FRAC_COPY_##wc(R, X); \
709 else \
711 /* NaN - NaN. */ \
712 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
715 goto sub_done; \
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) \
725 /* |X| < |Y|, negate result. */ \
726 _FP_FRAC_SUB_##wc(R, Y, X); \
727 R##_s = Y##_s; \
729 else if (_FP_FRAC_ZEROP_##wc(R)) \
731 R##_e = 0; \
732 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
733 goto sub_done; \
735 goto norm; \
737 sub3: \
738 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
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) \
750 /* R is denormalized. */ \
751 diff = diff - R##_e + 1; \
752 _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
753 R##_e = 0; \
755 else \
757 R##_e -= diff; \
758 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
761 sub_done: ; \
763 } while (0)
765 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
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, '-'); \
770 } while (0)
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.
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)
788 * Main multiplication routine. The input values should be cooked.
791 #define _FP_MUL(fs, wc, R, X, Y) \
792 do { \
793 R##_s = X##_s ^ Y##_s; \
794 R##_e = X##_e + Y##_e + 1; \
795 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
797 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
798 R##_c = FP_CLS_NORMAL; \
800 _FP_MUL_MEAT_##fs(R,X,Y); \
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; \
808 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
809 _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
810 break; \
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; \
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; \
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; \
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; \
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; \
844 default: \
845 abort(); \
847 } while (0)
850 /* Fused multiply-add. The input values should be cooked. */
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)) \
859 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
860 switch (Z##_c) \
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; \
869 case FP_CLS_ZERO: \
870 R##_c = FP_CLS_NORMAL; \
871 R##_s = T##_s; \
872 R##_e = T##_e; \
874 _FP_MUL_MEAT_##fs(R, X, Y); \
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; \
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) \
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 \
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); \
905 R##_s = T##_s; \
906 if (T##_s == Z##_s) \
907 _FP_FRAC_ADD_##dwc(RD, TD, ZD); \
908 else \
910 _FP_FRAC_SUB_##dwc(RD, TD, ZD); \
911 if (_FP_FRAC_NEGP_##dwc(RD)) \
913 R##_s = Z##_s; \
914 _FP_FRAC_SUB_##dwc(RD, ZD, TD); \
918 else \
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); \
935 if (_FP_FRAC_ZEROP_##dwc(RD)) \
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; \
944 else \
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; \
959 break; \
961 goto done_fma; \
963 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
964 _FP_CHOOSENAN(fs, wc, T, X, Y, '*'); \
965 break; \
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; \
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; \
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; \
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; \
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; \
999 default: \
1000 abort(); \
1003 /* T = X * Y is zero, infinity or NaN. */ \
1004 switch (_FP_CLS_COMBINE(T##_c, Z##_c)) \
1006 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
1007 _FP_CHOOSENAN(fs, wc, R, T, Z, '+'); \
1008 break; \
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; \
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; \
1029 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
1030 if (T##_s == Z##_s) \
1032 R##_s = Z##_s; \
1033 _FP_FRAC_COPY_##wc(R, Z); \
1034 R##_c = Z##_c; \
1036 else \
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); \
1043 break; \
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; \
1054 default: \
1055 abort(); \
1057 done_fma: ; \
1058 } while (0)
1062 * Main division routine. The input values should be cooked.
1065 #define _FP_DIV(fs, wc, R, X, Y) \
1066 do { \
1067 R##_s = X##_s ^ Y##_s; \
1068 R##_e = X##_e - Y##_e; \
1069 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
1071 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
1072 R##_c = FP_CLS_NORMAL; \
1074 _FP_DIV_MEAT_##fs(R,X,Y); \
1075 break; \
1077 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
1078 _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
1079 break; \
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; \
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; \
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; \
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; \
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; \
1118 default: \
1119 abort(); \
1121 } while (0)
1125 * Main differential comparison routine. The inputs should be raw not
1126 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
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))) \
1135 ret = un; \
1137 else \
1139 int __is_zero_x; \
1140 int __is_zero_y; \
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; \
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; \
1164 } while (0)
1167 /* Simplification for strict equality. */
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))) \
1175 ret = 1; \
1177 else \
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)))); \
1183 } while (0)
1185 /* Version to test unordered. */
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)
1194 * Main square root routine. The input value should be cooked.
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) \
1203 case FP_CLS_NAN: \
1204 _FP_FRAC_COPY_##wc(R, X); \
1205 R##_s = X##_s; \
1206 R##_c = FP_CLS_NAN; \
1207 break; \
1208 case FP_CLS_INF: \
1209 if (X##_s) \
1211 R##_s = _FP_NANSIGN_##fs; \
1212 R##_c = FP_CLS_NAN; /* NAN */ \
1213 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
1214 FP_SET_EXCEPTION(FP_EX_INVALID); \
1216 else \
1218 R##_s = 0; \
1219 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
1221 break; \
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: \
1227 R##_s = 0; \
1228 if (X##_s) \
1230 R##_c = FP_CLS_NAN; /* NAN */ \
1231 R##_s = _FP_NANSIGN_##fs; \
1232 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
1233 FP_SET_EXCEPTION(FP_EX_INVALID); \
1234 break; \
1236 R##_c = FP_CLS_NORMAL; \
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); \
1245 } while (0)
1248 * Convert from FP to integer. Input is raw.
1251 /* RSIGNED can have following values:
1252 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
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.
1258 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1259 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1260 * depending on the sign in such case.
1262 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1263 do { \
1264 if (X##_e < _FP_EXPBIAS_##fs) \
1266 r = 0; \
1267 if (X##_e == 0) \
1269 if (!_FP_FRAC_ZEROP_##wc(X)) \
1271 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1272 FP_SET_EXCEPTION(FP_EX_DENORM); \
1275 else \
1276 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1278 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1279 || (!rsigned && X##_s)) \
1281 /* Overflow or converting to the most negative integer. */ \
1282 if (rsigned) \
1284 r = 1; \
1285 r <<= rsize - 1; \
1286 r -= 1 - X##_s; \
1287 } else { \
1288 r = 0; \
1289 if (X##_s) \
1290 r = ~r; \
1293 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
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); \
1308 else \
1309 FP_SET_EXCEPTION(FP_EX_INVALID); \
1311 else \
1313 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
1314 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1316 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1317 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1319 else \
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); \
1330 if (rsigned && X##_s) \
1331 r = -r; \
1333 } while (0)
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) \
1341 rtype ur_; \
1343 if ((X##_s = (r < 0))) \
1344 r = -(rtype)r; \
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))); \
1363 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1364 && X##_e >= _FP_EXPMAX_##fs) \
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; \
1372 if (rsize <= _FP_FRACBITS_##fs \
1373 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1375 /* Exactly representable; shift left. */ \
1376 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
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)); \
1381 else \
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); \
1400 else \
1402 X##_s = 0; \
1403 X##_e = 0; \
1404 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
1406 } while (0)
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) \
1416 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1417 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
1418 abort(); \
1419 D##_s = S##_s; \
1420 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1421 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1423 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1424 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1426 else \
1428 if (S##_e == 0) \
1430 if (_FP_FRAC_ZEROP_##swc(S)) \
1431 D##_e = 0; \
1432 else if (_FP_EXPBIAS_##dfs \
1433 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1435 FP_SET_EXCEPTION(FP_EX_DENORM); \
1436 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1437 - _FP_FRACBITS_##sfs)); \
1438 D##_e = 0; \
1440 else \
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); \
1452 else \
1454 D##_e = _FP_EXPMAX_##dfs; \
1455 if (!_FP_FRAC_ZEROP_##swc(S)) \
1457 if (_FP_FRAC_SNANP(sfs, S)) \
1458 FP_SET_EXCEPTION(FP_EX_INVALID); \
1459 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1460 - _FP_FRACBITS_##sfs)); \
1464 } while (0)
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 \
1471 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1472 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
1473 abort(); \
1474 D##_s = S##_s; \
1475 if (_FP_EXP_NORMAL(sfs, swc, S)) \
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 \
1482 if (D##_e <= 0) \
1484 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1486 _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
1487 _FP_FRAC_LOW_##swc(S) |= 1; \
1489 else \
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); \
1496 D##_e = 0; \
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); \
1505 else \
1507 if (S##_e == 0) \
1509 D##_e = 0; \
1510 if (_FP_FRAC_ZEROP_##swc(S)) \
1511 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1512 else \
1514 FP_SET_EXCEPTION(FP_EX_DENORM); \
1515 if (_FP_EXPBIAS_##sfs \
1516 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
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); \
1523 else \
1525 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1526 _FP_FRAC_LOW_##dwc(D) |= 1; \
1530 else \
1532 D##_e = _FP_EXPMAX_##dfs; \
1533 if (_FP_FRAC_ZEROP_##swc(S)) \
1534 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1535 else \
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); \
1541 /* Semi-raw NaN must have all workbits cleared. */ \
1542 _FP_FRAC_LOW_##dwc(D) \
1543 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
1544 _FP_SETQNAN_SEMIRAW(dfs, dwc, D); \
1548 } while (0)
1551 * Helper primitives.
1554 /* Count leading zeros in a word. */
1556 #ifndef __FP_CLZ
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 (); \
1568 } while (0)
1569 #endif /* ndef __FP_CLZ */
1571 #define _FP_DIV_HELP_imm(q, r, n, d) \
1572 do { \
1573 q = n / d, r = n % d; \
1574 } while (0)
1577 /* A restoring bit-by-bit division primitive. */
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)) \
1596 _FP_FRAC_SUB_##wc (u, u, v); \
1597 _FP_FRAC_LOW_##wc (R) |= 1; \
1598 count--; \
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)) \
1609 _FP_FRAC_SUB_##wc (u, u, v); \
1610 _FP_FRAC_LOW_##wc (R) |= 1; \
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)
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)