soft-fp: Fix _FP_TO_INT latent bug in overflow handling.
[glibc.git] / soft-fp / op-common.h
blobe0a108a6ee375aac980483363b4fcb0a7f3dbae5
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997-2014 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 __attribute__ ((unused)); \
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))
48 /* Finish truly unpacking a native fp value by classifying the kind
49 of fp value and normalizing both the exponent and the fraction. */
51 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
52 do \
53 { \
54 switch (X##_e) \
55 { \
56 default: \
57 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \
58 _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \
59 X##_e -= _FP_EXPBIAS_##fs; \
60 X##_c = FP_CLS_NORMAL; \
61 break; \
63 case 0: \
64 if (_FP_FRAC_ZEROP_##wc (X)) \
65 X##_c = FP_CLS_ZERO; \
66 else \
67 { \
68 /* A denormalized number. */ \
69 _FP_I_TYPE _FP_UNPACK_CANONICAL_shift; \
70 _FP_FRAC_CLZ_##wc (_FP_UNPACK_CANONICAL_shift, \
71 X); \
72 _FP_UNPACK_CANONICAL_shift -= _FP_FRACXBITS_##fs; \
73 _FP_FRAC_SLL_##wc (X, (_FP_UNPACK_CANONICAL_shift \
74 + _FP_WORKBITS)); \
75 X##_e -= (_FP_EXPBIAS_##fs - 1 \
76 + _FP_UNPACK_CANONICAL_shift); \
77 X##_c = FP_CLS_NORMAL; \
78 FP_SET_EXCEPTION (FP_EX_DENORM); \
79 } \
80 break; \
82 case _FP_EXPMAX_##fs: \
83 if (_FP_FRAC_ZEROP_##wc (X)) \
84 X##_c = FP_CLS_INF; \
85 else \
86 { \
87 X##_c = FP_CLS_NAN; \
88 /* Check for signaling NaN. */ \
89 if (_FP_FRAC_SNANP (fs, X)) \
90 FP_SET_EXCEPTION (FP_EX_INVALID); \
91 } \
92 break; \
93 } \
94 } \
95 while (0)
97 /* Finish unpacking an fp value in semi-raw mode: the mantissa is
98 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
99 other classification is not done. */
100 #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc (X, _FP_WORKBITS)
102 /* A semi-raw value has overflowed to infinity. Adjust the mantissa
103 and exponent appropriately. */
104 #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
105 do \
107 if (FP_ROUNDMODE == FP_RND_NEAREST \
108 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
109 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
111 X##_e = _FP_EXPMAX_##fs; \
112 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
114 else \
116 X##_e = _FP_EXPMAX_##fs - 1; \
117 _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \
119 FP_SET_EXCEPTION (FP_EX_INEXACT); \
120 FP_SET_EXCEPTION (FP_EX_OVERFLOW); \
122 while (0)
124 /* Check for a semi-raw value being a signaling NaN and raise the
125 invalid exception if so. */
126 #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
127 do \
129 if (X##_e == _FP_EXPMAX_##fs \
130 && !_FP_FRAC_ZEROP_##wc (X) \
131 && _FP_FRAC_SNANP_SEMIRAW (fs, X)) \
132 FP_SET_EXCEPTION (FP_EX_INVALID); \
134 while (0)
136 /* Choose a NaN result from an operation on two semi-raw NaN
137 values. */
138 #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
139 do \
141 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
142 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
143 _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS); \
144 _FP_CHOOSENAN (fs, wc, R, X, Y, OP); \
145 _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \
147 while (0)
149 /* Make the fractional part a quiet NaN, preserving the payload
150 if possible, otherwise make it the canonical quiet NaN and set
151 the sign bit accordingly. */
152 #define _FP_SETQNAN(fs, wc, X) \
153 do \
155 if (_FP_QNANNEGATEDP) \
157 _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1; \
158 if (_FP_FRAC_ZEROP_##wc (X)) \
160 X##_s = _FP_NANSIGN_##fs; \
161 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
164 else \
165 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs; \
167 while (0)
168 #define _FP_SETQNAN_SEMIRAW(fs, wc, X) \
169 do \
171 if (_FP_QNANNEGATEDP) \
173 _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1; \
174 if (_FP_FRAC_ZEROP_##wc (X)) \
176 X##_s = _FP_NANSIGN_##fs; \
177 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
178 _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \
181 else \
182 _FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs; \
184 while (0)
186 /* Test whether a biased exponent is normal (not zero or maximum). */
187 #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
189 /* Prepare to pack an fp value in semi-raw mode: the mantissa is
190 rounded and shifted right, with the rounding possibly increasing
191 the exponent (including changing a finite value to infinity). */
192 #define _FP_PACK_SEMIRAW(fs, wc, X) \
193 do \
195 int _FP_PACK_SEMIRAW_is_tiny \
196 = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X); \
197 if (_FP_TININESS_AFTER_ROUNDING \
198 && _FP_PACK_SEMIRAW_is_tiny) \
200 FP_DECL_##fs (_FP_PACK_SEMIRAW_T); \
201 _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X); \
202 _FP_PACK_SEMIRAW_T##_s = X##_s; \
203 _FP_PACK_SEMIRAW_T##_e = X##_e; \
204 _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1); \
205 _FP_ROUND (wc, _FP_PACK_SEMIRAW_T); \
206 if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T)) \
207 _FP_PACK_SEMIRAW_is_tiny = 0; \
209 _FP_ROUND (wc, X); \
210 if (_FP_PACK_SEMIRAW_is_tiny) \
212 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
213 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
214 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
216 if (_FP_FRAC_HIGH_##fs (X) \
217 & (_FP_OVERFLOW_##fs >> 1)) \
219 _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1); \
220 X##_e++; \
221 if (X##_e == _FP_EXPMAX_##fs) \
222 _FP_OVERFLOW_SEMIRAW (fs, wc, X); \
224 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
225 if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
227 if (!_FP_KEEPNANFRACP) \
229 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
230 X##_s = _FP_NANSIGN_##fs; \
232 else \
233 _FP_SETQNAN (fs, wc, X); \
236 while (0)
238 /* Before packing the bits back into the native fp result, take care
239 of such mundane things as rounding and overflow. Also, for some
240 kinds of fp values, the original parts may not have been fully
241 extracted -- but that is ok, we can regenerate them now. */
243 #define _FP_PACK_CANONICAL(fs, wc, X) \
244 do \
246 switch (X##_c) \
248 case FP_CLS_NORMAL: \
249 X##_e += _FP_EXPBIAS_##fs; \
250 if (X##_e > 0) \
252 _FP_ROUND (wc, X); \
253 if (_FP_FRAC_OVERP_##wc (fs, X)) \
255 _FP_FRAC_CLEAR_OVERP_##wc (fs, X); \
256 X##_e++; \
258 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
259 if (X##_e >= _FP_EXPMAX_##fs) \
261 /* Overflow. */ \
262 switch (FP_ROUNDMODE) \
264 case FP_RND_NEAREST: \
265 X##_c = FP_CLS_INF; \
266 break; \
267 case FP_RND_PINF: \
268 if (!X##_s) \
269 X##_c = FP_CLS_INF; \
270 break; \
271 case FP_RND_MINF: \
272 if (X##_s) \
273 X##_c = FP_CLS_INF; \
274 break; \
276 if (X##_c == FP_CLS_INF) \
278 /* Overflow to infinity. */ \
279 X##_e = _FP_EXPMAX_##fs; \
280 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
282 else \
284 /* Overflow to maximum normal. */ \
285 X##_e = _FP_EXPMAX_##fs - 1; \
286 _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \
288 FP_SET_EXCEPTION (FP_EX_OVERFLOW); \
289 FP_SET_EXCEPTION (FP_EX_INEXACT); \
292 else \
294 /* We've got a denormalized number. */ \
295 int _FP_PACK_CANONICAL_is_tiny = 1; \
296 if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \
298 FP_DECL_##fs (_FP_PACK_CANONICAL_T); \
299 _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X); \
300 _FP_PACK_CANONICAL_T##_s = X##_s; \
301 _FP_PACK_CANONICAL_T##_e = X##_e; \
302 _FP_ROUND (wc, _FP_PACK_CANONICAL_T); \
303 if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T)) \
304 _FP_PACK_CANONICAL_is_tiny = 0; \
306 X##_e = -X##_e + 1; \
307 if (X##_e <= _FP_WFRACBITS_##fs) \
309 _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs); \
310 _FP_ROUND (wc, X); \
311 if (_FP_FRAC_HIGH_##fs (X) \
312 & (_FP_OVERFLOW_##fs >> 1)) \
314 X##_e = 1; \
315 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
316 FP_SET_EXCEPTION (FP_EX_INEXACT); \
318 else \
320 X##_e = 0; \
321 _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
323 if (_FP_PACK_CANONICAL_is_tiny \
324 && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
325 || (FP_TRAPPING_EXCEPTIONS \
326 & FP_EX_UNDERFLOW))) \
327 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
329 else \
331 /* Underflow to zero. */ \
332 X##_e = 0; \
333 if (!_FP_FRAC_ZEROP_##wc (X)) \
335 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
336 _FP_ROUND (wc, X); \
337 _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS); \
339 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
342 break; \
344 case FP_CLS_ZERO: \
345 X##_e = 0; \
346 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
347 break; \
349 case FP_CLS_INF: \
350 X##_e = _FP_EXPMAX_##fs; \
351 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
352 break; \
354 case FP_CLS_NAN: \
355 X##_e = _FP_EXPMAX_##fs; \
356 if (!_FP_KEEPNANFRACP) \
358 _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \
359 X##_s = _FP_NANSIGN_##fs; \
361 else \
362 _FP_SETQNAN (fs, wc, X); \
363 break; \
366 while (0)
368 /* This one accepts raw argument and not cooked, returns
369 1 if X is a signaling NaN. */
370 #define _FP_ISSIGNAN(fs, wc, X) \
371 ({ \
372 int _FP_ISSIGNAN_ret = 0; \
373 if (X##_e == _FP_EXPMAX_##fs) \
375 if (!_FP_FRAC_ZEROP_##wc (X) \
376 && _FP_FRAC_SNANP (fs, X)) \
377 _FP_ISSIGNAN_ret = 1; \
379 _FP_ISSIGNAN_ret; \
386 /* Addition on semi-raw values. */
387 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
388 do \
390 if (X##_s == Y##_s) \
392 /* Addition. */ \
393 R##_s = X##_s; \
394 int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e; \
395 if (_FP_ADD_INTERNAL_ediff > 0) \
397 R##_e = X##_e; \
398 if (Y##_e == 0) \
400 /* Y is zero or denormalized. */ \
401 if (_FP_FRAC_ZEROP_##wc (Y)) \
403 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
404 _FP_FRAC_COPY_##wc (R, X); \
405 goto add_done; \
407 else \
409 FP_SET_EXCEPTION (FP_EX_DENORM); \
410 _FP_ADD_INTERNAL_ediff--; \
411 if (_FP_ADD_INTERNAL_ediff == 0) \
413 _FP_FRAC_ADD_##wc (R, X, Y); \
414 goto add3; \
416 if (X##_e == _FP_EXPMAX_##fs) \
418 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
419 _FP_FRAC_COPY_##wc (R, X); \
420 goto add_done; \
422 goto add1; \
425 else if (X##_e == _FP_EXPMAX_##fs) \
427 /* X is NaN or Inf, Y is normal. */ \
428 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
429 _FP_FRAC_COPY_##wc (R, X); \
430 goto add_done; \
433 /* Insert implicit MSB of Y. */ \
434 _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \
436 add1: \
437 /* Shift the mantissa of Y to the right \
438 _FP_ADD_INTERNAL_EDIFF steps; remember to account \
439 later for the implicit MSB of X. */ \
440 if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \
441 _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff, \
442 _FP_WFRACBITS_##fs); \
443 else if (!_FP_FRAC_ZEROP_##wc (Y)) \
444 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \
445 _FP_FRAC_ADD_##wc (R, X, Y); \
447 else if (_FP_ADD_INTERNAL_ediff < 0) \
449 _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff; \
450 R##_e = Y##_e; \
451 if (X##_e == 0) \
453 /* X is zero or denormalized. */ \
454 if (_FP_FRAC_ZEROP_##wc (X)) \
456 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
457 _FP_FRAC_COPY_##wc (R, Y); \
458 goto add_done; \
460 else \
462 FP_SET_EXCEPTION (FP_EX_DENORM); \
463 _FP_ADD_INTERNAL_ediff--; \
464 if (_FP_ADD_INTERNAL_ediff == 0) \
466 _FP_FRAC_ADD_##wc (R, Y, X); \
467 goto add3; \
469 if (Y##_e == _FP_EXPMAX_##fs) \
471 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
472 _FP_FRAC_COPY_##wc (R, Y); \
473 goto add_done; \
475 goto add2; \
478 else if (Y##_e == _FP_EXPMAX_##fs) \
480 /* Y is NaN or Inf, X is normal. */ \
481 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
482 _FP_FRAC_COPY_##wc (R, Y); \
483 goto add_done; \
486 /* Insert implicit MSB of X. */ \
487 _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \
489 add2: \
490 /* Shift the mantissa of X to the right \
491 _FP_ADD_INTERNAL_EDIFF steps; remember to account \
492 later for the implicit MSB of Y. */ \
493 if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \
494 _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff, \
495 _FP_WFRACBITS_##fs); \
496 else if (!_FP_FRAC_ZEROP_##wc (X)) \
497 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
498 _FP_FRAC_ADD_##wc (R, Y, X); \
500 else \
502 /* _FP_ADD_INTERNAL_ediff == 0. */ \
503 if (!_FP_EXP_NORMAL (fs, wc, X)) \
505 if (X##_e == 0) \
507 /* X and Y are zero or denormalized. */ \
508 R##_e = 0; \
509 if (_FP_FRAC_ZEROP_##wc (X)) \
511 if (!_FP_FRAC_ZEROP_##wc (Y)) \
512 FP_SET_EXCEPTION (FP_EX_DENORM); \
513 _FP_FRAC_COPY_##wc (R, Y); \
514 goto add_done; \
516 else if (_FP_FRAC_ZEROP_##wc (Y)) \
518 FP_SET_EXCEPTION (FP_EX_DENORM); \
519 _FP_FRAC_COPY_##wc (R, X); \
520 goto add_done; \
522 else \
524 FP_SET_EXCEPTION (FP_EX_DENORM); \
525 _FP_FRAC_ADD_##wc (R, X, Y); \
526 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
528 /* Normalized result. */ \
529 _FP_FRAC_HIGH_##fs (R) \
530 &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
531 R##_e = 1; \
533 goto add_done; \
536 else \
538 /* X and Y are NaN or Inf. */ \
539 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
540 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
541 R##_e = _FP_EXPMAX_##fs; \
542 if (_FP_FRAC_ZEROP_##wc (X)) \
543 _FP_FRAC_COPY_##wc (R, Y); \
544 else if (_FP_FRAC_ZEROP_##wc (Y)) \
545 _FP_FRAC_COPY_##wc (R, X); \
546 else \
547 _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
548 goto add_done; \
551 /* The exponents of X and Y, both normal, are equal. The \
552 implicit MSBs will always add to increase the \
553 exponent. */ \
554 _FP_FRAC_ADD_##wc (R, X, Y); \
555 R##_e = X##_e + 1; \
556 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
557 if (R##_e == _FP_EXPMAX_##fs) \
558 /* Overflow to infinity (depending on rounding mode). */ \
559 _FP_OVERFLOW_SEMIRAW (fs, wc, R); \
560 goto add_done; \
562 add3: \
563 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
565 /* Overflow. */ \
566 _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
567 R##_e++; \
568 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
569 if (R##_e == _FP_EXPMAX_##fs) \
570 /* Overflow to infinity (depending on rounding mode). */ \
571 _FP_OVERFLOW_SEMIRAW (fs, wc, R); \
573 add_done: ; \
575 else \
577 /* Subtraction. */ \
578 int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e; \
579 if (_FP_ADD_INTERNAL_ediff > 0) \
581 R##_e = X##_e; \
582 R##_s = X##_s; \
583 if (Y##_e == 0) \
585 /* Y is zero or denormalized. */ \
586 if (_FP_FRAC_ZEROP_##wc (Y)) \
588 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
589 _FP_FRAC_COPY_##wc (R, X); \
590 goto sub_done; \
592 else \
594 FP_SET_EXCEPTION (FP_EX_DENORM); \
595 _FP_ADD_INTERNAL_ediff--; \
596 if (_FP_ADD_INTERNAL_ediff == 0) \
598 _FP_FRAC_SUB_##wc (R, X, Y); \
599 goto sub3; \
601 if (X##_e == _FP_EXPMAX_##fs) \
603 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
604 _FP_FRAC_COPY_##wc (R, X); \
605 goto sub_done; \
607 goto sub1; \
610 else if (X##_e == _FP_EXPMAX_##fs) \
612 /* X is NaN or Inf, Y is normal. */ \
613 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
614 _FP_FRAC_COPY_##wc (R, X); \
615 goto sub_done; \
618 /* Insert implicit MSB of Y. */ \
619 _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \
621 sub1: \
622 /* Shift the mantissa of Y to the right \
623 _FP_ADD_INTERNAL_EDIFF steps; remember to account \
624 later for the implicit MSB of X. */ \
625 if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \
626 _FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff, \
627 _FP_WFRACBITS_##fs); \
628 else if (!_FP_FRAC_ZEROP_##wc (Y)) \
629 _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \
630 _FP_FRAC_SUB_##wc (R, X, Y); \
632 else if (_FP_ADD_INTERNAL_ediff < 0) \
634 _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff; \
635 R##_e = Y##_e; \
636 R##_s = Y##_s; \
637 if (X##_e == 0) \
639 /* X is zero or denormalized. */ \
640 if (_FP_FRAC_ZEROP_##wc (X)) \
642 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
643 _FP_FRAC_COPY_##wc (R, Y); \
644 goto sub_done; \
646 else \
648 FP_SET_EXCEPTION (FP_EX_DENORM); \
649 _FP_ADD_INTERNAL_ediff--; \
650 if (_FP_ADD_INTERNAL_ediff == 0) \
652 _FP_FRAC_SUB_##wc (R, Y, X); \
653 goto sub3; \
655 if (Y##_e == _FP_EXPMAX_##fs) \
657 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
658 _FP_FRAC_COPY_##wc (R, Y); \
659 goto sub_done; \
661 goto sub2; \
664 else if (Y##_e == _FP_EXPMAX_##fs) \
666 /* Y is NaN or Inf, X is normal. */ \
667 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
668 _FP_FRAC_COPY_##wc (R, Y); \
669 goto sub_done; \
672 /* Insert implicit MSB of X. */ \
673 _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \
675 sub2: \
676 /* Shift the mantissa of X to the right \
677 _FP_ADD_INTERNAL_EDIFF steps; remember to account \
678 later for the implicit MSB of Y. */ \
679 if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs) \
680 _FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff, \
681 _FP_WFRACBITS_##fs); \
682 else if (!_FP_FRAC_ZEROP_##wc (X)) \
683 _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \
684 _FP_FRAC_SUB_##wc (R, Y, X); \
686 else \
688 /* ediff == 0. */ \
689 if (!_FP_EXP_NORMAL (fs, wc, X)) \
691 if (X##_e == 0) \
693 /* X and Y are zero or denormalized. */ \
694 R##_e = 0; \
695 if (_FP_FRAC_ZEROP_##wc (X)) \
697 _FP_FRAC_COPY_##wc (R, Y); \
698 if (_FP_FRAC_ZEROP_##wc (Y)) \
699 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
700 else \
702 FP_SET_EXCEPTION (FP_EX_DENORM); \
703 R##_s = Y##_s; \
705 goto sub_done; \
707 else if (_FP_FRAC_ZEROP_##wc (Y)) \
709 FP_SET_EXCEPTION (FP_EX_DENORM); \
710 _FP_FRAC_COPY_##wc (R, X); \
711 R##_s = X##_s; \
712 goto sub_done; \
714 else \
716 FP_SET_EXCEPTION (FP_EX_DENORM); \
717 _FP_FRAC_SUB_##wc (R, X, Y); \
718 R##_s = X##_s; \
719 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
721 /* |X| < |Y|, negate result. */ \
722 _FP_FRAC_SUB_##wc (R, Y, X); \
723 R##_s = Y##_s; \
725 else if (_FP_FRAC_ZEROP_##wc (R)) \
726 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
727 goto sub_done; \
730 else \
732 /* X and Y are NaN or Inf, of opposite signs. */ \
733 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \
734 _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \
735 R##_e = _FP_EXPMAX_##fs; \
736 if (_FP_FRAC_ZEROP_##wc (X)) \
738 if (_FP_FRAC_ZEROP_##wc (Y)) \
740 /* Inf - Inf. */ \
741 R##_s = _FP_NANSIGN_##fs; \
742 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
743 _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \
744 FP_SET_EXCEPTION (FP_EX_INVALID); \
746 else \
748 /* Inf - NaN. */ \
749 R##_s = Y##_s; \
750 _FP_FRAC_COPY_##wc (R, Y); \
753 else \
755 if (_FP_FRAC_ZEROP_##wc (Y)) \
757 /* NaN - Inf. */ \
758 R##_s = X##_s; \
759 _FP_FRAC_COPY_##wc (R, X); \
761 else \
763 /* NaN - NaN. */ \
764 _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
767 goto sub_done; \
770 /* The exponents of X and Y, both normal, are equal. The \
771 implicit MSBs cancel. */ \
772 R##_e = X##_e; \
773 _FP_FRAC_SUB_##wc (R, X, Y); \
774 R##_s = X##_s; \
775 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
777 /* |X| < |Y|, negate result. */ \
778 _FP_FRAC_SUB_##wc (R, Y, X); \
779 R##_s = Y##_s; \
781 else if (_FP_FRAC_ZEROP_##wc (R)) \
783 R##_e = 0; \
784 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
785 goto sub_done; \
787 goto norm; \
789 sub3: \
790 if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
792 int _FP_ADD_INTERNAL_diff; \
793 /* Carry into most significant bit of larger one of X and Y, \
794 canceling it; renormalize. */ \
795 _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1; \
796 norm: \
797 _FP_FRAC_CLZ_##wc (_FP_ADD_INTERNAL_diff, R); \
798 _FP_ADD_INTERNAL_diff -= _FP_WFRACXBITS_##fs; \
799 _FP_FRAC_SLL_##wc (R, _FP_ADD_INTERNAL_diff); \
800 if (R##_e <= _FP_ADD_INTERNAL_diff) \
802 /* R is denormalized. */ \
803 _FP_ADD_INTERNAL_diff \
804 = _FP_ADD_INTERNAL_diff - R##_e + 1; \
805 _FP_FRAC_SRS_##wc (R, _FP_ADD_INTERNAL_diff, \
806 _FP_WFRACBITS_##fs); \
807 R##_e = 0; \
809 else \
811 R##_e -= _FP_ADD_INTERNAL_diff; \
812 _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
815 sub_done: ; \
818 while (0)
820 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+')
821 #define _FP_SUB(fs, wc, R, X, Y) \
822 do \
824 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
825 Y##_s ^= 1; \
826 _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-'); \
828 while (0)
831 /* Main negation routine. The input value is raw. */
833 #define _FP_NEG(fs, wc, R, X) \
834 do \
836 _FP_FRAC_COPY_##wc (R, X); \
837 R##_e = X##_e; \
838 R##_s = 1 ^ X##_s; \
840 while (0)
843 /* Main multiplication routine. The input values should be cooked. */
845 #define _FP_MUL(fs, wc, R, X, Y) \
846 do \
848 R##_s = X##_s ^ Y##_s; \
849 R##_e = X##_e + Y##_e + 1; \
850 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
852 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
853 R##_c = FP_CLS_NORMAL; \
855 _FP_MUL_MEAT_##fs (R, X, Y); \
857 if (_FP_FRAC_OVERP_##wc (fs, R)) \
858 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
859 else \
860 R##_e--; \
861 break; \
863 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
864 _FP_CHOOSENAN (fs, wc, R, X, Y, '*'); \
865 break; \
867 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
868 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
869 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
870 R##_s = X##_s; \
872 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
873 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
874 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
875 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
876 _FP_FRAC_COPY_##wc (R, X); \
877 R##_c = X##_c; \
878 break; \
880 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
881 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
882 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
883 R##_s = Y##_s; \
885 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
886 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
887 _FP_FRAC_COPY_##wc (R, Y); \
888 R##_c = Y##_c; \
889 break; \
891 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
892 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
893 R##_s = _FP_NANSIGN_##fs; \
894 R##_c = FP_CLS_NAN; \
895 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
896 FP_SET_EXCEPTION (FP_EX_INVALID); \
897 break; \
899 default: \
900 abort (); \
903 while (0)
906 /* Fused multiply-add. The input values should be cooked. */
908 #define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \
909 do \
911 FP_DECL_##fs (_FP_FMA_T); \
912 _FP_FMA_T##_s = X##_s ^ Y##_s; \
913 _FP_FMA_T##_e = X##_e + Y##_e + 1; \
914 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
916 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
917 switch (Z##_c) \
919 case FP_CLS_INF: \
920 case FP_CLS_NAN: \
921 R##_s = Z##_s; \
922 _FP_FRAC_COPY_##wc (R, Z); \
923 R##_c = Z##_c; \
924 break; \
926 case FP_CLS_ZERO: \
927 R##_c = FP_CLS_NORMAL; \
928 R##_s = _FP_FMA_T##_s; \
929 R##_e = _FP_FMA_T##_e; \
931 _FP_MUL_MEAT_##fs (R, X, Y); \
933 if (_FP_FRAC_OVERP_##wc (fs, R)) \
934 _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \
935 else \
936 R##_e--; \
937 break; \
939 case FP_CLS_NORMAL:; \
940 _FP_FRAC_DECL_##dwc (_FP_FMA_TD); \
941 _FP_FRAC_DECL_##dwc (_FP_FMA_ZD); \
942 _FP_FRAC_DECL_##dwc (_FP_FMA_RD); \
943 _FP_MUL_MEAT_DW_##fs (_FP_FMA_TD, X, Y); \
944 R##_e = _FP_FMA_T##_e; \
945 int _FP_FMA_tsh \
946 = _FP_FRAC_HIGHBIT_DW_##dwc (fs, _FP_FMA_TD) == 0; \
947 _FP_FMA_T##_e -= _FP_FMA_tsh; \
948 int _FP_FMA_ediff = _FP_FMA_T##_e - Z##_e; \
949 if (_FP_FMA_ediff >= 0) \
951 int _FP_FMA_shift \
952 = _FP_WFRACBITS_##fs - _FP_FMA_tsh - _FP_FMA_ediff; \
953 if (_FP_FMA_shift <= -_FP_WFRACBITS_##fs) \
954 _FP_FRAC_SET_##dwc (_FP_FMA_ZD, _FP_MINFRAC_##dwc); \
955 else \
957 _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z); \
958 if (_FP_FMA_shift < 0) \
959 _FP_FRAC_SRS_##dwc (_FP_FMA_ZD, -_FP_FMA_shift, \
960 _FP_WFRACBITS_DW_##fs); \
961 else if (_FP_FMA_shift > 0) \
962 _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_FMA_shift); \
964 R##_s = _FP_FMA_T##_s; \
965 if (_FP_FMA_T##_s == Z##_s) \
966 _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_TD, \
967 _FP_FMA_ZD); \
968 else \
970 _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_TD, \
971 _FP_FMA_ZD); \
972 if (_FP_FRAC_NEGP_##dwc (_FP_FMA_RD)) \
974 R##_s = Z##_s; \
975 _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \
976 _FP_FMA_TD); \
980 else \
982 R##_e = Z##_e; \
983 R##_s = Z##_s; \
984 _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z); \
985 _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_WFRACBITS_##fs); \
986 int _FP_FMA_shift = -_FP_FMA_ediff - _FP_FMA_tsh; \
987 if (_FP_FMA_shift >= _FP_WFRACBITS_DW_##fs) \
988 _FP_FRAC_SET_##dwc (_FP_FMA_TD, _FP_MINFRAC_##dwc); \
989 else if (_FP_FMA_shift > 0) \
990 _FP_FRAC_SRS_##dwc (_FP_FMA_TD, _FP_FMA_shift, \
991 _FP_WFRACBITS_DW_##fs); \
992 if (Z##_s == _FP_FMA_T##_s) \
993 _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \
994 _FP_FMA_TD); \
995 else \
996 _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD, \
997 _FP_FMA_TD); \
999 if (_FP_FRAC_ZEROP_##dwc (_FP_FMA_RD)) \
1001 if (_FP_FMA_T##_s == Z##_s) \
1002 R##_s = Z##_s; \
1003 else \
1004 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
1005 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1006 R##_c = FP_CLS_ZERO; \
1008 else \
1010 int _FP_FMA_rlz; \
1011 _FP_FRAC_CLZ_##dwc (_FP_FMA_rlz, _FP_FMA_RD); \
1012 _FP_FMA_rlz -= _FP_WFRACXBITS_DW_##fs; \
1013 R##_e -= _FP_FMA_rlz; \
1014 int _FP_FMA_shift = _FP_WFRACBITS_##fs - _FP_FMA_rlz; \
1015 if (_FP_FMA_shift > 0) \
1016 _FP_FRAC_SRS_##dwc (_FP_FMA_RD, _FP_FMA_shift, \
1017 _FP_WFRACBITS_DW_##fs); \
1018 else if (_FP_FMA_shift < 0) \
1019 _FP_FRAC_SLL_##dwc (_FP_FMA_RD, -_FP_FMA_shift); \
1020 _FP_FRAC_COPY_##wc##_##dwc (R, _FP_FMA_RD); \
1021 R##_c = FP_CLS_NORMAL; \
1023 break; \
1025 goto done_fma; \
1027 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1028 _FP_CHOOSENAN (fs, wc, _FP_FMA_T, X, Y, '*'); \
1029 break; \
1031 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1032 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1033 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1034 _FP_FMA_T##_s = X##_s; \
1036 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1037 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1038 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1039 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1040 _FP_FRAC_COPY_##wc (_FP_FMA_T, X); \
1041 _FP_FMA_T##_c = X##_c; \
1042 break; \
1044 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
1045 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1046 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1047 _FP_FMA_T##_s = Y##_s; \
1049 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
1050 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
1051 _FP_FRAC_COPY_##wc (_FP_FMA_T, Y); \
1052 _FP_FMA_T##_c = Y##_c; \
1053 break; \
1055 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1056 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1057 _FP_FMA_T##_s = _FP_NANSIGN_##fs; \
1058 _FP_FMA_T##_c = FP_CLS_NAN; \
1059 _FP_FRAC_SET_##wc (_FP_FMA_T, _FP_NANFRAC_##fs); \
1060 FP_SET_EXCEPTION (FP_EX_INVALID); \
1061 break; \
1063 default: \
1064 abort (); \
1067 /* T = X * Y is zero, infinity or NaN. */ \
1068 switch (_FP_CLS_COMBINE (_FP_FMA_T##_c, Z##_c)) \
1070 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1071 _FP_CHOOSENAN (fs, wc, R, _FP_FMA_T, Z, '+'); \
1072 break; \
1074 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1075 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1076 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1077 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1078 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1079 R##_s = _FP_FMA_T##_s; \
1080 _FP_FRAC_COPY_##wc (R, _FP_FMA_T); \
1081 R##_c = _FP_FMA_T##_c; \
1082 break; \
1084 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1085 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1086 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1087 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1088 R##_s = Z##_s; \
1089 _FP_FRAC_COPY_##wc (R, Z); \
1090 R##_c = Z##_c; \
1091 break; \
1093 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1094 if (_FP_FMA_T##_s == Z##_s) \
1096 R##_s = Z##_s; \
1097 _FP_FRAC_COPY_##wc (R, Z); \
1098 R##_c = Z##_c; \
1100 else \
1102 R##_s = _FP_NANSIGN_##fs; \
1103 R##_c = FP_CLS_NAN; \
1104 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1105 FP_SET_EXCEPTION (FP_EX_INVALID); \
1107 break; \
1109 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1110 if (_FP_FMA_T##_s == Z##_s) \
1111 R##_s = Z##_s; \
1112 else \
1113 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
1114 _FP_FRAC_COPY_##wc (R, Z); \
1115 R##_c = Z##_c; \
1116 break; \
1118 default: \
1119 abort (); \
1121 done_fma: ; \
1123 while (0)
1126 /* Main division routine. The input values should be cooked. */
1128 #define _FP_DIV(fs, wc, R, X, Y) \
1129 do \
1131 R##_s = X##_s ^ Y##_s; \
1132 R##_e = X##_e - Y##_e; \
1133 switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \
1135 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \
1136 R##_c = FP_CLS_NORMAL; \
1138 _FP_DIV_MEAT_##fs (R, X, Y); \
1139 break; \
1141 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \
1142 _FP_CHOOSENAN (fs, wc, R, X, Y, '/'); \
1143 break; \
1145 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \
1146 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \
1147 case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \
1148 R##_s = X##_s; \
1149 _FP_FRAC_COPY_##wc (R, X); \
1150 R##_c = X##_c; \
1151 break; \
1153 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \
1154 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \
1155 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \
1156 R##_s = Y##_s; \
1157 _FP_FRAC_COPY_##wc (R, Y); \
1158 R##_c = Y##_c; \
1159 break; \
1161 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \
1162 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \
1163 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \
1164 R##_c = FP_CLS_ZERO; \
1165 break; \
1167 case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \
1168 FP_SET_EXCEPTION (FP_EX_DIVZERO); \
1169 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \
1170 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \
1171 R##_c = FP_CLS_INF; \
1172 break; \
1174 case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \
1175 case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \
1176 R##_s = _FP_NANSIGN_##fs; \
1177 R##_c = FP_CLS_NAN; \
1178 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1179 FP_SET_EXCEPTION (FP_EX_INVALID); \
1180 break; \
1182 default: \
1183 abort (); \
1186 while (0)
1189 /* Helper for comparisons. EX is 0 not to raise exceptions, 1 to
1190 raise exceptions for signaling NaN operands, 2 to raise exceptions
1191 for all NaN operands. */
1193 #define _FP_CMP_CHECK_NAN(fs, wc, X, Y, ex) \
1194 do \
1196 if (ex) \
1198 if ((ex) == 2 \
1199 || _FP_ISSIGNAN (fs, wc, X) \
1200 || _FP_ISSIGNAN (fs, wc, Y)) \
1201 FP_SET_EXCEPTION (FP_EX_INVALID); \
1204 while (0)
1206 /* Main differential comparison routine. The inputs should be raw not
1207 cooked. The return is -1, 0, 1 for normal values, UN
1208 otherwise. */
1210 #define _FP_CMP(fs, wc, ret, X, Y, un, ex) \
1211 do \
1213 /* NANs are unordered. */ \
1214 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1215 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
1217 ret = un; \
1218 _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex); \
1220 else \
1222 int _FP_CMP_is_zero_x; \
1223 int _FP_CMP_is_zero_y; \
1225 _FP_CMP_is_zero_x \
1226 = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0; \
1227 _FP_CMP_is_zero_y \
1228 = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0; \
1230 if (_FP_CMP_is_zero_x && _FP_CMP_is_zero_y) \
1231 ret = 0; \
1232 else if (_FP_CMP_is_zero_x) \
1233 ret = Y##_s ? 1 : -1; \
1234 else if (_FP_CMP_is_zero_y) \
1235 ret = X##_s ? -1 : 1; \
1236 else if (X##_s != Y##_s) \
1237 ret = X##_s ? -1 : 1; \
1238 else if (X##_e > Y##_e) \
1239 ret = X##_s ? -1 : 1; \
1240 else if (X##_e < Y##_e) \
1241 ret = X##_s ? 1 : -1; \
1242 else if (_FP_FRAC_GT_##wc (X, Y)) \
1243 ret = X##_s ? -1 : 1; \
1244 else if (_FP_FRAC_GT_##wc (Y, X)) \
1245 ret = X##_s ? 1 : -1; \
1246 else \
1247 ret = 0; \
1250 while (0)
1253 /* Simplification for strict equality. */
1255 #define _FP_CMP_EQ(fs, wc, ret, X, Y, ex) \
1256 do \
1258 /* NANs are unordered. */ \
1259 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1260 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \
1262 ret = 1; \
1263 _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex); \
1265 else \
1267 ret = !(X##_e == Y##_e \
1268 && _FP_FRAC_EQ_##wc (X, Y) \
1269 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc (X)))); \
1272 while (0)
1274 /* Version to test unordered. */
1276 #define _FP_CMP_UNORD(fs, wc, ret, X, Y, ex) \
1277 do \
1279 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \
1280 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \
1281 if (ret) \
1282 _FP_CMP_CHECK_NAN (fs, wc, X, Y, ex); \
1284 while (0)
1286 /* Main square root routine. The input value should be cooked. */
1288 #define _FP_SQRT(fs, wc, R, X) \
1289 do \
1291 _FP_FRAC_DECL_##wc (_FP_SQRT_T); \
1292 _FP_FRAC_DECL_##wc (_FP_SQRT_S); \
1293 _FP_W_TYPE _FP_SQRT_q; \
1294 switch (X##_c) \
1296 case FP_CLS_NAN: \
1297 _FP_FRAC_COPY_##wc (R, X); \
1298 R##_s = X##_s; \
1299 R##_c = FP_CLS_NAN; \
1300 break; \
1301 case FP_CLS_INF: \
1302 if (X##_s) \
1304 R##_s = _FP_NANSIGN_##fs; \
1305 R##_c = FP_CLS_NAN; /* NAN */ \
1306 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1307 FP_SET_EXCEPTION (FP_EX_INVALID); \
1309 else \
1311 R##_s = 0; \
1312 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
1314 break; \
1315 case FP_CLS_ZERO: \
1316 R##_s = X##_s; \
1317 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
1318 break; \
1319 case FP_CLS_NORMAL: \
1320 R##_s = 0; \
1321 if (X##_s) \
1323 R##_c = FP_CLS_NAN; /* NAN */ \
1324 R##_s = _FP_NANSIGN_##fs; \
1325 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
1326 FP_SET_EXCEPTION (FP_EX_INVALID); \
1327 break; \
1329 R##_c = FP_CLS_NORMAL; \
1330 if (X##_e & 1) \
1331 _FP_FRAC_SLL_##wc (X, 1); \
1332 R##_e = X##_e >> 1; \
1333 _FP_FRAC_SET_##wc (_FP_SQRT_S, _FP_ZEROFRAC_##wc); \
1334 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1335 _FP_SQRT_q = _FP_OVERFLOW_##fs >> 1; \
1336 _FP_SQRT_MEAT_##wc (R, _FP_SQRT_S, _FP_SQRT_T, X, \
1337 _FP_SQRT_q); \
1340 while (0)
1342 /* Convert from FP to integer. Input is raw. */
1344 /* RSIGNED can have following values:
1345 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
1346 the result is either 0 or (2^rsize)-1 depending on the sign in such
1347 case.
1348 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
1349 NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1350 depending on the sign in such case.
1351 -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1352 set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1353 depending on the sign in such case. */
1354 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1355 do \
1357 if (X##_e < _FP_EXPBIAS_##fs) \
1359 r = 0; \
1360 if (X##_e == 0) \
1362 if (!_FP_FRAC_ZEROP_##wc (X)) \
1364 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1365 FP_SET_EXCEPTION (FP_EX_DENORM); \
1368 else \
1369 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1371 else if (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + rsize \
1372 ? _FP_EXPMAX_##fs \
1373 : _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s)) \
1374 || (!rsigned && X##_s)) \
1376 /* Overflow or converting to the most negative integer. */ \
1377 if (rsigned) \
1379 r = 1; \
1380 r <<= rsize - 1; \
1381 r -= 1 - X##_s; \
1383 else \
1385 r = 0; \
1386 if (!X##_s) \
1387 r = ~r; \
1390 if (_FP_EXPBIAS_##fs + rsize - 1 < _FP_EXPMAX_##fs \
1391 && rsigned \
1392 && X##_s \
1393 && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1395 /* Possibly converting to most negative integer; check the \
1396 mantissa. */ \
1397 int _FP_TO_INT_inexact = 0; \
1398 (void) ((_FP_FRACBITS_##fs > rsize) \
1399 ? ({ \
1400 _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact, \
1401 _FP_FRACBITS_##fs - rsize, \
1402 _FP_FRACBITS_##fs); \
1403 0; \
1404 }) \
1405 : 0); \
1406 if (!_FP_FRAC_ZEROP_##wc (X)) \
1407 FP_SET_EXCEPTION (FP_EX_INVALID); \
1408 else if (_FP_TO_INT_inexact) \
1409 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1411 else \
1412 FP_SET_EXCEPTION (FP_EX_INVALID); \
1414 else \
1416 _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \
1417 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1419 _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \
1420 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1422 else \
1424 int _FP_TO_INT_inexact; \
1425 _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact, \
1426 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1427 - X##_e), \
1428 _FP_FRACBITS_##fs); \
1429 if (_FP_TO_INT_inexact) \
1430 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1431 _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \
1433 if (rsigned && X##_s) \
1434 r = -r; \
1437 while (0)
1439 /* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1440 input is signed. */
1441 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1442 do \
1444 if (r) \
1446 rtype _FP_FROM_INT_ur; \
1448 if ((X##_s = (r < 0))) \
1449 r = -(rtype) r; \
1451 _FP_FROM_INT_ur = (rtype) r; \
1452 (void) ((rsize <= _FP_W_TYPE_SIZE) \
1453 ? ({ \
1454 int _FP_FROM_INT_lz; \
1455 __FP_CLZ (_FP_FROM_INT_lz, \
1456 (_FP_W_TYPE) _FP_FROM_INT_ur); \
1457 X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 \
1458 - _FP_FROM_INT_lz); \
1459 }) \
1460 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1461 ? ({ \
1462 int _FP_FROM_INT_lz; \
1463 __FP_CLZ_2 (_FP_FROM_INT_lz, \
1464 (_FP_W_TYPE) (_FP_FROM_INT_ur \
1465 >> _FP_W_TYPE_SIZE), \
1466 (_FP_W_TYPE) _FP_FROM_INT_ur); \
1467 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1468 - _FP_FROM_INT_lz); \
1469 }) \
1470 : (abort (), 0))); \
1472 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1473 && X##_e >= _FP_EXPMAX_##fs) \
1475 /* Exponent too big; overflow to infinity. (May also \
1476 happen after rounding below.) */ \
1477 _FP_OVERFLOW_SEMIRAW (fs, wc, X); \
1478 goto pack_semiraw; \
1481 if (rsize <= _FP_FRACBITS_##fs \
1482 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1484 /* Exactly representable; shift left. */ \
1485 _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, rsize); \
1486 if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \
1487 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \
1488 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1490 else \
1492 /* More bits in integer than in floating type; need to \
1493 round. */ \
1494 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1495 _FP_FROM_INT_ur \
1496 = ((_FP_FROM_INT_ur >> (X##_e - _FP_EXPBIAS_##fs \
1497 - _FP_WFRACBITS_##fs + 1)) \
1498 | ((_FP_FROM_INT_ur \
1499 << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1500 - _FP_WFRACBITS_##fs + 1))) \
1501 != 0)); \
1502 _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, rsize); \
1503 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
1504 _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \
1505 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1506 _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
1507 pack_semiraw: \
1508 _FP_PACK_SEMIRAW (fs, wc, X); \
1511 else \
1513 X##_s = 0; \
1514 X##_e = 0; \
1515 _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \
1518 while (0)
1521 /* Extend from a narrower floating-point format to a wider one. Input
1522 and output are raw. */
1523 #define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \
1524 do \
1526 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1527 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1528 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1529 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1530 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
1531 abort (); \
1532 D##_s = S##_s; \
1533 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1534 if (_FP_EXP_NORMAL (sfs, swc, S)) \
1536 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1537 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1539 else \
1541 if (S##_e == 0) \
1543 if (_FP_FRAC_ZEROP_##swc (S)) \
1544 D##_e = 0; \
1545 else if (_FP_EXPBIAS_##dfs \
1546 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1548 FP_SET_EXCEPTION (FP_EX_DENORM); \
1549 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \
1550 - _FP_FRACBITS_##sfs)); \
1551 D##_e = 0; \
1552 if (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW) \
1553 FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
1555 else \
1557 int FP_EXTEND_lz; \
1558 FP_SET_EXCEPTION (FP_EX_DENORM); \
1559 _FP_FRAC_CLZ_##swc (FP_EXTEND_lz, S); \
1560 _FP_FRAC_SLL_##dwc (D, \
1561 FP_EXTEND_lz + _FP_FRACBITS_##dfs \
1562 - _FP_FRACTBITS_##sfs); \
1563 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1564 + _FP_FRACXBITS_##sfs - FP_EXTEND_lz); \
1567 else \
1569 D##_e = _FP_EXPMAX_##dfs; \
1570 if (!_FP_FRAC_ZEROP_##swc (S)) \
1572 if (_FP_FRAC_SNANP (sfs, S)) \
1573 FP_SET_EXCEPTION (FP_EX_INVALID); \
1574 _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \
1575 - _FP_FRACBITS_##sfs)); \
1576 _FP_SETQNAN (dfs, dwc, D); \
1581 while (0)
1583 /* Truncate from a wider floating-point format to a narrower one.
1584 Input and output are semi-raw. */
1585 #define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \
1586 do \
1588 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1589 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1590 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
1591 abort (); \
1592 D##_s = S##_s; \
1593 if (_FP_EXP_NORMAL (sfs, swc, S)) \
1595 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1596 if (D##_e >= _FP_EXPMAX_##dfs) \
1597 _FP_OVERFLOW_SEMIRAW (dfs, dwc, D); \
1598 else \
1600 if (D##_e <= 0) \
1602 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1604 _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc); \
1605 _FP_FRAC_LOW_##swc (S) |= 1; \
1607 else \
1609 _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs; \
1610 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1611 - _FP_WFRACBITS_##dfs \
1612 + 1 - D##_e), \
1613 _FP_WFRACBITS_##sfs); \
1615 D##_e = 0; \
1617 else \
1618 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1619 - _FP_WFRACBITS_##dfs), \
1620 _FP_WFRACBITS_##sfs); \
1621 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1624 else \
1626 if (S##_e == 0) \
1628 D##_e = 0; \
1629 if (_FP_FRAC_ZEROP_##swc (S)) \
1630 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1631 else \
1633 FP_SET_EXCEPTION (FP_EX_DENORM); \
1634 if (_FP_EXPBIAS_##sfs \
1635 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1637 _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \
1638 - _FP_WFRACBITS_##dfs), \
1639 _FP_WFRACBITS_##sfs); \
1640 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1642 else \
1644 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1645 _FP_FRAC_LOW_##dwc (D) |= 1; \
1649 else \
1651 D##_e = _FP_EXPMAX_##dfs; \
1652 if (_FP_FRAC_ZEROP_##swc (S)) \
1653 _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \
1654 else \
1656 _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S); \
1657 _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs \
1658 - _FP_WFRACBITS_##dfs)); \
1659 _FP_FRAC_COPY_##dwc##_##swc (D, S); \
1660 /* Semi-raw NaN must have all workbits cleared. */ \
1661 _FP_FRAC_LOW_##dwc (D) \
1662 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
1663 _FP_SETQNAN_SEMIRAW (dfs, dwc, D); \
1668 while (0)
1670 /* Helper primitives. */
1672 /* Count leading zeros in a word. */
1674 #ifndef __FP_CLZ
1675 /* GCC 3.4 and later provide the builtins for us. */
1676 # define __FP_CLZ(r, x) \
1677 do \
1679 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1680 r = __builtin_clz (x); \
1681 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1682 r = __builtin_clzl (x); \
1683 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1684 r = __builtin_clzll (x); \
1685 else \
1686 abort (); \
1688 while (0)
1689 #endif /* ndef __FP_CLZ */
1691 #define _FP_DIV_HELP_imm(q, r, n, d) \
1692 do \
1694 q = n / d, r = n % d; \
1696 while (0)
1699 /* A restoring bit-by-bit division primitive. */
1701 #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1702 do \
1704 int _FP_DIV_MEAT_N_loop_count = _FP_WFRACBITS_##fs; \
1705 _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_u); \
1706 _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_v); \
1707 _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_u, X); \
1708 _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_v, Y); \
1709 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1710 /* Normalize _FP_DIV_MEAT_N_LOOP_U and _FP_DIV_MEAT_N_LOOP_V. */ \
1711 _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, _FP_WFRACXBITS_##fs); \
1712 _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_v, _FP_WFRACXBITS_##fs); \
1713 /* First round. Since the operands are normalized, either the \
1714 first or second bit will be set in the fraction. Produce a \
1715 normalized result by checking which and adjusting the loop \
1716 count and exponent accordingly. */ \
1717 if (_FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, _FP_DIV_MEAT_N_loop_v)) \
1719 _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u, \
1720 _FP_DIV_MEAT_N_loop_u, \
1721 _FP_DIV_MEAT_N_loop_v); \
1722 _FP_FRAC_LOW_##wc (R) |= 1; \
1723 _FP_DIV_MEAT_N_loop_count--; \
1725 else \
1726 R##_e--; \
1727 /* Subsequent rounds. */ \
1728 do \
1730 int _FP_DIV_MEAT_N_loop_msb \
1731 = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (_FP_DIV_MEAT_N_loop_u) < 0; \
1732 _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, 1); \
1733 _FP_FRAC_SLL_##wc (R, 1); \
1734 if (_FP_DIV_MEAT_N_loop_msb \
1735 || _FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, \
1736 _FP_DIV_MEAT_N_loop_v)) \
1738 _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u, \
1739 _FP_DIV_MEAT_N_loop_u, \
1740 _FP_DIV_MEAT_N_loop_v); \
1741 _FP_FRAC_LOW_##wc (R) |= 1; \
1744 while (--_FP_DIV_MEAT_N_loop_count > 0); \
1745 /* If there's anything left in _FP_DIV_MEAT_N_LOOP_U, the result \
1746 is inexact. */ \
1747 _FP_FRAC_LOW_##wc (R) \
1748 |= !_FP_FRAC_ZEROP_##wc (_FP_DIV_MEAT_N_loop_u); \
1750 while (0)
1752 #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1753 #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1754 #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)