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 1994-2021 Free Software Foundation, Inc.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* As a special exception, if you link this library with other files,
21 some of which are compiled with GCC, to produce an executable,
22 this library does not by itself cause the resulting executable
23 to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why
25 the executable file might be covered by the GNU General Public License. */
27 /* This implements IEEE 754 format arithmetic, but does not provide a
28 mechanism for setting the rounding mode, or for generating or handling
31 The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
32 Wilson, all of Cygnus Support. */
38 #include "sim-basics.h"
42 #include "sim-assert.h"
47 If digits is -1, then print all digits. */
50 print_bits (unsigned64 x
,
53 sim_fpu_print_func print
,
56 unsigned64 bit
= LSBIT64 (msbit
);
77 /* Quick and dirty conversion between a host double and host 64bit int. */
86 /* A packed IEEE floating point number.
88 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
89 32 and 64 bit numbers. This number is interpreted as:
91 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
92 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
94 Denormalized (0 == BIASEDEXP && FRAC != 0):
95 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
97 Zero (0 == BIASEDEXP && FRAC == 0):
98 (sign ? "-" : "+") 0.0
100 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
101 (sign ? "-" : "+") "infinity"
103 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
106 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
111 #define NR_EXPBITS (is_double ? 11 : 8)
112 #define NR_FRACBITS (is_double ? 52 : 23)
113 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
115 #define EXPMAX32 (255)
116 #define EXMPAX64 (2047)
117 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
119 #define EXPBIAS32 (127)
120 #define EXPBIAS64 (1023)
121 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
123 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
127 /* An unpacked floating point number.
129 When unpacked, the fraction of both a 32 and 64 bit floating point
130 number is stored using the same format:
132 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
133 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
135 #define NR_PAD32 (30)
137 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
138 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
140 #define NR_GUARDS32 (7 + NR_PAD32)
141 #define NR_GUARDS64 (8 + NR_PAD64)
142 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
143 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
145 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
146 #define GUARDLSB LSBIT64 (NR_PAD)
147 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
149 #define NR_FRAC_GUARD (60)
150 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
151 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
152 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
155 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
157 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
159 #define NORMAL_EXPMAX32 (EXPBIAS32)
160 #define NORMAL_EXPMAX64 (EXPBIAS64)
161 #define NORMAL_EXPMAX (EXPBIAS)
164 /* Integer constants */
166 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
167 #define MAX_UINT32 LSMASK64 (31, 0)
168 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
170 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
171 #define MAX_UINT64 LSMASK64 (63, 0)
172 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
174 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
175 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
176 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
177 #define NR_INTBITS (is_64bit ? 64 : 32)
179 /* Squeeze an unpacked sim_fpu struct into a 32/64 bit integer. */
180 STATIC_INLINE_SIM_FPU (unsigned64
)
181 pack_fpu (const sim_fpu
*src
,
192 case sim_fpu_class_qnan
:
195 /* Force fraction to correct class. */
196 fraction
= src
->fraction
;
197 fraction
>>= NR_GUARDS
;
198 #ifdef SIM_QUIET_NAN_NEGATED
199 fraction
|= QUIET_NAN
- 1;
201 fraction
|= QUIET_NAN
;
204 case sim_fpu_class_snan
:
207 /* Force fraction to correct class. */
208 fraction
= src
->fraction
;
209 fraction
>>= NR_GUARDS
;
210 #ifdef SIM_QUIET_NAN_NEGATED
211 fraction
|= QUIET_NAN
;
213 fraction
&= ~QUIET_NAN
;
216 case sim_fpu_class_infinity
:
221 case sim_fpu_class_zero
:
226 case sim_fpu_class_number
:
227 case sim_fpu_class_denorm
:
228 ASSERT (src
->fraction
>= IMPLICIT_1
);
229 ASSERT (src
->fraction
< IMPLICIT_2
);
230 if (src
->normal_exp
< NORMAL_EXPMIN
)
232 /* This number's exponent is too low to fit into the bits
233 available in the number We'll denormalize the number by
234 storing zero in the exponent and shift the fraction to
235 the right to make up for it. */
236 int nr_shift
= NORMAL_EXPMIN
- src
->normal_exp
;
237 if (nr_shift
> NR_FRACBITS
)
239 /* Underflow, just make the number zero. */
248 /* Shift by the value. */
249 fraction
= src
->fraction
;
250 fraction
>>= NR_GUARDS
;
251 fraction
>>= nr_shift
;
254 else if (src
->normal_exp
> NORMAL_EXPMAX
)
263 exp
= (src
->normal_exp
+ EXPBIAS
);
265 fraction
= src
->fraction
;
266 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
268 /* Round to nearest: If the guard bits are the all zero, but
269 the first, then we're half way between two numbers,
270 choose the one which makes the lsb of the answer 0. */
271 if ((fraction
& GUARDMASK
) == GUARDMSB
)
273 if ((fraction
& (GUARDMSB
<< 1)))
274 fraction
+= (GUARDMSB
<< 1);
278 /* Add a one to the guards to force round to nearest. */
279 fraction
+= GUARDROUND
;
281 if ((fraction
& IMPLICIT_2
)) /* Rounding resulted in carry. */
286 fraction
>>= NR_GUARDS
;
287 /* When exp == EXPMAX (overflow from carry) fraction must
288 have been made zero. */
289 ASSERT ((exp
== EXPMAX
) <= ((fraction
& ~IMPLICIT_1
) == 0));
296 packed
= ((sign
? SIGNBIT
: 0)
297 | (exp
<< NR_FRACBITS
)
298 | LSMASKED64 (fraction
, NR_FRACBITS
- 1, 0));
300 /* Trace operation. */
307 printf ("pack_fpu: ");
308 printf ("-> %c%0lX.%06lX\n",
309 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
310 (long) LSEXTRACTED32 (packed
, 30, 23),
311 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
319 /* Unpack a 32/64 bit integer into a sim_fpu structure. */
320 STATIC_INLINE_SIM_FPU (void)
321 unpack_fpu (sim_fpu
*dst
, unsigned64 packed
, int is_double
)
323 unsigned64 fraction
= LSMASKED64 (packed
, NR_FRACBITS
- 1, 0);
324 unsigned exp
= LSEXTRACTED64 (packed
, NR_EXPBITS
+ NR_FRACBITS
- 1, NR_FRACBITS
);
325 int sign
= (packed
& SIGNBIT
) != 0;
329 /* Hmm. Looks like 0 */
332 /* Tastes like zero. */
333 dst
->class = sim_fpu_class_zero
;
339 /* Zero exponent with non zero fraction - it's denormalized,
340 so there isn't a leading implicit one - we'll shift it so
342 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
343 dst
->class = sim_fpu_class_denorm
;
345 fraction
<<= NR_GUARDS
;
346 while (fraction
< IMPLICIT_1
)
351 dst
->fraction
= fraction
;
354 else if (exp
== EXPMAX
)
359 /* Attached to a zero fraction - means infinity. */
360 dst
->class = sim_fpu_class_infinity
;
362 /* dst->normal_exp = EXPBIAS; */
363 /* dst->fraction = 0; */
369 /* Non zero fraction, means NaN. */
371 dst
->fraction
= (fraction
<< NR_GUARDS
);
372 #ifdef SIM_QUIET_NAN_NEGATED
373 qnan
= (fraction
& QUIET_NAN
) == 0;
375 qnan
= fraction
>= QUIET_NAN
;
378 dst
->class = sim_fpu_class_qnan
;
380 dst
->class = sim_fpu_class_snan
;
385 /* Nothing strange about this number. */
386 dst
->class = sim_fpu_class_number
;
388 dst
->fraction
= ((fraction
<< NR_GUARDS
) | IMPLICIT_1
);
389 dst
->normal_exp
= exp
- EXPBIAS
;
392 /* Trace operation. */
399 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
400 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
401 (long) LSEXTRACTED32 (packed
, 30, 23),
402 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
409 val
.i
= pack_fpu (dst
, 1);
412 ASSERT (val
.i
== packed
);
416 unsigned32 val
= pack_fpu (dst
, 0);
417 unsigned32 org
= packed
;
424 /* Convert a floating point into an integer. */
425 STATIC_INLINE_SIM_FPU (int)
434 if (sim_fpu_is_zero (s
))
439 if (sim_fpu_is_snan (s
))
441 *i
= MIN_INT
; /* FIXME */
442 return sim_fpu_status_invalid_cvi
;
444 if (sim_fpu_is_qnan (s
))
446 *i
= MIN_INT
; /* FIXME */
447 return sim_fpu_status_invalid_cvi
;
449 /* Map infinity onto MAX_INT... */
450 if (sim_fpu_is_infinity (s
))
452 *i
= s
->sign
? MIN_INT
: MAX_INT
;
453 return sim_fpu_status_invalid_cvi
;
455 /* It is a number, but a small one. */
456 if (s
->normal_exp
< 0)
459 return sim_fpu_status_inexact
;
461 /* Is the floating point MIN_INT or just close? */
462 if (s
->sign
&& s
->normal_exp
== (NR_INTBITS
- 1))
465 ASSERT (s
->fraction
>= IMPLICIT_1
);
466 if (s
->fraction
== IMPLICIT_1
)
467 return 0; /* exact */
468 if (is_64bit
) /* can't round */
469 return sim_fpu_status_invalid_cvi
; /* must be overflow */
470 /* For a 32bit with MAX_INT, rounding is possible. */
473 case sim_fpu_round_default
:
475 case sim_fpu_round_zero
:
476 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
477 return sim_fpu_status_invalid_cvi
;
479 return sim_fpu_status_inexact
;
481 case sim_fpu_round_near
:
483 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
484 return sim_fpu_status_invalid_cvi
;
485 else if ((s
->fraction
& !FRAC32MASK
) >= (~FRAC32MASK
>> 1))
486 return sim_fpu_status_invalid_cvi
;
488 return sim_fpu_status_inexact
;
490 case sim_fpu_round_up
:
491 if ((s
->fraction
& FRAC32MASK
) == IMPLICIT_1
)
492 return sim_fpu_status_inexact
;
494 return sim_fpu_status_invalid_cvi
;
495 case sim_fpu_round_down
:
496 return sim_fpu_status_invalid_cvi
;
499 /* Would right shifting result in the FRAC being shifted into
500 (through) the integer's sign bit? */
501 if (s
->normal_exp
> (NR_INTBITS
- 2))
503 *i
= s
->sign
? MIN_INT
: MAX_INT
;
504 return sim_fpu_status_invalid_cvi
;
506 /* Normal number, shift it into place. */
508 shift
= (s
->normal_exp
- (NR_FRAC_GUARD
));
516 if (tmp
& ((SIGNED64 (1) << shift
) - 1))
517 status
|= sim_fpu_status_inexact
;
520 *i
= s
->sign
? (-tmp
) : (tmp
);
524 /* Convert an integer into a floating point. */
525 STATIC_INLINE_SIM_FPU (int)
526 i2fpu (sim_fpu
*f
, signed64 i
, int is_64bit
)
531 f
->class = sim_fpu_class_zero
;
537 f
->class = sim_fpu_class_number
;
539 f
->normal_exp
= NR_FRAC_GUARD
;
543 /* Special case for minint, since there is no corresponding
544 +ve integer representation for it. */
547 f
->fraction
= IMPLICIT_1
;
548 f
->normal_exp
= NR_INTBITS
- 1;
556 if (f
->fraction
>= IMPLICIT_2
)
560 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
563 while (f
->fraction
>= IMPLICIT_2
);
565 else if (f
->fraction
< IMPLICIT_1
)
572 while (f
->fraction
< IMPLICIT_1
);
576 /* trace operation */
579 printf ("i2fpu: 0x%08lX ->\n", (long) i
);
586 fpu2i (&val
, f
, is_64bit
, sim_fpu_round_zero
);
587 if (i
>= MIN_INT32
&& i
<= MAX_INT32
)
597 /* Convert a floating point into an integer. */
598 STATIC_INLINE_SIM_FPU (int)
599 fpu2u (unsigned64
*u
, const sim_fpu
*s
, int is_64bit
)
601 const int is_double
= 1;
604 if (sim_fpu_is_zero (s
))
609 if (sim_fpu_is_nan (s
))
614 /* It is a negative number. */
620 /* Get reasonable MAX_USI_INT... */
621 if (sim_fpu_is_infinity (s
))
626 /* It is a number, but a small one. */
627 if (s
->normal_exp
< 0)
633 if (s
->normal_exp
> (NR_INTBITS
- 1))
639 tmp
= (s
->fraction
& ~PADMASK
);
640 shift
= (s
->normal_exp
- (NR_FRACBITS
+ NR_GUARDS
));
654 /* Convert an unsigned integer into a floating point. */
655 STATIC_INLINE_SIM_FPU (int)
656 u2fpu (sim_fpu
*f
, unsigned64 u
, int is_64bit
)
660 f
->class = sim_fpu_class_zero
;
666 f
->class = sim_fpu_class_number
;
668 f
->normal_exp
= NR_FRAC_GUARD
;
671 while (f
->fraction
< IMPLICIT_1
)
681 /* register <-> sim_fpu */
683 INLINE_SIM_FPU (void)
684 sim_fpu_32to (sim_fpu
*f
, unsigned32 s
)
686 unpack_fpu (f
, s
, 0);
690 INLINE_SIM_FPU (void)
691 sim_fpu_232to (sim_fpu
*f
, unsigned32 h
, unsigned32 l
)
695 unpack_fpu (f
, s
, 1);
699 INLINE_SIM_FPU (void)
700 sim_fpu_64to (sim_fpu
*f
, unsigned64 s
)
702 unpack_fpu (f
, s
, 1);
706 INLINE_SIM_FPU (void)
707 sim_fpu_to32 (unsigned32
*s
,
710 *s
= pack_fpu (f
, 0);
714 INLINE_SIM_FPU (void)
715 sim_fpu_to232 (unsigned32
*h
, unsigned32
*l
,
718 unsigned64 s
= pack_fpu (f
, 1);
724 INLINE_SIM_FPU (void)
725 sim_fpu_to64 (unsigned64
*u
,
728 *u
= pack_fpu (f
, 1);
732 INLINE_SIM_FPU (void)
733 sim_fpu_fractionto (sim_fpu
*f
,
739 int shift
= (NR_FRAC_GUARD
- precision
);
740 f
->class = sim_fpu_class_number
;
742 f
->normal_exp
= normal_exp
;
743 /* Shift the fraction to where sim-fpu expects it. */
745 f
->fraction
= (fraction
<< shift
);
747 f
->fraction
= (fraction
>> -shift
);
748 f
->fraction
|= IMPLICIT_1
;
752 INLINE_SIM_FPU (unsigned64
)
753 sim_fpu_tofraction (const sim_fpu
*d
,
756 /* We have NR_FRAC_GUARD bits, we want only PRECISION bits. */
757 int shift
= (NR_FRAC_GUARD
- precision
);
758 unsigned64 fraction
= (d
->fraction
& ~IMPLICIT_1
);
760 return fraction
>> shift
;
762 return fraction
<< -shift
;
768 STATIC_INLINE_SIM_FPU (int)
769 do_normal_overflow (sim_fpu
*f
,
775 case sim_fpu_round_default
:
777 case sim_fpu_round_near
:
778 f
->class = sim_fpu_class_infinity
;
780 case sim_fpu_round_up
:
782 f
->class = sim_fpu_class_infinity
;
784 case sim_fpu_round_down
:
786 f
->class = sim_fpu_class_infinity
;
788 case sim_fpu_round_zero
:
791 f
->normal_exp
= NORMAL_EXPMAX
;
792 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
793 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
796 STATIC_INLINE_SIM_FPU (int)
797 do_normal_underflow (sim_fpu
*f
,
803 case sim_fpu_round_default
:
805 case sim_fpu_round_near
:
806 f
->class = sim_fpu_class_zero
;
808 case sim_fpu_round_up
:
810 f
->class = sim_fpu_class_zero
;
812 case sim_fpu_round_down
:
814 f
->class = sim_fpu_class_zero
;
816 case sim_fpu_round_zero
:
817 f
->class = sim_fpu_class_zero
;
820 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
821 f
->fraction
= IMPLICIT_1
;
822 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
827 /* Round a number using NR_GUARDS.
828 Will return the rounded number or F->FRACTION == 0 when underflow. */
830 STATIC_INLINE_SIM_FPU (int)
831 do_normal_round (sim_fpu
*f
,
835 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
836 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
837 unsigned64 fraclsb
= guardmsb
<< 1;
838 if ((f
->fraction
& guardmask
))
840 int status
= sim_fpu_status_inexact
;
843 case sim_fpu_round_default
:
845 case sim_fpu_round_near
:
846 if ((f
->fraction
& guardmsb
))
848 if ((f
->fraction
& fraclsb
))
850 status
|= sim_fpu_status_rounded
;
852 else if ((f
->fraction
& (guardmask
>> 1)))
854 status
|= sim_fpu_status_rounded
;
858 case sim_fpu_round_up
:
860 status
|= sim_fpu_status_rounded
;
862 case sim_fpu_round_down
:
864 status
|= sim_fpu_status_rounded
;
866 case sim_fpu_round_zero
:
869 f
->fraction
&= ~guardmask
;
870 /* Round if needed, handle resulting overflow. */
871 if ((status
& sim_fpu_status_rounded
))
873 f
->fraction
+= fraclsb
;
874 if ((f
->fraction
& IMPLICIT_2
))
887 STATIC_INLINE_SIM_FPU (int)
888 do_round (sim_fpu
*f
,
891 sim_fpu_denorm denorm
)
895 case sim_fpu_class_qnan
:
896 case sim_fpu_class_zero
:
897 case sim_fpu_class_infinity
:
900 case sim_fpu_class_snan
:
901 /* Quieten a SignalingNaN. */
902 f
->class = sim_fpu_class_qnan
;
903 return sim_fpu_status_invalid_snan
;
905 case sim_fpu_class_number
:
906 case sim_fpu_class_denorm
:
909 ASSERT (f
->fraction
< IMPLICIT_2
);
910 ASSERT (f
->fraction
>= IMPLICIT_1
);
911 if (f
->normal_exp
< NORMAL_EXPMIN
)
913 /* This number's exponent is too low to fit into the bits
914 available in the number. Round off any bits that will be
915 discarded as a result of denormalization. Edge case is
916 the implicit bit shifted to GUARD0 and then rounded
918 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
919 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
920 && !(denorm
& sim_fpu_denorm_zero
))
922 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
923 if (f
->fraction
== 0) /* Rounding underflowed. */
925 status
|= do_normal_underflow (f
, is_double
, round
);
927 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
929 status
|= sim_fpu_status_denorm
;
930 /* Any loss of precision when denormalizing is
931 underflow. Some processors check for underflow
932 before rounding, some after! */
933 if (status
& sim_fpu_status_inexact
)
934 status
|= sim_fpu_status_underflow
;
935 /* Flag that resultant value has been denormalized. */
936 f
->class = sim_fpu_class_denorm
;
938 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
940 if ((status
& sim_fpu_status_inexact
))
941 status
|= sim_fpu_status_underflow
;
946 status
= do_normal_underflow (f
, is_double
, round
);
949 else if (f
->normal_exp
> NORMAL_EXPMAX
)
952 status
= do_normal_overflow (f
, is_double
, round
);
956 status
= do_normal_round (f
, NR_GUARDS
, round
);
957 if (f
->fraction
== 0)
958 /* f->class = sim_fpu_class_zero; */
959 status
|= do_normal_underflow (f
, is_double
, round
);
960 else if (f
->normal_exp
> NORMAL_EXPMAX
)
961 /* Oops! rounding caused overflow. */
962 status
|= do_normal_overflow (f
, is_double
, round
);
964 ASSERT ((f
->class == sim_fpu_class_number
965 || f
->class == sim_fpu_class_denorm
)
966 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
974 sim_fpu_round_32 (sim_fpu
*f
,
976 sim_fpu_denorm denorm
)
978 return do_round (f
, 0, round
, denorm
);
982 sim_fpu_round_64 (sim_fpu
*f
,
984 sim_fpu_denorm denorm
)
986 return do_round (f
, 1, round
, denorm
);
994 sim_fpu_add (sim_fpu
*f
,
998 if (sim_fpu_is_snan (l
))
1001 f
->class = sim_fpu_class_qnan
;
1002 return sim_fpu_status_invalid_snan
;
1004 if (sim_fpu_is_snan (r
))
1007 f
->class = sim_fpu_class_qnan
;
1008 return sim_fpu_status_invalid_snan
;
1010 if (sim_fpu_is_qnan (l
))
1015 if (sim_fpu_is_qnan (r
))
1020 if (sim_fpu_is_infinity (l
))
1022 if (sim_fpu_is_infinity (r
)
1023 && l
->sign
!= r
->sign
)
1026 return sim_fpu_status_invalid_isi
;
1031 if (sim_fpu_is_infinity (r
))
1036 if (sim_fpu_is_zero (l
))
1038 if (sim_fpu_is_zero (r
))
1041 f
->sign
= l
->sign
& r
->sign
;
1047 if (sim_fpu_is_zero (r
))
1054 int shift
= l
->normal_exp
- r
->normal_exp
;
1055 unsigned64 lfraction
;
1056 unsigned64 rfraction
;
1057 /* use exp of larger */
1058 if (shift
>= NR_FRAC_GUARD
)
1060 /* left has much bigger magnitude */
1062 return sim_fpu_status_inexact
;
1064 if (shift
<= - NR_FRAC_GUARD
)
1066 /* right has much bigger magnitude */
1068 return sim_fpu_status_inexact
;
1070 lfraction
= l
->fraction
;
1071 rfraction
= r
->fraction
;
1074 f
->normal_exp
= l
->normal_exp
;
1075 if (rfraction
& LSMASK64 (shift
- 1, 0))
1077 status
|= sim_fpu_status_inexact
;
1078 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1080 rfraction
>>= shift
;
1084 f
->normal_exp
= r
->normal_exp
;
1085 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1087 status
|= sim_fpu_status_inexact
;
1088 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1090 lfraction
>>= -shift
;
1094 f
->normal_exp
= r
->normal_exp
;
1097 /* Perform the addition. */
1099 lfraction
= - lfraction
;
1101 rfraction
= - rfraction
;
1102 f
->fraction
= lfraction
+ rfraction
;
1105 if (f
->fraction
== 0)
1112 f
->class = sim_fpu_class_number
;
1113 if (((signed64
) f
->fraction
) >= 0)
1118 f
->fraction
= - f
->fraction
;
1122 if ((f
->fraction
& IMPLICIT_2
))
1124 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1127 else if (f
->fraction
< IMPLICIT_1
)
1134 while (f
->fraction
< IMPLICIT_1
);
1136 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1142 INLINE_SIM_FPU (int)
1143 sim_fpu_sub (sim_fpu
*f
,
1147 if (sim_fpu_is_snan (l
))
1150 f
->class = sim_fpu_class_qnan
;
1151 return sim_fpu_status_invalid_snan
;
1153 if (sim_fpu_is_snan (r
))
1156 f
->class = sim_fpu_class_qnan
;
1157 return sim_fpu_status_invalid_snan
;
1159 if (sim_fpu_is_qnan (l
))
1164 if (sim_fpu_is_qnan (r
))
1169 if (sim_fpu_is_infinity (l
))
1171 if (sim_fpu_is_infinity (r
)
1172 && l
->sign
== r
->sign
)
1175 return sim_fpu_status_invalid_isi
;
1180 if (sim_fpu_is_infinity (r
))
1186 if (sim_fpu_is_zero (l
))
1188 if (sim_fpu_is_zero (r
))
1191 f
->sign
= l
->sign
& !r
->sign
;
1200 if (sim_fpu_is_zero (r
))
1207 int shift
= l
->normal_exp
- r
->normal_exp
;
1208 unsigned64 lfraction
;
1209 unsigned64 rfraction
;
1210 /* use exp of larger */
1211 if (shift
>= NR_FRAC_GUARD
)
1213 /* left has much bigger magnitude */
1215 return sim_fpu_status_inexact
;
1217 if (shift
<= - NR_FRAC_GUARD
)
1219 /* right has much bigger magnitude */
1222 return sim_fpu_status_inexact
;
1224 lfraction
= l
->fraction
;
1225 rfraction
= r
->fraction
;
1228 f
->normal_exp
= l
->normal_exp
;
1229 if (rfraction
& LSMASK64 (shift
- 1, 0))
1231 status
|= sim_fpu_status_inexact
;
1232 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1234 rfraction
>>= shift
;
1238 f
->normal_exp
= r
->normal_exp
;
1239 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1241 status
|= sim_fpu_status_inexact
;
1242 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1244 lfraction
>>= -shift
;
1248 f
->normal_exp
= r
->normal_exp
;
1251 /* Perform the subtraction. */
1253 lfraction
= - lfraction
;
1255 rfraction
= - rfraction
;
1256 f
->fraction
= lfraction
+ rfraction
;
1259 if (f
->fraction
== 0)
1266 f
->class = sim_fpu_class_number
;
1267 if (((signed64
) f
->fraction
) >= 0)
1272 f
->fraction
= - f
->fraction
;
1276 if ((f
->fraction
& IMPLICIT_2
))
1278 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1281 else if (f
->fraction
< IMPLICIT_1
)
1288 while (f
->fraction
< IMPLICIT_1
);
1290 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1296 INLINE_SIM_FPU (int)
1297 sim_fpu_mul (sim_fpu
*f
,
1301 if (sim_fpu_is_snan (l
))
1304 f
->class = sim_fpu_class_qnan
;
1305 return sim_fpu_status_invalid_snan
;
1307 if (sim_fpu_is_snan (r
))
1310 f
->class = sim_fpu_class_qnan
;
1311 return sim_fpu_status_invalid_snan
;
1313 if (sim_fpu_is_qnan (l
))
1318 if (sim_fpu_is_qnan (r
))
1323 if (sim_fpu_is_infinity (l
))
1325 if (sim_fpu_is_zero (r
))
1328 return sim_fpu_status_invalid_imz
;
1331 f
->sign
= l
->sign
^ r
->sign
;
1334 if (sim_fpu_is_infinity (r
))
1336 if (sim_fpu_is_zero (l
))
1339 return sim_fpu_status_invalid_imz
;
1342 f
->sign
= l
->sign
^ r
->sign
;
1345 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1348 f
->sign
= l
->sign
^ r
->sign
;
1351 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1356 unsigned64 nl
= l
->fraction
& 0xffffffff;
1357 unsigned64 nh
= l
->fraction
>> 32;
1358 unsigned64 ml
= r
->fraction
& 0xffffffff;
1359 unsigned64 mh
= r
->fraction
>>32;
1360 unsigned64 pp_ll
= ml
* nl
;
1361 unsigned64 pp_hl
= mh
* nl
;
1362 unsigned64 pp_lh
= ml
* nh
;
1363 unsigned64 pp_hh
= mh
* nh
;
1364 unsigned64 res2
= 0;
1365 unsigned64 res0
= 0;
1366 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1367 if (ps_hh__
< pp_hl
)
1368 res2
+= UNSIGNED64 (0x100000000);
1369 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1370 res0
= pp_ll
+ pp_hl
;
1373 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1377 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1378 f
->sign
= l
->sign
^ r
->sign
;
1379 f
->class = sim_fpu_class_number
;
1381 /* Input is bounded by [1,2) ; [2^60,2^61)
1382 Output is bounded by [1,4) ; [2^120,2^122) */
1384 /* Adjust the exponent according to where the decimal point ended
1385 up in the high 64 bit word. In the source the decimal point
1386 was at NR_FRAC_GUARD. */
1387 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1389 /* The high word is bounded according to the above. Consequently
1390 it has never overflowed into IMPLICIT_2. */
1391 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1392 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1393 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1400 if (low
& LSBIT64 (63))
1404 while (high
< IMPLICIT_1
);
1406 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1409 f
->fraction
= (high
| 1); /* sticky */
1410 return sim_fpu_status_inexact
;
1421 INLINE_SIM_FPU (int)
1422 sim_fpu_div (sim_fpu
*f
,
1426 if (sim_fpu_is_snan (l
))
1429 f
->class = sim_fpu_class_qnan
;
1430 return sim_fpu_status_invalid_snan
;
1432 if (sim_fpu_is_snan (r
))
1435 f
->class = sim_fpu_class_qnan
;
1436 return sim_fpu_status_invalid_snan
;
1438 if (sim_fpu_is_qnan (l
))
1441 f
->class = sim_fpu_class_qnan
;
1444 if (sim_fpu_is_qnan (r
))
1447 f
->class = sim_fpu_class_qnan
;
1450 if (sim_fpu_is_infinity (l
))
1452 if (sim_fpu_is_infinity (r
))
1455 return sim_fpu_status_invalid_idi
;
1460 f
->sign
= l
->sign
^ r
->sign
;
1464 if (sim_fpu_is_zero (l
))
1466 if (sim_fpu_is_zero (r
))
1469 return sim_fpu_status_invalid_zdz
;
1474 f
->sign
= l
->sign
^ r
->sign
;
1478 if (sim_fpu_is_infinity (r
))
1481 f
->sign
= l
->sign
^ r
->sign
;
1484 if (sim_fpu_is_zero (r
))
1486 f
->class = sim_fpu_class_infinity
;
1487 f
->sign
= l
->sign
^ r
->sign
;
1488 return sim_fpu_status_invalid_div0
;
1491 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1494 /* quotient = ( ( numerator / denominator)
1495 x 2^(numerator exponent - denominator exponent)
1497 unsigned64 numerator
;
1498 unsigned64 denominator
;
1499 unsigned64 quotient
;
1502 f
->class = sim_fpu_class_number
;
1503 f
->sign
= l
->sign
^ r
->sign
;
1504 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1506 numerator
= l
->fraction
;
1507 denominator
= r
->fraction
;
1509 /* Fraction will be less than 1.0 */
1510 if (numerator
< denominator
)
1515 ASSERT (numerator
>= denominator
);
1517 /* Gain extra precision, already used one spare bit. */
1518 numerator
<<= NR_SPARE
;
1519 denominator
<<= NR_SPARE
;
1521 /* Does divide one bit at a time. Optimize??? */
1523 bit
= (IMPLICIT_1
<< NR_SPARE
);
1526 if (numerator
>= denominator
)
1529 numerator
-= denominator
;
1535 /* Discard (but save) the extra bits. */
1536 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1537 quotient
= (quotient
>> NR_SPARE
) | 1;
1539 quotient
= (quotient
>> NR_SPARE
);
1541 f
->fraction
= quotient
;
1542 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1545 f
->fraction
|= 1; /* Stick remaining bits. */
1546 return sim_fpu_status_inexact
;
1554 INLINE_SIM_FPU (int)
1555 sim_fpu_rem (sim_fpu
*f
,
1559 if (sim_fpu_is_snan (l
))
1562 f
->class = sim_fpu_class_qnan
;
1563 return sim_fpu_status_invalid_snan
;
1565 if (sim_fpu_is_snan (r
))
1568 f
->class = sim_fpu_class_qnan
;
1569 return sim_fpu_status_invalid_snan
;
1571 if (sim_fpu_is_qnan (l
))
1574 f
->class = sim_fpu_class_qnan
;
1577 if (sim_fpu_is_qnan (r
))
1580 f
->class = sim_fpu_class_qnan
;
1583 if (sim_fpu_is_infinity (l
))
1586 return sim_fpu_status_invalid_irx
;
1588 if (sim_fpu_is_zero (r
))
1591 return sim_fpu_status_invalid_div0
;
1593 if (sim_fpu_is_zero (l
))
1598 if (sim_fpu_is_infinity (r
))
1606 /* Remainder is calculated as l-n*r, where n is l/r rounded to the
1607 nearest integer. The variable n is rounded half even. */
1609 sim_fpu_div (&n
, l
, r
);
1610 sim_fpu_round_64 (&n
, 0, 0);
1612 if (n
.normal_exp
< -1) /* If n looks like zero just return l. */
1617 else if (n
.class == sim_fpu_class_number
1618 && n
.normal_exp
<= (NR_FRAC_GUARD
)) /* If not too large round. */
1619 do_normal_round (&n
, (NR_FRAC_GUARD
) - n
.normal_exp
, sim_fpu_round_near
);
1621 /* Mark 0's as zero so multiply can detect zero. */
1622 if (n
.fraction
== 0)
1623 n
.class = sim_fpu_class_zero
;
1625 /* Calculate n*r. */
1626 sim_fpu_mul (&tmp
, &n
, r
);
1627 sim_fpu_round_64 (&tmp
, 0, 0);
1629 /* Finally calculate l-n*r. */
1630 sim_fpu_sub (f
, l
, &tmp
);
1637 INLINE_SIM_FPU (int)
1638 sim_fpu_max (sim_fpu
*f
,
1642 if (sim_fpu_is_snan (l
))
1645 f
->class = sim_fpu_class_qnan
;
1646 return sim_fpu_status_invalid_snan
;
1648 if (sim_fpu_is_snan (r
))
1651 f
->class = sim_fpu_class_qnan
;
1652 return sim_fpu_status_invalid_snan
;
1654 if (sim_fpu_is_qnan (l
))
1659 if (sim_fpu_is_qnan (r
))
1664 if (sim_fpu_is_infinity (l
))
1666 if (sim_fpu_is_infinity (r
)
1667 && l
->sign
== r
->sign
)
1670 return sim_fpu_status_invalid_isi
;
1673 *f
= *r
; /* -inf < anything */
1675 *f
= *l
; /* +inf > anything */
1678 if (sim_fpu_is_infinity (r
))
1681 *f
= *l
; /* anything > -inf */
1683 *f
= *r
; /* anything < +inf */
1686 if (l
->sign
> r
->sign
)
1688 *f
= *r
; /* -ve < +ve */
1691 if (l
->sign
< r
->sign
)
1693 *f
= *l
; /* +ve > -ve */
1696 ASSERT (l
->sign
== r
->sign
);
1697 if (l
->normal_exp
> r
->normal_exp
1698 || (l
->normal_exp
== r
->normal_exp
1699 && l
->fraction
> r
->fraction
))
1703 *f
= *r
; /* -ve < -ve */
1705 *f
= *l
; /* +ve > +ve */
1712 *f
= *l
; /* -ve > -ve */
1714 *f
= *r
; /* +ve < +ve */
1720 INLINE_SIM_FPU (int)
1721 sim_fpu_min (sim_fpu
*f
,
1725 if (sim_fpu_is_snan (l
))
1728 f
->class = sim_fpu_class_qnan
;
1729 return sim_fpu_status_invalid_snan
;
1731 if (sim_fpu_is_snan (r
))
1734 f
->class = sim_fpu_class_qnan
;
1735 return sim_fpu_status_invalid_snan
;
1737 if (sim_fpu_is_qnan (l
))
1742 if (sim_fpu_is_qnan (r
))
1747 if (sim_fpu_is_infinity (l
))
1749 if (sim_fpu_is_infinity (r
)
1750 && l
->sign
== r
->sign
)
1753 return sim_fpu_status_invalid_isi
;
1756 *f
= *l
; /* -inf < anything */
1758 *f
= *r
; /* +inf > anthing */
1761 if (sim_fpu_is_infinity (r
))
1764 *f
= *r
; /* anything > -inf */
1766 *f
= *l
; /* anything < +inf */
1769 if (l
->sign
> r
->sign
)
1771 *f
= *l
; /* -ve < +ve */
1774 if (l
->sign
< r
->sign
)
1776 *f
= *r
; /* +ve > -ve */
1779 ASSERT (l
->sign
== r
->sign
);
1780 if (l
->normal_exp
> r
->normal_exp
1781 || (l
->normal_exp
== r
->normal_exp
1782 && l
->fraction
> r
->fraction
))
1786 *f
= *l
; /* -ve < -ve */
1788 *f
= *r
; /* +ve > +ve */
1795 *f
= *r
; /* -ve > -ve */
1797 *f
= *l
; /* +ve < +ve */
1803 INLINE_SIM_FPU (int)
1804 sim_fpu_neg (sim_fpu
*f
,
1807 if (sim_fpu_is_snan (r
))
1810 f
->class = sim_fpu_class_qnan
;
1811 return sim_fpu_status_invalid_snan
;
1813 if (sim_fpu_is_qnan (r
))
1824 INLINE_SIM_FPU (int)
1825 sim_fpu_abs (sim_fpu
*f
,
1830 if (sim_fpu_is_snan (r
))
1832 f
->class = sim_fpu_class_qnan
;
1833 return sim_fpu_status_invalid_snan
;
1839 INLINE_SIM_FPU (int)
1840 sim_fpu_inv (sim_fpu
*f
,
1843 return sim_fpu_div (f
, &sim_fpu_one
, r
);
1847 INLINE_SIM_FPU (int)
1848 sim_fpu_sqrt (sim_fpu
*f
,
1851 if (sim_fpu_is_snan (r
))
1854 return sim_fpu_status_invalid_snan
;
1856 if (sim_fpu_is_qnan (r
))
1861 if (sim_fpu_is_zero (r
))
1863 f
->class = sim_fpu_class_zero
;
1868 if (sim_fpu_is_infinity (r
))
1873 return sim_fpu_status_invalid_sqrt
;
1877 f
->class = sim_fpu_class_infinity
;
1886 return sim_fpu_status_invalid_sqrt
;
1889 /* @(#)e_sqrt.c 5.1 93/09/24 */
1891 * ====================================================
1892 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1894 * Developed at SunPro, a Sun Microsystems, Inc. business.
1895 * Permission to use, copy, modify, and distribute this
1896 * software is freely granted, provided that this notice
1898 * ====================================================
1901 /* __ieee754_sqrt(x)
1902 * Return correctly rounded sqrt.
1903 * ------------------------------------------
1904 * | Use the hardware sqrt if you have one |
1905 * ------------------------------------------
1907 * Bit by bit method using integer arithmetic. (Slow, but portable)
1909 * Scale x to y in [1,4) with even powers of 2:
1910 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1911 * sqrt(x) = 2^k * sqrt(y)
1914 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1915 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1917 - y = ((m even) ? x : 2.x)
1919 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1921 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1923 * 2. Bit by bit computation
1924 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1927 * s = 2*q , and y = 2 * ( y - q ). (1)
1930 * To compute q from q , one checks whether
1934 * (q + 2 ) <= y. (2)
1937 * If (2) is false, then q = q ; otherwise q = q + 2 .
1940 * With some algebraic manipulation, it is not difficult to see
1941 * that (2) is equivalent to
1946 * The advantage of (3) is that s and y can be computed by
1948 * the following recurrence formula:
1951 * s = s , y = y ; (4)
1960 * s = s + 2 , y = y - s - 2 (5)
1965 - NOTE: y = 2 (y - s - 2 )
1968 * One may easily use induction to prove (4) and (5).
1969 * Note. Since the left hand side of (3) contain only i+2 bits,
1970 * it does not necessary to do a full (53-bit) comparison
1973 * After generating the 53 bits result, we compute one more bit.
1974 * Together with the remainder, we can decide whether the
1975 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1976 * (it will never equal to 1/2ulp).
1977 * The rounding mode can be detected by checking whether
1978 * huge + tiny is equal to huge, and whether huge - tiny is
1979 * equal to huge for some floating point number "huge" and "tiny".
1982 * sqrt(+-0) = +-0 ... exact
1984 * sqrt(-ve) = NaN ... with invalid signal
1985 * sqrt(NaN) = NaN ... with invalid signal for signalling NaN
1987 * Other methods : see the appended file at the end of the program below.
1992 /* Generate sqrt(x) bit by bit. */
1998 f
->class = sim_fpu_class_number
;
2001 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
2003 /* Odd exp, double x to make it even. */
2004 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
2005 if ((r
->normal_exp
& 1))
2009 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
2011 /* Let loop determine first value of s (either 1 or 2) */
2018 unsigned64 t
= s
+ b
;
2029 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
2033 f
->fraction
|= 1; /* Stick remaining bits. */
2034 return sim_fpu_status_inexact
;
2042 /* int/long <-> sim_fpu */
2044 INLINE_SIM_FPU (int)
2045 sim_fpu_i32to (sim_fpu
*f
,
2047 sim_fpu_round round
)
2053 INLINE_SIM_FPU (int)
2054 sim_fpu_u32to (sim_fpu
*f
,
2056 sim_fpu_round round
)
2062 INLINE_SIM_FPU (int)
2063 sim_fpu_i64to (sim_fpu
*f
,
2065 sim_fpu_round round
)
2071 INLINE_SIM_FPU (int)
2072 sim_fpu_u64to (sim_fpu
*f
,
2074 sim_fpu_round round
)
2081 INLINE_SIM_FPU (int)
2082 sim_fpu_to32i (signed32
*i
,
2084 sim_fpu_round round
)
2087 int status
= fpu2i (&i64
, f
, 0, round
);
2092 INLINE_SIM_FPU (int)
2093 sim_fpu_to32u (unsigned32
*u
,
2095 sim_fpu_round round
)
2098 int status
= fpu2u (&u64
, f
, 0);
2103 INLINE_SIM_FPU (int)
2104 sim_fpu_to64i (signed64
*i
,
2106 sim_fpu_round round
)
2108 return fpu2i (i
, f
, 1, round
);
2112 INLINE_SIM_FPU (int)
2113 sim_fpu_to64u (unsigned64
*u
,
2115 sim_fpu_round round
)
2117 return fpu2u (u
, f
, 1);
2122 /* sim_fpu -> host format */
2125 INLINE_SIM_FPU (float)
2126 sim_fpu_2f (const sim_fpu
*f
)
2133 INLINE_SIM_FPU (double)
2134 sim_fpu_2d (const sim_fpu
*s
)
2137 if (sim_fpu_is_snan (s
))
2141 n
.class = sim_fpu_class_qnan
;
2142 val
.i
= pack_fpu (&n
, 1);
2146 val
.i
= pack_fpu (s
, 1);
2153 INLINE_SIM_FPU (void)
2154 sim_fpu_f2 (sim_fpu
*f
,
2159 unpack_fpu (f
, val
.i
, 1);
2164 INLINE_SIM_FPU (void)
2165 sim_fpu_d2 (sim_fpu
*f
,
2170 unpack_fpu (f
, val
.i
, 1);
2176 INLINE_SIM_FPU (int)
2177 sim_fpu_is_nan (const sim_fpu
*d
)
2181 case sim_fpu_class_qnan
:
2182 case sim_fpu_class_snan
:
2189 INLINE_SIM_FPU (int)
2190 sim_fpu_is_qnan (const sim_fpu
*d
)
2194 case sim_fpu_class_qnan
:
2201 INLINE_SIM_FPU (int)
2202 sim_fpu_is_snan (const sim_fpu
*d
)
2206 case sim_fpu_class_snan
:
2213 INLINE_SIM_FPU (int)
2214 sim_fpu_is_zero (const sim_fpu
*d
)
2218 case sim_fpu_class_zero
:
2225 INLINE_SIM_FPU (int)
2226 sim_fpu_is_infinity (const sim_fpu
*d
)
2230 case sim_fpu_class_infinity
:
2237 INLINE_SIM_FPU (int)
2238 sim_fpu_is_number (const sim_fpu
*d
)
2242 case sim_fpu_class_denorm
:
2243 case sim_fpu_class_number
:
2250 INLINE_SIM_FPU (int)
2251 sim_fpu_is_denorm (const sim_fpu
*d
)
2255 case sim_fpu_class_denorm
:
2263 INLINE_SIM_FPU (int)
2264 sim_fpu_sign (const sim_fpu
*d
)
2270 INLINE_SIM_FPU (int)
2271 sim_fpu_exp (const sim_fpu
*d
)
2273 return d
->normal_exp
;
2277 INLINE_SIM_FPU (unsigned64
)
2278 sim_fpu_fraction (const sim_fpu
*d
)
2284 INLINE_SIM_FPU (unsigned64
)
2285 sim_fpu_guard (const sim_fpu
*d
, int is_double
)
2288 unsigned64 guardmask
= LSMASK64 (NR_GUARDS
- 1, 0);
2289 rv
= (d
->fraction
& guardmask
) >> NR_PAD
;
2294 INLINE_SIM_FPU (int)
2295 sim_fpu_is (const sim_fpu
*d
)
2299 case sim_fpu_class_qnan
:
2300 return SIM_FPU_IS_QNAN
;
2301 case sim_fpu_class_snan
:
2302 return SIM_FPU_IS_SNAN
;
2303 case sim_fpu_class_infinity
:
2305 return SIM_FPU_IS_NINF
;
2307 return SIM_FPU_IS_PINF
;
2308 case sim_fpu_class_number
:
2310 return SIM_FPU_IS_NNUMBER
;
2312 return SIM_FPU_IS_PNUMBER
;
2313 case sim_fpu_class_denorm
:
2315 return SIM_FPU_IS_NDENORM
;
2317 return SIM_FPU_IS_PDENORM
;
2318 case sim_fpu_class_zero
:
2320 return SIM_FPU_IS_NZERO
;
2322 return SIM_FPU_IS_PZERO
;
2329 INLINE_SIM_FPU (int)
2330 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2333 sim_fpu_sub (&res
, l
, r
);
2334 return sim_fpu_is (&res
);
2337 INLINE_SIM_FPU (int)
2338 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2341 sim_fpu_lt (&status
, l
, r
);
2345 INLINE_SIM_FPU (int)
2346 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2349 sim_fpu_le (&is
, l
, r
);
2353 INLINE_SIM_FPU (int)
2354 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2357 sim_fpu_eq (&is
, l
, r
);
2361 INLINE_SIM_FPU (int)
2362 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2365 sim_fpu_ne (&is
, l
, r
);
2369 INLINE_SIM_FPU (int)
2370 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2373 sim_fpu_ge (&is
, l
, r
);
2377 INLINE_SIM_FPU (int)
2378 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2381 sim_fpu_gt (&is
, l
, r
);
2386 /* Compare operators */
2388 INLINE_SIM_FPU (int)
2389 sim_fpu_lt (int *is
,
2393 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2397 lval
.i
= pack_fpu (l
, 1);
2398 rval
.i
= pack_fpu (r
, 1);
2399 (*is
) = (lval
.d
< rval
.d
);
2402 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2405 return sim_fpu_status_invalid_snan
;
2410 return sim_fpu_status_invalid_qnan
;
2414 INLINE_SIM_FPU (int)
2415 sim_fpu_le (int *is
,
2419 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2423 lval
.i
= pack_fpu (l
, 1);
2424 rval
.i
= pack_fpu (r
, 1);
2425 *is
= (lval
.d
<= rval
.d
);
2428 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2431 return sim_fpu_status_invalid_snan
;
2436 return sim_fpu_status_invalid_qnan
;
2440 INLINE_SIM_FPU (int)
2441 sim_fpu_eq (int *is
,
2445 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2449 lval
.i
= pack_fpu (l
, 1);
2450 rval
.i
= pack_fpu (r
, 1);
2451 (*is
) = (lval
.d
== rval
.d
);
2454 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2457 return sim_fpu_status_invalid_snan
;
2462 return sim_fpu_status_invalid_qnan
;
2466 INLINE_SIM_FPU (int)
2467 sim_fpu_ne (int *is
,
2471 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2475 lval
.i
= pack_fpu (l
, 1);
2476 rval
.i
= pack_fpu (r
, 1);
2477 (*is
) = (lval
.d
!= rval
.d
);
2480 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2483 return sim_fpu_status_invalid_snan
;
2488 return sim_fpu_status_invalid_qnan
;
2492 INLINE_SIM_FPU (int)
2493 sim_fpu_ge (int *is
,
2497 return sim_fpu_le (is
, r
, l
);
2500 INLINE_SIM_FPU (int)
2501 sim_fpu_gt (int *is
,
2505 return sim_fpu_lt (is
, r
, l
);
2509 /* A number of useful constants */
2511 #if EXTERN_SIM_FPU_P
2512 const sim_fpu sim_fpu_zero
= {
2513 sim_fpu_class_zero
, 0, 0, 0
2515 const sim_fpu sim_fpu_qnan
= {
2516 sim_fpu_class_qnan
, 0, 0, 0
2518 const sim_fpu sim_fpu_one
= {
2519 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2521 const sim_fpu sim_fpu_two
= {
2522 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2524 const sim_fpu sim_fpu_max32
= {
2525 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2527 const sim_fpu sim_fpu_max64
= {
2528 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2535 INLINE_SIM_FPU (void)
2536 sim_fpu_print_fpu (const sim_fpu
*f
,
2537 sim_fpu_print_func
*print
,
2540 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2543 INLINE_SIM_FPU (void)
2544 sim_fpu_printn_fpu (const sim_fpu
*f
,
2545 sim_fpu_print_func
*print
,
2549 print (arg
, "%s", f
->sign
? "-" : "+");
2552 case sim_fpu_class_qnan
:
2554 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2555 print (arg
, "*QuietNaN");
2557 case sim_fpu_class_snan
:
2559 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2560 print (arg
, "*SignalNaN");
2562 case sim_fpu_class_zero
:
2565 case sim_fpu_class_infinity
:
2568 case sim_fpu_class_number
:
2569 case sim_fpu_class_denorm
:
2571 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2572 print (arg
, "*2^%+d", f
->normal_exp
);
2573 ASSERT (f
->fraction
>= IMPLICIT_1
);
2574 ASSERT (f
->fraction
< IMPLICIT_2
);
2579 INLINE_SIM_FPU (void)
2580 sim_fpu_print_status (int status
,
2581 sim_fpu_print_func
*print
,
2585 const char *prefix
= "";
2588 switch ((sim_fpu_status
) (status
& i
))
2590 case sim_fpu_status_denorm
:
2591 print (arg
, "%sD", prefix
);
2593 case sim_fpu_status_invalid_snan
:
2594 print (arg
, "%sSNaN", prefix
);
2596 case sim_fpu_status_invalid_qnan
:
2597 print (arg
, "%sQNaN", prefix
);
2599 case sim_fpu_status_invalid_isi
:
2600 print (arg
, "%sISI", prefix
);
2602 case sim_fpu_status_invalid_idi
:
2603 print (arg
, "%sIDI", prefix
);
2605 case sim_fpu_status_invalid_zdz
:
2606 print (arg
, "%sZDZ", prefix
);
2608 case sim_fpu_status_invalid_imz
:
2609 print (arg
, "%sIMZ", prefix
);
2611 case sim_fpu_status_invalid_cvi
:
2612 print (arg
, "%sCVI", prefix
);
2614 case sim_fpu_status_invalid_cmp
:
2615 print (arg
, "%sCMP", prefix
);
2617 case sim_fpu_status_invalid_sqrt
:
2618 print (arg
, "%sSQRT", prefix
);
2620 case sim_fpu_status_invalid_irx
:
2621 print (arg
, "%sIRX", prefix
);
2623 case sim_fpu_status_inexact
:
2624 print (arg
, "%sX", prefix
);
2626 case sim_fpu_status_overflow
:
2627 print (arg
, "%sO", prefix
);
2629 case sim_fpu_status_underflow
:
2630 print (arg
, "%sU", prefix
);
2632 case sim_fpu_status_invalid_div0
:
2633 print (arg
, "%s/", prefix
);
2635 case sim_fpu_status_rounded
:
2636 print (arg
, "%sR", prefix
);