Define pie-ccflag and PIE-ccflag variables.
[glibc/history.git] / soft-fp / op-common.h
blobef11b527b7063a0bd57c2978bcff8c65929b8526
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997,1998,1999,2006,2007 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, write to the Free
30 Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
31 MA 02110-1301, USA. */
33 #define _FP_DECL(wc, X) \
34 _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \
35 _FP_FRAC_DECL_##wc(X)
38 * Finish truely unpacking a native fp value by classifying the kind
39 * of fp value and normalizing both the exponent and the fraction.
42 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
43 do { \
44 switch (X##_e) \
45 { \
46 default: \
47 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
48 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
49 X##_e -= _FP_EXPBIAS_##fs; \
50 X##_c = FP_CLS_NORMAL; \
51 break; \
53 case 0: \
54 if (_FP_FRAC_ZEROP_##wc(X)) \
55 X##_c = FP_CLS_ZERO; \
56 else \
57 { \
58 /* a denormalized number */ \
59 _FP_I_TYPE _shift; \
60 _FP_FRAC_CLZ_##wc(_shift, X); \
61 _shift -= _FP_FRACXBITS_##fs; \
62 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
63 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
64 X##_c = FP_CLS_NORMAL; \
65 FP_SET_EXCEPTION(FP_EX_DENORM); \
66 } \
67 break; \
69 case _FP_EXPMAX_##fs: \
70 if (_FP_FRAC_ZEROP_##wc(X)) \
71 X##_c = FP_CLS_INF; \
72 else \
73 { \
74 X##_c = FP_CLS_NAN; \
75 /* Check for signaling NaN */ \
76 if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
77 FP_SET_EXCEPTION(FP_EX_INVALID); \
78 } \
79 break; \
80 } \
81 } while (0)
83 /* Finish unpacking an fp value in semi-raw mode: the mantissa is
84 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
85 other classification is not done. */
86 #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
88 /* A semi-raw value has overflowed to infinity. Adjust the mantissa
89 and exponent appropriately. */
90 #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
91 do { \
92 if (FP_ROUNDMODE == FP_RND_NEAREST \
93 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
94 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
95 { \
96 X##_e = _FP_EXPMAX_##fs; \
97 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
98 } \
99 else \
101 X##_e = _FP_EXPMAX_##fs - 1; \
102 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
104 FP_SET_EXCEPTION(FP_EX_INEXACT); \
105 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
106 } while (0)
108 /* Check for a semi-raw value being a signaling NaN and raise the
109 invalid exception if so. */
110 #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
111 do { \
112 if (X##_e == _FP_EXPMAX_##fs \
113 && !_FP_FRAC_ZEROP_##wc(X) \
114 && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
115 FP_SET_EXCEPTION(FP_EX_INVALID); \
116 } while (0)
118 /* Choose a NaN result from an operation on two semi-raw NaN
119 values. */
120 #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
121 do { \
122 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
123 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
124 _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
125 _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
126 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
127 } while (0)
129 /* Test whether a biased exponent is normal (not zero or maximum). */
130 #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
132 /* Prepare to pack an fp value in semi-raw mode: the mantissa is
133 rounded and shifted right, with the rounding possibly increasing
134 the exponent (including changing a finite value to infinity). */
135 #define _FP_PACK_SEMIRAW(fs, wc, X) \
136 do { \
137 _FP_ROUND(wc, X); \
138 if (_FP_FRAC_HIGH_##fs(X) \
139 & (_FP_OVERFLOW_##fs >> 1)) \
141 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
142 X##_e++; \
143 if (X##_e == _FP_EXPMAX_##fs) \
144 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
146 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
147 if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \
149 if (X##_e == 0) \
150 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
151 else \
153 if (!_FP_KEEPNANFRACP) \
155 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
156 X##_s = _FP_NANSIGN_##fs; \
158 else \
159 _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); \
231 else \
233 X##_e = 0; \
234 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
235 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
238 else \
240 /* underflow to zero */ \
241 X##_e = 0; \
242 if (!_FP_FRAC_ZEROP_##wc(X)) \
244 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
245 _FP_ROUND(wc, X); \
246 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
248 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
251 break; \
253 case FP_CLS_ZERO: \
254 X##_e = 0; \
255 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
256 break; \
258 case FP_CLS_INF: \
259 X##_e = _FP_EXPMAX_##fs; \
260 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
261 break; \
263 case FP_CLS_NAN: \
264 X##_e = _FP_EXPMAX_##fs; \
265 if (!_FP_KEEPNANFRACP) \
267 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
268 X##_s = _FP_NANSIGN_##fs; \
270 else \
271 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
272 break; \
274 } while (0)
276 /* This one accepts raw argument and not cooked, returns
277 * 1 if X is a signaling NaN.
279 #define _FP_ISSIGNAN(fs, wc, X) \
280 ({ \
281 int __ret = 0; \
282 if (X##_e == _FP_EXPMAX_##fs) \
284 if (!_FP_FRAC_ZEROP_##wc(X) \
285 && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
286 __ret = 1; \
288 __ret; \
295 /* Addition on semi-raw values. */
296 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
297 do { \
298 if (X##_s == Y##_s) \
300 /* Addition. */ \
301 R##_s = X##_s; \
302 int ediff = X##_e - Y##_e; \
303 if (ediff > 0) \
305 R##_e = X##_e; \
306 if (Y##_e == 0) \
308 /* Y is zero or denormalized. */ \
309 if (_FP_FRAC_ZEROP_##wc(Y)) \
311 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
312 _FP_FRAC_COPY_##wc(R, X); \
313 goto add_done; \
315 else \
317 FP_SET_EXCEPTION(FP_EX_DENORM); \
318 ediff--; \
319 if (ediff == 0) \
321 _FP_FRAC_ADD_##wc(R, X, Y); \
322 goto add3; \
324 if (X##_e == _FP_EXPMAX_##fs) \
326 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
327 _FP_FRAC_COPY_##wc(R, X); \
328 goto add_done; \
330 goto add1; \
333 else if (X##_e == _FP_EXPMAX_##fs) \
335 /* X is NaN or Inf, Y is normal. */ \
336 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
337 _FP_FRAC_COPY_##wc(R, X); \
338 goto add_done; \
341 /* Insert implicit MSB of Y. */ \
342 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
344 add1: \
345 /* Shift the mantissa of Y to the right EDIFF steps; \
346 remember to account later for the implicit MSB of X. */ \
347 if (ediff <= _FP_WFRACBITS_##fs) \
348 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
349 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
350 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
351 _FP_FRAC_ADD_##wc(R, X, Y); \
353 else if (ediff < 0) \
355 ediff = -ediff; \
356 R##_e = Y##_e; \
357 if (X##_e == 0) \
359 /* X is zero or denormalized. */ \
360 if (_FP_FRAC_ZEROP_##wc(X)) \
362 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
363 _FP_FRAC_COPY_##wc(R, Y); \
364 goto add_done; \
366 else \
368 FP_SET_EXCEPTION(FP_EX_DENORM); \
369 ediff--; \
370 if (ediff == 0) \
372 _FP_FRAC_ADD_##wc(R, Y, X); \
373 goto add3; \
375 if (Y##_e == _FP_EXPMAX_##fs) \
377 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
378 _FP_FRAC_COPY_##wc(R, Y); \
379 goto add_done; \
381 goto add2; \
384 else if (Y##_e == _FP_EXPMAX_##fs) \
386 /* Y is NaN or Inf, X is normal. */ \
387 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
388 _FP_FRAC_COPY_##wc(R, Y); \
389 goto add_done; \
392 /* Insert implicit MSB of X. */ \
393 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
395 add2: \
396 /* Shift the mantissa of X to the right EDIFF steps; \
397 remember to account later for the implicit MSB of Y. */ \
398 if (ediff <= _FP_WFRACBITS_##fs) \
399 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
400 else if (!_FP_FRAC_ZEROP_##wc(X)) \
401 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
402 _FP_FRAC_ADD_##wc(R, Y, X); \
404 else \
406 /* ediff == 0. */ \
407 if (!_FP_EXP_NORMAL(fs, wc, X)) \
409 if (X##_e == 0) \
411 /* X and Y are zero or denormalized. */ \
412 R##_e = 0; \
413 if (_FP_FRAC_ZEROP_##wc(X)) \
415 if (!_FP_FRAC_ZEROP_##wc(Y)) \
416 FP_SET_EXCEPTION(FP_EX_DENORM); \
417 _FP_FRAC_COPY_##wc(R, Y); \
418 goto add_done; \
420 else if (_FP_FRAC_ZEROP_##wc(Y)) \
422 FP_SET_EXCEPTION(FP_EX_DENORM); \
423 _FP_FRAC_COPY_##wc(R, X); \
424 goto add_done; \
426 else \
428 FP_SET_EXCEPTION(FP_EX_DENORM); \
429 _FP_FRAC_ADD_##wc(R, X, Y); \
430 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
432 /* Normalized result. */ \
433 _FP_FRAC_HIGH_##fs(R) \
434 &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
435 R##_e = 1; \
437 goto add_done; \
440 else \
442 /* X and Y are NaN or Inf. */ \
443 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
444 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
445 R##_e = _FP_EXPMAX_##fs; \
446 if (_FP_FRAC_ZEROP_##wc(X)) \
447 _FP_FRAC_COPY_##wc(R, Y); \
448 else if (_FP_FRAC_ZEROP_##wc(Y)) \
449 _FP_FRAC_COPY_##wc(R, X); \
450 else \
451 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
452 goto add_done; \
455 /* The exponents of X and Y, both normal, are equal. The \
456 implicit MSBs will always add to increase the \
457 exponent. */ \
458 _FP_FRAC_ADD_##wc(R, X, Y); \
459 R##_e = X##_e + 1; \
460 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
461 if (R##_e == _FP_EXPMAX_##fs) \
462 /* Overflow to infinity (depending on rounding mode). */ \
463 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
464 goto add_done; \
466 add3: \
467 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
469 /* Overflow. */ \
470 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
471 R##_e++; \
472 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
473 if (R##_e == _FP_EXPMAX_##fs) \
474 /* Overflow to infinity (depending on rounding mode). */ \
475 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
477 add_done: ; \
479 else \
481 /* Subtraction. */ \
482 int ediff = X##_e - Y##_e; \
483 if (ediff > 0) \
485 R##_e = X##_e; \
486 R##_s = X##_s; \
487 if (Y##_e == 0) \
489 /* Y is zero or denormalized. */ \
490 if (_FP_FRAC_ZEROP_##wc(Y)) \
492 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
493 _FP_FRAC_COPY_##wc(R, X); \
494 goto sub_done; \
496 else \
498 FP_SET_EXCEPTION(FP_EX_DENORM); \
499 ediff--; \
500 if (ediff == 0) \
502 _FP_FRAC_SUB_##wc(R, X, Y); \
503 goto sub3; \
505 if (X##_e == _FP_EXPMAX_##fs) \
507 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
508 _FP_FRAC_COPY_##wc(R, X); \
509 goto sub_done; \
511 goto sub1; \
514 else if (X##_e == _FP_EXPMAX_##fs) \
516 /* X is NaN or Inf, Y is normal. */ \
517 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
518 _FP_FRAC_COPY_##wc(R, X); \
519 goto sub_done; \
522 /* Insert implicit MSB of Y. */ \
523 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
525 sub1: \
526 /* Shift the mantissa of Y to the right EDIFF steps; \
527 remember to account later for the implicit MSB of X. */ \
528 if (ediff <= _FP_WFRACBITS_##fs) \
529 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
530 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
531 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
532 _FP_FRAC_SUB_##wc(R, X, Y); \
534 else if (ediff < 0) \
536 ediff = -ediff; \
537 R##_e = Y##_e; \
538 R##_s = Y##_s; \
539 if (X##_e == 0) \
541 /* X is zero or denormalized. */ \
542 if (_FP_FRAC_ZEROP_##wc(X)) \
544 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
545 _FP_FRAC_COPY_##wc(R, Y); \
546 goto sub_done; \
548 else \
550 FP_SET_EXCEPTION(FP_EX_DENORM); \
551 ediff--; \
552 if (ediff == 0) \
554 _FP_FRAC_SUB_##wc(R, Y, X); \
555 goto sub3; \
557 if (Y##_e == _FP_EXPMAX_##fs) \
559 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
560 _FP_FRAC_COPY_##wc(R, Y); \
561 goto sub_done; \
563 goto sub2; \
566 else if (Y##_e == _FP_EXPMAX_##fs) \
568 /* Y is NaN or Inf, X is normal. */ \
569 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
570 _FP_FRAC_COPY_##wc(R, Y); \
571 goto sub_done; \
574 /* Insert implicit MSB of X. */ \
575 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
577 sub2: \
578 /* Shift the mantissa of X to the right EDIFF steps; \
579 remember to account later for the implicit MSB of Y. */ \
580 if (ediff <= _FP_WFRACBITS_##fs) \
581 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
582 else if (!_FP_FRAC_ZEROP_##wc(X)) \
583 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
584 _FP_FRAC_SUB_##wc(R, Y, X); \
586 else \
588 /* ediff == 0. */ \
589 if (!_FP_EXP_NORMAL(fs, wc, X)) \
591 if (X##_e == 0) \
593 /* X and Y are zero or denormalized. */ \
594 R##_e = 0; \
595 if (_FP_FRAC_ZEROP_##wc(X)) \
597 _FP_FRAC_COPY_##wc(R, Y); \
598 if (_FP_FRAC_ZEROP_##wc(Y)) \
599 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
600 else \
602 FP_SET_EXCEPTION(FP_EX_DENORM); \
603 R##_s = Y##_s; \
605 goto sub_done; \
607 else if (_FP_FRAC_ZEROP_##wc(Y)) \
609 FP_SET_EXCEPTION(FP_EX_DENORM); \
610 _FP_FRAC_COPY_##wc(R, X); \
611 R##_s = X##_s; \
612 goto sub_done; \
614 else \
616 FP_SET_EXCEPTION(FP_EX_DENORM); \
617 _FP_FRAC_SUB_##wc(R, X, Y); \
618 R##_s = X##_s; \
619 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
621 /* |X| < |Y|, negate result. */ \
622 _FP_FRAC_SUB_##wc(R, Y, X); \
623 R##_s = Y##_s; \
625 else if (_FP_FRAC_ZEROP_##wc(R)) \
626 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
627 goto sub_done; \
630 else \
632 /* X and Y are NaN or Inf, of opposite signs. */ \
633 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
634 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
635 R##_e = _FP_EXPMAX_##fs; \
636 if (_FP_FRAC_ZEROP_##wc(X)) \
638 if (_FP_FRAC_ZEROP_##wc(Y)) \
640 /* Inf - Inf. */ \
641 R##_s = _FP_NANSIGN_##fs; \
642 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
643 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
644 FP_SET_EXCEPTION(FP_EX_INVALID); \
646 else \
648 /* Inf - NaN. */ \
649 R##_s = Y##_s; \
650 _FP_FRAC_COPY_##wc(R, Y); \
653 else \
655 if (_FP_FRAC_ZEROP_##wc(Y)) \
657 /* NaN - Inf. */ \
658 R##_s = X##_s; \
659 _FP_FRAC_COPY_##wc(R, X); \
661 else \
663 /* NaN - NaN. */ \
664 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
667 goto sub_done; \
670 /* The exponents of X and Y, both normal, are equal. The \
671 implicit MSBs cancel. */ \
672 R##_e = X##_e; \
673 _FP_FRAC_SUB_##wc(R, X, Y); \
674 R##_s = X##_s; \
675 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
677 /* |X| < |Y|, negate result. */ \
678 _FP_FRAC_SUB_##wc(R, Y, X); \
679 R##_s = Y##_s; \
681 else if (_FP_FRAC_ZEROP_##wc(R)) \
683 R##_e = 0; \
684 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
685 goto sub_done; \
687 goto norm; \
689 sub3: \
690 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
692 int diff; \
693 /* Carry into most significant bit of larger one of X and Y, \
694 canceling it; renormalize. */ \
695 _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
696 norm: \
697 _FP_FRAC_CLZ_##wc(diff, R); \
698 diff -= _FP_WFRACXBITS_##fs; \
699 _FP_FRAC_SLL_##wc(R, diff); \
700 if (R##_e <= diff) \
702 /* R is denormalized. */ \
703 diff = diff - R##_e + 1; \
704 _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
705 R##_e = 0; \
707 else \
709 R##_e -= diff; \
710 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
713 sub_done: ; \
715 } while (0)
717 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
718 #define _FP_SUB(fs, wc, R, X, Y) \
719 do { \
720 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
721 _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
722 } while (0)
726 * Main negation routine. FIXME -- when we care about setting exception
727 * bits reliably, this will not do. We should examine all of the fp classes.
730 #define _FP_NEG(fs, wc, R, X) \
731 do { \
732 _FP_FRAC_COPY_##wc(R, X); \
733 R##_c = X##_c; \
734 R##_e = X##_e; \
735 R##_s = 1 ^ X##_s; \
736 } while (0)
740 * Main multiplication routine. The input values should be cooked.
743 #define _FP_MUL(fs, wc, R, X, Y) \
744 do { \
745 R##_s = X##_s ^ Y##_s; \
746 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
748 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
749 R##_c = FP_CLS_NORMAL; \
750 R##_e = X##_e + Y##_e + 1; \
752 _FP_MUL_MEAT_##fs(R,X,Y); \
754 if (_FP_FRAC_OVERP_##wc(fs, R)) \
755 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
756 else \
757 R##_e--; \
758 break; \
760 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
761 _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
762 break; \
764 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
765 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
766 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
767 R##_s = X##_s; \
769 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
770 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
771 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
772 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
773 _FP_FRAC_COPY_##wc(R, X); \
774 R##_c = X##_c; \
775 break; \
777 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
778 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
779 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
780 R##_s = Y##_s; \
782 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
783 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
784 _FP_FRAC_COPY_##wc(R, Y); \
785 R##_c = Y##_c; \
786 break; \
788 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
789 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
790 R##_s = _FP_NANSIGN_##fs; \
791 R##_c = FP_CLS_NAN; \
792 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
793 FP_SET_EXCEPTION(FP_EX_INVALID); \
794 break; \
796 default: \
797 abort(); \
799 } while (0)
803 * Main division routine. The input values should be cooked.
806 #define _FP_DIV(fs, wc, R, X, Y) \
807 do { \
808 R##_s = X##_s ^ Y##_s; \
809 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
811 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
812 R##_c = FP_CLS_NORMAL; \
813 R##_e = X##_e - Y##_e; \
815 _FP_DIV_MEAT_##fs(R,X,Y); \
816 break; \
818 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
819 _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
820 break; \
822 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
823 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
824 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
825 R##_s = X##_s; \
826 _FP_FRAC_COPY_##wc(R, X); \
827 R##_c = X##_c; \
828 break; \
830 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
831 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
832 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
833 R##_s = Y##_s; \
834 _FP_FRAC_COPY_##wc(R, Y); \
835 R##_c = Y##_c; \
836 break; \
838 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
839 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
840 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
841 R##_c = FP_CLS_ZERO; \
842 break; \
844 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
845 FP_SET_EXCEPTION(FP_EX_DIVZERO); \
846 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
847 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
848 R##_c = FP_CLS_INF; \
849 break; \
851 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
852 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
853 R##_s = _FP_NANSIGN_##fs; \
854 R##_c = FP_CLS_NAN; \
855 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
856 FP_SET_EXCEPTION(FP_EX_INVALID); \
857 break; \
859 default: \
860 abort(); \
862 } while (0)
866 * Main differential comparison routine. The inputs should be raw not
867 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
870 #define _FP_CMP(fs, wc, ret, X, Y, un) \
871 do { \
872 /* NANs are unordered */ \
873 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
874 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
876 ret = un; \
878 else \
880 int __is_zero_x; \
881 int __is_zero_y; \
883 __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
884 __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
886 if (__is_zero_x && __is_zero_y) \
887 ret = 0; \
888 else if (__is_zero_x) \
889 ret = Y##_s ? 1 : -1; \
890 else if (__is_zero_y) \
891 ret = X##_s ? -1 : 1; \
892 else if (X##_s != Y##_s) \
893 ret = X##_s ? -1 : 1; \
894 else if (X##_e > Y##_e) \
895 ret = X##_s ? -1 : 1; \
896 else if (X##_e < Y##_e) \
897 ret = X##_s ? 1 : -1; \
898 else if (_FP_FRAC_GT_##wc(X, Y)) \
899 ret = X##_s ? -1 : 1; \
900 else if (_FP_FRAC_GT_##wc(Y, X)) \
901 ret = X##_s ? 1 : -1; \
902 else \
903 ret = 0; \
905 } while (0)
908 /* Simplification for strict equality. */
910 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
911 do { \
912 /* NANs are unordered */ \
913 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
914 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
916 ret = 1; \
918 else \
920 ret = !(X##_e == Y##_e \
921 && _FP_FRAC_EQ_##wc(X, Y) \
922 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
924 } while (0)
926 /* Version to test unordered. */
928 #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
929 do { \
930 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
931 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
932 } while (0)
935 * Main square root routine. The input value should be cooked.
938 #define _FP_SQRT(fs, wc, R, X) \
939 do { \
940 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
941 _FP_W_TYPE q; \
942 switch (X##_c) \
944 case FP_CLS_NAN: \
945 _FP_FRAC_COPY_##wc(R, X); \
946 R##_s = X##_s; \
947 R##_c = FP_CLS_NAN; \
948 break; \
949 case FP_CLS_INF: \
950 if (X##_s) \
952 R##_s = _FP_NANSIGN_##fs; \
953 R##_c = FP_CLS_NAN; /* NAN */ \
954 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
955 FP_SET_EXCEPTION(FP_EX_INVALID); \
957 else \
959 R##_s = 0; \
960 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
962 break; \
963 case FP_CLS_ZERO: \
964 R##_s = X##_s; \
965 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
966 break; \
967 case FP_CLS_NORMAL: \
968 R##_s = 0; \
969 if (X##_s) \
971 R##_c = FP_CLS_NAN; /* sNAN */ \
972 R##_s = _FP_NANSIGN_##fs; \
973 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
974 FP_SET_EXCEPTION(FP_EX_INVALID); \
975 break; \
977 R##_c = FP_CLS_NORMAL; \
978 if (X##_e & 1) \
979 _FP_FRAC_SLL_##wc(X, 1); \
980 R##_e = X##_e >> 1; \
981 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
982 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
983 q = _FP_OVERFLOW_##fs >> 1; \
984 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
986 } while (0)
989 * Convert from FP to integer. Input is raw.
992 /* RSIGNED can have following values:
993 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
994 * the result is either 0 or (2^rsize)-1 depending on the sign in such
995 * case.
996 * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
997 * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
998 * depending on the sign in such case.
999 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1000 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1001 * depending on the sign in such case.
1003 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1004 do { \
1005 if (X##_e < _FP_EXPBIAS_##fs) \
1007 r = 0; \
1008 if (X##_e == 0) \
1010 if (!_FP_FRAC_ZEROP_##wc(X)) \
1012 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1013 FP_SET_EXCEPTION(FP_EX_DENORM); \
1016 else \
1017 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1019 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1020 || (!rsigned && X##_s)) \
1022 /* Overflow or converting to the most negative integer. */ \
1023 if (rsigned) \
1025 r = 1; \
1026 r <<= rsize - 1; \
1027 r -= 1 - X##_s; \
1028 } else { \
1029 r = 0; \
1030 if (X##_s) \
1031 r = ~r; \
1034 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1036 /* Possibly converting to most negative integer; check the \
1037 mantissa. */ \
1038 int inexact = 0; \
1039 (void)((_FP_FRACBITS_##fs > rsize) \
1040 ? ({ _FP_FRAC_SRST_##wc(X, inexact, \
1041 _FP_FRACBITS_##fs - rsize, \
1042 _FP_FRACBITS_##fs); 0; }) \
1043 : 0); \
1044 if (!_FP_FRAC_ZEROP_##wc(X)) \
1045 FP_SET_EXCEPTION(FP_EX_INVALID); \
1046 else if (inexact) \
1047 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1049 else \
1050 FP_SET_EXCEPTION(FP_EX_INVALID); \
1052 else \
1054 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
1055 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1057 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1058 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1060 else \
1062 int inexact; \
1063 _FP_FRAC_SRST_##wc(X, inexact, \
1064 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1065 - X##_e), \
1066 _FP_FRACBITS_##fs); \
1067 if (inexact) \
1068 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1069 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1071 if (rsigned && X##_s) \
1072 r = -r; \
1074 } while (0)
1076 /* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1077 input is signed. */
1078 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1079 do { \
1080 if (r) \
1082 rtype ur_; \
1084 if ((X##_s = (r < 0))) \
1085 r = -(rtype)r; \
1087 ur_ = (rtype) r; \
1088 (void)((rsize <= _FP_W_TYPE_SIZE) \
1089 ? ({ \
1090 int lz_; \
1091 __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
1092 X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
1093 }) \
1094 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1095 ? ({ \
1096 int lz_; \
1097 __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
1098 (_FP_W_TYPE)ur_); \
1099 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1100 - lz_); \
1101 }) \
1102 : (abort(), 0))); \
1104 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1105 && X##_e >= _FP_EXPMAX_##fs) \
1107 /* Exponent too big; overflow to infinity. (May also \
1108 happen after rounding below.) */ \
1109 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
1110 goto pack_semiraw; \
1113 if (rsize <= _FP_FRACBITS_##fs \
1114 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1116 /* Exactly representable; shift left. */ \
1117 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1118 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1119 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1121 else \
1123 /* More bits in integer than in floating type; need to \
1124 round. */ \
1125 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1126 ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
1127 - _FP_WFRACBITS_##fs + 1)) \
1128 | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1129 - _FP_WFRACBITS_##fs + 1))) \
1130 != 0)); \
1131 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1132 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
1133 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1134 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1135 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
1136 pack_semiraw: \
1137 _FP_PACK_SEMIRAW(fs, wc, X); \
1140 else \
1142 X##_s = 0; \
1143 X##_e = 0; \
1144 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
1146 } while (0)
1149 /* Extend from a narrower floating-point format to a wider one. Input
1150 and output are raw. */
1151 #define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
1152 do { \
1153 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1154 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1155 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1156 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1157 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
1158 abort(); \
1159 D##_s = S##_s; \
1160 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1161 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1163 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1164 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1166 else \
1168 if (S##_e == 0) \
1170 if (_FP_FRAC_ZEROP_##swc(S)) \
1171 D##_e = 0; \
1172 else if (_FP_EXPBIAS_##dfs \
1173 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1175 FP_SET_EXCEPTION(FP_EX_DENORM); \
1176 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1177 - _FP_FRACBITS_##sfs)); \
1178 D##_e = 0; \
1180 else \
1182 int _lz; \
1183 FP_SET_EXCEPTION(FP_EX_DENORM); \
1184 _FP_FRAC_CLZ_##swc(_lz, S); \
1185 _FP_FRAC_SLL_##dwc(D, \
1186 _lz + _FP_FRACBITS_##dfs \
1187 - _FP_FRACTBITS_##sfs); \
1188 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1189 + _FP_FRACXBITS_##sfs - _lz); \
1192 else \
1194 D##_e = _FP_EXPMAX_##dfs; \
1195 if (!_FP_FRAC_ZEROP_##swc(S)) \
1197 if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
1198 FP_SET_EXCEPTION(FP_EX_INVALID); \
1199 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1200 - _FP_FRACBITS_##sfs)); \
1204 } while (0)
1206 /* Truncate from a wider floating-point format to a narrower one.
1207 Input and output are semi-raw. */
1208 #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
1209 do { \
1210 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1211 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1212 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
1213 abort(); \
1214 D##_s = S##_s; \
1215 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1217 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1218 if (D##_e >= _FP_EXPMAX_##dfs) \
1219 _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
1220 else \
1222 if (D##_e <= 0) \
1224 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1226 _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
1227 _FP_FRAC_LOW_##swc(S) |= 1; \
1229 else \
1231 _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
1232 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1233 - _FP_WFRACBITS_##dfs + 1 - D##_e), \
1234 _FP_WFRACBITS_##sfs); \
1236 D##_e = 0; \
1238 else \
1239 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1240 - _FP_WFRACBITS_##dfs), \
1241 _FP_WFRACBITS_##sfs); \
1242 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1245 else \
1247 if (S##_e == 0) \
1249 D##_e = 0; \
1250 if (_FP_FRAC_ZEROP_##swc(S)) \
1251 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1252 else \
1254 FP_SET_EXCEPTION(FP_EX_DENORM); \
1255 if (_FP_EXPBIAS_##sfs \
1256 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1258 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1259 - _FP_WFRACBITS_##dfs), \
1260 _FP_WFRACBITS_##sfs); \
1261 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1263 else \
1265 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1266 _FP_FRAC_LOW_##dwc(D) |= 1; \
1270 else \
1272 D##_e = _FP_EXPMAX_##dfs; \
1273 if (_FP_FRAC_ZEROP_##swc(S)) \
1274 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1275 else \
1277 _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
1278 _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
1279 - _FP_WFRACBITS_##dfs)); \
1280 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1281 /* Semi-raw NaN must have all workbits cleared. */ \
1282 _FP_FRAC_LOW_##dwc(D) \
1283 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
1284 _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
1288 } while (0)
1291 * Helper primitives.
1294 /* Count leading zeros in a word. */
1296 #ifndef __FP_CLZ
1297 /* GCC 3.4 and later provide the builtins for us. */
1298 #define __FP_CLZ(r, x) \
1299 do { \
1300 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1301 r = __builtin_clz (x); \
1302 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1303 r = __builtin_clzl (x); \
1304 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1305 r = __builtin_clzll (x); \
1306 else \
1307 abort (); \
1308 } while (0)
1309 #endif /* ndef __FP_CLZ */
1311 #define _FP_DIV_HELP_imm(q, r, n, d) \
1312 do { \
1313 q = n / d, r = n % d; \
1314 } while (0)
1317 /* A restoring bit-by-bit division primitive. */
1319 #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1320 do { \
1321 int count = _FP_WFRACBITS_##fs; \
1322 _FP_FRAC_DECL_##wc (u); \
1323 _FP_FRAC_DECL_##wc (v); \
1324 _FP_FRAC_COPY_##wc (u, X); \
1325 _FP_FRAC_COPY_##wc (v, Y); \
1326 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1327 /* Normalize U and V. */ \
1328 _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
1329 _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
1330 /* First round. Since the operands are normalized, either the \
1331 first or second bit will be set in the fraction. Produce a \
1332 normalized result by checking which and adjusting the loop \
1333 count and exponent accordingly. */ \
1334 if (_FP_FRAC_GE_1 (u, v)) \
1336 _FP_FRAC_SUB_##wc (u, u, v); \
1337 _FP_FRAC_LOW_##wc (R) |= 1; \
1338 count--; \
1340 else \
1341 R##_e--; \
1342 /* Subsequent rounds. */ \
1343 do { \
1344 int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
1345 _FP_FRAC_SLL_##wc (u, 1); \
1346 _FP_FRAC_SLL_##wc (R, 1); \
1347 if (msb || _FP_FRAC_GE_1 (u, v)) \
1349 _FP_FRAC_SUB_##wc (u, u, v); \
1350 _FP_FRAC_LOW_##wc (R) |= 1; \
1352 } while (--count > 0); \
1353 /* If there's anything left in U, the result is inexact. */ \
1354 _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
1355 } while (0)
1357 #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1358 #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1359 #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)