1 #define _FP_DECL(wc, X) \
2 _FP_I_TYPE X##_c, X##_s, X##_e; \
6 * Finish truely unpacking a native fp value by classifying the kind
7 * of fp value and normalizing both the exponent and the fraction.
10 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
15 _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \
16 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
17 X##_e -= _FP_EXPBIAS_##fs; \
18 X##_c = FP_CLS_NORMAL; \
22 if (_FP_FRAC_ZEROP_##wc(X)) \
23 X##_c = FP_CLS_ZERO; \
26 /* a denormalized number */ \
28 _FP_FRAC_CLZ_##wc(_shift, X); \
29 _shift -= _FP_FRACXBITS_##fs; \
30 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
31 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
32 X##_c = FP_CLS_NORMAL; \
36 case _FP_EXPMAX_##fs: \
37 if (_FP_FRAC_ZEROP_##wc(X)) \
40 /* we don't differentiate between signaling and quiet nans */ \
48 * Before packing the bits back into the native fp result, take care
49 * of such mundane things as rounding and overflow. Also, for some
50 * kinds of fp values, the original parts may not have been fully
51 * extracted -- but that is ok, we can regenerate them now.
54 #define _FP_PACK_CANONICAL(fs, wc, X) \
59 X##_e += _FP_EXPBIAS_##fs; \
62 __ret |= _FP_ROUND(wc, X); \
63 if (_FP_FRAC_OVERP_##wc(fs, X)) \
65 _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
69 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
70 if (X##_e >= _FP_EXPMAX_##fs) \
72 /* overflow to infinity */ \
73 X##_e = _FP_EXPMAX_##fs; \
74 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
75 __ret |= EFLAG_OVERFLOW; \
80 /* we've got a denormalized number */ \
82 if (X##_e <= _FP_WFRACBITS_##fs) \
84 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
85 __ret |= _FP_ROUND(wc, X); \
86 _FP_FRAC_SLL_##wc(X, 1); \
87 if (_FP_FRAC_OVERP_##wc(fs, X)) \
90 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
95 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
96 __ret |= EFLAG_UNDERFLOW; \
101 /* underflow to zero */ \
103 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
104 __ret |= EFLAG_UNDERFLOW; \
111 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
115 X##_e = _FP_EXPMAX_##fs; \
116 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
120 X##_e = _FP_EXPMAX_##fs; \
121 if (!_FP_KEEPNANFRACP) \
123 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
127 _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
135 * Main addition routine. The input values should be cooked.
138 #define _FP_ADD(fs, wc, R, X, Y) \
140 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
142 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
144 /* shift the smaller number so that its exponent matches the larger */ \
145 _FP_I_TYPE diff = X##_e - Y##_e; \
150 if (diff <= _FP_WFRACBITS_##fs) \
151 _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
152 else if (!_FP_FRAC_ZEROP_##wc(X)) \
153 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
155 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
162 if (diff <= _FP_WFRACBITS_##fs) \
163 _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
164 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
165 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
167 _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
172 R##_c = FP_CLS_NORMAL; \
174 if (X##_s == Y##_s) \
177 _FP_FRAC_ADD_##wc(R, X, Y); \
178 if (_FP_FRAC_OVERP_##wc(fs, R)) \
180 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
187 _FP_FRAC_SUB_##wc(R, X, Y); \
188 if (_FP_FRAC_ZEROP_##wc(R)) \
190 /* return an exact zero */ \
191 if (FP_ROUNDMODE == FP_RND_MINF) \
195 R##_c = FP_CLS_ZERO; \
199 if (_FP_FRAC_NEGP_##wc(R)) \
201 _FP_FRAC_SUB_##wc(R, Y, X); \
205 /* renormalize after subtraction */ \
206 _FP_FRAC_CLZ_##wc(diff, R); \
207 diff -= _FP_WFRACXBITS_##fs; \
211 _FP_FRAC_SLL_##wc(R, diff); \
218 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
219 _FP_CHOOSENAN(fs, wc, R, X, Y); \
222 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
224 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
225 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
226 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
227 _FP_FRAC_COPY_##wc(R, X); \
232 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
234 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
235 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
236 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
237 _FP_FRAC_COPY_##wc(R, Y); \
242 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
243 if (X##_s != Y##_s) \
245 /* +INF + -INF => NAN */ \
246 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
247 R##_s = X##_s ^ Y##_s; \
248 R##_c = FP_CLS_NAN; \
253 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
254 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
256 R##_c = FP_CLS_INF; \
259 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
260 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
262 R##_c = FP_CLS_INF; \
265 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
266 /* make sure the sign is correct */ \
267 if (FP_ROUNDMODE == FP_RND_MINF) \
268 R##_s = X##_s | Y##_s; \
270 R##_s = X##_s & Y##_s; \
271 R##_c = FP_CLS_ZERO; \
281 * Main negation routine. FIXME -- when we care about setting exception
282 * bits reliably, this will not do. We should examine all of the fp classes.
285 #define _FP_NEG(fs, wc, R, X) \
287 _FP_FRAC_COPY_##wc(R, X); \
295 * Main multiplication routine. The input values should be cooked.
298 #define _FP_MUL(fs, wc, R, X, Y) \
300 R##_s = X##_s ^ Y##_s; \
301 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
303 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
304 R##_c = FP_CLS_NORMAL; \
305 R##_e = X##_e + Y##_e + 1; \
307 _FP_MUL_MEAT_##fs(R,X,Y); \
309 if (_FP_FRAC_OVERP_##wc(fs, R)) \
310 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
315 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
316 _FP_CHOOSENAN(fs, wc, R, X, Y); \
319 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
320 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
321 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
324 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
325 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
326 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
327 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
328 _FP_FRAC_COPY_##wc(R, X); \
332 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
333 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
334 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
337 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
338 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
339 _FP_FRAC_COPY_##wc(R, Y); \
343 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
344 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
345 R##_c = FP_CLS_NAN; \
346 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
356 * Main division routine. The input values should be cooked.
359 #define _FP_DIV(fs, wc, R, X, Y) \
361 R##_s = X##_s ^ Y##_s; \
362 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
364 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
365 R##_c = FP_CLS_NORMAL; \
366 R##_e = X##_e - Y##_e; \
368 _FP_DIV_MEAT_##fs(R,X,Y); \
371 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
372 _FP_CHOOSENAN(fs, wc, R, X, Y); \
375 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
376 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
377 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
379 _FP_FRAC_COPY_##wc(R, X); \
383 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
384 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
385 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
387 _FP_FRAC_COPY_##wc(R, Y); \
391 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
392 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
393 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
394 R##_c = FP_CLS_ZERO; \
397 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
398 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
399 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
400 R##_c = FP_CLS_INF; \
403 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
404 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
405 R##_c = FP_CLS_NAN; \
406 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
416 * Main differential comparison routine. The inputs should be raw not
417 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
420 #define _FP_CMP(fs, wc, ret, X, Y, un) \
422 /* NANs are unordered */ \
423 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
424 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
430 int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
431 int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
433 if (__x_zero && __y_zero) \
436 ret = Y##_s ? 1 : -1; \
438 ret = X##_s ? -1 : 1; \
439 else if (X##_s != Y##_s) \
440 ret = X##_s ? -1 : 1; \
441 else if (X##_e > Y##_e) \
442 ret = X##_s ? -1 : 1; \
443 else if (X##_e < Y##_e) \
444 ret = X##_s ? 1 : -1; \
445 else if (_FP_FRAC_GT_##wc(X, Y)) \
446 ret = X##_s ? -1 : 1; \
447 else if (_FP_FRAC_GT_##wc(Y, X)) \
448 ret = X##_s ? 1 : -1; \
455 /* Simplification for strict equality. */
457 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
459 /* NANs are unordered */ \
460 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
461 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
467 ret = !(X##_e == Y##_e \
468 && _FP_FRAC_EQ_##wc(X, Y) \
469 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
474 * Main square root routine. The input value should be cooked.
477 #define _FP_SQRT(fs, wc, R, X) \
479 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
485 R##_c = FP_CLS_NAN; \
486 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
492 R##_c = FP_CLS_NAN; /* sNAN */ \
497 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
502 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
504 case FP_CLS_NORMAL: \
508 R##_c = FP_CLS_NAN; /* sNAN */ \
511 R##_c = FP_CLS_NORMAL; \
513 _FP_FRAC_SLL_##wc(X, 1); \
514 R##_e = X##_e >> 1; \
515 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
516 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
517 q = _FP_OVERFLOW_##fs; \
518 _FP_FRAC_SLL_##wc(X, 1); \
519 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
520 _FP_FRAC_SRL_##wc(R, 1); \
525 * Convert from FP to integer
528 /* "When a NaN, infinity, large positive argument >= 2147483648.0, or
529 * large negative argument <= -2147483649.0 is converted to an integer,
530 * the invalid_current bit...should be set and fp_exception_IEEE_754 should
531 * be raised. If the floating point invalid trap is disabled, no trap occurs
532 * and a numerical result is generated: if the sign bit of the operand
533 * is 0, the result is 2147483647; if the sign bit of the operand is 1,
534 * the result is -2147483648."
535 * Similarly for conversion to extended ints, except that the boundaries
536 * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
538 * -- SPARC Architecture Manual V9, Appendix B, which specifies how
539 * SPARCs resolve implementation dependencies in the IEEE-754 spec.
540 * I don't believe that the code below follows this. I'm not even sure
542 * It doesn't cope with needing to convert to an n bit integer when there
543 * is no n bit integer type. Fortunately gcc provides long long so this
544 * isn't a problem for sparc32.
545 * I have, however, fixed its NaN handling to conform as above.
547 * NB: rsigned is not 'is r declared signed?' but 'should the value stored
548 * in r be signed or unsigned?'. r is always(?) declared unsigned.
549 * Comments below are mine, BTW -- PMM
551 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
555 case FP_CLS_NORMAL: \
558 /* case FP_CLS_NAN: see above! */ \
562 else if (X##_e >= rsize - (rsigned != 0)) \
581 if (_FP_W_TYPE_SIZE*wc < rsize) \
583 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
584 r <<= X##_e - _FP_WFRACBITS_##fs; \
588 if (X##_e >= _FP_WFRACBITS_##fs) \
589 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
591 _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
592 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
594 if (rsigned && X##_s) \
601 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
605 X##_c = FP_CLS_NORMAL; \
607 if ((X##_s = (r < 0))) \
609 /* Note that `r' is now considered unsigned, so we don't have \
610 to worry about the single signed overflow case. */ \
612 if (rsize <= _FP_W_TYPE_SIZE) \
613 __FP_CLZ(X##_e, r); \
615 __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \
617 if (rsize < _FP_W_TYPE_SIZE) \
618 X##_e -= (_FP_W_TYPE_SIZE - rsize); \
619 X##_e = rsize - X##_e - 1; \
621 if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
622 __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \
623 r &= ~((_FP_W_TYPE)1 << X##_e); \
624 _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \
625 _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
629 X##_c = FP_CLS_ZERO, X##_s = 0; \
634 #define FP_CONV(dfs,sfs,dwc,swc,D,S) \
636 _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
646 /* Count leading zeros in a word. */
649 #if _FP_W_TYPE_SIZE < 64
650 /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
651 #define __FP_CLZ(r, x) \
653 _FP_W_TYPE _t = (x); \
654 r = _FP_W_TYPE_SIZE - 1; \
655 if (_t > 0xffff) r -= 16; \
656 if (_t > 0xffff) _t >>= 16; \
657 if (_t > 0xff) r -= 8; \
658 if (_t > 0xff) _t >>= 8; \
659 if (_t & 0xf0) r -= 4; \
660 if (_t & 0xf0) _t >>= 4; \
661 if (_t & 0xc) r -= 2; \
662 if (_t & 0xc) _t >>= 2; \
663 if (_t & 0x2) r -= 1; \
665 #else /* not _FP_W_TYPE_SIZE < 64 */
666 #define __FP_CLZ(r, x) \
668 _FP_W_TYPE _t = (x); \
669 r = _FP_W_TYPE_SIZE - 1; \
670 if (_t > 0xffffffff) r -= 32; \
671 if (_t > 0xffffffff) _t >>= 32; \
672 if (_t > 0xffff) r -= 16; \
673 if (_t > 0xffff) _t >>= 16; \
674 if (_t > 0xff) r -= 8; \
675 if (_t > 0xff) _t >>= 8; \
676 if (_t & 0xf0) r -= 4; \
677 if (_t & 0xf0) _t >>= 4; \
678 if (_t & 0xc) r -= 2; \
679 if (_t & 0xc) _t >>= 2; \
680 if (_t & 0x2) r -= 1; \
682 #endif /* not _FP_W_TYPE_SIZE < 64 */
683 #endif /* ndef __FP_CLZ */
685 #define _FP_DIV_HELP_imm(q, r, n, d) \
687 q = n / d, r = n % d; \