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 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);
717 STATIC_INLINE_SIM_FPU (int)
718 do_normal_overflow (sim_fpu
*f
,
724 case sim_fpu_round_default
:
726 case sim_fpu_round_near
:
727 f
->class = sim_fpu_class_infinity
;
729 case sim_fpu_round_up
:
731 f
->class = sim_fpu_class_infinity
;
733 case sim_fpu_round_down
:
735 f
->class = sim_fpu_class_infinity
;
737 case sim_fpu_round_zero
:
740 f
->normal_exp
= NORMAL_EXPMAX
;
741 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
742 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
745 STATIC_INLINE_SIM_FPU (int)
746 do_normal_underflow (sim_fpu
*f
,
752 case sim_fpu_round_default
:
754 case sim_fpu_round_near
:
755 f
->class = sim_fpu_class_zero
;
757 case sim_fpu_round_up
:
759 f
->class = sim_fpu_class_zero
;
761 case sim_fpu_round_down
:
763 f
->class = sim_fpu_class_zero
;
765 case sim_fpu_round_zero
:
766 f
->class = sim_fpu_class_zero
;
769 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
770 f
->fraction
= IMPLICIT_1
;
771 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
776 /* Round a number using NR_GUARDS.
777 Will return the rounded number or F->FRACTION == 0 when underflow */
779 STATIC_INLINE_SIM_FPU (int)
780 do_normal_round (sim_fpu
*f
,
784 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
785 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
786 unsigned64 fraclsb
= guardmsb
<< 1;
787 if ((f
->fraction
& guardmask
))
789 int status
= sim_fpu_status_inexact
;
792 case sim_fpu_round_default
:
794 case sim_fpu_round_near
:
795 if ((f
->fraction
& guardmsb
))
797 if ((f
->fraction
& fraclsb
))
799 status
|= sim_fpu_status_rounded
;
801 else if ((f
->fraction
& (guardmask
>> 1)))
803 status
|= sim_fpu_status_rounded
;
807 case sim_fpu_round_up
:
809 status
|= sim_fpu_status_rounded
;
811 case sim_fpu_round_down
:
813 status
|= sim_fpu_status_rounded
;
815 case sim_fpu_round_zero
:
818 f
->fraction
&= ~guardmask
;
819 /* round if needed, handle resulting overflow */
820 if ((status
& sim_fpu_status_rounded
))
822 f
->fraction
+= fraclsb
;
823 if ((f
->fraction
& IMPLICIT_2
))
836 STATIC_INLINE_SIM_FPU (int)
837 do_round (sim_fpu
*f
,
840 sim_fpu_denorm denorm
)
844 case sim_fpu_class_qnan
:
845 case sim_fpu_class_zero
:
846 case sim_fpu_class_infinity
:
849 case sim_fpu_class_snan
:
850 /* Quieten a SignalingNaN */
851 f
->class = sim_fpu_class_qnan
;
852 return sim_fpu_status_invalid_snan
;
854 case sim_fpu_class_number
:
855 case sim_fpu_class_denorm
:
858 ASSERT (f
->fraction
< IMPLICIT_2
);
859 ASSERT (f
->fraction
>= IMPLICIT_1
);
860 if (f
->normal_exp
< NORMAL_EXPMIN
)
862 /* This number's exponent is too low to fit into the bits
863 available in the number. Round off any bits that will be
864 discarded as a result of denormalization. Edge case is
865 the implicit bit shifted to GUARD0 and then rounded
867 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
868 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
869 && !(denorm
& sim_fpu_denorm_zero
))
871 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
872 if (f
->fraction
== 0) /* rounding underflowed */
874 status
|= do_normal_underflow (f
, is_double
, round
);
876 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
878 status
|= sim_fpu_status_denorm
;
879 /* Any loss of precision when denormalizing is
880 underflow. Some processors check for underflow
881 before rounding, some after! */
882 if (status
& sim_fpu_status_inexact
)
883 status
|= sim_fpu_status_underflow
;
884 /* Flag that resultant value has been denormalized */
885 f
->class = sim_fpu_class_denorm
;
887 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
889 if ((status
& sim_fpu_status_inexact
))
890 status
|= sim_fpu_status_underflow
;
895 status
= do_normal_underflow (f
, is_double
, round
);
898 else if (f
->normal_exp
> NORMAL_EXPMAX
)
901 status
= do_normal_overflow (f
, is_double
, round
);
905 status
= do_normal_round (f
, NR_GUARDS
, round
);
906 if (f
->fraction
== 0)
907 /* f->class = sim_fpu_class_zero; */
908 status
|= do_normal_underflow (f
, is_double
, round
);
909 else if (f
->normal_exp
> NORMAL_EXPMAX
)
910 /* oops! rounding caused overflow */
911 status
|= do_normal_overflow (f
, is_double
, round
);
913 ASSERT ((f
->class == sim_fpu_class_number
914 || f
->class == sim_fpu_class_denorm
)
915 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
923 sim_fpu_round_32 (sim_fpu
*f
,
925 sim_fpu_denorm denorm
)
927 return do_round (f
, 0, round
, denorm
);
931 sim_fpu_round_64 (sim_fpu
*f
,
933 sim_fpu_denorm denorm
)
935 return do_round (f
, 1, round
, denorm
);
943 sim_fpu_add (sim_fpu
*f
,
947 if (sim_fpu_is_snan (l
))
950 f
->class = sim_fpu_class_qnan
;
951 return sim_fpu_status_invalid_snan
;
953 if (sim_fpu_is_snan (r
))
956 f
->class = sim_fpu_class_qnan
;
957 return sim_fpu_status_invalid_snan
;
959 if (sim_fpu_is_qnan (l
))
964 if (sim_fpu_is_qnan (r
))
969 if (sim_fpu_is_infinity (l
))
971 if (sim_fpu_is_infinity (r
)
972 && l
->sign
!= r
->sign
)
975 return sim_fpu_status_invalid_isi
;
980 if (sim_fpu_is_infinity (r
))
985 if (sim_fpu_is_zero (l
))
987 if (sim_fpu_is_zero (r
))
990 f
->sign
= l
->sign
& r
->sign
;
996 if (sim_fpu_is_zero (r
))
1003 int shift
= l
->normal_exp
- r
->normal_exp
;
1004 unsigned64 lfraction
;
1005 unsigned64 rfraction
;
1006 /* use exp of larger */
1007 if (shift
>= NR_FRAC_GUARD
)
1009 /* left has much bigger magnitute */
1011 return sim_fpu_status_inexact
;
1013 if (shift
<= - NR_FRAC_GUARD
)
1015 /* right has much bigger magnitute */
1017 return sim_fpu_status_inexact
;
1019 lfraction
= l
->fraction
;
1020 rfraction
= r
->fraction
;
1023 f
->normal_exp
= l
->normal_exp
;
1024 if (rfraction
& LSMASK64 (shift
- 1, 0))
1026 status
|= sim_fpu_status_inexact
;
1027 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1029 rfraction
>>= shift
;
1033 f
->normal_exp
= r
->normal_exp
;
1034 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1036 status
|= sim_fpu_status_inexact
;
1037 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1039 lfraction
>>= -shift
;
1043 f
->normal_exp
= r
->normal_exp
;
1046 /* perform the addition */
1048 lfraction
= - lfraction
;
1050 rfraction
= - rfraction
;
1051 f
->fraction
= lfraction
+ rfraction
;
1054 if (f
->fraction
== 0)
1061 f
->class = sim_fpu_class_number
;
1062 if ((signed64
) f
->fraction
>= 0)
1067 f
->fraction
= - f
->fraction
;
1071 if ((f
->fraction
& IMPLICIT_2
))
1073 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1076 else if (f
->fraction
< IMPLICIT_1
)
1083 while (f
->fraction
< IMPLICIT_1
);
1085 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1091 INLINE_SIM_FPU (int)
1092 sim_fpu_sub (sim_fpu
*f
,
1096 if (sim_fpu_is_snan (l
))
1099 f
->class = sim_fpu_class_qnan
;
1100 return sim_fpu_status_invalid_snan
;
1102 if (sim_fpu_is_snan (r
))
1105 f
->class = sim_fpu_class_qnan
;
1106 return sim_fpu_status_invalid_snan
;
1108 if (sim_fpu_is_qnan (l
))
1113 if (sim_fpu_is_qnan (r
))
1118 if (sim_fpu_is_infinity (l
))
1120 if (sim_fpu_is_infinity (r
)
1121 && l
->sign
== r
->sign
)
1124 return sim_fpu_status_invalid_isi
;
1129 if (sim_fpu_is_infinity (r
))
1135 if (sim_fpu_is_zero (l
))
1137 if (sim_fpu_is_zero (r
))
1140 f
->sign
= l
->sign
& !r
->sign
;
1149 if (sim_fpu_is_zero (r
))
1156 int shift
= l
->normal_exp
- r
->normal_exp
;
1157 unsigned64 lfraction
;
1158 unsigned64 rfraction
;
1159 /* use exp of larger */
1160 if (shift
>= NR_FRAC_GUARD
)
1162 /* left has much bigger magnitute */
1164 return sim_fpu_status_inexact
;
1166 if (shift
<= - NR_FRAC_GUARD
)
1168 /* right has much bigger magnitute */
1171 return sim_fpu_status_inexact
;
1173 lfraction
= l
->fraction
;
1174 rfraction
= r
->fraction
;
1177 f
->normal_exp
= l
->normal_exp
;
1178 if (rfraction
& LSMASK64 (shift
- 1, 0))
1180 status
|= sim_fpu_status_inexact
;
1181 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1183 rfraction
>>= shift
;
1187 f
->normal_exp
= r
->normal_exp
;
1188 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1190 status
|= sim_fpu_status_inexact
;
1191 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1193 lfraction
>>= -shift
;
1197 f
->normal_exp
= r
->normal_exp
;
1200 /* perform the subtraction */
1202 lfraction
= - lfraction
;
1204 rfraction
= - rfraction
;
1205 f
->fraction
= lfraction
+ rfraction
;
1208 if (f
->fraction
== 0)
1215 f
->class = sim_fpu_class_number
;
1216 if ((signed64
) f
->fraction
>= 0)
1221 f
->fraction
= - f
->fraction
;
1225 if ((f
->fraction
& IMPLICIT_2
))
1227 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1230 else if (f
->fraction
< IMPLICIT_1
)
1237 while (f
->fraction
< IMPLICIT_1
);
1239 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1245 INLINE_SIM_FPU (int)
1246 sim_fpu_mul (sim_fpu
*f
,
1250 if (sim_fpu_is_snan (l
))
1253 f
->class = sim_fpu_class_qnan
;
1254 return sim_fpu_status_invalid_snan
;
1256 if (sim_fpu_is_snan (r
))
1259 f
->class = sim_fpu_class_qnan
;
1260 return sim_fpu_status_invalid_snan
;
1262 if (sim_fpu_is_qnan (l
))
1267 if (sim_fpu_is_qnan (r
))
1272 if (sim_fpu_is_infinity (l
))
1274 if (sim_fpu_is_zero (r
))
1277 return sim_fpu_status_invalid_imz
;
1280 f
->sign
= l
->sign
^ r
->sign
;
1283 if (sim_fpu_is_infinity (r
))
1285 if (sim_fpu_is_zero (l
))
1288 return sim_fpu_status_invalid_imz
;
1291 f
->sign
= l
->sign
^ r
->sign
;
1294 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1297 f
->sign
= l
->sign
^ r
->sign
;
1300 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1305 unsigned64 nl
= l
->fraction
& 0xffffffff;
1306 unsigned64 nh
= l
->fraction
>> 32;
1307 unsigned64 ml
= r
->fraction
& 0xffffffff;
1308 unsigned64 mh
= r
->fraction
>>32;
1309 unsigned64 pp_ll
= ml
* nl
;
1310 unsigned64 pp_hl
= mh
* nl
;
1311 unsigned64 pp_lh
= ml
* nh
;
1312 unsigned64 pp_hh
= mh
* nh
;
1313 unsigned64 res2
= 0;
1314 unsigned64 res0
= 0;
1315 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1316 if (ps_hh__
< pp_hl
)
1317 res2
+= UNSIGNED64 (0x100000000);
1318 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1319 res0
= pp_ll
+ pp_hl
;
1322 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1326 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1327 f
->sign
= l
->sign
^ r
->sign
;
1328 f
->class = sim_fpu_class_number
;
1330 /* Input is bounded by [1,2) ; [2^60,2^61)
1331 Output is bounded by [1,4) ; [2^120,2^122) */
1333 /* Adjust the exponent according to where the decimal point ended
1334 up in the high 64 bit word. In the source the decimal point
1335 was at NR_FRAC_GUARD. */
1336 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1338 /* The high word is bounded according to the above. Consequently
1339 it has never overflowed into IMPLICIT_2. */
1340 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1341 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1342 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1346 print_bits (high
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1348 print_bits (low
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1357 if (low
& LSBIT64 (63))
1361 while (high
< IMPLICIT_1
);
1364 print_bits (high
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1366 print_bits (low
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1370 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1373 f
->fraction
= (high
| 1); /* sticky */
1374 return sim_fpu_status_inexact
;
1385 INLINE_SIM_FPU (int)
1386 sim_fpu_div (sim_fpu
*f
,
1390 if (sim_fpu_is_snan (l
))
1393 f
->class = sim_fpu_class_qnan
;
1394 return sim_fpu_status_invalid_snan
;
1396 if (sim_fpu_is_snan (r
))
1399 f
->class = sim_fpu_class_qnan
;
1400 return sim_fpu_status_invalid_snan
;
1402 if (sim_fpu_is_qnan (l
))
1405 f
->class = sim_fpu_class_qnan
;
1408 if (sim_fpu_is_qnan (r
))
1411 f
->class = sim_fpu_class_qnan
;
1414 if (sim_fpu_is_infinity (l
))
1416 if (sim_fpu_is_infinity (r
))
1419 return sim_fpu_status_invalid_idi
;
1424 f
->sign
= l
->sign
^ r
->sign
;
1428 if (sim_fpu_is_zero (l
))
1430 if (sim_fpu_is_zero (r
))
1433 return sim_fpu_status_invalid_zdz
;
1438 f
->sign
= l
->sign
^ r
->sign
;
1442 if (sim_fpu_is_infinity (r
))
1445 f
->sign
= l
->sign
^ r
->sign
;
1448 if (sim_fpu_is_zero (r
))
1450 f
->class = sim_fpu_class_infinity
;
1451 f
->sign
= l
->sign
^ r
->sign
;
1452 return sim_fpu_status_invalid_div0
;
1455 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1458 /* quotient = ( ( numerator / denominator)
1459 x 2^(numerator exponent - denominator exponent)
1461 unsigned64 numerator
;
1462 unsigned64 denominator
;
1463 unsigned64 quotient
;
1466 f
->class = sim_fpu_class_number
;
1467 f
->sign
= l
->sign
^ r
->sign
;
1468 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1470 numerator
= l
->fraction
;
1471 denominator
= r
->fraction
;
1473 /* Fraction will be less than 1.0 */
1474 if (numerator
< denominator
)
1479 ASSERT (numerator
>= denominator
);
1481 /* Gain extra precision, already used one spare bit */
1482 numerator
<<= NR_SPARE
;
1483 denominator
<<= NR_SPARE
;
1485 /* Does divide one bit at a time. Optimize??? */
1487 bit
= (IMPLICIT_1
<< NR_SPARE
);
1490 if (numerator
>= denominator
)
1493 numerator
-= denominator
;
1501 print_bits (quotient
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1503 print_bits (numerator
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1505 print_bits (denominator
, 63, (sim_fpu_print_func
*)fprintf
, stdout
);
1509 /* discard (but save) the extra bits */
1510 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1511 quotient
= (quotient
>> NR_SPARE
) | 1;
1513 quotient
= (quotient
>> NR_SPARE
);
1515 f
->fraction
= quotient
;
1516 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1519 f
->fraction
|= 1; /* stick remaining bits */
1520 return sim_fpu_status_inexact
;
1528 INLINE_SIM_FPU (int)
1529 sim_fpu_max (sim_fpu
*f
,
1533 if (sim_fpu_is_snan (l
))
1536 f
->class = sim_fpu_class_qnan
;
1537 return sim_fpu_status_invalid_snan
;
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 (l
))
1550 if (sim_fpu_is_qnan (r
))
1555 if (sim_fpu_is_infinity (l
))
1557 if (sim_fpu_is_infinity (r
)
1558 && l
->sign
== r
->sign
)
1561 return sim_fpu_status_invalid_isi
;
1564 *f
= *r
; /* -inf < anything */
1566 *f
= *l
; /* +inf > anthing */
1569 if (sim_fpu_is_infinity (r
))
1572 *f
= *l
; /* anything > -inf */
1574 *f
= *r
; /* anthing < +inf */
1577 if (l
->sign
> r
->sign
)
1579 *f
= *r
; /* -ve < +ve */
1582 if (l
->sign
< r
->sign
)
1584 *f
= *l
; /* +ve > -ve */
1587 ASSERT (l
->sign
== r
->sign
);
1588 if (l
->normal_exp
> r
->normal_exp
1589 || (l
->normal_exp
== r
->normal_exp
&&
1590 l
->fraction
> r
->fraction
))
1594 *f
= *r
; /* -ve < -ve */
1596 *f
= *l
; /* +ve > +ve */
1603 *f
= *l
; /* -ve > -ve */
1605 *f
= *r
; /* +ve < +ve */
1611 INLINE_SIM_FPU (int)
1612 sim_fpu_min (sim_fpu
*f
,
1616 if (sim_fpu_is_snan (l
))
1619 f
->class = sim_fpu_class_qnan
;
1620 return sim_fpu_status_invalid_snan
;
1622 if (sim_fpu_is_snan (r
))
1625 f
->class = sim_fpu_class_qnan
;
1626 return sim_fpu_status_invalid_snan
;
1628 if (sim_fpu_is_qnan (l
))
1633 if (sim_fpu_is_qnan (r
))
1638 if (sim_fpu_is_infinity (l
))
1640 if (sim_fpu_is_infinity (r
)
1641 && l
->sign
== r
->sign
)
1644 return sim_fpu_status_invalid_isi
;
1647 *f
= *l
; /* -inf < anything */
1649 *f
= *r
; /* +inf > anthing */
1652 if (sim_fpu_is_infinity (r
))
1655 *f
= *r
; /* anything > -inf */
1657 *f
= *l
; /* anything < +inf */
1660 if (l
->sign
> r
->sign
)
1662 *f
= *l
; /* -ve < +ve */
1665 if (l
->sign
< r
->sign
)
1667 *f
= *r
; /* +ve > -ve */
1670 ASSERT (l
->sign
== r
->sign
);
1671 if (l
->normal_exp
> r
->normal_exp
1672 || (l
->normal_exp
== r
->normal_exp
&&
1673 l
->fraction
> r
->fraction
))
1677 *f
= *l
; /* -ve < -ve */
1679 *f
= *r
; /* +ve > +ve */
1686 *f
= *r
; /* -ve > -ve */
1688 *f
= *l
; /* +ve < +ve */
1694 INLINE_SIM_FPU (int)
1695 sim_fpu_neg (sim_fpu
*f
,
1698 if (sim_fpu_is_snan (r
))
1701 f
->class = sim_fpu_class_qnan
;
1702 return sim_fpu_status_invalid_snan
;
1704 if (sim_fpu_is_qnan (r
))
1715 INLINE_SIM_FPU (int)
1716 sim_fpu_abs (sim_fpu
*f
,
1719 if (sim_fpu_is_snan (r
))
1722 f
->class = sim_fpu_class_qnan
;
1723 return sim_fpu_status_invalid_snan
;
1725 if (sim_fpu_is_qnan (r
))
1736 INLINE_SIM_FPU (int)
1737 sim_fpu_inv (sim_fpu
*f
,
1740 if (sim_fpu_is_snan (r
))
1743 f
->class = sim_fpu_class_qnan
;
1744 return sim_fpu_status_invalid_snan
;
1746 if (sim_fpu_is_qnan (r
))
1749 f
->class = sim_fpu_class_qnan
;
1752 if (sim_fpu_is_infinity (r
))
1758 if (sim_fpu_is_zero (r
))
1760 f
->class = sim_fpu_class_infinity
;
1762 return sim_fpu_status_invalid_div0
;
1765 f
->normal_exp
= - r
->normal_exp
;
1770 INLINE_SIM_FPU (int)
1771 sim_fpu_sqrt (sim_fpu
*f
,
1774 if (sim_fpu_is_snan (r
))
1777 return sim_fpu_status_invalid_snan
;
1779 if (sim_fpu_is_qnan (r
))
1784 if (sim_fpu_is_zero (r
))
1786 f
->class = sim_fpu_class_zero
;
1790 if (sim_fpu_is_infinity (r
))
1795 return sim_fpu_status_invalid_sqrt
;
1799 f
->class = sim_fpu_class_infinity
;
1808 return sim_fpu_status_invalid_sqrt
;
1811 /* @(#)e_sqrt.c 5.1 93/09/24 */
1813 * ====================================================
1814 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1816 * Developed at SunPro, a Sun Microsystems, Inc. business.
1817 * Permission to use, copy, modify, and distribute this
1818 * software is freely granted, provided that this notice
1820 * ====================================================
1823 /* __ieee754_sqrt(x)
1824 * Return correctly rounded sqrt.
1825 * ------------------------------------------
1826 * | Use the hardware sqrt if you have one |
1827 * ------------------------------------------
1829 * Bit by bit method using integer arithmetic. (Slow, but portable)
1831 * Scale x to y in [1,4) with even powers of 2:
1832 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1833 * sqrt(x) = 2^k * sqrt(y)
1836 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1837 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1839 - y = ((m even) ? x : 2.x)
1841 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1843 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1845 * 2. Bit by bit computation
1846 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1849 * s = 2*q , and y = 2 * ( y - q ). (1)
1852 * To compute q from q , one checks whether
1856 * (q + 2 ) <= y. (2)
1859 * If (2) is false, then q = q ; otherwise q = q + 2 .
1862 * With some algebric manipulation, it is not difficult to see
1863 * that (2) is equivalent to
1868 * The advantage of (3) is that s and y can be computed by
1870 * the following recurrence formula:
1873 * s = s , y = y ; (4)
1882 * s = s + 2 , y = y - s - 2 (5)
1887 - NOTE: y = 2 (y - s - 2 )
1890 * One may easily use induction to prove (4) and (5).
1891 * Note. Since the left hand side of (3) contain only i+2 bits,
1892 * it does not necessary to do a full (53-bit) comparison
1895 * After generating the 53 bits result, we compute one more bit.
1896 * Together with the remainder, we can decide whether the
1897 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1898 * (it will never equal to 1/2ulp).
1899 * The rounding mode can be detected by checking whether
1900 * huge + tiny is equal to huge, and whether huge - tiny is
1901 * equal to huge for some floating point number "huge" and "tiny".
1904 * sqrt(+-0) = +-0 ... exact
1906 * sqrt(-ve) = NaN ... with invalid signal
1907 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1909 * Other methods : see the appended file at the end of the program below.
1914 /* generate sqrt(x) bit by bit */
1920 f
->class = sim_fpu_class_number
;
1923 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1925 /* odd exp, double x to make it even */
1926 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1927 if ((r
->normal_exp
& 1))
1931 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1933 /* Let loop determine first value of s (either 1 or 2) */
1940 unsigned64 t
= s
+ b
;
1951 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1955 f
->fraction
|= 1; /* stick remaining bits */
1956 return sim_fpu_status_inexact
;
1964 /* int/long <-> sim_fpu */
1966 INLINE_SIM_FPU (int)
1967 sim_fpu_i32to (sim_fpu
*f
,
1969 sim_fpu_round round
)
1975 INLINE_SIM_FPU (int)
1976 sim_fpu_u32to (sim_fpu
*f
,
1978 sim_fpu_round round
)
1984 INLINE_SIM_FPU (int)
1985 sim_fpu_i64to (sim_fpu
*f
,
1987 sim_fpu_round round
)
1993 INLINE_SIM_FPU (int)
1994 sim_fpu_u64to (sim_fpu
*f
,
1996 sim_fpu_round round
)
2003 INLINE_SIM_FPU (int)
2004 sim_fpu_to32i (signed32
*i
,
2006 sim_fpu_round round
)
2009 int status
= fpu2i (&i64
, f
, 0, round
);
2014 INLINE_SIM_FPU (int)
2015 sim_fpu_to32u (unsigned32
*u
,
2017 sim_fpu_round round
)
2020 int status
= fpu2u (&u64
, f
, 0);
2025 INLINE_SIM_FPU (int)
2026 sim_fpu_to64i (signed64
*i
,
2028 sim_fpu_round round
)
2030 return fpu2i (i
, f
, 1, round
);
2034 INLINE_SIM_FPU (int)
2035 sim_fpu_to64u (unsigned64
*u
,
2037 sim_fpu_round round
)
2039 return fpu2u (u
, f
, 1);
2044 /* sim_fpu -> host format */
2047 INLINE_SIM_FPU (float)
2048 sim_fpu_2f (const sim_fpu
*f
)
2055 INLINE_SIM_FPU (double)
2056 sim_fpu_2d (const sim_fpu
*s
)
2059 val
.i
= pack_fpu (s
, 1);
2065 INLINE_SIM_FPU (void)
2066 sim_fpu_f2 (sim_fpu
*f
,
2071 unpack_fpu (f
, val
.i
, 1);
2076 INLINE_SIM_FPU (void)
2077 sim_fpu_d2 (sim_fpu
*f
,
2082 unpack_fpu (f
, val
.i
, 1);
2088 INLINE_SIM_FPU (int)
2089 sim_fpu_is_nan (const sim_fpu
*d
)
2093 case sim_fpu_class_qnan
:
2094 case sim_fpu_class_snan
:
2101 INLINE_SIM_FPU (int)
2102 sim_fpu_is_qnan (const sim_fpu
*d
)
2106 case sim_fpu_class_qnan
:
2113 INLINE_SIM_FPU (int)
2114 sim_fpu_is_snan (const sim_fpu
*d
)
2118 case sim_fpu_class_snan
:
2125 INLINE_SIM_FPU (int)
2126 sim_fpu_is_zero (const sim_fpu
*d
)
2130 case sim_fpu_class_zero
:
2137 INLINE_SIM_FPU (int)
2138 sim_fpu_is_infinity (const sim_fpu
*d
)
2142 case sim_fpu_class_infinity
:
2149 INLINE_SIM_FPU (int)
2150 sim_fpu_is_number (const sim_fpu
*d
)
2154 case sim_fpu_class_denorm
:
2155 case sim_fpu_class_number
:
2162 INLINE_SIM_FPU (int)
2163 sim_fpu_is_denorm (const sim_fpu
*d
)
2167 case sim_fpu_class_denorm
:
2175 INLINE_SIM_FPU (int)
2176 sim_fpu_sign (const sim_fpu
*d
)
2182 INLINE_SIM_FPU (int)
2183 sim_fpu_exp (const sim_fpu
*d
)
2185 return d
->normal_exp
;
2189 INLINE_SIM_FPU (int)
2190 sim_fpu_is (const sim_fpu
*d
)
2194 case sim_fpu_class_qnan
:
2195 return SIM_FPU_IS_QNAN
;
2196 case sim_fpu_class_snan
:
2197 return SIM_FPU_IS_SNAN
;
2198 case sim_fpu_class_infinity
:
2199 return SIM_FPU_IS_NINF
;
2200 return SIM_FPU_IS_PINF
;
2201 case sim_fpu_class_number
:
2203 return SIM_FPU_IS_NNUMBER
;
2205 return SIM_FPU_IS_PNUMBER
;
2206 case sim_fpu_class_denorm
:
2208 return SIM_FPU_IS_NDENORM
;
2210 return SIM_FPU_IS_PDENORM
;
2211 case sim_fpu_class_zero
:
2213 return SIM_FPU_IS_NZERO
;
2215 return SIM_FPU_IS_PZERO
;
2222 INLINE_SIM_FPU (int)
2223 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2226 sim_fpu_sub (&res
, l
, r
);
2227 return sim_fpu_is (&res
);
2230 INLINE_SIM_FPU (int)
2231 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2234 sim_fpu_lt (&status
, l
, r
);
2238 INLINE_SIM_FPU (int)
2239 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2242 sim_fpu_le (&is
, l
, r
);
2246 INLINE_SIM_FPU (int)
2247 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2250 sim_fpu_eq (&is
, l
, r
);
2254 INLINE_SIM_FPU (int)
2255 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2258 sim_fpu_ne (&is
, l
, r
);
2262 INLINE_SIM_FPU (int)
2263 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2266 sim_fpu_ge (&is
, l
, r
);
2270 INLINE_SIM_FPU (int)
2271 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2274 sim_fpu_gt (&is
, l
, r
);
2279 /* Compare operators */
2281 INLINE_SIM_FPU (int)
2282 sim_fpu_lt (int *is
,
2286 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2290 lval
.i
= pack_fpu (l
, 1);
2291 rval
.i
= pack_fpu (r
, 1);
2292 (*is
) = (lval
.d
< rval
.d
);
2295 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2298 return sim_fpu_status_invalid_snan
;
2303 return sim_fpu_status_invalid_qnan
;
2307 INLINE_SIM_FPU (int)
2308 sim_fpu_le (int *is
,
2312 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2316 lval
.i
= pack_fpu (l
, 1);
2317 rval
.i
= pack_fpu (r
, 1);
2318 *is
= (lval
.d
<= rval
.d
);
2321 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2324 return sim_fpu_status_invalid_snan
;
2329 return sim_fpu_status_invalid_qnan
;
2333 INLINE_SIM_FPU (int)
2334 sim_fpu_eq (int *is
,
2338 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2342 lval
.i
= pack_fpu (l
, 1);
2343 rval
.i
= pack_fpu (r
, 1);
2344 (*is
) = (lval
.d
== rval
.d
);
2347 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2350 return sim_fpu_status_invalid_snan
;
2355 return sim_fpu_status_invalid_qnan
;
2359 INLINE_SIM_FPU (int)
2360 sim_fpu_ne (int *is
,
2364 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2368 lval
.i
= pack_fpu (l
, 1);
2369 rval
.i
= pack_fpu (r
, 1);
2370 (*is
) = (lval
.d
!= rval
.d
);
2373 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2376 return sim_fpu_status_invalid_snan
;
2381 return sim_fpu_status_invalid_qnan
;
2385 INLINE_SIM_FPU (int)
2386 sim_fpu_ge (int *is
,
2390 return sim_fpu_le (is
, r
, l
);
2393 INLINE_SIM_FPU (int)
2394 sim_fpu_gt (int *is
,
2398 return sim_fpu_lt (is
, r
, l
);
2402 /* A number of useful constants */
2404 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_zero
= {
2407 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_qnan
= {
2410 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_one
= {
2411 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2413 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_two
= {
2414 sim_fpu_class_number
, 0, IMPLICIT_1
, 2
2416 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_max32
= {
2417 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2419 EXTERN_SIM_FPU (const sim_fpu
) sim_fpu_max64
= {
2420 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2426 INLINE_SIM_FPU (void)
2427 sim_fpu_print_fpu (const sim_fpu
*f
,
2428 sim_fpu_print_func
*print
,
2431 print (arg
, "%s", f
->sign
? "-" : "+");
2434 case sim_fpu_class_qnan
:
2436 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2437 print (arg
, "*QuietNaN");
2439 case sim_fpu_class_snan
:
2441 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2442 print (arg
, "*SignalNaN");
2444 case sim_fpu_class_zero
:
2447 case sim_fpu_class_infinity
:
2450 case sim_fpu_class_number
:
2451 case sim_fpu_class_denorm
:
2453 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, print
, arg
);
2454 print (arg
, "*2^%+-5d", f
->normal_exp
);
2455 ASSERT (f
->fraction
>= IMPLICIT_1
);
2456 ASSERT (f
->fraction
< IMPLICIT_2
);
2461 INLINE_SIM_FPU (void)
2462 sim_fpu_print_status (int status
,
2463 sim_fpu_print_func
*print
,
2470 switch ((sim_fpu_status
) (status
& i
))
2472 case sim_fpu_status_denorm
:
2473 print (arg
, "%sD", prefix
);
2475 case sim_fpu_status_invalid_snan
:
2476 print (arg
, "%sSNaN", prefix
);
2478 case sim_fpu_status_invalid_qnan
:
2479 print (arg
, "%sQNaN", prefix
);
2481 case sim_fpu_status_invalid_isi
:
2482 print (arg
, "%sISI", prefix
);
2484 case sim_fpu_status_invalid_idi
:
2485 print (arg
, "%sIDI", prefix
);
2487 case sim_fpu_status_invalid_zdz
:
2488 print (arg
, "%sZDZ", prefix
);
2490 case sim_fpu_status_invalid_imz
:
2491 print (arg
, "%sIMZ", prefix
);
2493 case sim_fpu_status_invalid_cvi
:
2494 print (arg
, "%sCVI", prefix
);
2496 case sim_fpu_status_invalid_cmp
:
2497 print (arg
, "%sCMP", prefix
);
2499 case sim_fpu_status_invalid_sqrt
:
2500 print (arg
, "%sSQRT", prefix
);
2503 case sim_fpu_status_inexact
:
2504 print (arg
, "%sX", prefix
);
2507 case sim_fpu_status_overflow
:
2508 print (arg
, "%sO", prefix
);
2511 case sim_fpu_status_underflow
:
2512 print (arg
, "%sU", prefix
);
2515 case sim_fpu_status_invalid_div0
:
2516 print (arg
, "%s/", prefix
);
2519 case sim_fpu_status_rounded
:
2520 print (arg
, "%sR", prefix
);