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 STATIC_INLINE_SIM_FPU (unsigned64
)
167 pack_fpu (const sim_fpu
*src
,
178 case sim_fpu_class_qnan
:
181 /* force fraction to correct class */
182 fraction
= src
->fraction
;
183 fraction
>>= NR_GUARDS
;
184 fraction
|= QUIET_NAN
;
186 case sim_fpu_class_snan
:
189 /* force fraction to correct class */
190 fraction
= src
->fraction
;
191 fraction
>>= NR_GUARDS
;
192 fraction
&= ~QUIET_NAN
;
194 case sim_fpu_class_infinity
:
199 case sim_fpu_class_zero
:
204 case sim_fpu_class_number
:
205 ASSERT (src
->fraction
>= IMPLICIT_1
);
206 ASSERT (src
->fraction
< IMPLICIT_2
);
207 if (src
->normal_exp
< NORMAL_EXPMIN
)
209 /* This number's exponent is too low to fit into the bits
210 available in the number We'll denormalize the number by
211 storing zero in the exponent and shift the fraction to
212 the right to make up for it. */
213 int nr_shift
= NORMAL_EXPMIN
- src
->normal_exp
;
214 if (nr_shift
> NR_FRACBITS
)
216 /* underflow, just make the number zero */
225 /* Shift by the value */
226 fraction
= src
->fraction
;
227 fraction
>>= NR_GUARDS
;
228 fraction
>>= nr_shift
;
231 else if (src
->normal_exp
> NORMAL_EXPMAX
)
240 exp
= (src
->normal_exp
+ EXPBIAS
);
242 fraction
= src
->fraction
;
243 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
245 /* Round to nearest: If the guard bits are the all zero, but
246 the first, then we're half way between two numbers,
247 choose the one which makes the lsb of the answer 0. */
248 if ((fraction
& GUARDMASK
) == GUARDMSB
)
250 if ((fraction
& (GUARDMSB
<< 1)))
251 fraction
+= (GUARDMSB
<< 1);
255 /* Add a one to the guards to force round to nearest */
256 fraction
+= GUARDROUND
;
258 if ((fraction
& IMPLICIT_2
)) /* rounding resulted in carry */
263 fraction
>>= NR_GUARDS
;
264 /* When exp == EXPMAX (overflow from carry) fraction must
265 have been made zero */
266 ASSERT ((exp
== EXPMAX
) <= ((fraction
& ~IMPLICIT_1
) == 0));
273 packed
= ((sign
? SIGNBIT
: 0)
274 | (exp
<< NR_FRACBITS
)
275 | LSMASKED64 (fraction
, NR_FRACBITS
- 1, 0));
277 /* trace operation */
284 printf ("pack_fpu: ");
285 printf ("-> %c%0lX.%06lX\n",
286 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
287 (long) LSEXTRACTED32 (packed
, 30, 23),
288 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
296 STATIC_INLINE_SIM_FPU (void)
297 unpack_fpu (sim_fpu
*dst
, unsigned64 packed
, int is_double
)
299 unsigned64 fraction
= LSMASKED64 (packed
, NR_FRACBITS
- 1, 0);
300 unsigned exp
= LSEXTRACTED64 (packed
, NR_EXPBITS
+ NR_FRACBITS
- 1, NR_FRACBITS
);
301 int sign
= (packed
& SIGNBIT
) != 0;
305 /* Hmm. Looks like 0 */
308 /* tastes like zero */
309 dst
->class = sim_fpu_class_zero
;
314 /* Zero exponent with non zero fraction - it's denormalized,
315 so there isn't a leading implicit one - we'll shift it so
317 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
318 dst
->class = sim_fpu_class_number
;
320 fraction
<<= NR_GUARDS
;
321 while (fraction
< IMPLICIT_1
)
326 dst
->fraction
= fraction
;
329 else if (exp
== EXPMAX
)
334 /* Attached to a zero fraction - means infinity */
335 dst
->class = sim_fpu_class_infinity
;
337 /* dst->normal_exp = EXPBIAS; */
338 /* dst->fraction = 0; */
342 /* Non zero fraction, means NaN */
344 dst
->fraction
= (fraction
<< NR_GUARDS
);
345 if (fraction
>= QUIET_NAN
)
346 dst
->class = sim_fpu_class_qnan
;
348 dst
->class = sim_fpu_class_snan
;
353 /* Nothing strange about this number */
354 dst
->class = sim_fpu_class_number
;
356 dst
->fraction
= ((fraction
<< NR_GUARDS
) | IMPLICIT_1
);
357 dst
->normal_exp
= exp
- EXPBIAS
;
360 /* trace operation */
367 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
368 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
369 (long) LSEXTRACTED32 (packed
, 30, 23),
370 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
377 val
.i
= pack_fpu (dst
, 1);
380 ASSERT (val
.i
== packed
);
384 unsigned32 val
= pack_fpu (dst
, 0);
385 unsigned32 org
= packed
;
392 STATIC_INLINE_SIM_FPU (int)
401 if (sim_fpu_is_zero (s
))
406 if (sim_fpu_is_snan (s
))
408 *i
= MIN_INT
; /* FIXME */
409 return sim_fpu_status_invalid_cvi
;
411 if (sim_fpu_is_qnan (s
))
413 *i
= MIN_INT
; /* FIXME */
414 return sim_fpu_status_invalid_cvi
;
416 /* map infinity onto MAX_INT... */
417 if (sim_fpu_is_infinity (s
))
419 *i
= s
->sign
? MIN_INT
: MAX_INT
;
420 return sim_fpu_status_invalid_cvi
;
422 /* it is a number, but a small one */
423 if (s
->normal_exp
< 0)
426 return sim_fpu_status_inexact
;
428 /* Is the floating point MIN_INT or just close? */
429 if (s
->sign
&& s
->normal_exp
== (NR_INTBITS
- 1))
432 ASSERT (s
->fraction
>= IMPLICIT_1
);
433 if (s
->fraction
== IMPLICIT_1
)
434 return 0; /* exact */
435 if (is_64bit
) /* can't round */
436 return sim_fpu_status_invalid_cvi
; /* must be overflow */
437 /* For a 32bit with MAX_INT, rounding is possible */
440 case sim_fpu_round_default
:
442 case sim_fpu_round_zero
:
443 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
444 return sim_fpu_status_invalid_cvi
;
446 return sim_fpu_status_inexact
;
448 case sim_fpu_round_near
:
450 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
451 return sim_fpu_status_invalid_cvi
;
452 else if ((s
->fraction
& !FRAC32MASK
) >= (~FRAC32MASK
>> 1))
453 return sim_fpu_status_invalid_cvi
;
455 return sim_fpu_status_inexact
;
457 case sim_fpu_round_up
:
458 if ((s
->fraction
& FRAC32MASK
) == IMPLICIT_1
)
459 return sim_fpu_status_inexact
;
461 return sim_fpu_status_invalid_cvi
;
462 case sim_fpu_round_down
:
463 return sim_fpu_status_invalid_cvi
;
466 /* Would right shifting result in the FRAC being shifted into
467 (through) the integer's sign bit? */
468 if (s
->normal_exp
> (NR_INTBITS
- 2))
470 *i
= s
->sign
? MIN_INT
: MAX_INT
;
471 return sim_fpu_status_invalid_cvi
;
473 /* normal number shift it into place */
475 shift
= (s
->normal_exp
- (NR_FRAC_GUARD
));
483 if (tmp
& ((SIGNED64 (1) << shift
) - 1))
484 status
|= sim_fpu_status_inexact
;
487 *i
= s
->sign
? (-tmp
) : (tmp
);
491 STATIC_INLINE_SIM_FPU (int)
492 i2fpu (sim_fpu
*f
, signed64 i
, int is_64bit
)
497 f
->class = sim_fpu_class_zero
;
502 f
->class = sim_fpu_class_number
;
504 f
->normal_exp
= NR_FRAC_GUARD
;
508 /* Special case for minint, since there is no corresponding
509 +ve integer representation for it */
512 f
->fraction
= IMPLICIT_1
;
513 f
->normal_exp
= NR_INTBITS
- 1;
521 if (f
->fraction
>= IMPLICIT_2
)
528 while (f
->fraction
>= IMPLICIT_2
);
530 else if (f
->fraction
< IMPLICIT_1
)
537 while (f
->fraction
< IMPLICIT_1
);
541 /* trace operation */
544 printf ("i2fpu: 0x%08lX ->\n", (long) i
);
551 fpu2i (&val
, f
, is_64bit
, sim_fpu_round_zero
);
552 if (i
>= MIN_INT32
&& i
<= MAX_INT32
)
562 STATIC_INLINE_SIM_FPU (int)
563 fpu2u (unsigned64
*u
, const sim_fpu
*s
, int is_64bit
)
565 const int is_double
= 1;
568 if (sim_fpu_is_zero (s
))
573 if (sim_fpu_is_nan (s
))
578 /* it is a negative number */
584 /* get reasonable MAX_USI_INT... */
585 if (sim_fpu_is_infinity (s
))
590 /* it is a number, but a small one */
591 if (s
->normal_exp
< 0)
597 if (s
->normal_exp
> (NR_INTBITS
- 1))
603 tmp
= (s
->fraction
& ~PADMASK
);
604 shift
= (s
->normal_exp
- (NR_FRACBITS
+ NR_GUARDS
));
618 STATIC_INLINE_SIM_FPU (int)
619 u2fpu (sim_fpu
*f
, unsigned64 u
, int is_64bit
)
623 f
->class = sim_fpu_class_zero
;
628 f
->class = sim_fpu_class_number
;
630 f
->normal_exp
= NR_FRAC_GUARD
;
633 while (f
->fraction
< IMPLICIT_1
)
643 /* register <-> sim_fpu */
645 INLINE_SIM_FPU (void)
646 sim_fpu_32to (sim_fpu
*f
, unsigned32 s
)
648 unpack_fpu (f
, s
, 0);
652 INLINE_SIM_FPU (void)
653 sim_fpu_232to (sim_fpu
*f
, unsigned32 h
, unsigned32 l
)
657 unpack_fpu (f
, s
, 1);
661 INLINE_SIM_FPU (void)
662 sim_fpu_64to (sim_fpu
*f
, unsigned64 s
)
664 unpack_fpu (f
, s
, 1);
668 INLINE_SIM_FPU (void)
669 sim_fpu_to32 (unsigned32
*s
,
672 *s
= pack_fpu (f
, 0);
676 INLINE_SIM_FPU (void)
677 sim_fpu_to232 (unsigned32
*h
, unsigned32
*l
,
680 unsigned64 s
= pack_fpu (f
, 1);
686 INLINE_SIM_FPU (void)
687 sim_fpu_to64 (unsigned64
*u
,
690 *u
= pack_fpu (f
, 1);
696 STATIC_INLINE_SIM_FPU (int)
697 do_normal_overflow (sim_fpu
*f
,
703 case sim_fpu_round_default
:
705 case sim_fpu_round_near
:
706 f
->class = sim_fpu_class_infinity
;
708 case sim_fpu_round_up
:
710 f
->class = sim_fpu_class_infinity
;
712 case sim_fpu_round_down
:
714 f
->class = sim_fpu_class_infinity
;
716 case sim_fpu_round_zero
:
719 f
->normal_exp
= NORMAL_EXPMAX
;
720 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
721 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
724 STATIC_INLINE_SIM_FPU (int)
725 do_normal_underflow (sim_fpu
*f
,
731 case sim_fpu_round_default
:
733 case sim_fpu_round_near
:
734 f
->class = sim_fpu_class_zero
;
736 case sim_fpu_round_up
:
738 f
->class = sim_fpu_class_zero
;
740 case sim_fpu_round_down
:
742 f
->class = sim_fpu_class_zero
;
744 case sim_fpu_round_zero
:
745 f
->class = sim_fpu_class_zero
;
748 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
749 f
->fraction
= IMPLICIT_1
;
750 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
755 /* Round a number using NR_GUARDS.
756 Will return the rounded number or F->FRACTION == 0 when underflow */
758 STATIC_INLINE_SIM_FPU (int)
759 do_normal_round (sim_fpu
*f
,
763 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
764 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
765 unsigned64 fraclsb
= guardmsb
<< 1;
766 if ((f
->fraction
& guardmask
))
768 int status
= sim_fpu_status_inexact
;
771 case sim_fpu_round_default
:
773 case sim_fpu_round_near
:
774 if ((f
->fraction
& guardmsb
))
776 if ((f
->fraction
& fraclsb
))
778 status
|= sim_fpu_status_rounded
;
780 else if ((f
->fraction
& (guardmask
>> 1)))
782 status
|= sim_fpu_status_rounded
;
786 case sim_fpu_round_up
:
788 status
|= sim_fpu_status_rounded
;
790 case sim_fpu_round_down
:
792 status
|= sim_fpu_status_rounded
;
794 case sim_fpu_round_zero
:
797 f
->fraction
&= ~guardmask
;
798 /* round if needed, handle resulting overflow */
799 if ((status
& sim_fpu_status_rounded
))
801 f
->fraction
+= fraclsb
;
802 if ((f
->fraction
& IMPLICIT_2
))
815 STATIC_INLINE_SIM_FPU (int)
816 do_round (sim_fpu
*f
,
819 sim_fpu_denorm denorm
)
823 case sim_fpu_class_qnan
:
824 case sim_fpu_class_zero
:
825 case sim_fpu_class_infinity
:
828 case sim_fpu_class_snan
:
829 /* Quieten a SignalingNaN */
830 f
->class = sim_fpu_class_qnan
;
831 return sim_fpu_status_invalid_snan
;
833 case sim_fpu_class_number
:
836 ASSERT (f
->fraction
< IMPLICIT_2
);
837 ASSERT (f
->fraction
>= IMPLICIT_1
);
838 if (f
->normal_exp
< NORMAL_EXPMIN
)
840 /* This number's exponent is too low to fit into the bits
841 available in the number. Round off any bits that will be
842 discarded as a result of denormalization. Edge case is
843 the implicit bit shifted to GUARD0 and then rounded
845 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
846 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
847 && !(denorm
& sim_fpu_denorm_zero
))
850 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
851 if (f
->fraction
== 0) /* rounding underflowed */
852 status
|= do_normal_underflow (f
, is_double
, round
);
853 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
855 status
|= sim_fpu_status_denorm
;
856 /* Any loss of precision when denormalizing is
857 underflow. Some processors check for underflow
858 before rounding, some after! */
859 if (status
& sim_fpu_status_inexact
)
860 status
|= sim_fpu_status_underflow
;
862 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
864 if ((status
& sim_fpu_status_inexact
))
865 status
|= sim_fpu_status_underflow
;
870 status
= do_normal_underflow (f
, is_double
, round
);
873 else if (f
->normal_exp
> NORMAL_EXPMAX
)
876 status
= do_normal_overflow (f
, is_double
, round
);
880 status
= do_normal_round (f
, NR_GUARDS
, round
);
881 if (f
->fraction
== 0)
882 /* f->class = sim_fpu_class_zero; */
883 status
|= do_normal_underflow (f
, is_double
, round
);
884 else if (f
->normal_exp
> NORMAL_EXPMAX
)
885 /* oops! rounding caused overflow */
886 status
|= do_normal_overflow (f
, is_double
, round
);
888 ASSERT ((f
->class == sim_fpu_class_number
)
889 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
897 sim_fpu_round_32 (sim_fpu
*f
,
899 sim_fpu_denorm denorm
)
901 return do_round (f
, 0, round
, denorm
);
905 sim_fpu_round_64 (sim_fpu
*f
,
907 sim_fpu_denorm denorm
)
909 return do_round (f
, 1, round
, denorm
);
917 sim_fpu_add (sim_fpu
*f
,
921 if (sim_fpu_is_snan (l
))
924 f
->class = sim_fpu_class_qnan
;
925 return sim_fpu_status_invalid_snan
;
927 if (sim_fpu_is_snan (r
))
930 f
->class = sim_fpu_class_qnan
;
931 return sim_fpu_status_invalid_snan
;
933 if (sim_fpu_is_qnan (l
))
938 if (sim_fpu_is_qnan (r
))
943 if (sim_fpu_is_infinity (l
))
945 if (sim_fpu_is_infinity (r
)
946 && l
->sign
!= r
->sign
)
949 return sim_fpu_status_invalid_isi
;
954 if (sim_fpu_is_infinity (r
))
959 if (sim_fpu_is_zero (l
))
961 if (sim_fpu_is_zero (r
))
964 f
->sign
= l
->sign
& r
->sign
;
970 if (sim_fpu_is_zero (r
))
977 int shift
= l
->normal_exp
- r
->normal_exp
;
978 unsigned64 lfraction
;
979 unsigned64 rfraction
;
980 /* use exp of larger */
981 if (shift
>= NR_FRAC_GUARD
)
983 /* left has much bigger magnitute */
985 return sim_fpu_status_inexact
;
987 if (shift
<= - NR_FRAC_GUARD
)
989 /* right has much bigger magnitute */
991 return sim_fpu_status_inexact
;
993 lfraction
= l
->fraction
;
994 rfraction
= r
->fraction
;
997 f
->normal_exp
= l
->normal_exp
;
998 if (rfraction
& LSMASK64 (shift
- 1, 0))
1000 status
|= sim_fpu_status_inexact
;
1001 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1003 rfraction
>>= shift
;
1007 f
->normal_exp
= r
->normal_exp
;
1008 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1010 status
|= sim_fpu_status_inexact
;
1011 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1013 lfraction
>>= -shift
;
1017 f
->normal_exp
= r
->normal_exp
;
1020 /* perform the addition */
1022 lfraction
= - lfraction
;
1024 rfraction
= - rfraction
;
1025 f
->fraction
= lfraction
+ rfraction
;
1028 if (f
->fraction
== 0)
1035 f
->class = sim_fpu_class_number
;
1036 if ((signed64
) f
->fraction
>= 0)
1041 f
->fraction
= - f
->fraction
;
1045 if ((f
->fraction
& IMPLICIT_2
))
1047 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1050 else if (f
->fraction
< IMPLICIT_1
)
1057 while (f
->fraction
< IMPLICIT_1
);
1059 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1065 INLINE_SIM_FPU (int)
1066 sim_fpu_sub (sim_fpu
*f
,
1070 if (sim_fpu_is_snan (l
))
1073 f
->class = sim_fpu_class_qnan
;
1074 return sim_fpu_status_invalid_snan
;
1076 if (sim_fpu_is_snan (r
))
1079 f
->class = sim_fpu_class_qnan
;
1080 return sim_fpu_status_invalid_snan
;
1082 if (sim_fpu_is_qnan (l
))
1087 if (sim_fpu_is_qnan (r
))
1092 if (sim_fpu_is_infinity (l
))
1094 if (sim_fpu_is_infinity (r
)
1095 && l
->sign
== r
->sign
)
1098 return sim_fpu_status_invalid_isi
;
1103 if (sim_fpu_is_infinity (r
))
1109 if (sim_fpu_is_zero (l
))
1111 if (sim_fpu_is_zero (r
))
1114 f
->sign
= l
->sign
& !r
->sign
;
1123 if (sim_fpu_is_zero (r
))
1130 int shift
= l
->normal_exp
- r
->normal_exp
;
1131 unsigned64 lfraction
;
1132 unsigned64 rfraction
;
1133 /* use exp of larger */
1134 if (shift
>= NR_FRAC_GUARD
)
1136 /* left has much bigger magnitute */
1138 return sim_fpu_status_inexact
;
1140 if (shift
<= - NR_FRAC_GUARD
)
1142 /* right has much bigger magnitute */
1145 return sim_fpu_status_inexact
;
1147 lfraction
= l
->fraction
;
1148 rfraction
= r
->fraction
;
1151 f
->normal_exp
= l
->normal_exp
;
1152 if (rfraction
& LSMASK64 (shift
- 1, 0))
1154 status
|= sim_fpu_status_inexact
;
1155 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1157 rfraction
>>= shift
;
1161 f
->normal_exp
= r
->normal_exp
;
1162 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1164 status
|= sim_fpu_status_inexact
;
1165 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1167 lfraction
>>= -shift
;
1171 f
->normal_exp
= r
->normal_exp
;
1174 /* perform the subtraction */
1176 lfraction
= - lfraction
;
1178 rfraction
= - rfraction
;
1179 f
->fraction
= lfraction
+ rfraction
;
1182 if (f
->fraction
== 0)
1189 f
->class = sim_fpu_class_number
;
1190 if ((signed64
) f
->fraction
>= 0)
1195 f
->fraction
= - f
->fraction
;
1199 if ((f
->fraction
& IMPLICIT_2
))
1201 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1204 else if (f
->fraction
< IMPLICIT_1
)
1211 while (f
->fraction
< IMPLICIT_1
);
1213 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1219 INLINE_SIM_FPU (int)
1220 sim_fpu_mul (sim_fpu
*f
,
1224 if (sim_fpu_is_snan (l
))
1227 f
->class = sim_fpu_class_qnan
;
1228 return sim_fpu_status_invalid_snan
;
1230 if (sim_fpu_is_snan (r
))
1233 f
->class = sim_fpu_class_qnan
;
1234 return sim_fpu_status_invalid_snan
;
1236 if (sim_fpu_is_qnan (l
))
1241 if (sim_fpu_is_qnan (r
))
1246 if (sim_fpu_is_infinity (l
))
1248 if (sim_fpu_is_zero (r
))
1251 return sim_fpu_status_invalid_imz
;
1254 f
->sign
= l
->sign
^ r
->sign
;
1257 if (sim_fpu_is_infinity (r
))
1259 if (sim_fpu_is_zero (l
))
1262 return sim_fpu_status_invalid_imz
;
1265 f
->sign
= l
->sign
^ r
->sign
;
1268 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1271 f
->sign
= l
->sign
^ r
->sign
;
1274 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1279 unsigned64 nl
= l
->fraction
& 0xffffffff;
1280 unsigned64 nh
= l
->fraction
>> 32;
1281 unsigned64 ml
= r
->fraction
& 0xffffffff;
1282 unsigned64 mh
= r
->fraction
>>32;
1283 unsigned64 pp_ll
= ml
* nl
;
1284 unsigned64 pp_hl
= mh
* nl
;
1285 unsigned64 pp_lh
= ml
* nh
;
1286 unsigned64 pp_hh
= mh
* nh
;
1287 unsigned64 res2
= 0;
1288 unsigned64 res0
= 0;
1289 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1290 if (ps_hh__
< pp_hl
)
1291 res2
+= UNSIGNED64 (0x100000000);
1292 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1293 res0
= pp_ll
+ pp_hl
;
1296 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1300 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1301 f
->sign
= l
->sign
^ r
->sign
;
1302 f
->class = sim_fpu_class_number
;
1304 /* Input is bounded by [1,2) ; [2^60,2^61)
1305 Output is bounded by [1,4) ; [2^120,2^122) */
1307 /* Adjust the exponent according to where the decimal point ended
1308 up in the high 64 bit word. In the source the decimal point
1309 was at NR_FRAC_GUARD. */
1310 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1312 /* The high word is bounded according to the above. Consequently
1313 it has never overflowed into IMPLICIT_2. */
1314 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1315 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1316 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1320 print_bits (high
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1322 print_bits (low
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1331 if (low
& LSBIT64 (63))
1335 while (high
< IMPLICIT_1
);
1338 print_bits (high
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1340 print_bits (low
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1344 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1347 f
->fraction
= (high
| 1); /* sticky */
1348 return sim_fpu_status_inexact
;
1359 INLINE_SIM_FPU (int)
1360 sim_fpu_div (sim_fpu
*f
,
1364 if (sim_fpu_is_snan (l
))
1367 f
->class = sim_fpu_class_qnan
;
1368 return sim_fpu_status_invalid_snan
;
1370 if (sim_fpu_is_snan (r
))
1373 f
->class = sim_fpu_class_qnan
;
1374 return sim_fpu_status_invalid_snan
;
1376 if (sim_fpu_is_qnan (l
))
1379 f
->class = sim_fpu_class_qnan
;
1382 if (sim_fpu_is_qnan (r
))
1385 f
->class = sim_fpu_class_qnan
;
1388 if (sim_fpu_is_infinity (l
))
1390 if (sim_fpu_is_infinity (r
))
1393 return sim_fpu_status_invalid_idi
;
1398 f
->sign
= l
->sign
^ r
->sign
;
1402 if (sim_fpu_is_zero (l
))
1404 if (sim_fpu_is_zero (r
))
1407 return sim_fpu_status_invalid_zdz
;
1412 f
->sign
= l
->sign
^ r
->sign
;
1416 if (sim_fpu_is_infinity (r
))
1419 f
->sign
= l
->sign
^ r
->sign
;
1422 if (sim_fpu_is_zero (r
))
1424 f
->class = sim_fpu_class_infinity
;
1425 f
->sign
= l
->sign
^ r
->sign
;
1426 return sim_fpu_status_invalid_div0
;
1429 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1432 /* quotient = ( ( numerator / denominator)
1433 x 2^(numerator exponent - denominator exponent)
1435 unsigned64 numerator
;
1436 unsigned64 denominator
;
1437 unsigned64 quotient
;
1440 f
->class = sim_fpu_class_number
;
1441 f
->sign
= l
->sign
^ r
->sign
;
1442 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1444 numerator
= l
->fraction
;
1445 denominator
= r
->fraction
;
1447 /* Fraction will be less than 1.0 */
1448 if (numerator
< denominator
)
1453 ASSERT (numerator
>= denominator
);
1455 /* Gain extra precision, already used one spare bit */
1456 numerator
<<= NR_SPARE
;
1457 denominator
<<= NR_SPARE
;
1459 /* Does divide one bit at a time. Optimize??? */
1461 bit
= (IMPLICIT_1
<< NR_SPARE
);
1464 if (numerator
>= denominator
)
1467 numerator
-= denominator
;
1475 print_bits (quotient
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1477 print_bits (numerator
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1479 print_bits (denominator
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1483 /* discard (but save) the extra bits */
1484 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1485 quotient
= (quotient
>> NR_SPARE
) | 1;
1487 quotient
= (quotient
>> NR_SPARE
);
1489 f
->fraction
= quotient
;
1490 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1493 f
->fraction
|= 1; /* stick remaining bits */
1494 return sim_fpu_status_inexact
;
1502 INLINE_SIM_FPU (int)
1503 sim_fpu_neg (sim_fpu
*f
,
1506 if (sim_fpu_is_snan (r
))
1509 f
->class = sim_fpu_class_qnan
;
1510 return sim_fpu_status_invalid_snan
;
1512 if (sim_fpu_is_qnan (r
))
1523 INLINE_SIM_FPU (int)
1524 sim_fpu_abs (sim_fpu
*f
,
1527 if (sim_fpu_is_snan (r
))
1530 f
->class = sim_fpu_class_qnan
;
1531 return sim_fpu_status_invalid_snan
;
1533 if (sim_fpu_is_qnan (r
))
1544 INLINE_SIM_FPU (int)
1545 sim_fpu_inv (sim_fpu
*f
,
1548 if (sim_fpu_is_snan (r
))
1551 f
->class = sim_fpu_class_qnan
;
1552 return sim_fpu_status_invalid_snan
;
1554 if (sim_fpu_is_qnan (r
))
1557 f
->class = sim_fpu_class_qnan
;
1560 if (sim_fpu_is_infinity (r
))
1566 if (sim_fpu_is_zero (r
))
1568 f
->class = sim_fpu_class_infinity
;
1570 return sim_fpu_status_invalid_div0
;
1573 f
->normal_exp
= - r
->normal_exp
;
1578 INLINE_SIM_FPU (int)
1579 sim_fpu_sqrt (sim_fpu
*f
,
1582 if (sim_fpu_is_snan (r
))
1585 return sim_fpu_status_invalid_snan
;
1587 if (sim_fpu_is_qnan (r
))
1592 if (sim_fpu_is_zero (r
))
1594 f
->class = sim_fpu_class_zero
;
1598 if (sim_fpu_is_infinity (r
))
1603 return sim_fpu_status_invalid_sqrt
;
1607 f
->class = sim_fpu_class_infinity
;
1616 return sim_fpu_status_invalid_sqrt
;
1619 /* @(#)e_sqrt.c 5.1 93/09/24 */
1621 * ====================================================
1622 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1624 * Developed at SunPro, a Sun Microsystems, Inc. business.
1625 * Permission to use, copy, modify, and distribute this
1626 * software is freely granted, provided that this notice
1628 * ====================================================
1631 /* __ieee754_sqrt(x)
1632 * Return correctly rounded sqrt.
1633 * ------------------------------------------
1634 * | Use the hardware sqrt if you have one |
1635 * ------------------------------------------
1637 * Bit by bit method using integer arithmetic. (Slow, but portable)
1639 * Scale x to y in [1,4) with even powers of 2:
1640 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1641 * sqrt(x) = 2^k * sqrt(y)
1644 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1645 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1647 - y = ((m even) ? x : 2.x)
1649 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1651 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1653 * 2. Bit by bit computation
1654 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1657 * s = 2*q , and y = 2 * ( y - q ). (1)
1660 * To compute q from q , one checks whether
1664 * (q + 2 ) <= y. (2)
1667 * If (2) is false, then q = q ; otherwise q = q + 2 .
1670 * With some algebric manipulation, it is not difficult to see
1671 * that (2) is equivalent to
1676 * The advantage of (3) is that s and y can be computed by
1678 * the following recurrence formula:
1681 * s = s , y = y ; (4)
1690 * s = s + 2 , y = y - s - 2 (5)
1695 - NOTE: y = 2 (y - s - 2 )
1698 * One may easily use induction to prove (4) and (5).
1699 * Note. Since the left hand side of (3) contain only i+2 bits,
1700 * it does not necessary to do a full (53-bit) comparison
1703 * After generating the 53 bits result, we compute one more bit.
1704 * Together with the remainder, we can decide whether the
1705 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1706 * (it will never equal to 1/2ulp).
1707 * The rounding mode can be detected by checking whether
1708 * huge + tiny is equal to huge, and whether huge - tiny is
1709 * equal to huge for some floating point number "huge" and "tiny".
1712 * sqrt(+-0) = +-0 ... exact
1714 * sqrt(-ve) = NaN ... with invalid signal
1715 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1717 * Other methods : see the appended file at the end of the program below.
1722 /* generate sqrt(x) bit by bit */
1728 f
->class = sim_fpu_class_number
;
1731 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1733 /* odd exp, double x to make it even */
1734 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1735 if ((r
->normal_exp
& 1))
1739 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1741 /* Let loop determine first value of s (either 1 or 2) */
1748 unsigned64 t
= s
+ b
;
1759 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1763 f
->fraction
|= 1; /* stick remaining bits */
1764 return sim_fpu_status_inexact
;
1772 /* int/long <-> sim_fpu */
1774 INLINE_SIM_FPU (int)
1775 sim_fpu_i32to (sim_fpu
*f
,
1777 sim_fpu_round round
)
1783 INLINE_SIM_FPU (int)
1784 sim_fpu_u32to (sim_fpu
*f
,
1786 sim_fpu_round round
)
1792 INLINE_SIM_FPU (int)
1793 sim_fpu_i64to (sim_fpu
*f
,
1795 sim_fpu_round round
)
1801 INLINE_SIM_FPU (int)
1802 sim_fpu_u64to (sim_fpu
*f
,
1804 sim_fpu_round round
)
1811 INLINE_SIM_FPU (int)
1812 sim_fpu_to32i (signed32
*i
,
1814 sim_fpu_round round
)
1817 int status
= fpu2i (&i64
, f
, 0, round
);
1822 INLINE_SIM_FPU (int)
1823 sim_fpu_to32u (unsigned32
*u
,
1825 sim_fpu_round round
)
1828 int status
= fpu2u (&u64
, f
, 0);
1833 INLINE_SIM_FPU (int)
1834 sim_fpu_to64i (signed64
*i
,
1836 sim_fpu_round round
)
1838 return fpu2i (i
, f
, 1, round
);
1842 INLINE_SIM_FPU (int)
1843 sim_fpu_to64u (unsigned64
*u
,
1845 sim_fpu_round round
)
1847 return fpu2u (u
, f
, 1);
1852 /* sim_fpu -> host format */
1855 INLINE_SIM_FPU (float)
1856 sim_fpu_2f (const sim_fpu
*f
)
1863 INLINE_SIM_FPU (double)
1864 sim_fpu_2d (const sim_fpu
*s
)
1867 val
.i
= pack_fpu (s
, 1);
1873 INLINE_SIM_FPU (void)
1874 sim_fpu_f2 (sim_fpu
*f
,
1879 unpack_fpu (f
, val
.i
, 1);
1884 INLINE_SIM_FPU (void)
1885 sim_fpu_d2 (sim_fpu
*f
,
1890 unpack_fpu (f
, val
.i
, 1);
1896 INLINE_SIM_FPU (int)
1897 sim_fpu_is_nan (const sim_fpu
*d
)
1901 case sim_fpu_class_qnan
:
1902 case sim_fpu_class_snan
:
1909 INLINE_SIM_FPU (int)
1910 sim_fpu_is_qnan (const sim_fpu
*d
)
1914 case sim_fpu_class_qnan
:
1921 INLINE_SIM_FPU (int)
1922 sim_fpu_is_snan (const sim_fpu
*d
)
1926 case sim_fpu_class_snan
:
1933 INLINE_SIM_FPU (int)
1934 sim_fpu_is_zero (const sim_fpu
*d
)
1938 case sim_fpu_class_zero
:
1945 INLINE_SIM_FPU (int)
1946 sim_fpu_is_infinity (const sim_fpu
*d
)
1950 case sim_fpu_class_infinity
:
1957 INLINE_SIM_FPU (int)
1958 sim_fpu_is_number (const sim_fpu
*d
)
1962 case sim_fpu_class_number
:
1969 INLINE_SIM_FPU (int)
1970 sim_fpu_is (const sim_fpu
*d
)
1974 case sim_fpu_class_qnan
:
1975 return SIM_FPU_IS_QNAN
;
1976 case sim_fpu_class_snan
:
1977 return SIM_FPU_IS_SNAN
;
1978 case sim_fpu_class_infinity
:
1979 return SIM_FPU_IS_NINF
;
1980 return SIM_FPU_IS_PINF
;
1981 case sim_fpu_class_number
:
1983 return SIM_FPU_IS_NNUM
;
1985 return SIM_FPU_IS_PNUM
;
1987 /* FIXME: Since the intermediate sim_fpu format can hold numbers
1988 far smaller then the targets FP format, the test for denorm
1989 is currently bogus. Perhaphs the code converting a number to
1990 the internal format should flag such situtations with
1994 return SIM_FPU_IS_NDENORM
;
1996 return SIM_FPU_IS_PDENORM
;
1998 case sim_fpu_class_zero
:
2000 return SIM_FPU_IS_NZERO
;
2002 return SIM_FPU_IS_PZERO
;
2009 INLINE_SIM_FPU (int)
2010 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2013 sim_fpu_sub (&res
, l
, r
);
2014 return sim_fpu_is (&res
);
2017 INLINE_SIM_FPU (int)
2018 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2021 sim_fpu_lt (&status
, l
, r
);
2025 INLINE_SIM_FPU (int)
2026 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2029 sim_fpu_le (&is
, l
, r
);
2033 INLINE_SIM_FPU (int)
2034 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2037 sim_fpu_eq (&is
, l
, r
);
2041 INLINE_SIM_FPU (int)
2042 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2045 sim_fpu_ne (&is
, l
, r
);
2049 INLINE_SIM_FPU (int)
2050 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2053 sim_fpu_ge (&is
, l
, r
);
2057 INLINE_SIM_FPU (int)
2058 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2061 sim_fpu_gt (&is
, l
, r
);
2066 /* Compare operators */
2068 INLINE_SIM_FPU (int)
2069 sim_fpu_lt (int *is
,
2073 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2077 lval
.i
= pack_fpu (l
, 1);
2078 rval
.i
= pack_fpu (r
, 1);
2079 (*is
) = (lval
.d
< rval
.d
);
2082 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2085 return sim_fpu_status_invalid_snan
;
2090 return sim_fpu_status_invalid_qnan
;
2094 INLINE_SIM_FPU (int)
2095 sim_fpu_le (int *is
,
2099 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2103 lval
.i
= pack_fpu (l
, 1);
2104 rval
.i
= pack_fpu (r
, 1);
2105 *is
= (lval
.d
<= rval
.d
);
2108 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2111 return sim_fpu_status_invalid_snan
;
2116 return sim_fpu_status_invalid_qnan
;
2120 INLINE_SIM_FPU (int)
2121 sim_fpu_eq (int *is
,
2125 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2129 lval
.i
= pack_fpu (l
, 1);
2130 rval
.i
= pack_fpu (r
, 1);
2131 (*is
) = (lval
.d
== rval
.d
);
2134 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2137 return sim_fpu_status_invalid_snan
;
2142 return sim_fpu_status_invalid_qnan
;
2146 INLINE_SIM_FPU (int)
2147 sim_fpu_ne (int *is
,
2151 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2155 lval
.i
= pack_fpu (l
, 1);
2156 rval
.i
= pack_fpu (r
, 1);
2157 (*is
) = (lval
.d
!= rval
.d
);
2160 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2163 return sim_fpu_status_invalid_snan
;
2168 return sim_fpu_status_invalid_qnan
;
2172 INLINE_SIM_FPU (int)
2173 sim_fpu_ge (int *is
,
2177 return sim_fpu_le (is
, r
, l
);
2180 INLINE_SIM_FPU (int)
2181 sim_fpu_gt (int *is
,
2185 return sim_fpu_lt (is
, r
, l
);
2189 /* A number of useful constants */
2191 const sim_fpu sim_fpu_zero
= { sim_fpu_class_zero
, };
2192 const sim_fpu sim_fpu_qnan
= { sim_fpu_class_qnan
, };
2197 INLINE_SIM_FPU (void)
2198 sim_fpu_print_fpu (const sim_fpu
*f
,
2199 sim_fpu_print_func
*print
,
2202 print (arg
, "%s", f
->sign
? "-" : "+");
2205 case sim_fpu_class_qnan
:
2207 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2208 print (arg
, "*QuietNaN");
2210 case sim_fpu_class_snan
:
2212 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2213 print (arg
, "*SignalNaN");
2215 case sim_fpu_class_zero
:
2218 case sim_fpu_class_infinity
:
2221 case sim_fpu_class_number
:
2223 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2224 print (arg
, "*2^%+-5d", f
->normal_exp
);
2225 ASSERT (f
->fraction
>= IMPLICIT_1
);
2226 ASSERT (f
->fraction
< IMPLICIT_2
);
2231 INLINE_SIM_FPU (void)
2232 sim_fpu_print_status (int status
,
2233 sim_fpu_print_func
*print
,
2240 switch ((sim_fpu_status
) (status
& i
))
2242 case sim_fpu_status_denorm
:
2243 print (arg
, "%sD", prefix
);
2245 case sim_fpu_status_invalid_snan
:
2246 print (arg
, "%sSNaN", prefix
);
2248 case sim_fpu_status_invalid_qnan
:
2249 print (arg
, "%sQNaN", prefix
);
2251 case sim_fpu_status_invalid_isi
:
2252 print (arg
, "%sISI", prefix
);
2254 case sim_fpu_status_invalid_idi
:
2255 print (arg
, "%sIDI", prefix
);
2257 case sim_fpu_status_invalid_zdz
:
2258 print (arg
, "%sZDZ", prefix
);
2260 case sim_fpu_status_invalid_imz
:
2261 print (arg
, "%sIMZ", prefix
);
2263 case sim_fpu_status_invalid_cvi
:
2264 print (arg
, "%sCVI", prefix
);
2266 case sim_fpu_status_invalid_cmp
:
2267 print (arg
, "%sCMP", prefix
);
2269 case sim_fpu_status_invalid_sqrt
:
2270 print (arg
, "%sSQRT", prefix
);
2273 case sim_fpu_status_inexact
:
2274 print (arg
, "%sX", prefix
);
2277 case sim_fpu_status_overflow
:
2278 print (arg
, "%sO", prefix
);
2281 case sim_fpu_status_underflow
:
2282 print (arg
, "%sU", prefix
);
2285 case sim_fpu_status_invalid_div0
:
2286 print (arg
, "%s/", prefix
);
2289 case sim_fpu_status_rounded
:
2290 print (arg
, "%sR", prefix
);