2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / libgcc / soft-fp / op-common.h
blob12fb16e5efe9eb4fe57ea71cd4534eaa91ead5b4
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997,1998,1999,2006,2007,2012 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)), X##_s, X##_e; \
34 _FP_FRAC_DECL_##wc(X)
37 * Finish truely unpacking a native fp value by classifying the kind
38 * of fp value and normalizing both the exponent and the fraction.
41 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
42 do { \
43 switch (X##_e) \
44 { \
45 default: \
46 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
47 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
48 X##_e -= _FP_EXPBIAS_##fs; \
49 X##_c = FP_CLS_NORMAL; \
50 break; \
52 case 0: \
53 if (_FP_FRAC_ZEROP_##wc(X)) \
54 X##_c = FP_CLS_ZERO; \
55 else \
56 { \
57 /* a denormalized number */ \
58 _FP_I_TYPE _shift; \
59 _FP_FRAC_CLZ_##wc(_shift, X); \
60 _shift -= _FP_FRACXBITS_##fs; \
61 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
62 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
63 X##_c = FP_CLS_NORMAL; \
64 FP_SET_EXCEPTION(FP_EX_DENORM); \
65 } \
66 break; \
68 case _FP_EXPMAX_##fs: \
69 if (_FP_FRAC_ZEROP_##wc(X)) \
70 X##_c = FP_CLS_INF; \
71 else \
72 { \
73 X##_c = FP_CLS_NAN; \
74 /* Check for signaling NaN */ \
75 if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
76 FP_SET_EXCEPTION(FP_EX_INVALID); \
77 } \
78 break; \
79 } \
80 } while (0)
82 /* Finish unpacking an fp value in semi-raw mode: the mantissa is
83 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
84 other classification is not done. */
85 #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
87 /* A semi-raw value has overflowed to infinity. Adjust the mantissa
88 and exponent appropriately. */
89 #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
90 do { \
91 if (FP_ROUNDMODE == FP_RND_NEAREST \
92 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
93 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
94 { \
95 X##_e = _FP_EXPMAX_##fs; \
96 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
97 } \
98 else \
99 { \
100 X##_e = _FP_EXPMAX_##fs - 1; \
101 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
103 FP_SET_EXCEPTION(FP_EX_INEXACT); \
104 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
105 } while (0)
107 /* Check for a semi-raw value being a signaling NaN and raise the
108 invalid exception if so. */
109 #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
110 do { \
111 if (X##_e == _FP_EXPMAX_##fs \
112 && !_FP_FRAC_ZEROP_##wc(X) \
113 && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
114 FP_SET_EXCEPTION(FP_EX_INVALID); \
115 } while (0)
117 /* Choose a NaN result from an operation on two semi-raw NaN
118 values. */
119 #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
120 do { \
121 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
122 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
123 _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
124 _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
125 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
126 } while (0)
128 /* Test whether a biased exponent is normal (not zero or maximum). */
129 #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
131 /* Prepare to pack an fp value in semi-raw mode: the mantissa is
132 rounded and shifted right, with the rounding possibly increasing
133 the exponent (including changing a finite value to infinity). */
134 #define _FP_PACK_SEMIRAW(fs, wc, X) \
135 do { \
136 _FP_ROUND(wc, X); \
137 if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \
139 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
140 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
141 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
143 if (_FP_FRAC_HIGH_##fs(X) \
144 & (_FP_OVERFLOW_##fs >> 1)) \
146 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
147 X##_e++; \
148 if (X##_e == _FP_EXPMAX_##fs) \
149 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
151 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
152 if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
154 if (!_FP_KEEPNANFRACP) \
156 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
157 X##_s = _FP_NANSIGN_##fs; \
159 else \
160 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
162 } while (0)
165 * Before packing the bits back into the native fp result, take care
166 * of such mundane things as rounding and overflow. Also, for some
167 * kinds of fp values, the original parts may not have been fully
168 * extracted -- but that is ok, we can regenerate them now.
171 #define _FP_PACK_CANONICAL(fs, wc, X) \
172 do { \
173 switch (X##_c) \
175 case FP_CLS_NORMAL: \
176 X##_e += _FP_EXPBIAS_##fs; \
177 if (X##_e > 0) \
179 _FP_ROUND(wc, X); \
180 if (_FP_FRAC_OVERP_##wc(fs, X)) \
182 _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
183 X##_e++; \
185 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
186 if (X##_e >= _FP_EXPMAX_##fs) \
188 /* overflow */ \
189 switch (FP_ROUNDMODE) \
191 case FP_RND_NEAREST: \
192 X##_c = FP_CLS_INF; \
193 break; \
194 case FP_RND_PINF: \
195 if (!X##_s) X##_c = FP_CLS_INF; \
196 break; \
197 case FP_RND_MINF: \
198 if (X##_s) X##_c = FP_CLS_INF; \
199 break; \
201 if (X##_c == FP_CLS_INF) \
203 /* Overflow to infinity */ \
204 X##_e = _FP_EXPMAX_##fs; \
205 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
207 else \
209 /* Overflow to maximum normal */ \
210 X##_e = _FP_EXPMAX_##fs - 1; \
211 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
213 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
214 FP_SET_EXCEPTION(FP_EX_INEXACT); \
217 else \
219 /* we've got a denormalized number */ \
220 X##_e = -X##_e + 1; \
221 if (X##_e <= _FP_WFRACBITS_##fs) \
223 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
224 _FP_ROUND(wc, X); \
225 if (_FP_FRAC_HIGH_##fs(X) \
226 & (_FP_OVERFLOW_##fs >> 1)) \
228 X##_e = 1; \
229 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
230 FP_SET_EXCEPTION(FP_EX_INEXACT); \
232 else \
234 X##_e = 0; \
235 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
237 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
238 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
239 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
241 else \
243 /* underflow to zero */ \
244 X##_e = 0; \
245 if (!_FP_FRAC_ZEROP_##wc(X)) \
247 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
248 _FP_ROUND(wc, X); \
249 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
251 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
254 break; \
256 case FP_CLS_ZERO: \
257 X##_e = 0; \
258 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
259 break; \
261 case FP_CLS_INF: \
262 X##_e = _FP_EXPMAX_##fs; \
263 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
264 break; \
266 case FP_CLS_NAN: \
267 X##_e = _FP_EXPMAX_##fs; \
268 if (!_FP_KEEPNANFRACP) \
270 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
271 X##_s = _FP_NANSIGN_##fs; \
273 else \
274 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
275 break; \
277 } while (0)
279 /* This one accepts raw argument and not cooked, returns
280 * 1 if X is a signaling NaN.
282 #define _FP_ISSIGNAN(fs, wc, X) \
283 ({ \
284 int __ret = 0; \
285 if (X##_e == _FP_EXPMAX_##fs) \
287 if (!_FP_FRAC_ZEROP_##wc(X) \
288 && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
289 __ret = 1; \
291 __ret; \
298 /* Addition on semi-raw values. */
299 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
300 do { \
301 if (X##_s == Y##_s) \
303 /* Addition. */ \
304 R##_s = X##_s; \
305 int ediff = X##_e - Y##_e; \
306 if (ediff > 0) \
308 R##_e = X##_e; \
309 if (Y##_e == 0) \
311 /* Y is zero or denormalized. */ \
312 if (_FP_FRAC_ZEROP_##wc(Y)) \
314 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
315 _FP_FRAC_COPY_##wc(R, X); \
316 goto add_done; \
318 else \
320 FP_SET_EXCEPTION(FP_EX_DENORM); \
321 ediff--; \
322 if (ediff == 0) \
324 _FP_FRAC_ADD_##wc(R, X, Y); \
325 goto add3; \
327 if (X##_e == _FP_EXPMAX_##fs) \
329 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
330 _FP_FRAC_COPY_##wc(R, X); \
331 goto add_done; \
333 goto add1; \
336 else if (X##_e == _FP_EXPMAX_##fs) \
338 /* X is NaN or Inf, Y is normal. */ \
339 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
340 _FP_FRAC_COPY_##wc(R, X); \
341 goto add_done; \
344 /* Insert implicit MSB of Y. */ \
345 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
347 add1: \
348 /* Shift the mantissa of Y to the right EDIFF steps; \
349 remember to account later for the implicit MSB of X. */ \
350 if (ediff <= _FP_WFRACBITS_##fs) \
351 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
352 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
353 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
354 _FP_FRAC_ADD_##wc(R, X, Y); \
356 else if (ediff < 0) \
358 ediff = -ediff; \
359 R##_e = Y##_e; \
360 if (X##_e == 0) \
362 /* X is zero or denormalized. */ \
363 if (_FP_FRAC_ZEROP_##wc(X)) \
365 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
366 _FP_FRAC_COPY_##wc(R, Y); \
367 goto add_done; \
369 else \
371 FP_SET_EXCEPTION(FP_EX_DENORM); \
372 ediff--; \
373 if (ediff == 0) \
375 _FP_FRAC_ADD_##wc(R, Y, X); \
376 goto add3; \
378 if (Y##_e == _FP_EXPMAX_##fs) \
380 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
381 _FP_FRAC_COPY_##wc(R, Y); \
382 goto add_done; \
384 goto add2; \
387 else if (Y##_e == _FP_EXPMAX_##fs) \
389 /* Y is NaN or Inf, X is normal. */ \
390 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
391 _FP_FRAC_COPY_##wc(R, Y); \
392 goto add_done; \
395 /* Insert implicit MSB of X. */ \
396 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
398 add2: \
399 /* Shift the mantissa of X to the right EDIFF steps; \
400 remember to account later for the implicit MSB of Y. */ \
401 if (ediff <= _FP_WFRACBITS_##fs) \
402 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
403 else if (!_FP_FRAC_ZEROP_##wc(X)) \
404 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
405 _FP_FRAC_ADD_##wc(R, Y, X); \
407 else \
409 /* ediff == 0. */ \
410 if (!_FP_EXP_NORMAL(fs, wc, X)) \
412 if (X##_e == 0) \
414 /* X and Y are zero or denormalized. */ \
415 R##_e = 0; \
416 if (_FP_FRAC_ZEROP_##wc(X)) \
418 if (!_FP_FRAC_ZEROP_##wc(Y)) \
419 FP_SET_EXCEPTION(FP_EX_DENORM); \
420 _FP_FRAC_COPY_##wc(R, Y); \
421 goto add_done; \
423 else if (_FP_FRAC_ZEROP_##wc(Y)) \
425 FP_SET_EXCEPTION(FP_EX_DENORM); \
426 _FP_FRAC_COPY_##wc(R, X); \
427 goto add_done; \
429 else \
431 FP_SET_EXCEPTION(FP_EX_DENORM); \
432 _FP_FRAC_ADD_##wc(R, X, Y); \
433 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
435 /* Normalized result. */ \
436 _FP_FRAC_HIGH_##fs(R) \
437 &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
438 R##_e = 1; \
440 goto add_done; \
443 else \
445 /* X and Y are NaN or Inf. */ \
446 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
447 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
448 R##_e = _FP_EXPMAX_##fs; \
449 if (_FP_FRAC_ZEROP_##wc(X)) \
450 _FP_FRAC_COPY_##wc(R, Y); \
451 else if (_FP_FRAC_ZEROP_##wc(Y)) \
452 _FP_FRAC_COPY_##wc(R, X); \
453 else \
454 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
455 goto add_done; \
458 /* The exponents of X and Y, both normal, are equal. The \
459 implicit MSBs will always add to increase the \
460 exponent. */ \
461 _FP_FRAC_ADD_##wc(R, X, Y); \
462 R##_e = X##_e + 1; \
463 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
464 if (R##_e == _FP_EXPMAX_##fs) \
465 /* Overflow to infinity (depending on rounding mode). */ \
466 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
467 goto add_done; \
469 add3: \
470 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
472 /* Overflow. */ \
473 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
474 R##_e++; \
475 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
476 if (R##_e == _FP_EXPMAX_##fs) \
477 /* Overflow to infinity (depending on rounding mode). */ \
478 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
480 add_done: ; \
482 else \
484 /* Subtraction. */ \
485 int ediff = X##_e - Y##_e; \
486 if (ediff > 0) \
488 R##_e = X##_e; \
489 R##_s = X##_s; \
490 if (Y##_e == 0) \
492 /* Y is zero or denormalized. */ \
493 if (_FP_FRAC_ZEROP_##wc(Y)) \
495 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
496 _FP_FRAC_COPY_##wc(R, X); \
497 goto sub_done; \
499 else \
501 FP_SET_EXCEPTION(FP_EX_DENORM); \
502 ediff--; \
503 if (ediff == 0) \
505 _FP_FRAC_SUB_##wc(R, X, Y); \
506 goto sub3; \
508 if (X##_e == _FP_EXPMAX_##fs) \
510 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
511 _FP_FRAC_COPY_##wc(R, X); \
512 goto sub_done; \
514 goto sub1; \
517 else if (X##_e == _FP_EXPMAX_##fs) \
519 /* X is NaN or Inf, Y is normal. */ \
520 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
521 _FP_FRAC_COPY_##wc(R, X); \
522 goto sub_done; \
525 /* Insert implicit MSB of Y. */ \
526 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
528 sub1: \
529 /* Shift the mantissa of Y to the right EDIFF steps; \
530 remember to account later for the implicit MSB of X. */ \
531 if (ediff <= _FP_WFRACBITS_##fs) \
532 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
533 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
534 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
535 _FP_FRAC_SUB_##wc(R, X, Y); \
537 else if (ediff < 0) \
539 ediff = -ediff; \
540 R##_e = Y##_e; \
541 R##_s = Y##_s; \
542 if (X##_e == 0) \
544 /* X is zero or denormalized. */ \
545 if (_FP_FRAC_ZEROP_##wc(X)) \
547 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
548 _FP_FRAC_COPY_##wc(R, Y); \
549 goto sub_done; \
551 else \
553 FP_SET_EXCEPTION(FP_EX_DENORM); \
554 ediff--; \
555 if (ediff == 0) \
557 _FP_FRAC_SUB_##wc(R, Y, X); \
558 goto sub3; \
560 if (Y##_e == _FP_EXPMAX_##fs) \
562 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
563 _FP_FRAC_COPY_##wc(R, Y); \
564 goto sub_done; \
566 goto sub2; \
569 else if (Y##_e == _FP_EXPMAX_##fs) \
571 /* Y is NaN or Inf, X is normal. */ \
572 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
573 _FP_FRAC_COPY_##wc(R, Y); \
574 goto sub_done; \
577 /* Insert implicit MSB of X. */ \
578 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
580 sub2: \
581 /* Shift the mantissa of X to the right EDIFF steps; \
582 remember to account later for the implicit MSB of Y. */ \
583 if (ediff <= _FP_WFRACBITS_##fs) \
584 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
585 else if (!_FP_FRAC_ZEROP_##wc(X)) \
586 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
587 _FP_FRAC_SUB_##wc(R, Y, X); \
589 else \
591 /* ediff == 0. */ \
592 if (!_FP_EXP_NORMAL(fs, wc, X)) \
594 if (X##_e == 0) \
596 /* X and Y are zero or denormalized. */ \
597 R##_e = 0; \
598 if (_FP_FRAC_ZEROP_##wc(X)) \
600 _FP_FRAC_COPY_##wc(R, Y); \
601 if (_FP_FRAC_ZEROP_##wc(Y)) \
602 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
603 else \
605 FP_SET_EXCEPTION(FP_EX_DENORM); \
606 R##_s = Y##_s; \
608 goto sub_done; \
610 else if (_FP_FRAC_ZEROP_##wc(Y)) \
612 FP_SET_EXCEPTION(FP_EX_DENORM); \
613 _FP_FRAC_COPY_##wc(R, X); \
614 R##_s = X##_s; \
615 goto sub_done; \
617 else \
619 FP_SET_EXCEPTION(FP_EX_DENORM); \
620 _FP_FRAC_SUB_##wc(R, X, Y); \
621 R##_s = X##_s; \
622 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
624 /* |X| < |Y|, negate result. */ \
625 _FP_FRAC_SUB_##wc(R, Y, X); \
626 R##_s = Y##_s; \
628 else if (_FP_FRAC_ZEROP_##wc(R)) \
629 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
630 goto sub_done; \
633 else \
635 /* X and Y are NaN or Inf, of opposite signs. */ \
636 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
637 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
638 R##_e = _FP_EXPMAX_##fs; \
639 if (_FP_FRAC_ZEROP_##wc(X)) \
641 if (_FP_FRAC_ZEROP_##wc(Y)) \
643 /* Inf - Inf. */ \
644 R##_s = _FP_NANSIGN_##fs; \
645 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
646 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
647 FP_SET_EXCEPTION(FP_EX_INVALID); \
649 else \
651 /* Inf - NaN. */ \
652 R##_s = Y##_s; \
653 _FP_FRAC_COPY_##wc(R, Y); \
656 else \
658 if (_FP_FRAC_ZEROP_##wc(Y)) \
660 /* NaN - Inf. */ \
661 R##_s = X##_s; \
662 _FP_FRAC_COPY_##wc(R, X); \
664 else \
666 /* NaN - NaN. */ \
667 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
670 goto sub_done; \
673 /* The exponents of X and Y, both normal, are equal. The \
674 implicit MSBs cancel. */ \
675 R##_e = X##_e; \
676 _FP_FRAC_SUB_##wc(R, X, Y); \
677 R##_s = X##_s; \
678 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
680 /* |X| < |Y|, negate result. */ \
681 _FP_FRAC_SUB_##wc(R, Y, X); \
682 R##_s = Y##_s; \
684 else if (_FP_FRAC_ZEROP_##wc(R)) \
686 R##_e = 0; \
687 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
688 goto sub_done; \
690 goto norm; \
692 sub3: \
693 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
695 int diff; \
696 /* Carry into most significant bit of larger one of X and Y, \
697 canceling it; renormalize. */ \
698 _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
699 norm: \
700 _FP_FRAC_CLZ_##wc(diff, R); \
701 diff -= _FP_WFRACXBITS_##fs; \
702 _FP_FRAC_SLL_##wc(R, diff); \
703 if (R##_e <= diff) \
705 /* R is denormalized. */ \
706 diff = diff - R##_e + 1; \
707 _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
708 R##_e = 0; \
710 else \
712 R##_e -= diff; \
713 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
716 sub_done: ; \
718 } while (0)
720 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
721 #define _FP_SUB(fs, wc, R, X, Y) \
722 do { \
723 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
724 _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
725 } while (0)
729 * Main negation routine. FIXME -- when we care about setting exception
730 * bits reliably, this will not do. We should examine all of the fp classes.
733 #define _FP_NEG(fs, wc, R, X) \
734 do { \
735 _FP_FRAC_COPY_##wc(R, X); \
736 R##_c = X##_c; \
737 R##_e = X##_e; \
738 R##_s = 1 ^ X##_s; \
739 } while (0)
743 * Main multiplication routine. The input values should be cooked.
746 #define _FP_MUL(fs, wc, R, X, Y) \
747 do { \
748 R##_s = X##_s ^ Y##_s; \
749 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
751 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
752 R##_c = FP_CLS_NORMAL; \
753 R##_e = X##_e + Y##_e + 1; \
755 _FP_MUL_MEAT_##fs(R,X,Y); \
757 if (_FP_FRAC_OVERP_##wc(fs, R)) \
758 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
759 else \
760 R##_e--; \
761 break; \
763 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
764 _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
765 break; \
767 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
768 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
769 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
770 R##_s = X##_s; \
772 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
773 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
774 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
775 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
776 _FP_FRAC_COPY_##wc(R, X); \
777 R##_c = X##_c; \
778 break; \
780 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
781 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
782 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
783 R##_s = Y##_s; \
785 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
786 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
787 _FP_FRAC_COPY_##wc(R, Y); \
788 R##_c = Y##_c; \
789 break; \
791 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
792 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
793 R##_s = _FP_NANSIGN_##fs; \
794 R##_c = FP_CLS_NAN; \
795 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
796 FP_SET_EXCEPTION(FP_EX_INVALID); \
797 break; \
799 default: \
800 abort(); \
802 } while (0)
806 * Main division routine. The input values should be cooked.
809 #define _FP_DIV(fs, wc, R, X, Y) \
810 do { \
811 R##_s = X##_s ^ Y##_s; \
812 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
814 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
815 R##_c = FP_CLS_NORMAL; \
816 R##_e = X##_e - Y##_e; \
818 _FP_DIV_MEAT_##fs(R,X,Y); \
819 break; \
821 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
822 _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
823 break; \
825 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
826 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
827 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
828 R##_s = X##_s; \
829 _FP_FRAC_COPY_##wc(R, X); \
830 R##_c = X##_c; \
831 break; \
833 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
834 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
835 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
836 R##_s = Y##_s; \
837 _FP_FRAC_COPY_##wc(R, Y); \
838 R##_c = Y##_c; \
839 break; \
841 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
842 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
843 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
844 R##_c = FP_CLS_ZERO; \
845 break; \
847 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
848 FP_SET_EXCEPTION(FP_EX_DIVZERO); \
849 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
850 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
851 R##_c = FP_CLS_INF; \
852 break; \
854 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
855 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
856 R##_s = _FP_NANSIGN_##fs; \
857 R##_c = FP_CLS_NAN; \
858 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
859 FP_SET_EXCEPTION(FP_EX_INVALID); \
860 break; \
862 default: \
863 abort(); \
865 } while (0)
869 * Main differential comparison routine. The inputs should be raw not
870 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
873 #define _FP_CMP(fs, wc, ret, X, Y, un) \
874 do { \
875 /* NANs are unordered */ \
876 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
877 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
879 ret = un; \
881 else \
883 int __is_zero_x; \
884 int __is_zero_y; \
886 __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
887 __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
889 if (__is_zero_x && __is_zero_y) \
890 ret = 0; \
891 else if (__is_zero_x) \
892 ret = Y##_s ? 1 : -1; \
893 else if (__is_zero_y) \
894 ret = X##_s ? -1 : 1; \
895 else if (X##_s != Y##_s) \
896 ret = X##_s ? -1 : 1; \
897 else if (X##_e > Y##_e) \
898 ret = X##_s ? -1 : 1; \
899 else if (X##_e < Y##_e) \
900 ret = X##_s ? 1 : -1; \
901 else if (_FP_FRAC_GT_##wc(X, Y)) \
902 ret = X##_s ? -1 : 1; \
903 else if (_FP_FRAC_GT_##wc(Y, X)) \
904 ret = X##_s ? 1 : -1; \
905 else \
906 ret = 0; \
908 } while (0)
911 /* Simplification for strict equality. */
913 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
914 do { \
915 /* NANs are unordered */ \
916 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
917 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
919 ret = 1; \
921 else \
923 ret = !(X##_e == Y##_e \
924 && _FP_FRAC_EQ_##wc(X, Y) \
925 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
927 } while (0)
929 /* Version to test unordered. */
931 #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
932 do { \
933 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
934 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
935 } while (0)
938 * Main square root routine. The input value should be cooked.
941 #define _FP_SQRT(fs, wc, R, X) \
942 do { \
943 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
944 _FP_W_TYPE q; \
945 switch (X##_c) \
947 case FP_CLS_NAN: \
948 _FP_FRAC_COPY_##wc(R, X); \
949 R##_s = X##_s; \
950 R##_c = FP_CLS_NAN; \
951 break; \
952 case FP_CLS_INF: \
953 if (X##_s) \
955 R##_s = _FP_NANSIGN_##fs; \
956 R##_c = FP_CLS_NAN; /* NAN */ \
957 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
958 FP_SET_EXCEPTION(FP_EX_INVALID); \
960 else \
962 R##_s = 0; \
963 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
965 break; \
966 case FP_CLS_ZERO: \
967 R##_s = X##_s; \
968 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
969 break; \
970 case FP_CLS_NORMAL: \
971 R##_s = 0; \
972 if (X##_s) \
974 R##_c = FP_CLS_NAN; /* sNAN */ \
975 R##_s = _FP_NANSIGN_##fs; \
976 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
977 FP_SET_EXCEPTION(FP_EX_INVALID); \
978 break; \
980 R##_c = FP_CLS_NORMAL; \
981 if (X##_e & 1) \
982 _FP_FRAC_SLL_##wc(X, 1); \
983 R##_e = X##_e >> 1; \
984 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
985 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
986 q = _FP_OVERFLOW_##fs >> 1; \
987 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
989 } while (0)
992 * Convert from FP to integer. Input is raw.
995 /* RSIGNED can have following values:
996 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
997 * the result is either 0 or (2^rsize)-1 depending on the sign in such
998 * case.
999 * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
1000 * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1001 * depending on the sign in such case.
1002 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1003 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1004 * depending on the sign in such case.
1006 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1007 do { \
1008 if (X##_e < _FP_EXPBIAS_##fs) \
1010 r = 0; \
1011 if (X##_e == 0) \
1013 if (!_FP_FRAC_ZEROP_##wc(X)) \
1015 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1016 FP_SET_EXCEPTION(FP_EX_DENORM); \
1019 else \
1020 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1022 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1023 || (!rsigned && X##_s)) \
1025 /* Overflow or converting to the most negative integer. */ \
1026 if (rsigned) \
1028 r = 1; \
1029 r <<= rsize - 1; \
1030 r -= 1 - X##_s; \
1031 } else { \
1032 r = 0; \
1033 if (X##_s) \
1034 r = ~r; \
1037 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1039 /* Possibly converting to most negative integer; check the \
1040 mantissa. */ \
1041 int inexact = 0; \
1042 (void)((_FP_FRACBITS_##fs > rsize) \
1043 ? ({ _FP_FRAC_SRST_##wc(X, inexact, \
1044 _FP_FRACBITS_##fs - rsize, \
1045 _FP_FRACBITS_##fs); 0; }) \
1046 : 0); \
1047 if (!_FP_FRAC_ZEROP_##wc(X)) \
1048 FP_SET_EXCEPTION(FP_EX_INVALID); \
1049 else if (inexact) \
1050 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1052 else \
1053 FP_SET_EXCEPTION(FP_EX_INVALID); \
1055 else \
1057 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
1058 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1060 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1061 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1063 else \
1065 int inexact; \
1066 _FP_FRAC_SRST_##wc(X, inexact, \
1067 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1068 - X##_e), \
1069 _FP_FRACBITS_##fs); \
1070 if (inexact) \
1071 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1072 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1074 if (rsigned && X##_s) \
1075 r = -r; \
1077 } while (0)
1079 /* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1080 input is signed. */
1081 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1082 do { \
1083 if (r) \
1085 rtype ur_; \
1087 if ((X##_s = (r < 0))) \
1088 r = -(rtype)r; \
1090 ur_ = (rtype) r; \
1091 (void)((rsize <= _FP_W_TYPE_SIZE) \
1092 ? ({ \
1093 int lz_; \
1094 __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
1095 X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
1096 }) \
1097 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1098 ? ({ \
1099 int lz_; \
1100 __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
1101 (_FP_W_TYPE)ur_); \
1102 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1103 - lz_); \
1104 }) \
1105 : (abort(), 0))); \
1107 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1108 && X##_e >= _FP_EXPMAX_##fs) \
1110 /* Exponent too big; overflow to infinity. (May also \
1111 happen after rounding below.) */ \
1112 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
1113 goto pack_semiraw; \
1116 if (rsize <= _FP_FRACBITS_##fs \
1117 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1119 /* Exactly representable; shift left. */ \
1120 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1121 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1122 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1124 else \
1126 /* More bits in integer than in floating type; need to \
1127 round. */ \
1128 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1129 ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
1130 - _FP_WFRACBITS_##fs + 1)) \
1131 | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1132 - _FP_WFRACBITS_##fs + 1))) \
1133 != 0)); \
1134 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1135 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
1136 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1137 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1138 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
1139 pack_semiraw: \
1140 _FP_PACK_SEMIRAW(fs, wc, X); \
1143 else \
1145 X##_s = 0; \
1146 X##_e = 0; \
1147 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
1149 } while (0)
1152 /* Extend from a narrower floating-point format to a wider one. Input
1153 and output are raw. */
1154 #define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
1155 do { \
1156 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1157 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1158 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1159 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1160 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
1161 abort(); \
1162 D##_s = S##_s; \
1163 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1164 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1166 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1167 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1169 else \
1171 if (S##_e == 0) \
1173 if (_FP_FRAC_ZEROP_##swc(S)) \
1174 D##_e = 0; \
1175 else if (_FP_EXPBIAS_##dfs \
1176 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1178 FP_SET_EXCEPTION(FP_EX_DENORM); \
1179 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1180 - _FP_FRACBITS_##sfs)); \
1181 D##_e = 0; \
1183 else \
1185 int _lz; \
1186 FP_SET_EXCEPTION(FP_EX_DENORM); \
1187 _FP_FRAC_CLZ_##swc(_lz, S); \
1188 _FP_FRAC_SLL_##dwc(D, \
1189 _lz + _FP_FRACBITS_##dfs \
1190 - _FP_FRACTBITS_##sfs); \
1191 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1192 + _FP_FRACXBITS_##sfs - _lz); \
1195 else \
1197 D##_e = _FP_EXPMAX_##dfs; \
1198 if (!_FP_FRAC_ZEROP_##swc(S)) \
1200 if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
1201 FP_SET_EXCEPTION(FP_EX_INVALID); \
1202 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1203 - _FP_FRACBITS_##sfs)); \
1207 } while (0)
1209 /* Truncate from a wider floating-point format to a narrower one.
1210 Input and output are semi-raw. */
1211 #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
1212 do { \
1213 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1214 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1215 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
1216 abort(); \
1217 D##_s = S##_s; \
1218 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1220 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1221 if (D##_e >= _FP_EXPMAX_##dfs) \
1222 _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
1223 else \
1225 if (D##_e <= 0) \
1227 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1229 _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
1230 _FP_FRAC_LOW_##swc(S) |= 1; \
1232 else \
1234 _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
1235 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1236 - _FP_WFRACBITS_##dfs + 1 - D##_e), \
1237 _FP_WFRACBITS_##sfs); \
1239 D##_e = 0; \
1241 else \
1242 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1243 - _FP_WFRACBITS_##dfs), \
1244 _FP_WFRACBITS_##sfs); \
1245 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1248 else \
1250 if (S##_e == 0) \
1252 D##_e = 0; \
1253 if (_FP_FRAC_ZEROP_##swc(S)) \
1254 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1255 else \
1257 FP_SET_EXCEPTION(FP_EX_DENORM); \
1258 if (_FP_EXPBIAS_##sfs \
1259 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1261 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1262 - _FP_WFRACBITS_##dfs), \
1263 _FP_WFRACBITS_##sfs); \
1264 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1266 else \
1268 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1269 _FP_FRAC_LOW_##dwc(D) |= 1; \
1273 else \
1275 D##_e = _FP_EXPMAX_##dfs; \
1276 if (_FP_FRAC_ZEROP_##swc(S)) \
1277 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1278 else \
1280 _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
1281 _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
1282 - _FP_WFRACBITS_##dfs)); \
1283 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1284 /* Semi-raw NaN must have all workbits cleared. */ \
1285 _FP_FRAC_LOW_##dwc(D) \
1286 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
1287 _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
1291 } while (0)
1294 * Helper primitives.
1297 /* Count leading zeros in a word. */
1299 #ifndef __FP_CLZ
1300 /* GCC 3.4 and later provide the builtins for us. */
1301 #define __FP_CLZ(r, x) \
1302 do { \
1303 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1304 r = __builtin_clz (x); \
1305 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1306 r = __builtin_clzl (x); \
1307 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1308 r = __builtin_clzll (x); \
1309 else \
1310 abort (); \
1311 } while (0)
1312 #endif /* ndef __FP_CLZ */
1314 #define _FP_DIV_HELP_imm(q, r, n, d) \
1315 do { \
1316 q = n / d, r = n % d; \
1317 } while (0)
1320 /* A restoring bit-by-bit division primitive. */
1322 #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1323 do { \
1324 int count = _FP_WFRACBITS_##fs; \
1325 _FP_FRAC_DECL_##wc (u); \
1326 _FP_FRAC_DECL_##wc (v); \
1327 _FP_FRAC_COPY_##wc (u, X); \
1328 _FP_FRAC_COPY_##wc (v, Y); \
1329 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1330 /* Normalize U and V. */ \
1331 _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
1332 _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
1333 /* First round. Since the operands are normalized, either the \
1334 first or second bit will be set in the fraction. Produce a \
1335 normalized result by checking which and adjusting the loop \
1336 count and exponent accordingly. */ \
1337 if (_FP_FRAC_GE_1 (u, v)) \
1339 _FP_FRAC_SUB_##wc (u, u, v); \
1340 _FP_FRAC_LOW_##wc (R) |= 1; \
1341 count--; \
1343 else \
1344 R##_e--; \
1345 /* Subsequent rounds. */ \
1346 do { \
1347 int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
1348 _FP_FRAC_SLL_##wc (u, 1); \
1349 _FP_FRAC_SLL_##wc (R, 1); \
1350 if (msb || _FP_FRAC_GE_1 (u, v)) \
1352 _FP_FRAC_SUB_##wc (u, u, v); \
1353 _FP_FRAC_LOW_##wc (R) |= 1; \
1355 } while (--count > 0); \
1356 /* If there's anything left in U, the result is inexact. */ \
1357 _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
1358 } while (0)
1360 #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1361 #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1362 #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)