* sysdeps/unix/sysv/linux/sh/pread.c: Copy in mips pread.c.
[glibc.git] / soft-fp / op-common.h
blob957f71dacd77324770ce79e018c7c6d264b76e77
1 /* Software floating-point emulation. Common operations.
2 Copyright (C) 1997,1998,1999,2006 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 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with the GNU C Library; if not, write to the Free
21 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 02111-1307 USA. */
24 #define _FP_DECL(wc, X) \
25 _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e; \
26 _FP_FRAC_DECL_##wc(X)
29 * Finish truely unpacking a native fp value by classifying the kind
30 * of fp value and normalizing both the exponent and the fraction.
33 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
34 do { \
35 switch (X##_e) \
36 { \
37 default: \
38 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
39 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
40 X##_e -= _FP_EXPBIAS_##fs; \
41 X##_c = FP_CLS_NORMAL; \
42 break; \
44 case 0: \
45 if (_FP_FRAC_ZEROP_##wc(X)) \
46 X##_c = FP_CLS_ZERO; \
47 else \
48 { \
49 /* a denormalized number */ \
50 _FP_I_TYPE _shift; \
51 _FP_FRAC_CLZ_##wc(_shift, X); \
52 _shift -= _FP_FRACXBITS_##fs; \
53 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
54 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
55 X##_c = FP_CLS_NORMAL; \
56 FP_SET_EXCEPTION(FP_EX_DENORM); \
57 } \
58 break; \
60 case _FP_EXPMAX_##fs: \
61 if (_FP_FRAC_ZEROP_##wc(X)) \
62 X##_c = FP_CLS_INF; \
63 else \
64 { \
65 X##_c = FP_CLS_NAN; \
66 /* Check for signaling NaN */ \
67 if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
68 FP_SET_EXCEPTION(FP_EX_INVALID); \
69 } \
70 break; \
71 } \
72 } while (0)
74 /* Finish unpacking an fp value in semi-raw mode: the mantissa is
75 shifted by _FP_WORKBITS but the implicit MSB is not inserted and
76 other classification is not done. */
77 #define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
79 /* A semi-raw value has overflowed to infinity. Adjust the mantissa
80 and exponent appropriately. */
81 #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \
82 do { \
83 if (FP_ROUNDMODE == FP_RND_NEAREST \
84 || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \
85 || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \
86 { \
87 X##_e = _FP_EXPMAX_##fs; \
88 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
89 } \
90 else \
91 { \
92 X##_e = _FP_EXPMAX_##fs - 1; \
93 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
94 FP_SET_EXCEPTION(FP_EX_INEXACT); \
95 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
96 } \
97 } while (0)
99 /* Check for a semi-raw value being a signaling NaN and raise the
100 invalid exception if so. */
101 #define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \
102 do { \
103 if (X##_e == _FP_EXPMAX_##fs \
104 && !_FP_FRAC_ZEROP_##wc(X) \
105 && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
106 FP_SET_EXCEPTION(FP_EX_INVALID); \
107 } while (0)
109 /* Choose a NaN result from an operation on two semi-raw NaN
110 values. */
111 #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \
112 do { \
113 /* _FP_CHOOSENAN expects raw values, so shift as required. */ \
114 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
115 _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \
116 _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \
117 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
118 } while (0)
120 /* Test whether a biased exponent is normal (not zero or maximum). */
121 #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
123 /* Prepare to pack an fp value in semi-raw mode: the mantissa is
124 rounded and shifted right, with the rounding possibly increasing
125 the exponent (including changing a finite value to infinity). */
126 #define _FP_PACK_SEMIRAW(fs, wc, X) \
127 do { \
128 _FP_ROUND(wc, X); \
129 if (_FP_FRAC_HIGH_##fs(X) \
130 & (_FP_OVERFLOW_##fs >> 1)) \
132 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \
133 X##_e++; \
134 if (X##_e == _FP_EXPMAX_##fs) \
135 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
137 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
138 if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \
140 if (X##_e == 0) \
141 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
142 else \
144 if (!_FP_KEEPNANFRACP) \
146 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
147 X##_s = _FP_NANSIGN_##fs; \
149 else \
150 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
153 } while (0)
156 * Before packing the bits back into the native fp result, take care
157 * of such mundane things as rounding and overflow. Also, for some
158 * kinds of fp values, the original parts may not have been fully
159 * extracted -- but that is ok, we can regenerate them now.
162 #define _FP_PACK_CANONICAL(fs, wc, X) \
163 do { \
164 switch (X##_c) \
166 case FP_CLS_NORMAL: \
167 X##_e += _FP_EXPBIAS_##fs; \
168 if (X##_e > 0) \
170 _FP_ROUND(wc, X); \
171 if (_FP_FRAC_OVERP_##wc(fs, X)) \
173 _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \
174 X##_e++; \
176 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
177 if (X##_e >= _FP_EXPMAX_##fs) \
179 /* overflow */ \
180 switch (FP_ROUNDMODE) \
182 case FP_RND_NEAREST: \
183 X##_c = FP_CLS_INF; \
184 break; \
185 case FP_RND_PINF: \
186 if (!X##_s) X##_c = FP_CLS_INF; \
187 break; \
188 case FP_RND_MINF: \
189 if (X##_s) X##_c = FP_CLS_INF; \
190 break; \
192 if (X##_c == FP_CLS_INF) \
194 /* Overflow to infinity */ \
195 X##_e = _FP_EXPMAX_##fs; \
196 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
198 else \
200 /* Overflow to maximum normal */ \
201 X##_e = _FP_EXPMAX_##fs - 1; \
202 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \
204 FP_SET_EXCEPTION(FP_EX_OVERFLOW); \
205 FP_SET_EXCEPTION(FP_EX_INEXACT); \
208 else \
210 /* we've got a denormalized number */ \
211 X##_e = -X##_e + 1; \
212 if (X##_e <= _FP_WFRACBITS_##fs) \
214 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
215 _FP_ROUND(wc, X); \
216 if (_FP_FRAC_HIGH_##fs(X) \
217 & (_FP_OVERFLOW_##fs >> 1)) \
219 X##_e = 1; \
220 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
222 else \
224 X##_e = 0; \
225 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
226 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
229 else \
231 /* underflow to zero */ \
232 X##_e = 0; \
233 if (!_FP_FRAC_ZEROP_##wc(X)) \
235 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
236 _FP_ROUND(wc, X); \
237 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \
239 FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
242 break; \
244 case FP_CLS_ZERO: \
245 X##_e = 0; \
246 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
247 break; \
249 case FP_CLS_INF: \
250 X##_e = _FP_EXPMAX_##fs; \
251 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
252 break; \
254 case FP_CLS_NAN: \
255 X##_e = _FP_EXPMAX_##fs; \
256 if (!_FP_KEEPNANFRACP) \
258 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
259 X##_s = _FP_NANSIGN_##fs; \
261 else \
262 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
263 break; \
265 } while (0)
267 /* This one accepts raw argument and not cooked, returns
268 * 1 if X is a signaling NaN.
270 #define _FP_ISSIGNAN(fs, wc, X) \
271 ({ \
272 int __ret = 0; \
273 if (X##_e == _FP_EXPMAX_##fs) \
275 if (!_FP_FRAC_ZEROP_##wc(X) \
276 && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
277 __ret = 1; \
279 __ret; \
286 /* Addition on semi-raw values. */
287 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \
288 do { \
289 if (X##_s == Y##_s) \
291 /* Addition. */ \
292 R##_s = X##_s; \
293 int ediff = X##_e - Y##_e; \
294 if (ediff > 0) \
296 R##_e = X##_e; \
297 if (Y##_e == 0) \
299 /* Y is zero or denormalized. */ \
300 if (_FP_FRAC_ZEROP_##wc(Y)) \
302 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
303 _FP_FRAC_COPY_##wc(R, X); \
304 goto add_done; \
306 else \
308 FP_SET_EXCEPTION(FP_EX_DENORM); \
309 ediff--; \
310 if (ediff == 0) \
312 _FP_FRAC_ADD_##wc(R, X, Y); \
313 goto add3; \
315 if (X##_e == _FP_EXPMAX_##fs) \
317 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
318 _FP_FRAC_COPY_##wc(R, X); \
319 goto add_done; \
321 goto add1; \
324 else if (X##_e == _FP_EXPMAX_##fs) \
326 /* X is NaN or Inf, Y is normal. */ \
327 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
328 _FP_FRAC_COPY_##wc(R, X); \
329 goto add_done; \
332 /* Insert implicit MSB of Y. */ \
333 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
335 add1: \
336 /* Shift the mantissa of Y to the right EDIFF steps; \
337 remember to account later for the implicit MSB of X. */ \
338 if (ediff <= _FP_WFRACBITS_##fs) \
339 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
340 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
341 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
342 _FP_FRAC_ADD_##wc(R, X, Y); \
344 else if (ediff < 0) \
346 ediff = -ediff; \
347 R##_e = Y##_e; \
348 if (X##_e == 0) \
350 /* X is zero or denormalized. */ \
351 if (_FP_FRAC_ZEROP_##wc(X)) \
353 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
354 _FP_FRAC_COPY_##wc(R, Y); \
355 goto add_done; \
357 else \
359 FP_SET_EXCEPTION(FP_EX_DENORM); \
360 ediff--; \
361 if (ediff == 0) \
363 _FP_FRAC_ADD_##wc(R, Y, X); \
364 goto add3; \
366 if (Y##_e == _FP_EXPMAX_##fs) \
368 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
369 _FP_FRAC_COPY_##wc(R, Y); \
370 goto add_done; \
372 goto add2; \
375 else if (Y##_e == _FP_EXPMAX_##fs) \
377 /* Y is NaN or Inf, X is normal. */ \
378 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
379 _FP_FRAC_COPY_##wc(R, Y); \
380 goto add_done; \
383 /* Insert implicit MSB of X. */ \
384 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
386 add2: \
387 /* Shift the mantissa of X to the right EDIFF steps; \
388 remember to account later for the implicit MSB of Y. */ \
389 if (ediff <= _FP_WFRACBITS_##fs) \
390 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
391 else if (!_FP_FRAC_ZEROP_##wc(X)) \
392 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
393 _FP_FRAC_ADD_##wc(R, Y, X); \
395 else \
397 /* ediff == 0. */ \
398 if (!_FP_EXP_NORMAL(fs, wc, X)) \
400 if (X##_e == 0) \
402 /* X and Y are zero or denormalized. */ \
403 R##_e = 0; \
404 if (_FP_FRAC_ZEROP_##wc(X)) \
406 if (!_FP_FRAC_ZEROP_##wc(Y)) \
407 FP_SET_EXCEPTION(FP_EX_DENORM); \
408 _FP_FRAC_COPY_##wc(R, Y); \
409 goto add_done; \
411 else if (_FP_FRAC_ZEROP_##wc(Y)) \
413 FP_SET_EXCEPTION(FP_EX_DENORM); \
414 _FP_FRAC_COPY_##wc(R, X); \
415 goto add_done; \
417 else \
419 FP_SET_EXCEPTION(FP_EX_DENORM); \
420 _FP_FRAC_ADD_##wc(R, X, Y); \
421 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
423 /* Normalized result. */ \
424 _FP_FRAC_HIGH_##fs(R) \
425 &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
426 R##_e = 1; \
428 goto add_done; \
431 else \
433 /* X and Y are NaN or Inf. */ \
434 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
435 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
436 R##_e = _FP_EXPMAX_##fs; \
437 if (_FP_FRAC_ZEROP_##wc(X)) \
438 _FP_FRAC_COPY_##wc(R, Y); \
439 else if (_FP_FRAC_ZEROP_##wc(Y)) \
440 _FP_FRAC_COPY_##wc(R, X); \
441 else \
442 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
443 goto add_done; \
446 /* The exponents of X and Y, both normal, are equal. The \
447 implicit MSBs will always add to increase the \
448 exponent. */ \
449 _FP_FRAC_ADD_##wc(R, X, Y); \
450 R##_e = X##_e + 1; \
451 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
452 if (R##_e == _FP_EXPMAX_##fs) \
453 /* Overflow to infinity (depending on rounding mode). */ \
454 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
455 goto add_done; \
457 add3: \
458 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
460 /* Overflow. */ \
461 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
462 R##_e++; \
463 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
464 if (R##_e == _FP_EXPMAX_##fs) \
465 /* Overflow to infinity (depending on rounding mode). */ \
466 _FP_OVERFLOW_SEMIRAW(fs, wc, R); \
468 add_done: ; \
470 else \
472 /* Subtraction. */ \
473 int ediff = X##_e - Y##_e; \
474 if (ediff > 0) \
476 R##_e = X##_e; \
477 R##_s = X##_s; \
478 if (Y##_e == 0) \
480 /* Y is zero or denormalized. */ \
481 if (_FP_FRAC_ZEROP_##wc(Y)) \
483 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
484 _FP_FRAC_COPY_##wc(R, X); \
485 goto sub_done; \
487 else \
489 FP_SET_EXCEPTION(FP_EX_DENORM); \
490 ediff--; \
491 if (ediff == 0) \
493 _FP_FRAC_SUB_##wc(R, X, Y); \
494 goto sub3; \
496 if (X##_e == _FP_EXPMAX_##fs) \
498 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
499 _FP_FRAC_COPY_##wc(R, X); \
500 goto sub_done; \
502 goto sub1; \
505 else if (X##_e == _FP_EXPMAX_##fs) \
507 /* X is NaN or Inf, Y is normal. */ \
508 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
509 _FP_FRAC_COPY_##wc(R, X); \
510 goto sub_done; \
513 /* Insert implicit MSB of Y. */ \
514 _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \
516 sub1: \
517 /* Shift the mantissa of Y to the right EDIFF steps; \
518 remember to account later for the implicit MSB of X. */ \
519 if (ediff <= _FP_WFRACBITS_##fs) \
520 _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \
521 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
522 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
523 _FP_FRAC_SUB_##wc(R, X, Y); \
525 else if (ediff < 0) \
527 ediff = -ediff; \
528 R##_e = Y##_e; \
529 R##_s = Y##_s; \
530 if (X##_e == 0) \
532 /* X is zero or denormalized. */ \
533 if (_FP_FRAC_ZEROP_##wc(X)) \
535 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
536 _FP_FRAC_COPY_##wc(R, Y); \
537 goto sub_done; \
539 else \
541 FP_SET_EXCEPTION(FP_EX_DENORM); \
542 ediff--; \
543 if (ediff == 0) \
545 _FP_FRAC_SUB_##wc(R, Y, X); \
546 goto sub3; \
548 if (Y##_e == _FP_EXPMAX_##fs) \
550 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
551 _FP_FRAC_COPY_##wc(R, Y); \
552 goto sub_done; \
554 goto sub2; \
557 else if (Y##_e == _FP_EXPMAX_##fs) \
559 /* Y is NaN or Inf, X is normal. */ \
560 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
561 _FP_FRAC_COPY_##wc(R, Y); \
562 goto sub_done; \
565 /* Insert implicit MSB of X. */ \
566 _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \
568 sub2: \
569 /* Shift the mantissa of X to the right EDIFF steps; \
570 remember to account later for the implicit MSB of Y. */ \
571 if (ediff <= _FP_WFRACBITS_##fs) \
572 _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \
573 else if (!_FP_FRAC_ZEROP_##wc(X)) \
574 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
575 _FP_FRAC_SUB_##wc(R, Y, X); \
577 else \
579 /* ediff == 0. */ \
580 if (!_FP_EXP_NORMAL(fs, wc, X)) \
582 if (X##_e == 0) \
584 /* X and Y are zero or denormalized. */ \
585 R##_e = 0; \
586 if (_FP_FRAC_ZEROP_##wc(X)) \
588 _FP_FRAC_COPY_##wc(R, Y); \
589 if (_FP_FRAC_ZEROP_##wc(Y)) \
590 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
591 else \
593 FP_SET_EXCEPTION(FP_EX_DENORM); \
594 R##_s = Y##_s; \
596 goto sub_done; \
598 else if (_FP_FRAC_ZEROP_##wc(Y)) \
600 FP_SET_EXCEPTION(FP_EX_DENORM); \
601 _FP_FRAC_COPY_##wc(R, X); \
602 R##_s = X##_s; \
603 goto sub_done; \
605 else \
607 FP_SET_EXCEPTION(FP_EX_DENORM); \
608 _FP_FRAC_SUB_##wc(R, X, Y); \
609 R##_s = X##_s; \
610 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
612 /* |X| < |Y|, negate result. */ \
613 _FP_FRAC_SUB_##wc(R, Y, X); \
614 R##_s = Y##_s; \
616 else if (_FP_FRAC_ZEROP_##wc(R)) \
617 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
618 goto sub_done; \
621 else \
623 /* X and Y are NaN or Inf, of opposite signs. */ \
624 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \
625 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \
626 R##_e = _FP_EXPMAX_##fs; \
627 if (_FP_FRAC_ZEROP_##wc(X)) \
629 if (_FP_FRAC_ZEROP_##wc(Y)) \
631 /* Inf - Inf. */ \
632 R##_s = _FP_NANSIGN_##fs; \
633 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
634 _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
635 FP_SET_EXCEPTION(FP_EX_INVALID); \
637 else \
639 /* Inf - NaN. */ \
640 R##_s = Y##_s; \
641 _FP_FRAC_COPY_##wc(R, Y); \
644 else \
646 if (_FP_FRAC_ZEROP_##wc(Y)) \
648 /* NaN - Inf. */ \
649 R##_s = X##_s; \
650 _FP_FRAC_COPY_##wc(R, X); \
652 else \
654 /* NaN - NaN. */ \
655 _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \
658 goto sub_done; \
661 /* The exponents of X and Y, both normal, are equal. The \
662 implicit MSBs cancel. */ \
663 R##_e = X##_e; \
664 _FP_FRAC_SUB_##wc(R, X, Y); \
665 R##_s = X##_s; \
666 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
668 /* |X| < |Y|, negate result. */ \
669 _FP_FRAC_SUB_##wc(R, Y, X); \
670 R##_s = Y##_s; \
672 else if (_FP_FRAC_ZEROP_##wc(R)) \
674 R##_e = 0; \
675 R##_s = (FP_ROUNDMODE == FP_RND_MINF); \
676 goto sub_done; \
678 goto norm; \
680 sub3: \
681 if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \
683 int diff; \
684 /* Carry into most significant bit of larger one of X and Y, \
685 canceling it; renormalize. */ \
686 _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \
687 norm: \
688 _FP_FRAC_CLZ_##wc(diff, R); \
689 diff -= _FP_WFRACXBITS_##fs; \
690 _FP_FRAC_SLL_##wc(R, diff); \
691 if (R##_e <= diff) \
693 /* R is denormalized. */ \
694 diff = diff - R##_e + 1; \
695 _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \
696 R##_e = 0; \
698 else \
700 R##_e -= diff; \
701 _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
704 sub_done: ; \
706 } while (0)
708 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
709 #define _FP_SUB(fs, wc, R, X, Y) \
710 do { \
711 if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
712 _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \
713 } while (0)
717 * Main negation routine. FIXME -- when we care about setting exception
718 * bits reliably, this will not do. We should examine all of the fp classes.
721 #define _FP_NEG(fs, wc, R, X) \
722 do { \
723 _FP_FRAC_COPY_##wc(R, X); \
724 R##_c = X##_c; \
725 R##_e = X##_e; \
726 R##_s = 1 ^ X##_s; \
727 } while (0)
731 * Main multiplication routine. The input values should be cooked.
734 #define _FP_MUL(fs, wc, R, X, Y) \
735 do { \
736 R##_s = X##_s ^ Y##_s; \
737 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
739 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
740 R##_c = FP_CLS_NORMAL; \
741 R##_e = X##_e + Y##_e + 1; \
743 _FP_MUL_MEAT_##fs(R,X,Y); \
745 if (_FP_FRAC_OVERP_##wc(fs, R)) \
746 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
747 else \
748 R##_e--; \
749 break; \
751 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
752 _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \
753 break; \
755 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
756 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
757 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
758 R##_s = X##_s; \
760 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
761 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
762 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
763 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
764 _FP_FRAC_COPY_##wc(R, X); \
765 R##_c = X##_c; \
766 break; \
768 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
769 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
770 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
771 R##_s = Y##_s; \
773 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
774 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
775 _FP_FRAC_COPY_##wc(R, Y); \
776 R##_c = Y##_c; \
777 break; \
779 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
780 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
781 R##_s = _FP_NANSIGN_##fs; \
782 R##_c = FP_CLS_NAN; \
783 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
784 FP_SET_EXCEPTION(FP_EX_INVALID); \
785 break; \
787 default: \
788 abort(); \
790 } while (0)
794 * Main division routine. The input values should be cooked.
797 #define _FP_DIV(fs, wc, R, X, Y) \
798 do { \
799 R##_s = X##_s ^ Y##_s; \
800 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
802 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
803 R##_c = FP_CLS_NORMAL; \
804 R##_e = X##_e - Y##_e; \
806 _FP_DIV_MEAT_##fs(R,X,Y); \
807 break; \
809 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
810 _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \
811 break; \
813 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
814 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
815 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
816 R##_s = X##_s; \
817 _FP_FRAC_COPY_##wc(R, X); \
818 R##_c = X##_c; \
819 break; \
821 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
822 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
823 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
824 R##_s = Y##_s; \
825 _FP_FRAC_COPY_##wc(R, Y); \
826 R##_c = Y##_c; \
827 break; \
829 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
830 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
831 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
832 R##_c = FP_CLS_ZERO; \
833 break; \
835 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
836 FP_SET_EXCEPTION(FP_EX_DIVZERO); \
837 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
838 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
839 R##_c = FP_CLS_INF; \
840 break; \
842 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
843 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
844 R##_s = _FP_NANSIGN_##fs; \
845 R##_c = FP_CLS_NAN; \
846 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
847 FP_SET_EXCEPTION(FP_EX_INVALID); \
848 break; \
850 default: \
851 abort(); \
853 } while (0)
857 * Main differential comparison routine. The inputs should be raw not
858 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
861 #define _FP_CMP(fs, wc, ret, X, Y, un) \
862 do { \
863 /* NANs are unordered */ \
864 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
865 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
867 ret = un; \
869 else \
871 int __is_zero_x; \
872 int __is_zero_y; \
874 __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
875 __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
877 if (__is_zero_x && __is_zero_y) \
878 ret = 0; \
879 else if (__is_zero_x) \
880 ret = Y##_s ? 1 : -1; \
881 else if (__is_zero_y) \
882 ret = X##_s ? -1 : 1; \
883 else if (X##_s != Y##_s) \
884 ret = X##_s ? -1 : 1; \
885 else if (X##_e > Y##_e) \
886 ret = X##_s ? -1 : 1; \
887 else if (X##_e < Y##_e) \
888 ret = X##_s ? 1 : -1; \
889 else if (_FP_FRAC_GT_##wc(X, Y)) \
890 ret = X##_s ? -1 : 1; \
891 else if (_FP_FRAC_GT_##wc(Y, X)) \
892 ret = X##_s ? 1 : -1; \
893 else \
894 ret = 0; \
896 } while (0)
899 /* Simplification for strict equality. */
901 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
902 do { \
903 /* NANs are unordered */ \
904 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
905 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
907 ret = 1; \
909 else \
911 ret = !(X##_e == Y##_e \
912 && _FP_FRAC_EQ_##wc(X, Y) \
913 && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
915 } while (0)
917 /* Version to test unordered. */
919 #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \
920 do { \
921 ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
922 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \
923 } while (0)
926 * Main square root routine. The input value should be cooked.
929 #define _FP_SQRT(fs, wc, R, X) \
930 do { \
931 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
932 _FP_W_TYPE q; \
933 switch (X##_c) \
935 case FP_CLS_NAN: \
936 _FP_FRAC_COPY_##wc(R, X); \
937 R##_s = X##_s; \
938 R##_c = FP_CLS_NAN; \
939 break; \
940 case FP_CLS_INF: \
941 if (X##_s) \
943 R##_s = _FP_NANSIGN_##fs; \
944 R##_c = FP_CLS_NAN; /* NAN */ \
945 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
946 FP_SET_EXCEPTION(FP_EX_INVALID); \
948 else \
950 R##_s = 0; \
951 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
953 break; \
954 case FP_CLS_ZERO: \
955 R##_s = X##_s; \
956 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
957 break; \
958 case FP_CLS_NORMAL: \
959 R##_s = 0; \
960 if (X##_s) \
962 R##_c = FP_CLS_NAN; /* sNAN */ \
963 R##_s = _FP_NANSIGN_##fs; \
964 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
965 FP_SET_EXCEPTION(FP_EX_INVALID); \
966 break; \
968 R##_c = FP_CLS_NORMAL; \
969 if (X##_e & 1) \
970 _FP_FRAC_SLL_##wc(X, 1); \
971 R##_e = X##_e >> 1; \
972 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
973 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
974 q = _FP_OVERFLOW_##fs >> 1; \
975 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
977 } while (0)
980 * Convert from FP to integer. Input is raw.
983 /* RSIGNED can have following values:
984 * 0: the number is required to be 0..(2^rsize)-1, if not, NV is set plus
985 * the result is either 0 or (2^rsize)-1 depending on the sign in such
986 * case.
987 * 1: the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
988 * NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
989 * depending on the sign in such case.
990 * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
991 * set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
992 * depending on the sign in such case.
994 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
995 do { \
996 if (X##_e < _FP_EXPBIAS_##fs) \
998 r = 0; \
999 if (X##_e == 0) \
1001 if (!_FP_FRAC_ZEROP_##wc(X)) \
1003 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1004 FP_SET_EXCEPTION(FP_EX_DENORM); \
1007 else \
1008 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1010 else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \
1011 || (!rsigned && X##_s)) \
1013 /* Overflow or converting to the most negative integer. */ \
1014 if (rsigned) \
1016 r = 1; \
1017 r <<= rsize - 1; \
1018 r -= 1 - X##_s; \
1019 } else { \
1020 r = 0; \
1021 if (X##_s) \
1022 r = ~r; \
1025 if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \
1027 /* Possibly converting to most negative integer; check the \
1028 mantissa. */ \
1029 int inexact = 0; \
1030 (void)((_FP_FRACBITS_##fs > rsize) \
1031 ? ({ _FP_FRAC_SRST_##wc(X, inexact, \
1032 _FP_FRACBITS_##fs - rsize, \
1033 _FP_FRACBITS_##fs); 0; }) \
1034 : 0); \
1035 if (!_FP_FRAC_ZEROP_##wc(X)) \
1036 FP_SET_EXCEPTION(FP_EX_INVALID); \
1037 else if (inexact) \
1038 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1040 else \
1041 FP_SET_EXCEPTION(FP_EX_INVALID); \
1043 else \
1045 _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \
1046 if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \
1048 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1049 r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
1051 else \
1053 int inexact; \
1054 _FP_FRAC_SRST_##wc(X, inexact, \
1055 (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
1056 - X##_e), \
1057 _FP_FRACBITS_##fs); \
1058 if (inexact) \
1059 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1060 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
1062 if (rsigned && X##_s) \
1063 r = -r; \
1065 } while (0)
1067 /* Convert integer to fp. Output is raw. RTYPE is unsigned even if
1068 input is signed. */
1069 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
1070 do { \
1071 if (r) \
1073 rtype ur_; \
1075 if ((X##_s = (r < 0))) \
1076 r = -(rtype)r; \
1078 ur_ = (rtype) r; \
1079 (void)((rsize <= _FP_W_TYPE_SIZE) \
1080 ? ({ \
1081 int lz_; \
1082 __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \
1083 X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \
1084 }) \
1085 : ((rsize <= 2 * _FP_W_TYPE_SIZE) \
1086 ? ({ \
1087 int lz_; \
1088 __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
1089 (_FP_W_TYPE)ur_); \
1090 X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
1091 - lz_); \
1092 }) \
1093 : (abort(), 0))); \
1095 if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
1096 && X##_e >= _FP_EXPMAX_##fs) \
1098 /* Exponent too big; overflow to infinity. (May also \
1099 happen after rounding below.) */ \
1100 _FP_OVERFLOW_SEMIRAW(fs, wc, X); \
1101 goto pack_semiraw; \
1104 if (rsize <= _FP_FRACBITS_##fs \
1105 || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \
1107 /* Exactly representable; shift left. */ \
1108 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1109 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1110 + _FP_FRACBITS_##fs - 1 - X##_e)); \
1112 else \
1114 /* More bits in integer than in floating type; need to \
1115 round. */ \
1116 if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \
1117 ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \
1118 - _FP_WFRACBITS_##fs + 1)) \
1119 | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \
1120 - _FP_WFRACBITS_##fs + 1))) \
1121 != 0)); \
1122 _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \
1123 if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
1124 _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \
1125 + _FP_WFRACBITS_##fs - 1 - X##_e)); \
1126 _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
1127 pack_semiraw: \
1128 _FP_PACK_SEMIRAW(fs, wc, X); \
1131 else \
1133 X##_s = 0; \
1134 X##_e = 0; \
1135 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
1137 } while (0)
1140 /* Extend from a narrower floating-point format to a wider one. Input
1141 and output are raw. */
1142 #define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \
1143 do { \
1144 if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
1145 || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
1146 < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
1147 || _FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
1148 abort(); \
1149 D##_s = S##_s; \
1150 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1151 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1153 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1154 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
1156 else \
1158 if (S##_e == 0) \
1160 if (_FP_FRAC_ZEROP_##swc(S)) \
1161 D##_e = 0; \
1162 else \
1164 int _lz; \
1165 FP_SET_EXCEPTION(FP_EX_DENORM); \
1166 _FP_FRAC_CLZ_##swc(_lz, S); \
1167 _FP_FRAC_SLL_##dwc(D, \
1168 _lz + _FP_FRACBITS_##dfs \
1169 - _FP_FRACTBITS_##sfs); \
1170 D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \
1171 + _FP_FRACXBITS_##sfs - _lz); \
1174 else \
1176 D##_e = _FP_EXPMAX_##dfs; \
1177 if (!_FP_FRAC_ZEROP_##swc(S)) \
1179 if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
1180 FP_SET_EXCEPTION(FP_EX_INVALID); \
1181 _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
1182 - _FP_FRACBITS_##sfs)); \
1186 } while (0)
1188 /* Truncate from a wider floating-point format to a narrower one.
1189 Input and output are semi-raw. */
1190 #define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \
1191 do { \
1192 if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
1193 || _FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \
1194 abort(); \
1195 D##_s = S##_s; \
1196 if (_FP_EXP_NORMAL(sfs, swc, S)) \
1198 D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \
1199 if (D##_e >= _FP_EXPMAX_##dfs) \
1200 _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \
1201 else \
1203 if (D##_e <= 0) \
1205 if (D##_e <= 1 - _FP_FRACBITS_##dfs) \
1206 _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \
1207 else \
1209 _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \
1210 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1211 - _FP_WFRACBITS_##dfs + 1 - D##_e), \
1212 _FP_WFRACBITS_##sfs); \
1214 D##_e = 0; \
1216 else \
1217 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \
1218 - _FP_WFRACBITS_##dfs), \
1219 _FP_WFRACBITS_##sfs); \
1220 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1223 else \
1225 if (S##_e == 0) \
1227 D##_e = 0; \
1228 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1229 if (!_FP_FRAC_ZEROP_##swc(S)) \
1231 FP_SET_EXCEPTION(FP_EX_DENORM); \
1232 FP_SET_EXCEPTION(FP_EX_INEXACT); \
1235 else \
1237 D##_e = _FP_EXPMAX_##dfs; \
1238 if (_FP_FRAC_ZEROP_##swc(S)) \
1239 _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \
1240 else \
1242 _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \
1243 _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \
1244 - _FP_WFRACBITS_##dfs)); \
1245 _FP_FRAC_COPY_##dwc##_##swc(D, S); \
1246 _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
1250 } while (0)
1253 * Helper primitives.
1256 /* Count leading zeros in a word. */
1258 #ifndef __FP_CLZ
1259 /* GCC 3.4 and later provide the builtins for us. */
1260 #define __FP_CLZ(r, x) \
1261 do { \
1262 if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
1263 r = __builtin_clz (x); \
1264 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
1265 r = __builtin_clzl (x); \
1266 else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \
1267 r = __builtin_clzll (x); \
1268 else \
1269 abort (); \
1270 } while (0)
1271 #endif /* ndef __FP_CLZ */
1273 #define _FP_DIV_HELP_imm(q, r, n, d) \
1274 do { \
1275 q = n / d, r = n % d; \
1276 } while (0)
1279 /* A restoring bit-by-bit division primitive. */
1281 #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \
1282 do { \
1283 int count = _FP_WFRACBITS_##fs; \
1284 _FP_FRAC_DECL_##wc (u); \
1285 _FP_FRAC_DECL_##wc (v); \
1286 _FP_FRAC_COPY_##wc (u, X); \
1287 _FP_FRAC_COPY_##wc (v, Y); \
1288 _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \
1289 /* Normalize U and V. */ \
1290 _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \
1291 _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \
1292 /* First round. Since the operands are normalized, either the \
1293 first or second bit will be set in the fraction. Produce a \
1294 normalized result by checking which and adjusting the loop \
1295 count and exponent accordingly. */ \
1296 if (_FP_FRAC_GE_1 (u, v)) \
1298 _FP_FRAC_SUB_##wc (u, u, v); \
1299 _FP_FRAC_LOW_##wc (R) |= 1; \
1300 count--; \
1302 else \
1303 R##_e--; \
1304 /* Subsequent rounds. */ \
1305 do { \
1306 int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \
1307 _FP_FRAC_SLL_##wc (u, 1); \
1308 _FP_FRAC_SLL_##wc (R, 1); \
1309 if (msb || _FP_FRAC_GE_1 (u, v)) \
1311 _FP_FRAC_SUB_##wc (u, u, v); \
1312 _FP_FRAC_LOW_##wc (R) |= 1; \
1314 } while (--count > 0); \
1315 /* If there's anything left in U, the result is inexact. */ \
1316 _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \
1317 } while (0)
1319 #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1320 #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1321 #define _FP_DIV_MEAT_4_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)