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 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 EXPMAX ((unsigned) (is_double ? 2047 : 255))
117 #define EXPBIAS (is_double ? 1023 : 127)
119 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
123 /* An unpacked floating point number.
125 When unpacked, the fraction of both a 32 and 64 bit floating point
126 number is stored using the same format:
128 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
129 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
131 #define NR_PAD (is_double ? 0 : 30)
132 #define PADMASK (is_double ? 0 : LSMASK64 (29, 0))
133 #define NR_GUARDS ((is_double ? 8 : 7 ) + NR_PAD)
134 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
135 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
136 #define GUARDLSB LSBIT64 (NR_PAD)
137 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
139 #define NR_FRAC_GUARD (60)
140 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
141 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
142 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
145 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
147 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
148 #define NORMAL_EXPMAX (EXPBIAS)
151 /* Integer constants */
153 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
154 #define MAX_UINT32 LSMASK64 (31, 0)
155 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
157 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
158 #define MAX_UINT64 LSMASK64 (63, 0)
159 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
161 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
162 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
163 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
164 #define NR_INTBITS (is_64bit ? 64 : 32)
166 /* Squeese an unpacked sim_fpu struct into a 32/64 bit integer */
167 STATIC_INLINE_SIM_FPU (unsigned64)
168 pack_fpu (const sim_fpu *src,
179 case sim_fpu_class_qnan:
182 /* force fraction to correct class */
183 fraction = src->fraction;
184 fraction >>= NR_GUARDS;
185 fraction |= QUIET_NAN;
187 case sim_fpu_class_snan:
190 /* force fraction to correct class */
191 fraction = src->fraction;
192 fraction >>= NR_GUARDS;
193 fraction &= ~QUIET_NAN;
195 case sim_fpu_class_infinity:
200 case sim_fpu_class_zero:
205 case sim_fpu_class_number:
206 case sim_fpu_class_denorm:
207 ASSERT (src->fraction >= IMPLICIT_1);
208 ASSERT (src->fraction < IMPLICIT_2);
209 if (src->normal_exp < NORMAL_EXPMIN)
211 /* This number's exponent is too low to fit into the bits
212 available in the number We'll denormalize the number by
213 storing zero in the exponent and shift the fraction to
214 the right to make up for it. */
215 int nr_shift = NORMAL_EXPMIN - src->normal_exp;
216 if (nr_shift > NR_FRACBITS)
218 /* underflow, just make the number zero */
227 /* Shift by the value */
228 fraction = src->fraction;
229 fraction >>= NR_GUARDS;
230 fraction >>= nr_shift;
233 else if (src->normal_exp > NORMAL_EXPMAX)
242 exp = (src->normal_exp + EXPBIAS);
244 fraction = src->fraction;
245 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
247 /* Round to nearest: If the guard bits are the all zero, but
248 the first, then we're half way between two numbers,
249 choose the one which makes the lsb of the answer 0. */
250 if ((fraction & GUARDMASK) == GUARDMSB)
252 if ((fraction & (GUARDMSB << 1)))
253 fraction += (GUARDMSB << 1);
257 /* Add a one to the guards to force round to nearest */
258 fraction += GUARDROUND;
260 if ((fraction & IMPLICIT_2)) /* rounding resulted in carry */
265 fraction >>= NR_GUARDS;
266 /* When exp == EXPMAX (overflow from carry) fraction must
267 have been made zero */
268 ASSERT ((exp == EXPMAX) <= ((fraction & ~IMPLICIT_1) == 0));
275 packed = ((sign ? SIGNBIT : 0)
276 | (exp << NR_FRACBITS)
277 | LSMASKED64 (fraction, NR_FRACBITS - 1, 0));
279 /* trace operation */
286 printf ("pack_fpu: ");
287 printf ("-> %c%0lX.%06lX\n",
288 LSMASKED32 (packed, 31, 31) ? '8' : '0',
289 (long) LSEXTRACTED32 (packed, 30, 23),
290 (long) LSEXTRACTED32 (packed, 23 - 1, 0));
298 /* Unpack a 32/64 bit integer into a sim_fpu structure */
299 STATIC_INLINE_SIM_FPU (void)
300 unpack_fpu (sim_fpu *dst, unsigned64 packed, int is_double)
302 unsigned64 fraction = LSMASKED64 (packed, NR_FRACBITS - 1, 0);
303 unsigned exp = LSEXTRACTED64 (packed, NR_EXPBITS + NR_FRACBITS - 1, NR_FRACBITS);
304 int sign = (packed & SIGNBIT) != 0;
308 /* Hmm. Looks like 0 */
311 /* tastes like zero */
312 dst->class = sim_fpu_class_zero;
317 /* Zero exponent with non zero fraction - it's denormalized,
318 so there isn't a leading implicit one - we'll shift it so
320 dst->normal_exp = exp - EXPBIAS + 1;
321 dst->class = sim_fpu_class_denorm;
323 fraction <<= NR_GUARDS;
324 while (fraction < IMPLICIT_1)
329 dst->fraction = fraction;
332 else if (exp == EXPMAX)
337 /* Attached to a zero fraction - means infinity */
338 dst->class = sim_fpu_class_infinity;
340 /* dst->normal_exp = EXPBIAS; */
341 /* dst->fraction = 0; */
345 /* Non zero fraction, means NaN */
347 dst->fraction = (fraction << NR_GUARDS);
348 if (fraction >= QUIET_NAN)
349 dst->class = sim_fpu_class_qnan;
351 dst->class = sim_fpu_class_snan;
356 /* Nothing strange about this number */
357 dst->class = sim_fpu_class_number;
359 dst->fraction = ((fraction << NR_GUARDS) | IMPLICIT_1);
360 dst->normal_exp = exp - EXPBIAS;
363 /* trace operation */
370 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
371 LSMASKED32 (packed, 31, 31) ? '8' : '0',
372 (long) LSEXTRACTED32 (packed, 30, 23),
373 (long) LSEXTRACTED32 (packed, 23 - 1, 0));
380 val.i = pack_fpu (dst, 1);
383 ASSERT (val.i == packed);
387 unsigned32 val = pack_fpu (dst, 0);
388 unsigned32 org = packed;
395 /* Convert a floating point into an integer */
396 STATIC_INLINE_SIM_FPU (int)
405 if (sim_fpu_is_zero (s))
410 if (sim_fpu_is_snan (s))
412 *i = MIN_INT; /* FIXME */
413 return sim_fpu_status_invalid_cvi;
415 if (sim_fpu_is_qnan (s))
417 *i = MIN_INT; /* FIXME */
418 return sim_fpu_status_invalid_cvi;
420 /* map infinity onto MAX_INT... */
421 if (sim_fpu_is_infinity (s))
423 *i = s->sign ? MIN_INT : MAX_INT;
424 return sim_fpu_status_invalid_cvi;
426 /* it is a number, but a small one */
427 if (s->normal_exp < 0)
430 return sim_fpu_status_inexact;
432 /* Is the floating point MIN_INT or just close? */
433 if (s->sign && s->normal_exp == (NR_INTBITS - 1))
436 ASSERT (s->fraction >= IMPLICIT_1);
437 if (s->fraction == IMPLICIT_1)
438 return 0; /* exact */
439 if (is_64bit) /* can't round */
440 return sim_fpu_status_invalid_cvi; /* must be overflow */
441 /* For a 32bit with MAX_INT, rounding is possible */
444 case sim_fpu_round_default:
446 case sim_fpu_round_zero:
447 if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
448 return sim_fpu_status_invalid_cvi;
450 return sim_fpu_status_inexact;
452 case sim_fpu_round_near:
454 if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
455 return sim_fpu_status_invalid_cvi;
456 else if ((s->fraction & !FRAC32MASK) >= (~FRAC32MASK >> 1))
457 return sim_fpu_status_invalid_cvi;
459 return sim_fpu_status_inexact;
461 case sim_fpu_round_up:
462 if ((s->fraction & FRAC32MASK) == IMPLICIT_1)
463 return sim_fpu_status_inexact;
465 return sim_fpu_status_invalid_cvi;
466 case sim_fpu_round_down:
467 return sim_fpu_status_invalid_cvi;
470 /* Would right shifting result in the FRAC being shifted into
471 (through) the integer's sign bit? */
472 if (s->normal_exp > (NR_INTBITS - 2))
474 *i = s->sign ? MIN_INT : MAX_INT;
475 return sim_fpu_status_invalid_cvi;
477 /* normal number shift it into place */
479 shift = (s->normal_exp - (NR_FRAC_GUARD));
487 if (tmp & ((SIGNED64 (1) << shift) - 1))
488 status |= sim_fpu_status_inexact;
491 *i = s->sign ? (-tmp) : (tmp);
495 /* convert an integer into a floating point */
496 STATIC_INLINE_SIM_FPU (int)
497 i2fpu (sim_fpu *f, signed64 i, int is_64bit)
502 f->class = sim_fpu_class_zero;
507 f->class = sim_fpu_class_number;
509 f->normal_exp = NR_FRAC_GUARD;
513 /* Special case for minint, since there is no corresponding
514 +ve integer representation for it */
517 f->fraction = IMPLICIT_1;
518 f->normal_exp = NR_INTBITS - 1;
526 if (f->fraction >= IMPLICIT_2)
533 while (f->fraction >= IMPLICIT_2);
535 else if (f->fraction < IMPLICIT_1)
542 while (f->fraction < IMPLICIT_1);
546 /* trace operation */
549 printf ("i2fpu: 0x%08lX ->\n", (long) i);
556 fpu2i (&val, f, is_64bit, sim_fpu_round_zero);
557 if (i >= MIN_INT32 && i <= MAX_INT32)
567 /* Convert a floating point into an integer */
568 STATIC_INLINE_SIM_FPU (int)
569 fpu2u (unsigned64 *u, const sim_fpu *s, int is_64bit)
571 const int is_double = 1;
574 if (sim_fpu_is_zero (s))
579 if (sim_fpu_is_nan (s))
584 /* it is a negative number */
590 /* get reasonable MAX_USI_INT... */
591 if (sim_fpu_is_infinity (s))
596 /* it is a number, but a small one */
597 if (s->normal_exp < 0)
603 if (s->normal_exp > (NR_INTBITS - 1))
609 tmp = (s->fraction & ~PADMASK);
610 shift = (s->normal_exp - (NR_FRACBITS + NR_GUARDS));
624 /* Convert an unsigned integer into a floating point */
625 STATIC_INLINE_SIM_FPU (int)
626 u2fpu (sim_fpu *f, unsigned64 u, int is_64bit)
630 f->class = sim_fpu_class_zero;
635 f->class = sim_fpu_class_number;
637 f->normal_exp = NR_FRAC_GUARD;
640 while (f->fraction < IMPLICIT_1)
650 /* register <-> sim_fpu */
652 INLINE_SIM_FPU (void)
653 sim_fpu_32to (sim_fpu *f, unsigned32 s)
655 unpack_fpu (f, s, 0);
659 INLINE_SIM_FPU (void)
660 sim_fpu_232to (sim_fpu *f, unsigned32 h, unsigned32 l)
664 unpack_fpu (f, s, 1);
668 INLINE_SIM_FPU (void)
669 sim_fpu_64to (sim_fpu *f, unsigned64 s)
671 unpack_fpu (f, s, 1);
675 INLINE_SIM_FPU (void)
676 sim_fpu_to32 (unsigned32 *s,
679 *s = pack_fpu (f, 0);
683 INLINE_SIM_FPU (void)
684 sim_fpu_to232 (unsigned32 *h, unsigned32 *l,
687 unsigned64 s = pack_fpu (f, 1);
693 INLINE_SIM_FPU (void)
694 sim_fpu_to64 (unsigned64 *u,
697 *u = pack_fpu (f, 1);
703 STATIC_INLINE_SIM_FPU (int)
704 do_normal_overflow (sim_fpu *f,
710 case sim_fpu_round_default:
712 case sim_fpu_round_near:
713 f->class = sim_fpu_class_infinity;
715 case sim_fpu_round_up:
717 f->class = sim_fpu_class_infinity;
719 case sim_fpu_round_down:
721 f->class = sim_fpu_class_infinity;
723 case sim_fpu_round_zero:
726 f->normal_exp = NORMAL_EXPMAX;
727 f->fraction = LSMASK64 (NR_FRAC_GUARD, NR_GUARDS);
728 return (sim_fpu_status_overflow | sim_fpu_status_inexact);
731 STATIC_INLINE_SIM_FPU (int)
732 do_normal_underflow (sim_fpu *f,
738 case sim_fpu_round_default:
740 case sim_fpu_round_near:
741 f->class = sim_fpu_class_zero;
743 case sim_fpu_round_up:
745 f->class = sim_fpu_class_zero;
747 case sim_fpu_round_down:
749 f->class = sim_fpu_class_zero;
751 case sim_fpu_round_zero:
752 f->class = sim_fpu_class_zero;
755 f->normal_exp = NORMAL_EXPMIN - NR_FRACBITS;
756 f->fraction = IMPLICIT_1;
757 return (sim_fpu_status_inexact | sim_fpu_status_underflow);
762 /* Round a number using NR_GUARDS.
763 Will return the rounded number or F->FRACTION == 0 when underflow */
765 STATIC_INLINE_SIM_FPU (int)
766 do_normal_round (sim_fpu *f,
770 unsigned64 guardmask = LSMASK64 (nr_guards - 1, 0);
771 unsigned64 guardmsb = LSBIT64 (nr_guards - 1);
772 unsigned64 fraclsb = guardmsb << 1;
773 if ((f->fraction & guardmask))
775 int status = sim_fpu_status_inexact;
778 case sim_fpu_round_default:
780 case sim_fpu_round_near:
781 if ((f->fraction & guardmsb))
783 if ((f->fraction & fraclsb))
785 status |= sim_fpu_status_rounded;
787 else if ((f->fraction & (guardmask >> 1)))
789 status |= sim_fpu_status_rounded;
793 case sim_fpu_round_up:
795 status |= sim_fpu_status_rounded;
797 case sim_fpu_round_down:
799 status |= sim_fpu_status_rounded;
801 case sim_fpu_round_zero:
804 f->fraction &= ~guardmask;
805 /* round if needed, handle resulting overflow */
806 if ((status & sim_fpu_status_rounded))
808 f->fraction += fraclsb;
809 if ((f->fraction & IMPLICIT_2))
822 STATIC_INLINE_SIM_FPU (int)
823 do_round (sim_fpu *f,
826 sim_fpu_denorm denorm)
830 case sim_fpu_class_qnan:
831 case sim_fpu_class_zero:
832 case sim_fpu_class_infinity:
835 case sim_fpu_class_snan:
836 /* Quieten a SignalingNaN */
837 f->class = sim_fpu_class_qnan;
838 return sim_fpu_status_invalid_snan;
840 case sim_fpu_class_number:
841 case sim_fpu_class_denorm:
844 ASSERT (f->fraction < IMPLICIT_2);
845 ASSERT (f->fraction >= IMPLICIT_1);
846 if (f->normal_exp < NORMAL_EXPMIN)
848 /* This number's exponent is too low to fit into the bits
849 available in the number. Round off any bits that will be
850 discarded as a result of denormalization. Edge case is
851 the implicit bit shifted to GUARD0 and then rounded
853 int shift = NORMAL_EXPMIN - f->normal_exp;
854 if (shift + NR_GUARDS <= NR_FRAC_GUARD + 1
855 && !(denorm & sim_fpu_denorm_zero))
857 status = do_normal_round (f, shift + NR_GUARDS, round);
858 if (f->fraction == 0) /* rounding underflowed */
860 status |= do_normal_underflow (f, is_double, round);
862 else if (f->normal_exp < NORMAL_EXPMIN) /* still underflow? */
864 status |= sim_fpu_status_denorm;
865 /* Any loss of precision when denormalizing is
866 underflow. Some processors check for underflow
867 before rounding, some after! */
868 if (status & sim_fpu_status_inexact)
869 status |= sim_fpu_status_underflow;
870 /* Flag that resultant value has been denormalized */
871 f->class = sim_fpu_class_denorm;
873 else if ((denorm & sim_fpu_denorm_underflow_inexact))
875 if ((status & sim_fpu_status_inexact))
876 status |= sim_fpu_status_underflow;
881 status = do_normal_underflow (f, is_double, round);
884 else if (f->normal_exp > NORMAL_EXPMAX)
887 status = do_normal_overflow (f, is_double, round);
891 status = do_normal_round (f, NR_GUARDS, round);
892 if (f->fraction == 0)
893 /* f->class = sim_fpu_class_zero; */
894 status |= do_normal_underflow (f, is_double, round);
895 else if (f->normal_exp > NORMAL_EXPMAX)
896 /* oops! rounding caused overflow */
897 status |= do_normal_overflow (f, is_double, round);
899 ASSERT ((f->class == sim_fpu_class_number
900 || f->class == sim_fpu_class_denorm)
901 <= (f->fraction < IMPLICIT_2 && f->fraction >= IMPLICIT_1));
909 sim_fpu_round_32 (sim_fpu *f,
911 sim_fpu_denorm denorm)
913 return do_round (f, 0, round, denorm);
917 sim_fpu_round_64 (sim_fpu *f,
919 sim_fpu_denorm denorm)
921 return do_round (f, 1, round, denorm);
929 sim_fpu_add (sim_fpu *f,
933 if (sim_fpu_is_snan (l))
936 f->class = sim_fpu_class_qnan;
937 return sim_fpu_status_invalid_snan;
939 if (sim_fpu_is_snan (r))
942 f->class = sim_fpu_class_qnan;
943 return sim_fpu_status_invalid_snan;
945 if (sim_fpu_is_qnan (l))
950 if (sim_fpu_is_qnan (r))
955 if (sim_fpu_is_infinity (l))
957 if (sim_fpu_is_infinity (r)
958 && l->sign != r->sign)
961 return sim_fpu_status_invalid_isi;
966 if (sim_fpu_is_infinity (r))
971 if (sim_fpu_is_zero (l))
973 if (sim_fpu_is_zero (r))
976 f->sign = l->sign & r->sign;
982 if (sim_fpu_is_zero (r))
989 int shift = l->normal_exp - r->normal_exp;
990 unsigned64 lfraction;
991 unsigned64 rfraction;
992 /* use exp of larger */
993 if (shift >= NR_FRAC_GUARD)
995 /* left has much bigger magnitute */
997 return sim_fpu_status_inexact;
999 if (shift <= - NR_FRAC_GUARD)
1001 /* right has much bigger magnitute */
1003 return sim_fpu_status_inexact;
1005 lfraction = l->fraction;
1006 rfraction = r->fraction;
1009 f->normal_exp = l->normal_exp;
1010 if (rfraction & LSMASK64 (shift - 1, 0))
1012 status |= sim_fpu_status_inexact;
1013 rfraction |= LSBIT64 (shift); /* stick LSBit */
1015 rfraction >>= shift;
1019 f->normal_exp = r->normal_exp;
1020 if (lfraction & LSMASK64 (- shift - 1, 0))
1022 status |= sim_fpu_status_inexact;
1023 lfraction |= LSBIT64 (- shift); /* stick LSBit */
1025 lfraction >>= -shift;
1029 f->normal_exp = r->normal_exp;
1032 /* perform the addition */
1034 lfraction = - lfraction;
1036 rfraction = - rfraction;
1037 f->fraction = lfraction + rfraction;
1040 if (f->fraction == 0)
1047 f->class = sim_fpu_class_number;
1048 if ((signed64) f->fraction >= 0)
1053 f->fraction = - f->fraction;
1057 if ((f->fraction & IMPLICIT_2))
1059 f->fraction = (f->fraction >> 1) | (f->fraction & 1);
1062 else if (f->fraction < IMPLICIT_1)
1069 while (f->fraction < IMPLICIT_1);
1071 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1077 INLINE_SIM_FPU (int)
1078 sim_fpu_sub (sim_fpu *f,
1082 if (sim_fpu_is_snan (l))
1085 f->class = sim_fpu_class_qnan;
1086 return sim_fpu_status_invalid_snan;
1088 if (sim_fpu_is_snan (r))
1091 f->class = sim_fpu_class_qnan;
1092 return sim_fpu_status_invalid_snan;
1094 if (sim_fpu_is_qnan (l))
1099 if (sim_fpu_is_qnan (r))
1104 if (sim_fpu_is_infinity (l))
1106 if (sim_fpu_is_infinity (r)
1107 && l->sign == r->sign)
1110 return sim_fpu_status_invalid_isi;
1115 if (sim_fpu_is_infinity (r))
1121 if (sim_fpu_is_zero (l))
1123 if (sim_fpu_is_zero (r))
1126 f->sign = l->sign & !r->sign;
1135 if (sim_fpu_is_zero (r))
1142 int shift = l->normal_exp - r->normal_exp;
1143 unsigned64 lfraction;
1144 unsigned64 rfraction;
1145 /* use exp of larger */
1146 if (shift >= NR_FRAC_GUARD)
1148 /* left has much bigger magnitute */
1150 return sim_fpu_status_inexact;
1152 if (shift <= - NR_FRAC_GUARD)
1154 /* right has much bigger magnitute */
1157 return sim_fpu_status_inexact;
1159 lfraction = l->fraction;
1160 rfraction = r->fraction;
1163 f->normal_exp = l->normal_exp;
1164 if (rfraction & LSMASK64 (shift - 1, 0))
1166 status |= sim_fpu_status_inexact;
1167 rfraction |= LSBIT64 (shift); /* stick LSBit */
1169 rfraction >>= shift;
1173 f->normal_exp = r->normal_exp;
1174 if (lfraction & LSMASK64 (- shift - 1, 0))
1176 status |= sim_fpu_status_inexact;
1177 lfraction |= LSBIT64 (- shift); /* stick LSBit */
1179 lfraction >>= -shift;
1183 f->normal_exp = r->normal_exp;
1186 /* perform the subtraction */
1188 lfraction = - lfraction;
1190 rfraction = - rfraction;
1191 f->fraction = lfraction + rfraction;
1194 if (f->fraction == 0)
1201 f->class = sim_fpu_class_number;
1202 if ((signed64) f->fraction >= 0)
1207 f->fraction = - f->fraction;
1211 if ((f->fraction & IMPLICIT_2))
1213 f->fraction = (f->fraction >> 1) | (f->fraction & 1);
1216 else if (f->fraction < IMPLICIT_1)
1223 while (f->fraction < IMPLICIT_1);
1225 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1231 INLINE_SIM_FPU (int)
1232 sim_fpu_mul (sim_fpu *f,
1236 if (sim_fpu_is_snan (l))
1239 f->class = sim_fpu_class_qnan;
1240 return sim_fpu_status_invalid_snan;
1242 if (sim_fpu_is_snan (r))
1245 f->class = sim_fpu_class_qnan;
1246 return sim_fpu_status_invalid_snan;
1248 if (sim_fpu_is_qnan (l))
1253 if (sim_fpu_is_qnan (r))
1258 if (sim_fpu_is_infinity (l))
1260 if (sim_fpu_is_zero (r))
1263 return sim_fpu_status_invalid_imz;
1266 f->sign = l->sign ^ r->sign;
1269 if (sim_fpu_is_infinity (r))
1271 if (sim_fpu_is_zero (l))
1274 return sim_fpu_status_invalid_imz;
1277 f->sign = l->sign ^ r->sign;
1280 if (sim_fpu_is_zero (l) || sim_fpu_is_zero (r))
1283 f->sign = l->sign ^ r->sign;
1286 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1291 unsigned64 nl = l->fraction & 0xffffffff;
1292 unsigned64 nh = l->fraction >> 32;
1293 unsigned64 ml = r->fraction & 0xffffffff;
1294 unsigned64 mh = r->fraction >>32;
1295 unsigned64 pp_ll = ml * nl;
1296 unsigned64 pp_hl = mh * nl;
1297 unsigned64 pp_lh = ml * nh;
1298 unsigned64 pp_hh = mh * nh;
1299 unsigned64 res2 = 0;
1300 unsigned64 res0 = 0;
1301 unsigned64 ps_hh__ = pp_hl + pp_lh;
1302 if (ps_hh__ < pp_hl)
1303 res2 += UNSIGNED64 (0x100000000);
1304 pp_hl = (ps_hh__ << 32) & UNSIGNED64 (0xffffffff00000000);
1305 res0 = pp_ll + pp_hl;
1308 res2 += ((ps_hh__ >> 32) & 0xffffffff) + pp_hh;
1312 f->normal_exp = l->normal_exp + r->normal_exp;
1313 f->sign = l->sign ^ r->sign;
1314 f->class = sim_fpu_class_number;
1316 /* Input is bounded by [1,2) ; [2^60,2^61)
1317 Output is bounded by [1,4) ; [2^120,2^122) */
1319 /* Adjust the exponent according to where the decimal point ended
1320 up in the high 64 bit word. In the source the decimal point
1321 was at NR_FRAC_GUARD. */
1322 f->normal_exp += NR_FRAC_GUARD + 64 - (NR_FRAC_GUARD * 2);
1324 /* The high word is bounded according to the above. Consequently
1325 it has never overflowed into IMPLICIT_2. */
1326 ASSERT (high < LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64));
1327 ASSERT (high >= LSBIT64 ((NR_FRAC_GUARD * 2) - 64));
1328 ASSERT (LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64) < IMPLICIT_1);
1332 print_bits (high, 63, (sim_fpu_print_func*)fprintf, stdout);
1334 print_bits (low, 63, (sim_fpu_print_func*)fprintf, stdout);
1343 if (low & LSBIT64 (63))
1347 while (high < IMPLICIT_1);
1350 print_bits (high, 63, (sim_fpu_print_func*)fprintf, stdout);
1352 print_bits (low, 63, (sim_fpu_print_func*)fprintf, stdout);
1356 ASSERT (high >= IMPLICIT_1 && high < IMPLICIT_2);
1359 f->fraction = (high | 1); /* sticky */
1360 return sim_fpu_status_inexact;
1371 INLINE_SIM_FPU (int)
1372 sim_fpu_div (sim_fpu *f,
1376 if (sim_fpu_is_snan (l))
1379 f->class = sim_fpu_class_qnan;
1380 return sim_fpu_status_invalid_snan;
1382 if (sim_fpu_is_snan (r))
1385 f->class = sim_fpu_class_qnan;
1386 return sim_fpu_status_invalid_snan;
1388 if (sim_fpu_is_qnan (l))
1391 f->class = sim_fpu_class_qnan;
1394 if (sim_fpu_is_qnan (r))
1397 f->class = sim_fpu_class_qnan;
1400 if (sim_fpu_is_infinity (l))
1402 if (sim_fpu_is_infinity (r))
1405 return sim_fpu_status_invalid_idi;
1410 f->sign = l->sign ^ r->sign;
1414 if (sim_fpu_is_zero (l))
1416 if (sim_fpu_is_zero (r))
1419 return sim_fpu_status_invalid_zdz;
1424 f->sign = l->sign ^ r->sign;
1428 if (sim_fpu_is_infinity (r))
1431 f->sign = l->sign ^ r->sign;
1434 if (sim_fpu_is_zero (r))
1436 f->class = sim_fpu_class_infinity;
1437 f->sign = l->sign ^ r->sign;
1438 return sim_fpu_status_invalid_div0;
1441 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1444 /* quotient = ( ( numerator / denominator)
1445 x 2^(numerator exponent - denominator exponent)
1447 unsigned64 numerator;
1448 unsigned64 denominator;
1449 unsigned64 quotient;
1452 f->class = sim_fpu_class_number;
1453 f->sign = l->sign ^ r->sign;
1454 f->normal_exp = l->normal_exp - r->normal_exp;
1456 numerator = l->fraction;
1457 denominator = r->fraction;
1459 /* Fraction will be less than 1.0 */
1460 if (numerator < denominator)
1465 ASSERT (numerator >= denominator);
1467 /* Gain extra precision, already used one spare bit */
1468 numerator <<= NR_SPARE;
1469 denominator <<= NR_SPARE;
1471 /* Does divide one bit at a time. Optimize??? */
1473 bit = (IMPLICIT_1 << NR_SPARE);
1476 if (numerator >= denominator)
1479 numerator -= denominator;
1487 print_bits (quotient, 63, (sim_fpu_print_func*)fprintf, stdout);
1489 print_bits (numerator, 63, (sim_fpu_print_func*)fprintf, stdout);
1491 print_bits (denominator, 63, (sim_fpu_print_func*)fprintf, stdout);
1495 /* discard (but save) the extra bits */
1496 if ((quotient & LSMASK64 (NR_SPARE -1, 0)))
1497 quotient = (quotient >> NR_SPARE) | 1;
1499 quotient = (quotient >> NR_SPARE);
1501 f->fraction = quotient;
1502 ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
1505 f->fraction |= 1; /* stick remaining bits */
1506 return sim_fpu_status_inexact;
1514 INLINE_SIM_FPU (int)
1515 sim_fpu_neg (sim_fpu *f,
1518 if (sim_fpu_is_snan (r))
1521 f->class = sim_fpu_class_qnan;
1522 return sim_fpu_status_invalid_snan;
1524 if (sim_fpu_is_qnan (r))
1535 INLINE_SIM_FPU (int)
1536 sim_fpu_abs (sim_fpu *f,
1539 if (sim_fpu_is_snan (r))
1542 f->class = sim_fpu_class_qnan;
1543 return sim_fpu_status_invalid_snan;
1545 if (sim_fpu_is_qnan (r))
1556 INLINE_SIM_FPU (int)
1557 sim_fpu_inv (sim_fpu *f,
1560 if (sim_fpu_is_snan (r))
1563 f->class = sim_fpu_class_qnan;
1564 return sim_fpu_status_invalid_snan;
1566 if (sim_fpu_is_qnan (r))
1569 f->class = sim_fpu_class_qnan;
1572 if (sim_fpu_is_infinity (r))
1578 if (sim_fpu_is_zero (r))
1580 f->class = sim_fpu_class_infinity;
1582 return sim_fpu_status_invalid_div0;
1585 f->normal_exp = - r->normal_exp;
1590 INLINE_SIM_FPU (int)
1591 sim_fpu_sqrt (sim_fpu *f,
1594 if (sim_fpu_is_snan (r))
1597 return sim_fpu_status_invalid_snan;
1599 if (sim_fpu_is_qnan (r))
1604 if (sim_fpu_is_zero (r))
1606 f->class = sim_fpu_class_zero;
1610 if (sim_fpu_is_infinity (r))
1615 return sim_fpu_status_invalid_sqrt;
1619 f->class = sim_fpu_class_infinity;
1628 return sim_fpu_status_invalid_sqrt;
1631 /* @(#)e_sqrt.c 5.1 93/09/24 */
1633 * ====================================================
1634 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1636 * Developed at SunPro, a Sun Microsystems, Inc. business.
1637 * Permission to use, copy, modify, and distribute this
1638 * software is freely granted, provided that this notice
1640 * ====================================================
1643 /* __ieee754_sqrt(x)
1644 * Return correctly rounded sqrt.
1645 * ------------------------------------------
1646 * | Use the hardware sqrt if you have one |
1647 * ------------------------------------------
1649 * Bit by bit method using integer arithmetic. (Slow, but portable)
1651 * Scale x to y in [1,4) with even powers of 2:
1652 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1653 * sqrt(x) = 2^k * sqrt(y)
1656 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1657 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1659 - y = ((m even) ? x : 2.x)
1661 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1663 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1665 * 2. Bit by bit computation
1666 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1669 * s = 2*q , and y = 2 * ( y - q ). (1)
1672 * To compute q from q , one checks whether
1676 * (q + 2 ) <= y. (2)
1679 * If (2) is false, then q = q ; otherwise q = q + 2 .
1682 * With some algebric manipulation, it is not difficult to see
1683 * that (2) is equivalent to
1688 * The advantage of (3) is that s and y can be computed by
1690 * the following recurrence formula:
1693 * s = s , y = y ; (4)
1702 * s = s + 2 , y = y - s - 2 (5)
1707 - NOTE: y = 2 (y - s - 2 )
1710 * One may easily use induction to prove (4) and (5).
1711 * Note. Since the left hand side of (3) contain only i+2 bits,
1712 * it does not necessary to do a full (53-bit) comparison
1715 * After generating the 53 bits result, we compute one more bit.
1716 * Together with the remainder, we can decide whether the
1717 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1718 * (it will never equal to 1/2ulp).
1719 * The rounding mode can be detected by checking whether
1720 * huge + tiny is equal to huge, and whether huge - tiny is
1721 * equal to huge for some floating point number "huge" and "tiny".
1724 * sqrt(+-0) = +-0 ... exact
1726 * sqrt(-ve) = NaN ... with invalid signal
1727 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1729 * Other methods : see the appended file at the end of the program below.
1734 /* generate sqrt(x) bit by bit */
1740 f->class = sim_fpu_class_number;
1743 f->normal_exp = (r->normal_exp >> 1); /* exp = [exp/2] */
1745 /* odd exp, double x to make it even */
1746 ASSERT (y >= IMPLICIT_1 && y < IMPLICIT_4);
1747 if ((r->normal_exp & 1))
1751 ASSERT (y >= IMPLICIT_1 && y < (IMPLICIT_2 << 1));
1753 /* Let loop determine first value of s (either 1 or 2) */
1760 unsigned64 t = s + b;
1771 ASSERT (q >= IMPLICIT_1 && q < IMPLICIT_2);
1775 f->fraction |= 1; /* stick remaining bits */
1776 return sim_fpu_status_inexact;
1784 /* int/long <-> sim_fpu */
1786 INLINE_SIM_FPU (int)
1787 sim_fpu_i32to (sim_fpu *f,
1789 sim_fpu_round round)
1795 INLINE_SIM_FPU (int)
1796 sim_fpu_u32to (sim_fpu *f,
1798 sim_fpu_round round)
1804 INLINE_SIM_FPU (int)
1805 sim_fpu_i64to (sim_fpu *f,
1807 sim_fpu_round round)
1813 INLINE_SIM_FPU (int)
1814 sim_fpu_u64to (sim_fpu *f,
1816 sim_fpu_round round)
1823 INLINE_SIM_FPU (int)
1824 sim_fpu_to32i (signed32 *i,
1826 sim_fpu_round round)
1829 int status = fpu2i (&i64, f, 0, round);
1834 INLINE_SIM_FPU (int)
1835 sim_fpu_to32u (unsigned32 *u,
1837 sim_fpu_round round)
1840 int status = fpu2u (&u64, f, 0);
1845 INLINE_SIM_FPU (int)
1846 sim_fpu_to64i (signed64 *i,
1848 sim_fpu_round round)
1850 return fpu2i (i, f, 1, round);
1854 INLINE_SIM_FPU (int)
1855 sim_fpu_to64u (unsigned64 *u,
1857 sim_fpu_round round)
1859 return fpu2u (u, f, 1);
1864 /* sim_fpu -> host format */
1867 INLINE_SIM_FPU (float)
1868 sim_fpu_2f (const sim_fpu *f)
1875 INLINE_SIM_FPU (double)
1876 sim_fpu_2d (const sim_fpu *s)
1879 val.i = pack_fpu (s, 1);
1885 INLINE_SIM_FPU (void)
1886 sim_fpu_f2 (sim_fpu *f,
1891 unpack_fpu (f, val.i, 1);
1896 INLINE_SIM_FPU (void)
1897 sim_fpu_d2 (sim_fpu *f,
1902 unpack_fpu (f, val.i, 1);
1908 INLINE_SIM_FPU (int)
1909 sim_fpu_is_nan (const sim_fpu *d)
1913 case sim_fpu_class_qnan:
1914 case sim_fpu_class_snan:
1921 INLINE_SIM_FPU (int)
1922 sim_fpu_is_qnan (const sim_fpu *d)
1926 case sim_fpu_class_qnan:
1933 INLINE_SIM_FPU (int)
1934 sim_fpu_is_snan (const sim_fpu *d)
1938 case sim_fpu_class_snan:
1945 INLINE_SIM_FPU (int)
1946 sim_fpu_is_zero (const sim_fpu *d)
1950 case sim_fpu_class_zero:
1957 INLINE_SIM_FPU (int)
1958 sim_fpu_is_infinity (const sim_fpu *d)
1962 case sim_fpu_class_infinity:
1969 INLINE_SIM_FPU (int)
1970 sim_fpu_is_number (const sim_fpu *d)
1974 case sim_fpu_class_denorm:
1975 case sim_fpu_class_number:
1982 INLINE_SIM_FPU (int)
1983 sim_fpu_is_denorm (const sim_fpu *d)
1987 case sim_fpu_class_denorm:
1994 INLINE_SIM_FPU (int)
1995 sim_fpu_is (const sim_fpu *d)
1999 case sim_fpu_class_qnan:
2000 return SIM_FPU_IS_QNAN;
2001 case sim_fpu_class_snan:
2002 return SIM_FPU_IS_SNAN;
2003 case sim_fpu_class_infinity:
2004 return SIM_FPU_IS_NINF;
2005 return SIM_FPU_IS_PINF;
2006 case sim_fpu_class_number:
2008 return SIM_FPU_IS_NNUMBER;
2010 return SIM_FPU_IS_PNUMBER;
2011 case sim_fpu_class_denorm:
2013 return SIM_FPU_IS_NDENORM;
2015 return SIM_FPU_IS_PDENORM;
2016 case sim_fpu_class_zero:
2018 return SIM_FPU_IS_NZERO;
2020 return SIM_FPU_IS_PZERO;
2027 INLINE_SIM_FPU (int)
2028 sim_fpu_cmp (const sim_fpu *l, const sim_fpu *r)
2031 sim_fpu_sub (&res, l, r);
2032 return sim_fpu_is (&res);
2035 INLINE_SIM_FPU (int)
2036 sim_fpu_is_lt (const sim_fpu *l, const sim_fpu *r)
2039 sim_fpu_lt (&status, l, r);
2043 INLINE_SIM_FPU (int)
2044 sim_fpu_is_le (const sim_fpu *l, const sim_fpu *r)
2047 sim_fpu_le (&is, l, r);
2051 INLINE_SIM_FPU (int)
2052 sim_fpu_is_eq (const sim_fpu *l, const sim_fpu *r)
2055 sim_fpu_eq (&is, l, r);
2059 INLINE_SIM_FPU (int)
2060 sim_fpu_is_ne (const sim_fpu *l, const sim_fpu *r)
2063 sim_fpu_ne (&is, l, r);
2067 INLINE_SIM_FPU (int)
2068 sim_fpu_is_ge (const sim_fpu *l, const sim_fpu *r)
2071 sim_fpu_ge (&is, l, r);
2075 INLINE_SIM_FPU (int)
2076 sim_fpu_is_gt (const sim_fpu *l, const sim_fpu *r)
2079 sim_fpu_gt (&is, l, r);
2084 /* Compare operators */
2086 INLINE_SIM_FPU (int)
2087 sim_fpu_lt (int *is,
2091 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2095 lval.i = pack_fpu (l, 1);
2096 rval.i = pack_fpu (r, 1);
2097 (*is) = (lval.d < rval.d);
2100 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2103 return sim_fpu_status_invalid_snan;
2108 return sim_fpu_status_invalid_qnan;
2112 INLINE_SIM_FPU (int)
2113 sim_fpu_le (int *is,
2117 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2121 lval.i = pack_fpu (l, 1);
2122 rval.i = pack_fpu (r, 1);
2123 *is = (lval.d <= rval.d);
2126 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2129 return sim_fpu_status_invalid_snan;
2134 return sim_fpu_status_invalid_qnan;
2138 INLINE_SIM_FPU (int)
2139 sim_fpu_eq (int *is,
2143 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2147 lval.i = pack_fpu (l, 1);
2148 rval.i = pack_fpu (r, 1);
2149 (*is) = (lval.d == rval.d);
2152 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2155 return sim_fpu_status_invalid_snan;
2160 return sim_fpu_status_invalid_qnan;
2164 INLINE_SIM_FPU (int)
2165 sim_fpu_ne (int *is,
2169 if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
2173 lval.i = pack_fpu (l, 1);
2174 rval.i = pack_fpu (r, 1);
2175 (*is) = (lval.d != rval.d);
2178 else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
2181 return sim_fpu_status_invalid_snan;
2186 return sim_fpu_status_invalid_qnan;
2190 INLINE_SIM_FPU (int)
2191 sim_fpu_ge (int *is,
2195 return sim_fpu_le (is, r, l);
2198 INLINE_SIM_FPU (int)
2199 sim_fpu_gt (int *is,
2203 return sim_fpu_lt (is, r, l);
2207 /* A number of useful constants */
2209 const sim_fpu sim_fpu_zero = { sim_fpu_class_zero, };
2210 const sim_fpu sim_fpu_qnan = { sim_fpu_class_qnan, };
2215 INLINE_SIM_FPU (void)
2216 sim_fpu_print_fpu (const sim_fpu *f,
2217 sim_fpu_print_func *print,
2220 print (arg, "%s", f->sign ? "-" : "+");
2223 case sim_fpu_class_qnan:
2225 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2226 print (arg, "*QuietNaN");
2228 case sim_fpu_class_snan:
2230 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2231 print (arg, "*SignalNaN");
2233 case sim_fpu_class_zero:
2236 case sim_fpu_class_infinity:
2239 case sim_fpu_class_number:
2240 case sim_fpu_class_denorm:
2242 print_bits (f->fraction, NR_FRAC_GUARD - 1, print, arg);
2243 print (arg, "*2^%+-5d", f->normal_exp);
2244 ASSERT (f->fraction >= IMPLICIT_1);
2245 ASSERT (f->fraction < IMPLICIT_2);
2250 INLINE_SIM_FPU (void)
2251 sim_fpu_print_status (int status,
2252 sim_fpu_print_func *print,
2259 switch ((sim_fpu_status) (status & i))
2261 case sim_fpu_status_denorm:
2262 print (arg, "%sD", prefix);
2264 case sim_fpu_status_invalid_snan:
2265 print (arg, "%sSNaN", prefix);
2267 case sim_fpu_status_invalid_qnan:
2268 print (arg, "%sQNaN", prefix);
2270 case sim_fpu_status_invalid_isi:
2271 print (arg, "%sISI", prefix);
2273 case sim_fpu_status_invalid_idi:
2274 print (arg, "%sIDI", prefix);
2276 case sim_fpu_status_invalid_zdz:
2277 print (arg, "%sZDZ", prefix);
2279 case sim_fpu_status_invalid_imz:
2280 print (arg, "%sIMZ", prefix);
2282 case sim_fpu_status_invalid_cvi:
2283 print (arg, "%sCVI", prefix);
2285 case sim_fpu_status_invalid_cmp:
2286 print (arg, "%sCMP", prefix);
2288 case sim_fpu_status_invalid_sqrt:
2289 print (arg, "%sSQRT", prefix);
2292 case sim_fpu_status_inexact:
2293 print (arg, "%sX", prefix);
2296 case sim_fpu_status_overflow:
2297 print (arg, "%sO", prefix);
2300 case sim_fpu_status_underflow:
2301 print (arg, "%sU", prefix);
2304 case sim_fpu_status_invalid_div0:
2305 print (arg, "%s/", prefix);
2308 case sim_fpu_status_rounded:
2309 print (arg, "%sR", prefix);