1 /* This is a software floating point library which can be used instead
2 of the floating point routines in libgcc1.c for targets without
3 hardware floating point. */
5 /* Copyright (C) 1994,1997-1998 Free Software Foundation, Inc.
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file with other programs, and to distribute
15 those programs without any restriction coming from the use of this
16 file. (The General Public License restrictions do apply in other
17 respects; for example, they cover modification of the file, and
18 distribution when not linked into another program.)
20 This file is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; see the file COPYING. If not, write to
27 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 /* As a special exception, if you link this library with other files,
30 some of which are compiled with GCC, to produce an executable,
31 this library does not by itself cause the resulting executable
32 to be covered by the GNU General Public License.
33 This exception does not however invalidate any other reasons why
34 the executable file might be covered by the GNU General Public License. */
36 /* This implements IEEE 754 format arithmetic, but does not provide a
37 mechanism for setting the rounding mode, or for generating or handling
40 The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
41 Wilson, all of Cygnus Support. */
47 #include "sim-basics.h"
51 #include "sim-assert.h"
54 /* Debugging support. */
57 print_bits (unsigned64 x,
59 sim_fpu_print_func print,
62 unsigned64 bit = LSBIT64 (msbit);
79 /* Quick and dirty conversion between a host double and host 64bit int */
87 /* A packed IEEE floating point number.
89 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
90 32 and 64 bit numbers. This number is interpreted as:
92 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
93 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
95 Denormalized (0 == BIASEDEXP && FRAC != 0):
96 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
98 Zero (0 == BIASEDEXP && FRAC == 0):
99 (sign ? "-" : "+") 0.0
101 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
102 (sign ? "-" : "+") "infinity"
104 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
107 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
112 #define NR_EXPBITS (is_double ? 11 : 8)
113 #define NR_FRACBITS (is_double ? 52 : 23)
114 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
116 #define EXPMAX32 (255)
117 #define EXMPAX64 (2047)
118 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
120 #define EXPBIAS32 (127)
121 #define EXPBIAS64 (1023)
122 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
124 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
128 /* An unpacked floating point number.
130 When unpacked, the fraction of both a 32 and 64 bit floating point
131 number is stored using the same format:
133 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
134 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
136 #define NR_PAD32 (30)
138 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
139 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
141 #define NR_GUARDS32 (7 + NR_PAD32)
142 #define NR_GUARDS64 (8 + NR_PAD64)
143 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
144 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
146 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
147 #define GUARDLSB LSBIT64 (NR_PAD)
148 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
150 #define NR_FRAC_GUARD (60)
151 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
152 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
153 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
156 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
158 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
160 #define NORMAL_EXPMAX32 (EXPBIAS32)
161 #define NORMAL_EXPMAX64 (EXPBIAS64)
162 #define NORMAL_EXPMAX (EXPBIAS)
165 /* Integer constants */
167 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
168 #define MAX_UINT32 LSMASK64 (31, 0)
169 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
171 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
172 #define MAX_UINT64 LSMASK64 (63, 0)
173 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
175 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
176 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
177 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
178 #define NR_INTBITS (is_64bit ? 64 : 32)
180 /* Squeese an unpacked sim_fpu struct into a 32/64 bit integer */
181 STATIC_INLINE_SIM_FPU (unsigned64)
182 pack_fpu (const sim_fpu *src,
193 case sim_fpu_class_qnan:
196 /* force fraction to correct class */
197 fraction = src->fraction;
198 fraction >>= NR_GUARDS;
199 fraction |= QUIET_NAN;
201 case sim_fpu_class_snan:
204 /* force fraction to correct class */
205 fraction = src->fraction;
206 fraction >>= NR_GUARDS;
207 fraction &= ~QUIET_NAN;
209 case sim_fpu_class_infinity:
214 case sim_fpu_class_zero:
219 case sim_fpu_class_number:
220 case sim_fpu_class_denorm:
221 ASSERT (src->fraction >= IMPLICIT_1);
222 ASSERT (src->fraction < IMPLICIT_2);
223 if (src->normal_exp < NORMAL_EXPMIN)
225 /* This number's exponent is too low to fit into the bits
226 available in the number We'll denormalize the number by
227 storing zero in the exponent and shift the fraction to
228 the right to make up for it. */
229 int nr_shift = NORMAL_EXPMIN - src->normal_exp;
230 if (nr_shift > NR_FRACBITS)
232 /* underflow, just make the number zero */
241 /* Shift by the value */
242 fraction = src->fraction;
243 fraction >>= NR_GUARDS;
244 fraction >>= nr_shift;
247 else if (src->normal_exp > NORMAL_EXPMAX)
256 exp = (src->normal_exp + EXPBIAS);
258 fraction = src->fraction;
259 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
261 /* Round to nearest: If the guard bits are the all zero, but
262 the first, then we're half way between two numbers,
263 choose the one which makes the lsb of the answer 0. */
264 if ((fraction & GUARDMASK) == GUARDMSB)
266 if ((fraction & (GUARDMSB << 1)))
267 fraction += (GUARDMSB << 1);
271 /* Add a one to the guards to force round to nearest */
272 fraction += GUARDROUND;
274 if ((fraction & IMPLICIT_2)) /* rounding resulted in carry */
279 fraction >>= NR_GUARDS;
280 /* When exp == EXPMAX (overflow from carry) fraction must
281 have been made zero */
282 ASSERT ((exp == EXPMAX) <= ((fraction & ~IMPLICIT_1) == 0));
289 packed = ((sign ? SIGNBIT : 0)
290 | (exp << NR_FRACBITS)
291 | LSMASKED64 (fraction, NR_FRACBITS - 1, 0));
293 /* trace operation */
300 printf ("pack_fpu: ");
301 printf ("-> %c%0lX.%06lX\n",
302 LSMASKED32 (packed, 31, 31) ? '8' : '0',
303 (long) LSEXTRACTED32 (packed, 30, 23),
304 (long) LSEXTRACTED32 (packed, 23 - 1, 0));
312 /* Unpack a 32/64 bit integer into a sim_fpu structure */
313 STATIC_INLINE_SIM_FPU (void)
314 unpack_fpu (sim_fpu *dst, unsigned64 packed, int is_double)
316 unsigned64 fraction = LSMASKED64 (packed, NR_FRACBITS - 1, 0);
317 unsigned exp = LSEXTRACTED64 (packed, NR_EXPBITS + NR_FRACBITS - 1, NR_FRACBITS);
318 int sign = (packed & SIGNBIT) != 0;
322 /* Hmm. Looks like 0 */
325 /* tastes like zero */
326 dst->class = sim_fpu_class_zero;
331 /* Zero exponent with non zero fraction - it's denormalized,
332 so there isn't a leading implicit one - we'll shift it so
334 dst->normal_exp = exp - EXPBIAS + 1;
335 dst->class = sim_fpu_class_denorm;
337 fraction <<= NR_GUARDS;
338 while (fraction < IMPLICIT_1)
343 dst->fraction = fraction;
346 else if (exp == EXPMAX)
351 /* Attached to a zero fraction - means infinity */
352 dst->class = sim_fpu_class_infinity;
354 /* dst->normal_exp = EXPBIAS; */
355 /* dst->fraction = 0; */
359 /* Non zero fraction, means NaN */
361 dst->fraction = (fraction << NR_GUARDS);
362 if (fraction >= QUIET_NAN)
363 dst->class = sim_fpu_class_qnan;
365 dst->class = sim_fpu_class_snan;
370 /* Nothing strange about this number */
371 dst->class = sim_fpu_class_number;
373 dst->fraction = ((fraction << NR_GUARDS) | IMPLICIT_1);
374 dst->normal_exp = exp - EXPBIAS;
377 /* trace operation */
384 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
385 LSMASKED32 (packed, 31, 31) ? '8' : '0',
386 (long) LSEXTRACTED32 (packed, 30, 23),
387 (long) LSEXTRACTED32 (packed, 23 - 1, 0));
394 val.i = pack_fpu (dst, 1);
397 ASSERT (val.i == packed);
401 unsigned32 val = pack_fpu (dst, 0);
402 unsigned32 org = packed;
409 /* Convert a floating point into an integer */
410 STATIC_INLINE_SIM_FPU (int)
419 if (sim_fpu_is_zero (s))
424 if (sim_fpu_is_snan (s))
426 *i = MIN_INT; /* FIXME */
427 return sim_fpu_status_invalid_cvi;
429 if (sim_fpu_is_qnan (s))
431 *i = MIN_INT; /* FIXME */
432 return sim_fpu_status_invalid_cvi;
434 /* map infinity onto MAX_INT... */
435 if (sim_fpu_is_infinity (s))
437 *i = s->sign ? MIN_INT : MAX_INT;
438 return sim_fpu_status_invalid_cvi;
440 /* it is a number, but a small one */
441 if (s->normal_exp < 0)
444 return sim_fpu_status_inexact;
446 /* Is the floating point MIN_INT or just close? */
447 if (s->sign && s->normal_exp == (NR_INTBITS - 1))
450 ASSERT (s->fraction >= IMPLICIT_1);
451 if (s->fraction == IMPLICIT_1)
452 return 0; /* exact */
453 if (is_64bit) /* can't round */
454 return sim_fpu_status_invalid_cvi; /* must be overflow */
455 /* For a 32bit with MAX_INT, rounding is possible */
458 case sim_fpu_round_default:
460 case sim_fpu_round_zero:
461 if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
462 return sim_fpu_status_invalid_cvi;
464 return sim_fpu_status_inexact;
466 case sim_fpu_round_near:
468 if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
469 return sim_fpu_status_invalid_cvi;
470 else if ((s->fraction & !FRAC32MASK) >= (~FRAC32MASK >> 1))
471 return sim_fpu_status_invalid_cvi;
473 return sim_fpu_status_inexact;
475 case sim_fpu_round_up:
476 if ((s->fraction & FRAC32MASK) == IMPLICIT_1)
477 return sim_fpu_status_inexact;
479 return sim_fpu_status_invalid_cvi;
480 case sim_fpu_round_down:
481 return sim_fpu_status_invalid_cvi;
484 /* Would right shifting result in the FRAC being shifted into
485 (through) the integer's sign bit? */
486 if (s->normal_exp > (NR_INTBITS - 2))
488 *i = s->sign ? MIN_INT : MAX_INT;
489 return sim_fpu_status_invalid_cvi;
491 /* normal number shift it into place */
493 shift = (s->normal_exp - (NR_FRAC_GUARD));
501 if (tmp & ((SIGNED64 (1) << shift) - 1))
502 status |= sim_fpu_status_inexact;
505 *i = s->sign ? (-tmp) : (tmp);
509 /* convert an integer into a floating point */
510 STATIC_INLINE_SIM_FPU (int)
511 i2fpu (sim_fpu *f, signed64 i, int is_64bit)
516 f->class = sim_fpu_class_zero;
521 f->class = sim_fpu_class_number;
523 f->normal_exp = NR_FRAC_GUARD;
527 /* Special case for minint, since there is no corresponding
528 +ve integer representation for it */
531 f->fraction = IMPLICIT_1;
532 f->normal_exp = NR_INTBITS - 1;
540 if (f->fraction >= IMPLICIT_2)
547 while (f->fraction >= IMPLICIT_2);
549 else if (f->fraction < IMPLICIT_1)
556 while (f->fraction < IMPLICIT_1);
560 /* trace operation */
563 printf ("i2fpu: 0x%08lX ->\n", (long) i);
570 fpu2i (&val, f, is_64bit, sim_fpu_round_zero);
571 if (i >= MIN_INT32 && i <= MAX_INT32)
581 /* Convert a floating point into an integer */
582 STATIC_INLINE_SIM_FPU (int)
583 fpu2u (unsigned64 *u, const sim_fpu *s, int is_64bit)
585 const int is_double = 1;
588 if (sim_fpu_is_zero (s))
593 if (sim_fpu_is_nan (s))
598 /* it is a negative number */
604 /* get reasonable MAX_USI_INT... */
605 if (sim_fpu_is_infinity (s))
610 /* it is a number, but a small one */
611 if (s->normal_exp < 0)
617 if (s->normal_exp > (NR_INTBITS - 1))
623 tmp = (s->fraction & ~PADMASK);
624 shift = (s->normal_exp - (NR_FRACBITS + NR_GUARDS));
638 /* Convert an unsigned integer into a floating point */
639 STATIC_INLINE_SIM_FPU (int)
640 u2fpu (sim_fpu *f, unsigned64 u, int is_64bit)
644 f->class = sim_fpu_class_zero;
649 f->class = sim_fpu_class_number;
651 f->normal_exp = NR_FRAC_GUARD;
654 while (f->fraction < IMPLICIT_1)
664 /* register <-> sim_fpu */
666 INLINE_SIM_FPU (void)
667 sim_fpu_32to (sim_fpu *f, unsigned32 s)
669 unpack_fpu (f, s, 0);
673 INLINE_SIM_FPU (void)
674 sim_fpu_232to (sim_fpu *f, unsigned32 h, unsigned32 l)
678 unpack_fpu (f, s, 1);
682 INLINE_SIM_FPU (void)
683 sim_fpu_64to (sim_fpu *f, unsigned64 s)
685 unpack_fpu (f, s, 1);
689 INLINE_SIM_FPU (void)
690 sim_fpu_to32 (unsigned32 *s,
693 *s = pack_fpu (f, 0);
697 INLINE_SIM_FPU (void)
698 sim_fpu_to232 (unsigned32 *h, unsigned32 *l,
701 unsigned64 s = pack_fpu (f, 1);
707 INLINE_SIM_FPU (void)
708 sim_fpu_to64 (unsigned64 *u,
711 *u = pack_fpu (f, 1);
715 INLINE_SIM_FPU (void)
716 sim_fpu_fractionto (sim_fpu *f,
722 int shift = (NR_FRAC_GUARD - precision);
723 f->class = sim_fpu_class_number;
725 f->normal_exp = normal_exp;
726 /* shift the fraction to where sim-fpu expects it */
728 f->fraction = (fraction << shift);
730 f->fraction = (fraction >> -shift);
731 f->fraction |= IMPLICIT_1;
735 INLINE_SIM_FPU (unsigned64)
736 sim_fpu_tofraction (const sim_fpu *d,
739 /* we have NR_FRAC_GUARD bits, we want only PRECISION bits */
740 int shift = (NR_FRAC_GUARD - precision);
741 unsigned64 fraction = (d->fraction & ~IMPLICIT_1);
743 return fraction >> shift;
745 return fraction << -shift;
751 STATIC_INLINE_SIM_FPU (int)
752 do_normal_overflow (sim_fpu *f,
758 case sim_fpu_round_default:
760 case sim_fpu_round_near:
761 f->class = sim_fpu_class_infinity;
763 case sim_fpu_round_up:
765 f->class = sim_fpu_class_infinity;
767 case sim_fpu_round_down:
769 f->class = sim_fpu_class_infinity;
771 case sim_fpu_round_zero:
774 f->normal_exp = NORMAL_EXPMAX;
775 f->fraction = LSMASK64 (NR_FRAC_GUARD, NR_GUARDS);
776 return (sim_fpu_status_overflow | sim_fpu_status_inexact);
779 STATIC_INLINE_SIM_FPU (int)
780 do_normal_underflow (sim_fpu *f,
786 case sim_fpu_round_default:
788 case sim_fpu_round_near:
789 f->class = sim_fpu_class_zero;
791 case sim_fpu_round_up:
793 f->class = sim_fpu_class_zero;
795 case sim_fpu_round_down:
797 f->class = sim_fpu_class_zero;
799 case sim_fpu_round_zero:
800 f->class = sim_fpu_class_zero;
803 f->normal_exp = NORMAL_EXPMIN - NR_FRACBITS;
804 f->fraction = IMPLICIT_1;
805 return (sim_fpu_status_inexact | sim_fpu_status_underflow);
810 /* Round a number using NR_GUARDS.
811 Will return the rounded number or F->FRACTION == 0 when underflow */
813 STATIC_INLINE_SIM_FPU (int)
814 do_normal_round (sim_fpu *f,
818 unsigned64 guardmask = LSMASK64 (nr_guards - 1, 0);
819 unsigned64 guardmsb = LSBIT64 (nr_guards - 1);
820 unsigned64 fraclsb = guardmsb << 1;
821 if ((f->fraction & guardmask))
823 int status = sim_fpu_status_inexact;
826 case sim_fpu_round_default:
828 case sim_fpu_round_near:
829 if ((f->fraction & guardmsb))
831 if ((f->fraction & fraclsb))
833 status |= sim_fpu_status_rounded;
835 else if ((f->fraction & (guardmask >> 1)))
837 status |= sim_fpu_status_rounded;
841 case sim_fpu_round_up:
843 status |= sim_fpu_status_rounded;
845 case sim_fpu_round_down:
847 status |= sim_fpu_status_rounded;
849 case sim_fpu_round_zero:
852 f->fraction &= ~guardmask;
853 /* round if needed, handle resulting overflow */
854 if ((status & sim_fpu_status_rounded))
856 f->fraction += fraclsb;
857 if ((f->fraction & IMPLICIT_2))
870 STATIC_INLINE_SIM_FPU (int)
871 do_round (sim_fpu *f,
874 sim_fpu_denorm denorm)
878 case sim_fpu_class_qnan:
879 case sim_fpu_class_zero:
880 case sim_fpu_class_infinity:
883 case sim_fpu_class_snan:
884 /* Quieten a SignalingNaN */
885 f->class = sim_fpu_class_qnan;
886 return sim_fpu_status_invalid_snan;
888 case sim_fpu_class_number:
889 case sim_fpu_class_denorm:
892 ASSERT (f->fraction < IMPLICIT_2);
893 ASSERT (f->fraction >= IMPLICIT_1);
894 if (f->normal_exp < NORMAL_EXPMIN)
896 /* This number's exponent is too low to fit into the bits
897 available in the number. Round off any bits that will be
898 discarded as a result of denormalization. Edge case is
899 the implicit bit shifted to GUARD0 and then rounded
901 int shift = NORMAL_EXPMIN - f->normal_exp;
902 if (shift + NR_GUARDS <= NR_FRAC_GUARD + 1
903 && !(denorm & sim_fpu_denorm_zero))
905 status = do_normal_round (f, shift + NR_GUARDS, round);
906 if (f->fraction == 0) /* rounding underflowed */
908 status |= do_normal_underflow (f, is_double, round);
910 else if (f->normal_exp < NORMAL_EXPMIN) /* still underflow? */
912 status |= sim_fpu_status_denorm;
913 /* Any loss of precision when denormalizing is
914 underflow. Some processors check for underflow
915 before rounding, some after! */
916 if (status & sim_fpu_status_inexact)
917 status |= sim_fpu_status_underflow;
918 /* Flag that resultant value has been denormalized */
919 f->class = sim_fpu_class_denorm;
921 else if ((denorm & sim_fpu_denorm_underflow_inexact))
923 if ((status & sim_fpu_status_inexact))
924 status |= sim_fpu_status_underflow;
929 status = do_normal_underflow (f, is_double, round);
932 else if (f->normal_exp > NORMAL_EXPMAX)
935 status = do_normal_overflow (f, is_double, round);
939 status = do_normal_round (f, NR_GUARDS, round);
940 if (f->fraction == 0)
941 /* f->class = sim_fpu_class_zero; */
942 status |= do_normal_underflow (f, is_double, round);
943 else if (f->normal_exp > NORMAL_EXPMAX)
944 /* oops! rounding caused overflow */
945 status |= do_normal_overflow (f, is_double, round);
947 ASSERT ((f->class == sim_fpu_class_number
948 || f->class == sim_fpu_class_denorm)
949 <= (f->fraction < IMPLICIT_2 && f->fraction >= IMPLICIT_1));
957 sim_fpu_round_32 (sim_fpu *f,
959 sim_fpu_denorm denorm)
961 return do_round (f, 0, round, denorm);
965 sim_fpu_round_64 (sim_fpu *f,
967 sim_fpu_denorm denorm)
969 return do_round (f, 1, round, denorm);
977 sim_fpu_add (sim_fpu *f,
981 if (sim_fpu_is_snan (l))
984 f->class = sim_fpu_class_qnan;
985 return sim_fpu_status_invalid_snan;
987 if (sim_fpu_is_snan (r))
990 f->class = sim_fpu_class_qnan;
991 return sim_fpu_status_invalid_snan;
993 if (sim_fpu_is_qnan (l))
998 if (sim_fpu_is_qnan (r))
1003 if (sim_fpu_is_infinity (l))
1005 if (sim_fpu_is_infinity (r)
1006 && l->sign != r->sign)
1009 return sim_fpu_status_invalid_isi;
1014 if (sim_fpu_is_infinity (r))
1019 if (sim_fpu_is_zero (l))
1021 if (sim_fpu_is_zero (r))
1024 f->sign = l->sign & r->sign;
1030 if (sim_fpu_is_zero (r))
1037 int shift = l->normal_exp - r->normal_exp;
1038 unsigned64 lfraction;
1039 unsigned64 rfraction;
1040 /* use exp of larger */
1041 if (shift >= NR_FRAC_GUARD)
1043 /* left has much bigger magnitute */
1045 return sim_fpu_status_inexact;
1047 if (shift <= - NR_FRAC_GUARD)
1049 /* right has much bigger magnitute */
1051 return sim_fpu_status_inexact;
1053 lfraction = l->fraction;
1054 rfraction = r->fraction;
1057 f->normal_exp = l->normal_exp;
1058 if (rfraction & LSMASK64 (shift - 1, 0))
1060 status |= sim_fpu_status_inexact;
1061 rfraction |= LSBIT64 (shift); /* stick LSBit */
1063 rfraction >>= shift;
1067 f->normal_exp = r->normal_exp;
1068 if (lfraction & LSMASK64 (- shift - 1, 0))
1070 status |= sim_fpu_status_inexact;
1071 lfraction |= LSBIT64 (- shift); /* stick LSBit */
1073 lfraction >>= -shift;
1077 f->normal_exp = r->normal_exp;
1080 /* perform the addition */
1082 lfraction = - lfraction;
1084 rfraction = - rfraction;
1085 f->fraction = lfraction + rfraction;
1088 if (f->fraction == 0)
1095 f->class = sim_fpu_class_number;
1096 if ((signed64) f->fraction >= 0)
1101 f->fraction = - f->fraction;
1105 if ((f->fraction & IMPLICIT_2))
1107 f->fraction = (f->fraction >> 1) | (f->fraction & 1);
1110 else if (f->fraction < IMPLICIT_1)
1117 while (f->fraction < IMPLICIT_1);
1119 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1125 INLINE_SIM_FPU (int)
1126 sim_fpu_sub (sim_fpu *f,
1130 if (sim_fpu_is_snan (l))
1133 f->class = sim_fpu_class_qnan;
1134 return sim_fpu_status_invalid_snan;
1136 if (sim_fpu_is_snan (r))
1139 f->class = sim_fpu_class_qnan;
1140 return sim_fpu_status_invalid_snan;
1142 if (sim_fpu_is_qnan (l))
1147 if (sim_fpu_is_qnan (r))
1152 if (sim_fpu_is_infinity (l))
1154 if (sim_fpu_is_infinity (r)
1155 && l->sign == r->sign)
1158 return sim_fpu_status_invalid_isi;
1163 if (sim_fpu_is_infinity (r))
1169 if (sim_fpu_is_zero (l))
1171 if (sim_fpu_is_zero (r))
1174 f->sign = l->sign & !r->sign;
1183 if (sim_fpu_is_zero (r))
1190 int shift = l->normal_exp - r->normal_exp;
1191 unsigned64 lfraction;
1192 unsigned64 rfraction;
1193 /* use exp of larger */
1194 if (shift >= NR_FRAC_GUARD)
1196 /* left has much bigger magnitute */
1198 return sim_fpu_status_inexact;
1200 if (shift <= - NR_FRAC_GUARD)
1202 /* right has much bigger magnitute */
1205 return sim_fpu_status_inexact;
1207 lfraction = l->fraction;
1208 rfraction = r->fraction;
1211 f->normal_exp = l->normal_exp;
1212 if (rfraction & LSMASK64 (shift - 1, 0))
1214 status |= sim_fpu_status_inexact;
1215 rfraction |= LSBIT64 (shift); /* stick LSBit */
1217 rfraction >>= shift;
1221 f->normal_exp = r->normal_exp;
1222 if (lfraction & LSMASK64 (- shift - 1, 0))
1224 status |= sim_fpu_status_inexact;
1225 lfraction |= LSBIT64 (- shift); /* stick LSBit */
1227 lfraction >>= -shift;
1231 f->normal_exp = r->normal_exp;
1234 /* perform the subtraction */
1236 lfraction = - lfraction;
1238 rfraction = - rfraction;
1239 f->fraction = lfraction + rfraction;
1242 if (f->fraction == 0)
1249 f->class = sim_fpu_class_number;
1250 if ((signed64) f->fraction >= 0)
1255 f->fraction = - f->fraction;
1259 if ((f->fraction & IMPLICIT_2))
1261 f->fraction = (f->fraction >> 1) | (f->fraction & 1);
1264 else if (f->fraction < IMPLICIT_1)
1271 while (f->fraction < IMPLICIT_1);
1273 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1279 INLINE_SIM_FPU (int)
1280 sim_fpu_mul (sim_fpu *f,
1284 if (sim_fpu_is_snan (l))
1287 f->class = sim_fpu_class_qnan;
1288 return sim_fpu_status_invalid_snan;
1290 if (sim_fpu_is_snan (r))
1293 f->class = sim_fpu_class_qnan;
1294 return sim_fpu_status_invalid_snan;
1296 if (sim_fpu_is_qnan (l))
1301 if (sim_fpu_is_qnan (r))
1306 if (sim_fpu_is_infinity (l))
1308 if (sim_fpu_is_zero (r))
1311 return sim_fpu_status_invalid_imz;
1314 f->sign = l->sign ^ r->sign;
1317 if (sim_fpu_is_infinity (r))
1319 if (sim_fpu_is_zero (l))
1322 return sim_fpu_status_invalid_imz;
1325 f->sign = l->sign ^ r->sign;
1328 if (sim_fpu_is_zero (l) || sim_fpu_is_zero (r))
1331 f->sign = l->sign ^ r->sign;
1334 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1339 unsigned64 nl = l->fraction & 0xffffffff;
1340 unsigned64 nh = l->fraction >> 32;
1341 unsigned64 ml = r->fraction & 0xffffffff;
1342 unsigned64 mh = r->fraction >>32;
1343 unsigned64 pp_ll = ml * nl;
1344 unsigned64 pp_hl = mh * nl;
1345 unsigned64 pp_lh = ml * nh;
1346 unsigned64 pp_hh = mh * nh;
1347 unsigned64 res2 = 0;
1348 unsigned64 res0 = 0;
1349 unsigned64 ps_hh__ = pp_hl + pp_lh;
1350 if (ps_hh__ < pp_hl)
1351 res2 += UNSIGNED64 (0x100000000);
1352 pp_hl = (ps_hh__ << 32) & UNSIGNED64 (0xffffffff00000000);
1353 res0 = pp_ll + pp_hl;
1356 res2 += ((ps_hh__ >> 32) & 0xffffffff) + pp_hh;
1360 f->normal_exp = l->normal_exp + r->normal_exp;
1361 f->sign = l->sign ^ r->sign;
1362 f->class = sim_fpu_class_number;
1364 /* Input is bounded by [1,2) ; [2^60,2^61)
1365 Output is bounded by [1,4) ; [2^120,2^122) */
1367 /* Adjust the exponent according to where the decimal point ended
1368 up in the high 64 bit word. In the source the decimal point
1369 was at NR_FRAC_GUARD. */
1370 f->normal_exp += NR_FRAC_GUARD + 64 - (NR_FRAC_GUARD * 2);
1372 /* The high word is bounded according to the above. Consequently
1373 it has never overflowed into IMPLICIT_2. */
1374 ASSERT (high < LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64));
1375 ASSERT (high >= LSBIT64 ((NR_FRAC_GUARD * 2) - 64));
1376 ASSERT (LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64) < IMPLICIT_1);
1380 print_bits (high, 63, (sim_fpu_print_func*)fprintf, stdout);
1382 print_bits (low, 63, (sim_fpu_print_func*)fprintf, stdout);
1391 if (low & LSBIT64 (63))
1395 while (high < IMPLICIT_1);
1398 print_bits (high, 63, (sim_fpu_print_func*)fprintf, stdout);
1400 print_bits (low, 63, (sim_fpu_print_func*)fprintf, stdout);
1404 ASSERT (high >= IMPLICIT_1 && high < IMPLICIT_2);
1407 f->fraction = (high | 1); /* sticky */
1408 return sim_fpu_status_inexact;
1419 INLINE_SIM_FPU (int)
1420 sim_fpu_div (sim_fpu *f,
1424 if (sim_fpu_is_snan (l))
1427 f->class = sim_fpu_class_qnan;
1428 return sim_fpu_status_invalid_snan;
1430 if (sim_fpu_is_snan (r))
1433 f->class = sim_fpu_class_qnan;
1434 return sim_fpu_status_invalid_snan;
1436 if (sim_fpu_is_qnan (l))
1439 f->class = sim_fpu_class_qnan;
1442 if (sim_fpu_is_qnan (r))
1445 f->class = sim_fpu_class_qnan;
1448 if (sim_fpu_is_infinity (l))
1450 if (sim_fpu_is_infinity (r))
1453 return sim_fpu_status_invalid_idi;
1458 f->sign = l->sign ^ r->sign;
1462 if (sim_fpu_is_zero (l))
1464 if (sim_fpu_is_zero (r))
1467 return sim_fpu_status_invalid_zdz;
1472 f->sign = l->sign ^ r->sign;
1476 if (sim_fpu_is_infinity (r))
1479 f->sign = l->sign ^ r->sign;
1482 if (sim_fpu_is_zero (r))
1484 f->class = sim_fpu_class_infinity;
1485 f->sign = l->sign ^ r->sign;
1486 return sim_fpu_status_invalid_div0;
1489 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1492 /* quotient = ( ( numerator / denominator)
1493 x 2^(numerator exponent - denominator exponent)
1495 unsigned64 numerator;
1496 unsigned64 denominator;
1497 unsigned64 quotient;
1500 f->class = sim_fpu_class_number;
1501 f->sign = l->sign ^ r->sign;
1502 f->normal_exp = l->normal_exp - r->normal_exp;
1504 numerator = l->fraction;
1505 denominator = r->fraction;
1507 /* Fraction will be less than 1.0 */
1508 if (numerator < denominator)
1513 ASSERT (numerator >= denominator);
1515 /* Gain extra precision, already used one spare bit */
1516 numerator <<= NR_SPARE;
1517 denominator <<= NR_SPARE;
1519 /* Does divide one bit at a time. Optimize??? */
1521 bit = (IMPLICIT_1 << NR_SPARE);
1524 if (numerator >= denominator)
1527 numerator -= denominator;
1535 print_bits (quotient, 63, (sim_fpu_print_func*)fprintf, stdout);
1537 print_bits (numerator, 63, (sim_fpu_print_func*)fprintf, stdout);
1539 print_bits (denominator, 63, (sim_fpu_print_func*)fprintf, stdout);
1543 /* discard (but save) the extra bits */
1544 if ((quotient & LSMASK64 (NR_SPARE -1, 0)))
1545 quotient = (quotient >> NR_SPARE) | 1;
1547 quotient = (quotient >> NR_SPARE);
1549 f->fraction = quotient;
1550 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1553 f->fraction |= 1; /* stick remaining bits */
1554 return sim_fpu_status_inexact;
1562 INLINE_SIM_FPU (int)
1563 sim_fpu_max (sim_fpu *f,
1567 if (sim_fpu_is_snan (l))
1570 f->class = sim_fpu_class_qnan;
1571 return sim_fpu_status_invalid_snan;
1573 if (sim_fpu_is_snan (r))
1576 f->class = sim_fpu_class_qnan;
1577 return sim_fpu_status_invalid_snan;
1579 if (sim_fpu_is_qnan (l))
1584 if (sim_fpu_is_qnan (r))
1589 if (sim_fpu_is_infinity (l))
1591 if (sim_fpu_is_infinity (r)
1592 && l->sign == r->sign)
1595 return sim_fpu_status_invalid_isi;
1598 *f = *r; /* -inf < anything */
1600 *f = *l; /* +inf > anthing */
1603 if (sim_fpu_is_infinity (r))
1606 *f = *l; /* anything > -inf */
1608 *f = *r; /* anthing < +inf */
1611 if (l->sign > r->sign)
1613 *f = *r; /* -ve < +ve */
1616 if (l->sign < r->sign)
1618 *f = *l; /* +ve > -ve */
1621 ASSERT (l->sign == r->sign);
1622 if (l->normal_exp > r->normal_exp
1623 || (l->normal_exp == r->normal_exp &&
1624 l->fraction > r->fraction))
1628 *f = *r; /* -ve < -ve */
1630 *f = *l; /* +ve > +ve */
1637 *f = *l; /* -ve > -ve */
1639 *f = *r; /* +ve < +ve */
1645 INLINE_SIM_FPU (int)
1646 sim_fpu_min (sim_fpu *f,
1650 if (sim_fpu_is_snan (l))
1653 f->class = sim_fpu_class_qnan;
1654 return sim_fpu_status_invalid_snan;
1656 if (sim_fpu_is_snan (r))
1659 f->class = sim_fpu_class_qnan;
1660 return sim_fpu_status_invalid_snan;
1662 if (sim_fpu_is_qnan (l))
1667 if (sim_fpu_is_qnan (r))
1672 if (sim_fpu_is_infinity (l))
1674 if (sim_fpu_is_infinity (r)
1675 && l->sign == r->sign)
1678 return sim_fpu_status_invalid_isi;
1681 *f = *l; /* -inf < anything */
1683 *f = *r; /* +inf > anthing */
1686 if (sim_fpu_is_infinity (r))
1689 *f = *r; /* anything > -inf */
1691 *f = *l; /* anything < +inf */
1694 if (l->sign > r->sign)
1696 *f = *l; /* -ve < +ve */
1699 if (l->sign < r->sign)
1701 *f = *r; /* +ve > -ve */
1704 ASSERT (l->sign == r->sign);
1705 if (l->normal_exp > r->normal_exp
1706 || (l->normal_exp == r->normal_exp &&
1707 l->fraction > r->fraction))
1711 *f = *l; /* -ve < -ve */
1713 *f = *r; /* +ve > +ve */
1720 *f = *r; /* -ve > -ve */
1722 *f = *l; /* +ve < +ve */
1728 INLINE_SIM_FPU (int)
1729 sim_fpu_neg (sim_fpu *f,
1732 if (sim_fpu_is_snan (r))
1735 f->class = sim_fpu_class_qnan;
1736 return sim_fpu_status_invalid_snan;
1738 if (sim_fpu_is_qnan (r))
1749 INLINE_SIM_FPU (int)
1750 sim_fpu_abs (sim_fpu *f,
1753 if (sim_fpu_is_snan (r))
1756 f->class = sim_fpu_class_qnan;
1757 return sim_fpu_status_invalid_snan;
1759 if (sim_fpu_is_qnan (r))
1770 INLINE_SIM_FPU (int)
1771 sim_fpu_inv (sim_fpu *f,
1774 if (sim_fpu_is_snan (r))
1777 f->class = sim_fpu_class_qnan;
1778 return sim_fpu_status_invalid_snan;
1780 if (sim_fpu_is_qnan (r))
1783 f->class = sim_fpu_class_qnan;
1786 if (sim_fpu_is_infinity (r))
1792 if (sim_fpu_is_zero (r))
1794 f->class = sim_fpu_class_infinity;
1796 return sim_fpu_status_invalid_div0;
1799 f->normal_exp = - r->normal_exp;
1804 INLINE_SIM_FPU (int)
1805 sim_fpu_sqrt (sim_fpu *f,
1808 if (sim_fpu_is_snan (r))
1811 return sim_fpu_status_invalid_snan;
1813 if (sim_fpu_is_qnan (r))
1818 if (sim_fpu_is_zero (r))
1820 f->class = sim_fpu_class_zero;
1824 if (sim_fpu_is_infinity (r))
1829 return sim_fpu_status_invalid_sqrt;
1833 f->class = sim_fpu_class_infinity;
1842 return sim_fpu_status_invalid_sqrt;
1845 /* @(#)e_sqrt.c 5.1 93/09/24 */
1847 * ====================================================
1848 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1850 * Developed at SunPro, a Sun Microsystems, Inc. business.
1851 * Permission to use, copy, modify, and distribute this
1852 * software is freely granted, provided that this notice
1854 * ====================================================
1857 /* __ieee754_sqrt(x)
1858 * Return correctly rounded sqrt.
1859 * ------------------------------------------
1860 * | Use the hardware sqrt if you have one |
1861 * ------------------------------------------
1863 * Bit by bit method using integer arithmetic. (Slow, but portable)
1865 * Scale x to y in [1,4) with even powers of 2:
1866 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1867 * sqrt(x) = 2^k * sqrt(y)
1870 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1871 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1873 - y = ((m even) ? x : 2.x)
1875 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1877 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1879 * 2. Bit by bit computation
1880 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1883 * s = 2*q , and y = 2 * ( y - q ). (1)
1886 * To compute q from q , one checks whether
1890 * (q + 2 ) <= y. (2)
1893 * If (2) is false, then q = q ; otherwise q = q + 2 .
1896 * With some algebric manipulation, it is not difficult to see
1897 * that (2) is equivalent to
1902 * The advantage of (3) is that s and y can be computed by
1904 * the following recurrence formula:
1907 * s = s , y = y ; (4)
1916 * s = s + 2 , y = y - s - 2 (5)
1921 - NOTE: y = 2 (y - s - 2 )
1924 * One may easily use induction to prove (4) and (5).
1925 * Note. Since the left hand side of (3) contain only i+2 bits,
1926 * it does not necessary to do a full (53-bit) comparison
1929 * After generating the 53 bits result, we compute one more bit.
1930 * Together with the remainder, we can decide whether the
1931 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1932 * (it will never equal to 1/2ulp).
1933 * The rounding mode can be detected by checking whether
1934 * huge + tiny is equal to huge, and whether huge - tiny is
1935 * equal to huge for some floating point number "huge" and "tiny".
1938 * sqrt(+-0) = +-0 ... exact
1940 * sqrt(-ve) = NaN ... with invalid signal
1941 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1943 * Other methods : see the appended file at the end of the program below.
1948 /* generate sqrt(x) bit by bit */
1954 f->class = sim_fpu_class_number;
1957 f->normal_exp = (r->normal_exp >> 1); /* exp = [exp/2] */
1959 /* odd exp, double x to make it even */
1960 ASSERT (y >= IMPLICIT_1 && y < IMPLICIT_4);
1961 if ((r->normal_exp & 1))
1965 ASSERT (y >= IMPLICIT_1 && y < (IMPLICIT_2 << 1));
1967 /* Let loop determine first value of s (either 1 or 2) */
1974 unsigned64 t = s + b;
1985 ASSERT (q >= IMPLICIT_1 && q < IMPLICIT_2);
1989 f->fraction |= 1; /* stick remaining bits */
1990 return sim_fpu_status_inexact;
1998 /* int/long <-> sim_fpu */
2000 INLINE_SIM_FPU (int)
2001 sim_fpu_i32to (sim_fpu *f,
2003 sim_fpu_round round)
2009 INLINE_SIM_FPU (int)
2010 sim_fpu_u32to (sim_fpu *f,
2012 sim_fpu_round round)
2018 INLINE_SIM_FPU (int)
2019 sim_fpu_i64to (sim_fpu *f,
2021 sim_fpu_round round)
2027 INLINE_SIM_FPU (int)
2028 sim_fpu_u64to (sim_fpu *f,
2030 sim_fpu_round round)
2037 INLINE_SIM_FPU (int)
2038 sim_fpu_to32i (signed32 *i,
2040 sim_fpu_round round)
2043 int status = fpu2i (&i64, f, 0, round);
2048 INLINE_SIM_FPU (int)
2049 sim_fpu_to32u (unsigned32 *u,
2051 sim_fpu_round round)
2054 int status = fpu2u (&u64, f, 0);
2059 INLINE_SIM_FPU (int)
2060 sim_fpu_to64i (signed64 *i,
2062 sim_fpu_round round)
2064 return fpu2i (i, f, 1, round);
2068 INLINE_SIM_FPU (int)
2069 sim_fpu_to64u (unsigned64 *u,
2071 sim_fpu_round round)
2073 return fpu2u (u, f, 1);
2078 /* sim_fpu -> host format */
2081 INLINE_SIM_FPU (float)
2082 sim_fpu_2f (const sim_fpu *f)
2089 INLINE_SIM_FPU (double)
2090 sim_fpu_2d (const sim_fpu *s)
2093 if (sim_fpu_is_snan (s))
2097 n.class = sim_fpu_class_qnan;
2098 val.i = pack_fpu (&n, 1);
2102 val.i = pack_fpu (s, 1);
2109 INLINE_SIM_FPU (void)
2110 sim_fpu_f2 (sim_fpu *f,
2115 unpack_fpu (f, val.i, 1);
2120 INLINE_SIM_FPU (void)
2121 sim_fpu_d2 (sim_fpu *f,
2126 unpack_fpu (f, val.i, 1);
2132 INLINE_SIM_FPU (int)
2133 sim_fpu_is_nan (const sim_fpu *d)
2137 case sim_fpu_class_qnan:
2138 case sim_fpu_class_snan:
2145 INLINE_SIM_FPU (int)
2146 sim_fpu_is_qnan (const sim_fpu *d)
2150 case sim_fpu_class_qnan:
2157 INLINE_SIM_FPU (int)
2158 sim_fpu_is_snan (const sim_fpu *d)
2162 case sim_fpu_class_snan:
2169 INLINE_SIM_FPU (int)
2170 sim_fpu_is_zero (const sim_fpu *d)
2174 case sim_fpu_class_zero:
2181 INLINE_SIM_FPU (int)
2182 sim_fpu_is_infinity (const sim_fpu *d)
2186 case sim_fpu_class_infinity:
2193 INLINE_SIM_FPU (int)
2194 sim_fpu_is_number (const sim_fpu *d)
2198 case sim_fpu_class_denorm:
2199 case sim_fpu_class_number:
2206 INLINE_SIM_FPU (int)
2207 sim_fpu_is_denorm (const sim_fpu *d)
2211 case sim_fpu_class_denorm:
2219 INLINE_SIM_FPU (int)
2220 sim_fpu_sign (const sim_fpu *d)
2226 INLINE_SIM_FPU (int)
2227 sim_fpu_exp (const sim_fpu *d)
2229 return d->normal_exp;
2234 INLINE_SIM_FPU (int)
2235 sim_fpu_is (const sim_fpu *d)
2239 case sim_fpu_class_qnan:
2240 return SIM_FPU_IS_QNAN;
2241 case sim_fpu_class_snan:
2242 return SIM_FPU_IS_SNAN;
2243 case sim_fpu_class_infinity:
2245 return SIM_FPU_IS_NINF;
2247 return SIM_FPU_IS_PINF;
2248 case sim_fpu_class_number:
2250 return SIM_FPU_IS_NNUMBER;
2252 return SIM_FPU_IS_PNUMBER;
2253 case sim_fpu_class_denorm:
2255 return SIM_FPU_IS_NDENORM;
2257 return SIM_FPU_IS_PDENORM;
2258 case sim_fpu_class_zero:
2260 return SIM_FPU_IS_NZERO;
2262 return SIM_FPU_IS_PZERO;
2269 INLINE_SIM_FPU (int)
2270 sim_fpu_cmp (const sim_fpu *l, const sim_fpu *r)
2273 sim_fpu_sub (&res, l, r);
2274 return sim_fpu_is (&res);
2277 INLINE_SIM_FPU (int)
2278 sim_fpu_is_lt (const sim_fpu *l, const sim_fpu *r)
2281 sim_fpu_lt (&status, l, r);
2285 INLINE_SIM_FPU (int)
2286 sim_fpu_is_le (const sim_fpu *l, const sim_fpu *r)
2289 sim_fpu_le (&is, l, r);
2293 INLINE_SIM_FPU (int)
2294 sim_fpu_is_eq (const sim_fpu *l, const sim_fpu *r)
2297 sim_fpu_eq (&is, l, r);
2301 INLINE_SIM_FPU (int)
2302 sim_fpu_is_ne (const sim_fpu *l, const sim_fpu *r)
2305 sim_fpu_ne (&is, l, r);
2309 INLINE_SIM_FPU (int)
2310 sim_fpu_is_ge (const sim_fpu *l, const sim_fpu *r)
2313 sim_fpu_ge (&is, l, r);
2317 INLINE_SIM_FPU (int)
2318 sim_fpu_is_gt (const sim_fpu *l, const sim_fpu *r)
2321 sim_fpu_gt (&is, l, r);
2326 /* Compare operators */
2328 INLINE_SIM_FPU (int)
2329 sim_fpu_lt (int *is,
2333 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2337 lval.i = pack_fpu (l, 1);
2338 rval.i = pack_fpu (r, 1);
2339 (*is) = (lval.d < rval.d);
2342 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2345 return sim_fpu_status_invalid_snan;
2350 return sim_fpu_status_invalid_qnan;
2354 INLINE_SIM_FPU (int)
2355 sim_fpu_le (int *is,
2359 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2363 lval.i = pack_fpu (l, 1);
2364 rval.i = pack_fpu (r, 1);
2365 *is = (lval.d <= rval.d);
2368 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2371 return sim_fpu_status_invalid_snan;
2376 return sim_fpu_status_invalid_qnan;
2380 INLINE_SIM_FPU (int)
2381 sim_fpu_eq (int *is,
2385 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2389 lval.i = pack_fpu (l, 1);
2390 rval.i = pack_fpu (r, 1);
2391 (*is) = (lval.d == rval.d);
2394 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2397 return sim_fpu_status_invalid_snan;
2402 return sim_fpu_status_invalid_qnan;
2406 INLINE_SIM_FPU (int)
2407 sim_fpu_ne (int *is,
2411 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2415 lval.i = pack_fpu (l, 1);
2416 rval.i = pack_fpu (r, 1);
2417 (*is) = (lval.d != rval.d);
2420 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2423 return sim_fpu_status_invalid_snan;
2428 return sim_fpu_status_invalid_qnan;
2432 INLINE_SIM_FPU (int)
2433 sim_fpu_ge (int *is,
2437 return sim_fpu_le (is, r, l);
2440 INLINE_SIM_FPU (int)
2441 sim_fpu_gt (int *is,
2445 return sim_fpu_lt (is, r, l);
2449 /* A number of useful constants */
2451 #if EXTERN_SIM_FPU_P
2452 const sim_fpu sim_fpu_zero = {
2455 const sim_fpu sim_fpu_qnan = {
2458 const sim_fpu sim_fpu_one = {
2459 sim_fpu_class_number, 0, IMPLICIT_1, 1
2461 const sim_fpu sim_fpu_two = {
2462 sim_fpu_class_number, 0, IMPLICIT_1, 2
2464 const sim_fpu sim_fpu_max32 = {
2465 sim_fpu_class_number, 0, LSMASK64 (NR_FRAC_GUARD, NR_GUARDS32), NORMAL_EXPMAX32
2467 const sim_fpu sim_fpu_max64 = {
2468 sim_fpu_class_number, 0, LSMASK64 (NR_FRAC_GUARD, NR_GUARDS64), NORMAL_EXPMAX64
2475 INLINE_SIM_FPU (void)
2476 sim_fpu_print_fpu (const sim_fpu *f,
2477 sim_fpu_print_func *print,
2480 print (arg, "%s", f->sign ? "-" : "+");
2483 case sim_fpu_class_qnan:
2485 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2486 print (arg, "*QuietNaN");
2488 case sim_fpu_class_snan:
2490 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2491 print (arg, "*SignalNaN");
2493 case sim_fpu_class_zero:
2496 case sim_fpu_class_infinity:
2499 case sim_fpu_class_number:
2500 case sim_fpu_class_denorm:
2502 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2503 print (arg, "*2^%+-5d", f->normal_exp);
2504 ASSERT (f->fraction >= IMPLICIT_1);
2505 ASSERT (f->fraction < IMPLICIT_2);
2510 INLINE_SIM_FPU (void)
2511 sim_fpu_print_status (int status,
2512 sim_fpu_print_func *print,
2519 switch ((sim_fpu_status) (status & i))
2521 case sim_fpu_status_denorm:
2522 print (arg, "%sD", prefix);
2524 case sim_fpu_status_invalid_snan:
2525 print (arg, "%sSNaN", prefix);
2527 case sim_fpu_status_invalid_qnan:
2528 print (arg, "%sQNaN", prefix);
2530 case sim_fpu_status_invalid_isi:
2531 print (arg, "%sISI", prefix);
2533 case sim_fpu_status_invalid_idi:
2534 print (arg, "%sIDI", prefix);
2536 case sim_fpu_status_invalid_zdz:
2537 print (arg, "%sZDZ", prefix);
2539 case sim_fpu_status_invalid_imz:
2540 print (arg, "%sIMZ", prefix);
2542 case sim_fpu_status_invalid_cvi:
2543 print (arg, "%sCVI", prefix);
2545 case sim_fpu_status_invalid_cmp:
2546 print (arg, "%sCMP", prefix);
2548 case sim_fpu_status_invalid_sqrt:
2549 print (arg, "%sSQRT", prefix);
2552 case sim_fpu_status_inexact:
2553 print (arg, "%sX", prefix);
2556 case sim_fpu_status_overflow:
2557 print (arg, "%sO", prefix);
2560 case sim_fpu_status_underflow:
2561 print (arg, "%sU", prefix);
2564 case sim_fpu_status_invalid_div0:
2565 print (arg, "%s/", prefix);
2568 case sim_fpu_status_rounded:
2569 print (arg, "%sR", prefix);