hppa: Cleanup libm-test-ulps.
[glibc.git] / soft-fp / op-common.h
bloba9d94d7f1648629319dcae64ba03d5dcf9128f9d
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997-2013 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Richard Henderson (rth@cygnus.com),
5 Jakub Jelinek (jj@ultra.linux.cz),
6 David S. Miller (davem@redhat.com) and
7 Peter Maydell (pmaydell@chiark.greenend.org.uk).
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
14 In addition to the permissions in the GNU Lesser General Public
15 License, the Free Software Foundation gives you unlimited
16 permission to link the compiled version of this file into
17 combinations with other programs, and to distribute those
18 combinations without any restriction coming from the use of this
19 file. (The Lesser General Public License restrictions do apply in
20 other respects; for example, they cover modification of the file,
21 and distribution when not linked into a combine executable.)
23 The GNU C Library is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 Lesser General Public License for more details.
28 You should have received a copy of the GNU Lesser General Public
29 License along with the GNU C Library; if not, see
30 <http://www.gnu.org/licenses/>. */
32 #define _FP_DECL(wc, X) \
33 _FP_I_TYPE X##_c __attribute__((unused)); \
34 _FP_I_TYPE X##_s __attribute__((unused)); \
35 _FP_I_TYPE X##_e; \
36 _FP_FRAC_DECL_##wc(X)
39 * Finish truely unpacking a native fp value by classifying the kind
40 * of fp value and normalizing both the exponent and the fraction.
43 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
44 do { \
45 switch (X##_e) \
46 { \
47 default: \
48 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
49 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
50 X##_e -= _FP_EXPBIAS_##fs; \
51 X##_c = FP_CLS_NORMAL; \
52 break; \
54 case 0: \
55 if (_FP_FRAC_ZEROP_##wc(X)) \
56 X##_c = FP_CLS_ZERO; \
57 else \
58 { \
59 /* a denormalized number */ \
60 _FP_I_TYPE _shift; \
61 _FP_FRAC_CLZ_##wc(_shift, X); \
62 _shift -= _FP_FRACXBITS_##fs; \
63 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
64 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
65 X##_c = FP_CLS_NORMAL; \
66 FP_SET_EXCEPTION(FP_EX_DENORM); \
67 } \
68 break; \
70 case _FP_EXPMAX_##fs: \
71 if (_FP_FRAC_ZEROP_##wc(X)) \
72 X##_c = FP_CLS_INF; \
73 else \
74 { \
75 X##_c = FP_CLS_NAN; \
76 /* Check for signaling NaN */ \
77 if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
78 FP_SET_EXCEPTION(FP_EX_INVALID); \
79 } \
80 break; \
81 } \
82 } while (0)
84 /* Finish unpacking an fp value in semi-raw mode: the mantissa is
85 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
86 other classification is not done. */
87 #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
89 /* A semi-raw value has overflowed to infinity. Adjust the mantissa
90 and exponent appropriately. */
91 #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
92 do { \
93 if (FP_ROUNDMODE == FP_RND_NEAREST \
94 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
95 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
96 { \
97 X##_e = _FP_EXPMAX_##fs; \
98 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
99 } \
100 else \
102 X##_e = _FP_EXPMAX_##fs - 1; \
103 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
105 FP_SET_EXCEPTION(FP_EX_INEXACT); \
106 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
107 } while (0)
109 /* Check for a semi-raw value being a signaling NaN and raise the
110 invalid exception if so. */
111 #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
112 do { \
113 if (X##_e == _FP_EXPMAX_##fs \
114 && !_FP_FRAC_ZEROP_##wc(X) \
115 && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
116 FP_SET_EXCEPTION(FP_EX_INVALID); \
117 } while (0)
119 /* Choose a NaN result from an operation on two semi-raw NaN
120 values. */
121 #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
122 do { \
123 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
124 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
125 _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
126 _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
127 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
128 } while (0)
130 /* Test whether a biased exponent is normal (not zero or maximum). */
131 #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
133 /* Prepare to pack an fp value in semi-raw mode: the mantissa is
134 rounded and shifted right, with the rounding possibly increasing
135 the exponent (including changing a finite value to infinity). */
136 #define _FP_PACK_SEMIRAW(fs, wc, X) \
137 do { \
138 _FP_ROUND(wc, X); \
139 if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \
141 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
142 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
143 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
145 if (_FP_FRAC_HIGH_##fs(X) \
146 & (_FP_OVERFLOW_##fs >> 1)) \
148 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
149 X##_e++; \
150 if (X##_e == _FP_EXPMAX_##fs) \
151 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
153 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
154 if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
156 if (!_FP_KEEPNANFRACP) \
158 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
159 X##_s = _FP_NANSIGN_##fs; \
161 else \
162 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
164 } while (0)
167 * Before packing the bits back into the native fp result, take care
168 * of such mundane things as rounding and overflow. Also, for some
169 * kinds of fp values, the original parts may not have been fully
170 * extracted -- but that is ok, we can regenerate them now.
173 #define _FP_PACK_CANONICAL(fs, wc, X) \
174 do { \
175 switch (X##_c) \
177 case FP_CLS_NORMAL: \
178 X##_e += _FP_EXPBIAS_##fs; \
179 if (X##_e > 0) \
181 _FP_ROUND(wc, X); \
182 if (_FP_FRAC_OVERP_##wc(fs, X)) \
184 _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
185 X##_e++; \
187 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
188 if (X##_e >= _FP_EXPMAX_##fs) \
190 /* overflow */ \
191 switch (FP_ROUNDMODE) \
193 case FP_RND_NEAREST: \
194 X##_c = FP_CLS_INF; \
195 break; \
196 case FP_RND_PINF: \
197 if (!X##_s) X##_c = FP_CLS_INF; \
198 break; \
199 case FP_RND_MINF: \
200 if (X##_s) X##_c = FP_CLS_INF; \
201 break; \
203 if (X##_c == FP_CLS_INF) \
205 /* Overflow to infinity */ \
206 X##_e = _FP_EXPMAX_##fs; \
207 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
209 else \
211 /* Overflow to maximum normal */ \
212 X##_e = _FP_EXPMAX_##fs - 1; \
213 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
215 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
216 FP_SET_EXCEPTION(FP_EX_INEXACT); \
219 else \
221 /* we've got a denormalized number */ \
222 X##_e = -X##_e + 1; \
223 if (X##_e <= _FP_WFRACBITS_##fs) \
225 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
226 _FP_ROUND(wc, X); \
227 if (_FP_FRAC_HIGH_##fs(X) \
228 & (_FP_OVERFLOW_##fs >> 1)) \
230 X##_e = 1; \
231 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
232 FP_SET_EXCEPTION(FP_EX_INEXACT); \
234 else \
236 X##_e = 0; \
237 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
239 if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
240 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
241 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
243 else \
245 /* underflow to zero */ \
246 X##_e = 0; \
247 if (!_FP_FRAC_ZEROP_##wc(X)) \
249 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
250 _FP_ROUND(wc, X); \
251 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
253 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
256 break; \
258 case FP_CLS_ZERO: \
259 X##_e = 0; \
260 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
261 break; \
263 case FP_CLS_INF: \
264 X##_e = _FP_EXPMAX_##fs; \
265 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
266 break; \
268 case FP_CLS_NAN: \
269 X##_e = _FP_EXPMAX_##fs; \
270 if (!_FP_KEEPNANFRACP) \
272 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
273 X##_s = _FP_NANSIGN_##fs; \
275 else \
276 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
277 break; \
279 } while (0)
281 /* This one accepts raw argument and not cooked, returns
282 * 1 if X is a signaling NaN.
284 #define _FP_ISSIGNAN(fs, wc, X) \
285 ({ \
286 int __ret = 0; \
287 if (X##_e == _FP_EXPMAX_##fs) \
289 if (!_FP_FRAC_ZEROP_##wc(X) \
290 && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
291 __ret = 1; \
293 __ret; \
300 /* Addition on semi-raw values. */
301 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
302 do { \
303 if (X##_s == Y##_s) \
305 /* Addition. */ \
306 R##_s = X##_s; \
307 int ediff = X##_e - Y##_e; \
308 if (ediff > 0) \
310 R##_e = X##_e; \
311 if (Y##_e == 0) \
313 /* Y is zero or denormalized. */ \
314 if (_FP_FRAC_ZEROP_##wc(Y)) \
316 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
317 _FP_FRAC_COPY_##wc(R, X); \
318 goto add_done; \
320 else \
322 FP_SET_EXCEPTION(FP_EX_DENORM); \
323 ediff--; \
324 if (ediff == 0) \
326 _FP_FRAC_ADD_##wc(R, X, Y); \
327 goto add3; \
329 if (X##_e == _FP_EXPMAX_##fs) \
331 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
332 _FP_FRAC_COPY_##wc(R, X); \
333 goto add_done; \
335 goto add1; \
338 else if (X##_e == _FP_EXPMAX_##fs) \
340 /* X is NaN or Inf, Y is normal. */ \
341 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
342 _FP_FRAC_COPY_##wc(R, X); \
343 goto add_done; \
346 /* Insert implicit MSB of Y. */ \
347 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
349 add1: \
350 /* Shift the mantissa of Y to the right EDIFF steps; \
351 remember to account later for the implicit MSB of X. */ \
352 if (ediff <= _FP_WFRACBITS_##fs) \
353 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
354 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
355 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
356 _FP_FRAC_ADD_##wc(R, X, Y); \
358 else if (ediff < 0) \
360 ediff = -ediff; \
361 R##_e = Y##_e; \
362 if (X##_e == 0) \
364 /* X is zero or denormalized. */ \
365 if (_FP_FRAC_ZEROP_##wc(X)) \
367 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
368 _FP_FRAC_COPY_##wc(R, Y); \
369 goto add_done; \
371 else \
373 FP_SET_EXCEPTION(FP_EX_DENORM); \
374 ediff--; \
375 if (ediff == 0) \
377 _FP_FRAC_ADD_##wc(R, Y, X); \
378 goto add3; \
380 if (Y##_e == _FP_EXPMAX_##fs) \
382 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
383 _FP_FRAC_COPY_##wc(R, Y); \
384 goto add_done; \
386 goto add2; \
389 else if (Y##_e == _FP_EXPMAX_##fs) \
391 /* Y is NaN or Inf, X is normal. */ \
392 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
393 _FP_FRAC_COPY_##wc(R, Y); \
394 goto add_done; \
397 /* Insert implicit MSB of X. */ \
398 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
400 add2: \
401 /* Shift the mantissa of X to the right EDIFF steps; \
402 remember to account later for the implicit MSB of Y. */ \
403 if (ediff <= _FP_WFRACBITS_##fs) \
404 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
405 else if (!_FP_FRAC_ZEROP_##wc(X)) \
406 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
407 _FP_FRAC_ADD_##wc(R, Y, X); \
409 else \
411 /* ediff == 0. */ \
412 if (!_FP_EXP_NORMAL(fs, wc, X)) \
414 if (X##_e == 0) \
416 /* X and Y are zero or denormalized. */ \
417 R##_e = 0; \
418 if (_FP_FRAC_ZEROP_##wc(X)) \
420 if (!_FP_FRAC_ZEROP_##wc(Y)) \
421 FP_SET_EXCEPTION(FP_EX_DENORM); \
422 _FP_FRAC_COPY_##wc(R, Y); \
423 goto add_done; \
425 else if (_FP_FRAC_ZEROP_##wc(Y)) \
427 FP_SET_EXCEPTION(FP_EX_DENORM); \
428 _FP_FRAC_COPY_##wc(R, X); \
429 goto add_done; \
431 else \
433 FP_SET_EXCEPTION(FP_EX_DENORM); \
434 _FP_FRAC_ADD_##wc(R, X, Y); \
435 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
437 /* Normalized result. */ \
438 _FP_FRAC_HIGH_##fs(R) \
439 &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
440 R##_e = 1; \
442 goto add_done; \
445 else \
447 /* X and Y are NaN or Inf. */ \
448 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
449 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
450 R##_e = _FP_EXPMAX_##fs; \
451 if (_FP_FRAC_ZEROP_##wc(X)) \
452 _FP_FRAC_COPY_##wc(R, Y); \
453 else if (_FP_FRAC_ZEROP_##wc(Y)) \
454 _FP_FRAC_COPY_##wc(R, X); \
455 else \
456 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
457 goto add_done; \
460 /* The exponents of X and Y, both normal, are equal. The \
461 implicit MSBs will always add to increase the \
462 exponent. */ \
463 _FP_FRAC_ADD_##wc(R, X, Y); \
464 R##_e = X##_e + 1; \
465 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
466 if (R##_e == _FP_EXPMAX_##fs) \
467 /* Overflow to infinity (depending on rounding mode). */ \
468 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
469 goto add_done; \
471 add3: \
472 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
474 /* Overflow. */ \
475 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
476 R##_e++; \
477 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
478 if (R##_e == _FP_EXPMAX_##fs) \
479 /* Overflow to infinity (depending on rounding mode). */ \
480 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
482 add_done: ; \
484 else \
486 /* Subtraction. */ \
487 int ediff = X##_e - Y##_e; \
488 if (ediff > 0) \
490 R##_e = X##_e; \
491 R##_s = X##_s; \
492 if (Y##_e == 0) \
494 /* Y is zero or denormalized. */ \
495 if (_FP_FRAC_ZEROP_##wc(Y)) \
497 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
498 _FP_FRAC_COPY_##wc(R, X); \
499 goto sub_done; \
501 else \
503 FP_SET_EXCEPTION(FP_EX_DENORM); \
504 ediff--; \
505 if (ediff == 0) \
507 _FP_FRAC_SUB_##wc(R, X, Y); \
508 goto sub3; \
510 if (X##_e == _FP_EXPMAX_##fs) \
512 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
513 _FP_FRAC_COPY_##wc(R, X); \
514 goto sub_done; \
516 goto sub1; \
519 else if (X##_e == _FP_EXPMAX_##fs) \
521 /* X is NaN or Inf, Y is normal. */ \
522 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
523 _FP_FRAC_COPY_##wc(R, X); \
524 goto sub_done; \
527 /* Insert implicit MSB of Y. */ \
528 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
530 sub1: \
531 /* Shift the mantissa of Y to the right EDIFF steps; \
532 remember to account later for the implicit MSB of X. */ \
533 if (ediff <= _FP_WFRACBITS_##fs) \
534 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
535 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
536 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
537 _FP_FRAC_SUB_##wc(R, X, Y); \
539 else if (ediff < 0) \
541 ediff = -ediff; \
542 R##_e = Y##_e; \
543 R##_s = Y##_s; \
544 if (X##_e == 0) \
546 /* X is zero or denormalized. */ \
547 if (_FP_FRAC_ZEROP_##wc(X)) \
549 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
550 _FP_FRAC_COPY_##wc(R, Y); \
551 goto sub_done; \
553 else \
555 FP_SET_EXCEPTION(FP_EX_DENORM); \
556 ediff--; \
557 if (ediff == 0) \
559 _FP_FRAC_SUB_##wc(R, Y, X); \
560 goto sub3; \
562 if (Y##_e == _FP_EXPMAX_##fs) \
564 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
565 _FP_FRAC_COPY_##wc(R, Y); \
566 goto sub_done; \
568 goto sub2; \
571 else if (Y##_e == _FP_EXPMAX_##fs) \
573 /* Y is NaN or Inf, X is normal. */ \
574 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
575 _FP_FRAC_COPY_##wc(R, Y); \
576 goto sub_done; \
579 /* Insert implicit MSB of X. */ \
580 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
582 sub2: \
583 /* Shift the mantissa of X to the right EDIFF steps; \
584 remember to account later for the implicit MSB of Y. */ \
585 if (ediff <= _FP_WFRACBITS_##fs) \
586 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
587 else if (!_FP_FRAC_ZEROP_##wc(X)) \
588 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
589 _FP_FRAC_SUB_##wc(R, Y, X); \
591 else \
593 /* ediff == 0. */ \
594 if (!_FP_EXP_NORMAL(fs, wc, X)) \
596 if (X##_e == 0) \
598 /* X and Y are zero or denormalized. */ \
599 R##_e = 0; \
600 if (_FP_FRAC_ZEROP_##wc(X)) \
602 _FP_FRAC_COPY_##wc(R, Y); \
603 if (_FP_FRAC_ZEROP_##wc(Y)) \
604 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
605 else \
607 FP_SET_EXCEPTION(FP_EX_DENORM); \
608 R##_s = Y##_s; \
610 goto sub_done; \
612 else if (_FP_FRAC_ZEROP_##wc(Y)) \
614 FP_SET_EXCEPTION(FP_EX_DENORM); \
615 _FP_FRAC_COPY_##wc(R, X); \
616 R##_s = X##_s; \
617 goto sub_done; \
619 else \
621 FP_SET_EXCEPTION(FP_EX_DENORM); \
622 _FP_FRAC_SUB_##wc(R, X, Y); \
623 R##_s = X##_s; \
624 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
626 /* |X| < |Y|, negate result. */ \
627 _FP_FRAC_SUB_##wc(R, Y, X); \
628 R##_s = Y##_s; \
630 else if (_FP_FRAC_ZEROP_##wc(R)) \
631 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
632 goto sub_done; \
635 else \
637 /* X and Y are NaN or Inf, of opposite signs. */ \
638 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
639 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
640 R##_e = _FP_EXPMAX_##fs; \
641 if (_FP_FRAC_ZEROP_##wc(X)) \
643 if (_FP_FRAC_ZEROP_##wc(Y)) \
645 /* Inf - Inf. */ \
646 R##_s = _FP_NANSIGN_##fs; \
647 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
648 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
649 FP_SET_EXCEPTION(FP_EX_INVALID); \
651 else \
653 /* Inf - NaN. */ \
654 R##_s = Y##_s; \
655 _FP_FRAC_COPY_##wc(R, Y); \
658 else \
660 if (_FP_FRAC_ZEROP_##wc(Y)) \
662 /* NaN - Inf. */ \
663 R##_s = X##_s; \
664 _FP_FRAC_COPY_##wc(R, X); \
666 else \
668 /* NaN - NaN. */ \
669 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
672 goto sub_done; \
675 /* The exponents of X and Y, both normal, are equal. The \
676 implicit MSBs cancel. */ \
677 R##_e = X##_e; \
678 _FP_FRAC_SUB_##wc(R, X, Y); \
679 R##_s = X##_s; \
680 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
682 /* |X| < |Y|, negate result. */ \
683 _FP_FRAC_SUB_##wc(R, Y, X); \
684 R##_s = Y##_s; \
686 else if (_FP_FRAC_ZEROP_##wc(R)) \
688 R##_e = 0; \
689 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
690 goto sub_done; \
692 goto norm; \
694 sub3: \
695 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
697 int diff; \
698 /* Carry into most significant bit of larger one of X and Y, \
699 canceling it; renormalize. */ \
700 _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
701 norm: \
702 _FP_FRAC_CLZ_##wc(diff, R); \
703 diff -= _FP_WFRACXBITS_##fs; \
704 _FP_FRAC_SLL_##wc(R, diff); \
705 if (R##_e <= diff) \
707 /* R is denormalized. */ \
708 diff = diff - R##_e + 1; \
709 _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
710 R##_e = 0; \
712 else \
714 R##_e -= diff; \
715 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
718 sub_done: ; \
720 } while (0)
722 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
723 #define _FP_SUB(fs, wc, R, X, Y) \
724 do { \
725 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
726 _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
727 } while (0)
731 * Main negation routine. FIXME -- when we care about setting exception
732 * bits reliably, this will not do. We should examine all of the fp classes.
735 #define _FP_NEG(fs, wc, R, X) \
736 do { \
737 _FP_FRAC_COPY_##wc(R, X); \
738 R##_c = X##_c; \
739 R##_e = X##_e; \
740 R##_s = 1 ^ X##_s; \
741 } while (0)
745 * Main multiplication routine. The input values should be cooked.
748 #define _FP_MUL(fs, wc, R, X, Y) \
749 do { \
750 R##_s = X##_s ^ Y##_s; \
751 R##_e = X##_e + Y##_e + 1; \
752 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
754 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
755 R##_c = FP_CLS_NORMAL; \
757 _FP_MUL_MEAT_##fs(R,X,Y); \
759 if (_FP_FRAC_OVERP_##wc(fs, R)) \
760 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
761 else \
762 R##_e--; \
763 break; \
765 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
766 _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
767 break; \
769 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
770 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
771 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
772 R##_s = X##_s; \
774 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
775 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
776 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
777 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
778 _FP_FRAC_COPY_##wc(R, X); \
779 R##_c = X##_c; \
780 break; \
782 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
783 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
784 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
785 R##_s = Y##_s; \
787 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
788 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
789 _FP_FRAC_COPY_##wc(R, Y); \
790 R##_c = Y##_c; \
791 break; \
793 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
794 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
795 R##_s = _FP_NANSIGN_##fs; \
796 R##_c = FP_CLS_NAN; \
797 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
798 FP_SET_EXCEPTION(FP_EX_INVALID); \
799 break; \
801 default: \
802 abort(); \
804 } while (0)
808 * Main division routine. The input values should be cooked.
811 #define _FP_DIV(fs, wc, R, X, Y) \
812 do { \
813 R##_s = X##_s ^ Y##_s; \
814 R##_e = X##_e - Y##_e; \
815 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
817 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
818 R##_c = FP_CLS_NORMAL; \
820 _FP_DIV_MEAT_##fs(R,X,Y); \
821 break; \
823 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
824 _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
825 break; \
827 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
828 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
829 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
830 R##_s = X##_s; \
831 _FP_FRAC_COPY_##wc(R, X); \
832 R##_c = X##_c; \
833 break; \
835 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
836 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
837 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
838 R##_s = Y##_s; \
839 _FP_FRAC_COPY_##wc(R, Y); \
840 R##_c = Y##_c; \
841 break; \
843 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
844 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
845 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
846 R##_c = FP_CLS_ZERO; \
847 break; \
849 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
850 FP_SET_EXCEPTION(FP_EX_DIVZERO); \
851 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
852 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
853 R##_c = FP_CLS_INF; \
854 break; \
856 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
857 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
858 R##_s = _FP_NANSIGN_##fs; \
859 R##_c = FP_CLS_NAN; \
860 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
861 FP_SET_EXCEPTION(FP_EX_INVALID); \
862 break; \
864 default: \
865 abort(); \
867 } while (0)
871 * Main differential comparison routine. The inputs should be raw not
872 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
875 #define _FP_CMP(fs, wc, ret, X, Y, un) \
876 do { \
877 /* NANs are unordered */ \
878 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
879 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
881 ret = un; \
883 else \
885 int __is_zero_x; \
886 int __is_zero_y; \
888 __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
889 __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
891 if (__is_zero_x && __is_zero_y) \
892 ret = 0; \
893 else if (__is_zero_x) \
894 ret = Y##_s ? 1 : -1; \
895 else if (__is_zero_y) \
896 ret = X##_s ? -1 : 1; \
897 else if (X##_s != Y##_s) \
898 ret = X##_s ? -1 : 1; \
899 else if (X##_e > Y##_e) \
900 ret = X##_s ? -1 : 1; \
901 else if (X##_e < Y##_e) \
902 ret = X##_s ? 1 : -1; \
903 else if (_FP_FRAC_GT_##wc(X, Y)) \
904 ret = X##_s ? -1 : 1; \
905 else if (_FP_FRAC_GT_##wc(Y, X)) \
906 ret = X##_s ? 1 : -1; \
907 else \
908 ret = 0; \
910 } while (0)
913 /* Simplification for strict equality. */
915 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
916 do { \
917 /* NANs are unordered */ \
918 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
919 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
921 ret = 1; \
923 else \
925 ret = !(X##_e == Y##_e \
926 && _FP_FRAC_EQ_##wc(X, Y) \
927 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
929 } while (0)
931 /* Version to test unordered. */
933 #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
934 do { \
935 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
936 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
937 } while (0)
940 * Main square root routine. The input value should be cooked.
943 #define _FP_SQRT(fs, wc, R, X) \
944 do { \
945 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
946 _FP_W_TYPE q; \
947 switch (X##_c) \
949 case FP_CLS_NAN: \
950 _FP_FRAC_COPY_##wc(R, X); \
951 R##_s = X##_s; \
952 R##_c = FP_CLS_NAN; \
953 break; \
954 case FP_CLS_INF: \
955 if (X##_s) \
957 R##_s = _FP_NANSIGN_##fs; \
958 R##_c = FP_CLS_NAN; /* NAN */ \
959 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
960 FP_SET_EXCEPTION(FP_EX_INVALID); \
962 else \
964 R##_s = 0; \
965 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
967 break; \
968 case FP_CLS_ZERO: \
969 R##_s = X##_s; \
970 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
971 break; \
972 case FP_CLS_NORMAL: \
973 R##_s = 0; \
974 if (X##_s) \
976 R##_c = FP_CLS_NAN; /* NAN */ \
977 R##_s = _FP_NANSIGN_##fs; \
978 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
979 FP_SET_EXCEPTION(FP_EX_INVALID); \
980 break; \
982 R##_c = FP_CLS_NORMAL; \
983 if (X##_e & 1) \
984 _FP_FRAC_SLL_##wc(X, 1); \
985 R##_e = X##_e >> 1; \
986 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
987 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
988 q = _FP_OVERFLOW_##fs >> 1; \
989 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
991 } while (0)
994 * Convert from FP to integer. Input is raw.
997 /* RSIGNED can have following values:
998 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
999 * the result is either 0 or (2^rsize)-1 depending on the sign in such
1000 * case.
1001 * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
1002 * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1003 * depending on the sign in such case.
1004 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1005 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1006 * depending on the sign in such case.
1008 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
1009 do { \
1010 if (X##_e < _FP_EXPBIAS_##fs) \
1012 r = 0; \
1013 if (X##_e == 0) \
1015 if (!_FP_FRAC_ZEROP_##wc(X)) \
1017 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1018 FP_SET_EXCEPTION(FP_EX_DENORM); \
1021 else \
1022 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1024 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1025 || (!rsigned && X##_s)) \
1027 /* Overflow or converting to the most negative integer. */ \
1028 if (rsigned) \
1030 r = 1; \
1031 r <<= rsize - 1; \
1032 r -= 1 - X##_s; \
1033 } else { \
1034 r = 0; \
1035 if (X##_s) \
1036 r = ~r; \
1039 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1041 /* Possibly converting to most negative integer; check the \
1042 mantissa. */ \
1043 int inexact = 0; \
1044 (void)((_FP_FRACBITS_##fs > rsize) \
1045 ? ({ _FP_FRAC_SRST_##wc(X, inexact, \
1046 _FP_FRACBITS_##fs - rsize, \
1047 _FP_FRACBITS_##fs); 0; }) \
1048 : 0); \
1049 if (!_FP_FRAC_ZEROP_##wc(X)) \
1050 FP_SET_EXCEPTION(FP_EX_INVALID); \
1051 else if (inexact) \
1052 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1054 else \
1055 FP_SET_EXCEPTION(FP_EX_INVALID); \
1057 else \
1059 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
1060 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1062 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1063 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1065 else \
1067 int inexact; \
1068 _FP_FRAC_SRST_##wc(X, inexact, \
1069 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1070 - X##_e), \
1071 _FP_FRACBITS_##fs); \
1072 if (inexact) \
1073 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1074 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1076 if (rsigned && X##_s) \
1077 r = -r; \
1079 } while (0)
1081 /* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1082 input is signed. */
1083 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1084 do { \
1085 if (r) \
1087 rtype ur_; \
1089 if ((X##_s = (r < 0))) \
1090 r = -(rtype)r; \
1092 ur_ = (rtype) r; \
1093 (void)((rsize <= _FP_W_TYPE_SIZE) \
1094 ? ({ \
1095 int lz_; \
1096 __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
1097 X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
1098 }) \
1099 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1100 ? ({ \
1101 int lz_; \
1102 __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
1103 (_FP_W_TYPE)ur_); \
1104 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1105 - lz_); \
1106 }) \
1107 : (abort(), 0))); \
1109 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1110 && X##_e >= _FP_EXPMAX_##fs) \
1112 /* Exponent too big; overflow to infinity. (May also \
1113 happen after rounding below.) */ \
1114 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
1115 goto pack_semiraw; \
1118 if (rsize <= _FP_FRACBITS_##fs \
1119 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1121 /* Exactly representable; shift left. */ \
1122 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1123 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1124 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1126 else \
1128 /* More bits in integer than in floating type; need to \
1129 round. */ \
1130 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1131 ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
1132 - _FP_WFRACBITS_##fs + 1)) \
1133 | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1134 - _FP_WFRACBITS_##fs + 1))) \
1135 != 0)); \
1136 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1137 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
1138 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1139 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1140 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
1141 pack_semiraw: \
1142 _FP_PACK_SEMIRAW(fs, wc, X); \
1145 else \
1147 X##_s = 0; \
1148 X##_e = 0; \
1149 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
1151 } while (0)
1154 /* Extend from a narrower floating-point format to a wider one. Input
1155 and output are raw. */
1156 #define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
1157 do { \
1158 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1159 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1160 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1161 || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1162 && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
1163 abort(); \
1164 D##_s = S##_s; \
1165 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1166 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1168 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1169 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1171 else \
1173 if (S##_e == 0) \
1175 if (_FP_FRAC_ZEROP_##swc(S)) \
1176 D##_e = 0; \
1177 else if (_FP_EXPBIAS_##dfs \
1178 < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1180 FP_SET_EXCEPTION(FP_EX_DENORM); \
1181 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1182 - _FP_FRACBITS_##sfs)); \
1183 D##_e = 0; \
1185 else \
1187 int _lz; \
1188 FP_SET_EXCEPTION(FP_EX_DENORM); \
1189 _FP_FRAC_CLZ_##swc(_lz, S); \
1190 _FP_FRAC_SLL_##dwc(D, \
1191 _lz + _FP_FRACBITS_##dfs \
1192 - _FP_FRACTBITS_##sfs); \
1193 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1194 + _FP_FRACXBITS_##sfs - _lz); \
1197 else \
1199 D##_e = _FP_EXPMAX_##dfs; \
1200 if (!_FP_FRAC_ZEROP_##swc(S)) \
1202 if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
1203 FP_SET_EXCEPTION(FP_EX_INVALID); \
1204 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1205 - _FP_FRACBITS_##sfs)); \
1209 } while (0)
1211 /* Truncate from a wider floating-point format to a narrower one.
1212 Input and output are semi-raw. */
1213 #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
1214 do { \
1215 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1216 || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
1217 && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
1218 abort(); \
1219 D##_s = S##_s; \
1220 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1222 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1223 if (D##_e >= _FP_EXPMAX_##dfs) \
1224 _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
1225 else \
1227 if (D##_e <= 0) \
1229 if (D##_e < 1 - _FP_FRACBITS_##dfs) \
1231 _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
1232 _FP_FRAC_LOW_##swc(S) |= 1; \
1234 else \
1236 _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
1237 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1238 - _FP_WFRACBITS_##dfs + 1 - D##_e), \
1239 _FP_WFRACBITS_##sfs); \
1241 D##_e = 0; \
1243 else \
1244 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1245 - _FP_WFRACBITS_##dfs), \
1246 _FP_WFRACBITS_##sfs); \
1247 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1250 else \
1252 if (S##_e == 0) \
1254 D##_e = 0; \
1255 if (_FP_FRAC_ZEROP_##swc(S)) \
1256 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1257 else \
1259 FP_SET_EXCEPTION(FP_EX_DENORM); \
1260 if (_FP_EXPBIAS_##sfs \
1261 < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1263 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1264 - _FP_WFRACBITS_##dfs), \
1265 _FP_WFRACBITS_##sfs); \
1266 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1268 else \
1270 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1271 _FP_FRAC_LOW_##dwc(D) |= 1; \
1275 else \
1277 D##_e = _FP_EXPMAX_##dfs; \
1278 if (_FP_FRAC_ZEROP_##swc(S)) \
1279 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1280 else \
1282 _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
1283 _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
1284 - _FP_WFRACBITS_##dfs)); \
1285 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1286 /* Semi-raw NaN must have all workbits cleared. */ \
1287 _FP_FRAC_LOW_##dwc(D) \
1288 &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
1289 _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
1293 } while (0)
1296 * Helper primitives.
1299 /* Count leading zeros in a word. */
1301 #ifndef __FP_CLZ
1302 /* GCC 3.4 and later provide the builtins for us. */
1303 #define __FP_CLZ(r, x) \
1304 do { \
1305 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1306 r = __builtin_clz (x); \
1307 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1308 r = __builtin_clzl (x); \
1309 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1310 r = __builtin_clzll (x); \
1311 else \
1312 abort (); \
1313 } while (0)
1314 #endif /* ndef __FP_CLZ */
1316 #define _FP_DIV_HELP_imm(q, r, n, d) \
1317 do { \
1318 q = n / d, r = n % d; \
1319 } while (0)
1322 /* A restoring bit-by-bit division primitive. */
1324 #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1325 do { \
1326 int count = _FP_WFRACBITS_##fs; \
1327 _FP_FRAC_DECL_##wc (u); \
1328 _FP_FRAC_DECL_##wc (v); \
1329 _FP_FRAC_COPY_##wc (u, X); \
1330 _FP_FRAC_COPY_##wc (v, Y); \
1331 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1332 /* Normalize U and V. */ \
1333 _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
1334 _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
1335 /* First round. Since the operands are normalized, either the \
1336 first or second bit will be set in the fraction. Produce a \
1337 normalized result by checking which and adjusting the loop \
1338 count and exponent accordingly. */ \
1339 if (_FP_FRAC_GE_1 (u, v)) \
1341 _FP_FRAC_SUB_##wc (u, u, v); \
1342 _FP_FRAC_LOW_##wc (R) |= 1; \
1343 count--; \
1345 else \
1346 R##_e--; \
1347 /* Subsequent rounds. */ \
1348 do { \
1349 int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
1350 _FP_FRAC_SLL_##wc (u, 1); \
1351 _FP_FRAC_SLL_##wc (R, 1); \
1352 if (msb || _FP_FRAC_GE_1 (u, v)) \
1354 _FP_FRAC_SUB_##wc (u, u, v); \
1355 _FP_FRAC_LOW_##wc (R) |= 1; \
1357 } while (--count > 0); \
1358 /* If there's anything left in U, the result is inexact. */ \
1359 _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
1360 } while (0)
1362 #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1363 #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1364 #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)