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-2023 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 /* This must come before any other includes. */
43 #include "sim-basics.h"
47 #include "sim-assert.h"
50 If digits is -1, then print all digits. */
53 print_bits (uint64_t x
,
56 sim_fpu_print_func print
,
59 uint64_t bit
= LSBIT64 (msbit
);
80 /* Quick and dirty conversion between a host double and host 64bit int. */
89 /* A packed IEEE floating point number.
91 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
92 32 and 64 bit numbers. This number is interpreted as:
94 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
95 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
97 Denormalized (0 == BIASEDEXP && FRAC != 0):
98 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
100 Zero (0 == BIASEDEXP && FRAC == 0):
101 (sign ? "-" : "+") 0.0
103 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
104 (sign ? "-" : "+") "infinity"
106 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
109 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
114 #define NR_EXPBITS (is_double ? 11 : 8)
115 #define NR_FRACBITS (is_double ? 52 : 23)
116 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
118 #define EXPMAX32 (255)
119 #define EXMPAX64 (2047)
120 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
122 #define EXPBIAS32 (127)
123 #define EXPBIAS64 (1023)
124 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
126 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
130 /* An unpacked floating point number.
132 When unpacked, the fraction of both a 32 and 64 bit floating point
133 number is stored using the same format:
135 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
136 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
138 #define NR_PAD32 (30)
140 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
141 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
143 #define NR_GUARDS32 (7 + NR_PAD32)
144 #define NR_GUARDS64 (8 + NR_PAD64)
145 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
146 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
148 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
149 #define GUARDLSB LSBIT64 (NR_PAD)
150 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
152 #define NR_FRAC_GUARD (60)
153 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
154 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
155 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
158 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
160 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
162 #define NORMAL_EXPMAX32 (EXPBIAS32)
163 #define NORMAL_EXPMAX64 (EXPBIAS64)
164 #define NORMAL_EXPMAX (EXPBIAS)
167 /* Integer constants */
169 #define MAX_INT32 ((int64_t) LSMASK64 (30, 0))
170 #define MAX_UINT32 LSMASK64 (31, 0)
171 #define MIN_INT32 ((int64_t) LSMASK64 (63, 31))
173 #define MAX_INT64 ((int64_t) LSMASK64 (62, 0))
174 #define MAX_UINT64 LSMASK64 (63, 0)
175 #define MIN_INT64 ((int64_t) LSMASK64 (63, 63))
177 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
178 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
179 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
180 #define NR_INTBITS (is_64bit ? 64 : 32)
182 /* Squeeze an unpacked sim_fpu struct into a 32/64 bit integer. */
183 STATIC_INLINE_SIM_FPU (uint64_t)
184 pack_fpu (const sim_fpu
*src
,
195 case sim_fpu_class_qnan
:
198 /* Force fraction to correct class. */
199 fraction
= src
->fraction
;
200 fraction
>>= NR_GUARDS
;
201 if (sim_fpu_quiet_nan_inverted
)
202 fraction
|= QUIET_NAN
- 1;
204 fraction
|= QUIET_NAN
;
206 case sim_fpu_class_snan
:
209 /* Force fraction to correct class. */
210 fraction
= src
->fraction
;
211 fraction
>>= NR_GUARDS
;
212 if (sim_fpu_quiet_nan_inverted
)
213 fraction
|= QUIET_NAN
;
215 fraction
&= ~QUIET_NAN
;
217 case sim_fpu_class_infinity
:
222 case sim_fpu_class_zero
:
227 case sim_fpu_class_number
:
228 case sim_fpu_class_denorm
:
229 ASSERT (src
->fraction
>= IMPLICIT_1
);
230 ASSERT (src
->fraction
< IMPLICIT_2
);
231 if (src
->normal_exp
< NORMAL_EXPMIN
)
233 /* This number's exponent is too low to fit into the bits
234 available in the number We'll denormalize the number by
235 storing zero in the exponent and shift the fraction to
236 the right to make up for it. */
237 int nr_shift
= NORMAL_EXPMIN
- src
->normal_exp
;
238 if (nr_shift
> NR_FRACBITS
)
240 /* Underflow, just make the number zero. */
249 /* Shift by the value. */
250 fraction
= src
->fraction
;
251 fraction
>>= NR_GUARDS
;
252 fraction
>>= nr_shift
;
255 else if (src
->normal_exp
> NORMAL_EXPMAX
)
264 exp
= (src
->normal_exp
+ EXPBIAS
);
266 fraction
= src
->fraction
;
267 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
269 /* Round to nearest: If the guard bits are the all zero, but
270 the first, then we're half way between two numbers,
271 choose the one which makes the lsb of the answer 0. */
272 if ((fraction
& GUARDMASK
) == GUARDMSB
)
274 if ((fraction
& (GUARDMSB
<< 1)))
275 fraction
+= (GUARDMSB
<< 1);
279 /* Add a one to the guards to force round to nearest. */
280 fraction
+= GUARDROUND
;
282 if ((fraction
& IMPLICIT_2
)) /* Rounding resulted in carry. */
287 fraction
>>= NR_GUARDS
;
288 /* When exp == EXPMAX (overflow from carry) fraction must
289 have been made zero. */
290 ASSERT ((exp
== EXPMAX
) <= ((fraction
& ~IMPLICIT_1
) == 0));
297 packed
= ((sign
? SIGNBIT
: 0)
298 | (exp
<< NR_FRACBITS
)
299 | LSMASKED64 (fraction
, NR_FRACBITS
- 1, 0));
301 /* Trace operation. */
308 printf ("pack_fpu: ");
309 printf ("-> %c%0lX.%06lX\n",
310 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
311 (long) LSEXTRACTED32 (packed
, 30, 23),
312 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
320 /* Unpack a 32/64 bit integer into a sim_fpu structure. */
321 STATIC_INLINE_SIM_FPU (void)
322 unpack_fpu (sim_fpu
*dst
, uint64_t packed
, int is_double
)
324 uint64_t fraction
= LSMASKED64 (packed
, NR_FRACBITS
- 1, 0);
325 unsigned exp
= LSEXTRACTED64 (packed
, NR_EXPBITS
+ NR_FRACBITS
- 1, NR_FRACBITS
);
326 int sign
= (packed
& SIGNBIT
) != 0;
330 /* Hmm. Looks like 0 */
333 /* Tastes like zero. */
334 dst
->class = sim_fpu_class_zero
;
340 /* Zero exponent with non zero fraction - it's denormalized,
341 so there isn't a leading implicit one - we'll shift it so
343 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
344 dst
->class = sim_fpu_class_denorm
;
346 fraction
<<= NR_GUARDS
;
347 while (fraction
< IMPLICIT_1
)
352 dst
->fraction
= fraction
;
355 else if (exp
== EXPMAX
)
360 /* Attached to a zero fraction - means infinity. */
361 dst
->class = sim_fpu_class_infinity
;
363 /* dst->normal_exp = EXPBIAS; */
364 /* dst->fraction = 0; */
370 /* Non zero fraction, means NaN. */
372 dst
->fraction
= (fraction
<< NR_GUARDS
);
373 if (sim_fpu_quiet_nan_inverted
)
374 qnan
= (fraction
& QUIET_NAN
) == 0;
376 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 uint32_t val
= pack_fpu (dst
, 0);
417 uint32_t 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
, int64_t 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 (uint64_t *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
, uint64_t 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
, uint32_t s
)
686 unpack_fpu (f
, s
, 0);
690 INLINE_SIM_FPU (void)
691 sim_fpu_232to (sim_fpu
*f
, uint32_t h
, uint32_t l
)
695 unpack_fpu (f
, s
, 1);
699 INLINE_SIM_FPU (void)
700 sim_fpu_64to (sim_fpu
*f
, uint64_t s
)
702 unpack_fpu (f
, s
, 1);
706 INLINE_SIM_FPU (void)
707 sim_fpu_to32 (uint32_t *s
,
710 *s
= pack_fpu (f
, 0);
714 INLINE_SIM_FPU (void)
715 sim_fpu_to232 (uint32_t *h
, uint32_t *l
,
718 uint64_t s
= pack_fpu (f
, 1);
724 INLINE_SIM_FPU (void)
725 sim_fpu_to64 (uint64_t *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 (uint64_t)
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 uint64_t 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 uint64_t guardmask
= LSMASK64 (nr_guards
- 1, 0);
836 uint64_t guardmsb
= LSBIT64 (nr_guards
- 1);
837 uint64_t 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
);
989 /* NaN handling for binary operations. */
992 sim_fpu_op_nan (sim_fpu
*f
, const sim_fpu
*l
, const sim_fpu
*r
)
994 if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
996 *f
= sim_fpu_is_snan (l
) ? *l
: *r
;
997 f
->class = sim_fpu_class_qnan
;
998 return sim_fpu_status_invalid_snan
;
1000 ASSERT (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
));
1001 if (sim_fpu_is_qnan (l
))
1003 else /* if (sim_fpu_is_qnan (r)) */
1008 /* NaN handling specific to min/max operations. */
1010 INLINE_SIM_FPU (int)
1011 sim_fpu_minmax_nan (sim_fpu
*f
, const sim_fpu
*l
, const sim_fpu
*r
)
1013 if (sim_fpu_is_snan (l
)
1014 || sim_fpu_is_snan (r
)
1015 || sim_fpu_is_ieee754_1985 ())
1016 return sim_fpu_op_nan (f
, l
, r
);
1018 /* if sim_fpu_is_ieee754_2008()
1019 && ((sim_fpu_is_qnan (l) || sim_fpu_is_qnan (r))) */
1022 "minNum/maxNum is ... the canonicalized number if one
1023 operand is a number and the other a quiet NaN." */
1024 if (sim_fpu_is_qnan (l
))
1026 else /* if (sim_fpu_is_qnan (r)) */
1032 /* Arithmetic ops */
1034 INLINE_SIM_FPU (int)
1035 sim_fpu_add (sim_fpu
*f
,
1039 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1040 return sim_fpu_op_nan (f
, l
, r
);
1041 if (sim_fpu_is_infinity (l
))
1043 if (sim_fpu_is_infinity (r
)
1044 && l
->sign
!= r
->sign
)
1047 return sim_fpu_status_invalid_isi
;
1052 if (sim_fpu_is_infinity (r
))
1057 if (sim_fpu_is_zero (l
))
1059 if (sim_fpu_is_zero (r
))
1062 f
->sign
= l
->sign
& r
->sign
;
1068 if (sim_fpu_is_zero (r
))
1075 int shift
= l
->normal_exp
- r
->normal_exp
;
1078 /* use exp of larger */
1079 if (shift
>= NR_FRAC_GUARD
)
1081 /* left has much bigger magnitude */
1083 return sim_fpu_status_inexact
;
1085 if (shift
<= - NR_FRAC_GUARD
)
1087 /* right has much bigger magnitude */
1089 return sim_fpu_status_inexact
;
1091 lfraction
= l
->fraction
;
1092 rfraction
= r
->fraction
;
1095 f
->normal_exp
= l
->normal_exp
;
1096 if (rfraction
& LSMASK64 (shift
- 1, 0))
1098 status
|= sim_fpu_status_inexact
;
1099 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1101 rfraction
>>= shift
;
1105 f
->normal_exp
= r
->normal_exp
;
1106 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1108 status
|= sim_fpu_status_inexact
;
1109 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1111 lfraction
>>= -shift
;
1115 f
->normal_exp
= r
->normal_exp
;
1118 /* Perform the addition. */
1120 lfraction
= - lfraction
;
1122 rfraction
= - rfraction
;
1123 f
->fraction
= lfraction
+ rfraction
;
1126 if (f
->fraction
== 0)
1133 f
->class = sim_fpu_class_number
;
1134 if (((int64_t) f
->fraction
) >= 0)
1139 f
->fraction
= - f
->fraction
;
1143 if ((f
->fraction
& IMPLICIT_2
))
1145 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1148 else if (f
->fraction
< IMPLICIT_1
)
1155 while (f
->fraction
< IMPLICIT_1
);
1157 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1163 INLINE_SIM_FPU (int)
1164 sim_fpu_sub (sim_fpu
*f
,
1168 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1169 return sim_fpu_op_nan (f
, l
, r
);
1170 if (sim_fpu_is_infinity (l
))
1172 if (sim_fpu_is_infinity (r
)
1173 && l
->sign
== r
->sign
)
1176 return sim_fpu_status_invalid_isi
;
1181 if (sim_fpu_is_infinity (r
))
1187 if (sim_fpu_is_zero (l
))
1189 if (sim_fpu_is_zero (r
))
1192 f
->sign
= l
->sign
& !r
->sign
;
1201 if (sim_fpu_is_zero (r
))
1208 int shift
= l
->normal_exp
- r
->normal_exp
;
1211 /* use exp of larger */
1212 if (shift
>= NR_FRAC_GUARD
)
1214 /* left has much bigger magnitude */
1216 return sim_fpu_status_inexact
;
1218 if (shift
<= - NR_FRAC_GUARD
)
1220 /* right has much bigger magnitude */
1223 return sim_fpu_status_inexact
;
1225 lfraction
= l
->fraction
;
1226 rfraction
= r
->fraction
;
1229 f
->normal_exp
= l
->normal_exp
;
1230 if (rfraction
& LSMASK64 (shift
- 1, 0))
1232 status
|= sim_fpu_status_inexact
;
1233 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1235 rfraction
>>= shift
;
1239 f
->normal_exp
= r
->normal_exp
;
1240 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1242 status
|= sim_fpu_status_inexact
;
1243 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1245 lfraction
>>= -shift
;
1249 f
->normal_exp
= r
->normal_exp
;
1252 /* Perform the subtraction. */
1254 lfraction
= - lfraction
;
1256 rfraction
= - rfraction
;
1257 f
->fraction
= lfraction
+ rfraction
;
1260 if (f
->fraction
== 0)
1267 f
->class = sim_fpu_class_number
;
1268 if (((int64_t) f
->fraction
) >= 0)
1273 f
->fraction
= - f
->fraction
;
1277 if ((f
->fraction
& IMPLICIT_2
))
1279 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1282 else if (f
->fraction
< IMPLICIT_1
)
1289 while (f
->fraction
< IMPLICIT_1
);
1291 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1297 INLINE_SIM_FPU (int)
1298 sim_fpu_mul (sim_fpu
*f
,
1302 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1303 return sim_fpu_op_nan (f
, l
, r
);
1304 if (sim_fpu_is_infinity (l
))
1306 if (sim_fpu_is_zero (r
))
1309 return sim_fpu_status_invalid_imz
;
1312 f
->sign
= l
->sign
^ r
->sign
;
1315 if (sim_fpu_is_infinity (r
))
1317 if (sim_fpu_is_zero (l
))
1320 return sim_fpu_status_invalid_imz
;
1323 f
->sign
= l
->sign
^ r
->sign
;
1326 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1329 f
->sign
= l
->sign
^ r
->sign
;
1332 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1337 uint64_t nl
= l
->fraction
& 0xffffffff;
1338 uint64_t nh
= l
->fraction
>> 32;
1339 uint64_t ml
= r
->fraction
& 0xffffffff;
1340 uint64_t mh
= r
->fraction
>>32;
1341 uint64_t pp_ll
= ml
* nl
;
1342 uint64_t pp_hl
= mh
* nl
;
1343 uint64_t pp_lh
= ml
* nh
;
1344 uint64_t pp_hh
= mh
* nh
;
1347 uint64_t ps_hh__
= pp_hl
+ pp_lh
;
1348 if (ps_hh__
< pp_hl
)
1349 res2
+= UNSIGNED64 (0x100000000);
1350 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1351 res0
= pp_ll
+ pp_hl
;
1354 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1358 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1359 f
->sign
= l
->sign
^ r
->sign
;
1360 f
->class = sim_fpu_class_number
;
1362 /* Input is bounded by [1,2) ; [2^60,2^61)
1363 Output is bounded by [1,4) ; [2^120,2^122) */
1365 /* Adjust the exponent according to where the decimal point ended
1366 up in the high 64 bit word. In the source the decimal point
1367 was at NR_FRAC_GUARD. */
1368 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1370 /* The high word is bounded according to the above. Consequently
1371 it has never overflowed into IMPLICIT_2. */
1372 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1373 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1374 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1381 if (low
& LSBIT64 (63))
1385 while (high
< IMPLICIT_1
);
1387 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1390 f
->fraction
= (high
| 1); /* sticky */
1391 return sim_fpu_status_inexact
;
1402 INLINE_SIM_FPU (int)
1403 sim_fpu_div (sim_fpu
*f
,
1407 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1408 return sim_fpu_op_nan (f
, l
, r
);
1409 if (sim_fpu_is_infinity (l
))
1411 if (sim_fpu_is_infinity (r
))
1414 return sim_fpu_status_invalid_idi
;
1419 f
->sign
= l
->sign
^ r
->sign
;
1423 if (sim_fpu_is_zero (l
))
1425 if (sim_fpu_is_zero (r
))
1428 return sim_fpu_status_invalid_zdz
;
1433 f
->sign
= l
->sign
^ r
->sign
;
1437 if (sim_fpu_is_infinity (r
))
1440 f
->sign
= l
->sign
^ r
->sign
;
1443 if (sim_fpu_is_zero (r
))
1445 f
->class = sim_fpu_class_infinity
;
1446 f
->sign
= l
->sign
^ r
->sign
;
1447 return sim_fpu_status_invalid_div0
;
1450 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1453 /* quotient = ( ( numerator / denominator)
1454 x 2^(numerator exponent - denominator exponent)
1457 uint64_t denominator
;
1461 f
->class = sim_fpu_class_number
;
1462 f
->sign
= l
->sign
^ r
->sign
;
1463 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1465 numerator
= l
->fraction
;
1466 denominator
= r
->fraction
;
1468 /* Fraction will be less than 1.0 */
1469 if (numerator
< denominator
)
1474 ASSERT (numerator
>= denominator
);
1476 /* Gain extra precision, already used one spare bit. */
1477 numerator
<<= NR_SPARE
;
1478 denominator
<<= NR_SPARE
;
1480 /* Does divide one bit at a time. Optimize??? */
1482 bit
= (IMPLICIT_1
<< NR_SPARE
);
1485 if (numerator
>= denominator
)
1488 numerator
-= denominator
;
1494 /* Discard (but save) the extra bits. */
1495 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1496 quotient
= (quotient
>> NR_SPARE
) | 1;
1498 quotient
= (quotient
>> NR_SPARE
);
1500 f
->fraction
= quotient
;
1501 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1504 f
->fraction
|= 1; /* Stick remaining bits. */
1505 return sim_fpu_status_inexact
;
1513 INLINE_SIM_FPU (int)
1514 sim_fpu_rem (sim_fpu
*f
,
1518 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1519 return sim_fpu_op_nan (f
, l
, r
);
1520 if (sim_fpu_is_infinity (l
))
1523 return sim_fpu_status_invalid_irx
;
1525 if (sim_fpu_is_zero (r
))
1528 return sim_fpu_status_invalid_div0
;
1530 if (sim_fpu_is_zero (l
))
1535 if (sim_fpu_is_infinity (r
))
1543 /* Remainder is calculated as l-n*r, where n is l/r rounded to the
1544 nearest integer. The variable n is rounded half even. */
1546 sim_fpu_div (&n
, l
, r
);
1547 sim_fpu_round_64 (&n
, 0, 0);
1549 if (n
.normal_exp
< -1) /* If n looks like zero just return l. */
1554 else if (n
.class == sim_fpu_class_number
1555 && n
.normal_exp
<= (NR_FRAC_GUARD
)) /* If not too large round. */
1556 do_normal_round (&n
, (NR_FRAC_GUARD
) - n
.normal_exp
, sim_fpu_round_near
);
1558 /* Mark 0's as zero so multiply can detect zero. */
1559 if (n
.fraction
== 0)
1560 n
.class = sim_fpu_class_zero
;
1562 /* Calculate n*r. */
1563 sim_fpu_mul (&tmp
, &n
, r
);
1564 sim_fpu_round_64 (&tmp
, 0, 0);
1566 /* Finally calculate l-n*r. */
1567 sim_fpu_sub (f
, l
, &tmp
);
1574 INLINE_SIM_FPU (int)
1575 sim_fpu_max (sim_fpu
*f
,
1579 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1580 return sim_fpu_minmax_nan (f
, l
, r
);
1581 if (sim_fpu_is_infinity (l
))
1583 if (sim_fpu_is_infinity (r
)
1584 && l
->sign
== r
->sign
)
1587 return sim_fpu_status_invalid_isi
;
1590 *f
= *r
; /* -inf < anything */
1592 *f
= *l
; /* +inf > anything */
1595 if (sim_fpu_is_infinity (r
))
1598 *f
= *l
; /* anything > -inf */
1600 *f
= *r
; /* anything < +inf */
1603 if (l
->sign
> r
->sign
)
1605 *f
= *r
; /* -ve < +ve */
1608 if (l
->sign
< r
->sign
)
1610 *f
= *l
; /* +ve > -ve */
1613 ASSERT (l
->sign
== r
->sign
);
1614 if (l
->normal_exp
> r
->normal_exp
1615 || (l
->normal_exp
== r
->normal_exp
1616 && l
->fraction
> r
->fraction
))
1620 *f
= *r
; /* -ve < -ve */
1622 *f
= *l
; /* +ve > +ve */
1629 *f
= *l
; /* -ve > -ve */
1631 *f
= *r
; /* +ve < +ve */
1637 INLINE_SIM_FPU (int)
1638 sim_fpu_min (sim_fpu
*f
,
1642 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1643 return sim_fpu_minmax_nan (f
, l
, r
);
1644 if (sim_fpu_is_infinity (l
))
1646 if (sim_fpu_is_infinity (r
)
1647 && l
->sign
== r
->sign
)
1650 return sim_fpu_status_invalid_isi
;
1653 *f
= *l
; /* -inf < anything */
1655 *f
= *r
; /* +inf > anthing */
1658 if (sim_fpu_is_infinity (r
))
1661 *f
= *r
; /* anything > -inf */
1663 *f
= *l
; /* anything < +inf */
1666 if (l
->sign
> r
->sign
)
1668 *f
= *l
; /* -ve < +ve */
1671 if (l
->sign
< r
->sign
)
1673 *f
= *r
; /* +ve > -ve */
1676 ASSERT (l
->sign
== r
->sign
);
1677 if (l
->normal_exp
> r
->normal_exp
1678 || (l
->normal_exp
== r
->normal_exp
1679 && l
->fraction
> r
->fraction
))
1683 *f
= *l
; /* -ve < -ve */
1685 *f
= *r
; /* +ve > +ve */
1692 *f
= *r
; /* -ve > -ve */
1694 *f
= *l
; /* +ve < +ve */
1700 INLINE_SIM_FPU (int)
1701 sim_fpu_neg (sim_fpu
*f
,
1704 if (sim_fpu_is_ieee754_1985 () && sim_fpu_is_snan (r
))
1707 f
->class = sim_fpu_class_qnan
;
1708 return sim_fpu_status_invalid_snan
;
1710 if (sim_fpu_is_qnan (r
))
1721 INLINE_SIM_FPU (int)
1722 sim_fpu_abs (sim_fpu
*f
,
1727 if (sim_fpu_is_ieee754_1985 () && sim_fpu_is_snan (r
))
1729 f
->class = sim_fpu_class_qnan
;
1730 return sim_fpu_status_invalid_snan
;
1736 INLINE_SIM_FPU (int)
1737 sim_fpu_inv (sim_fpu
*f
,
1740 return sim_fpu_div (f
, &sim_fpu_one
, r
);
1744 INLINE_SIM_FPU (int)
1745 sim_fpu_sqrt (sim_fpu
*f
,
1748 if (sim_fpu_is_snan (r
))
1751 return sim_fpu_status_invalid_snan
;
1753 if (sim_fpu_is_qnan (r
))
1758 if (sim_fpu_is_zero (r
))
1760 f
->class = sim_fpu_class_zero
;
1765 if (sim_fpu_is_infinity (r
))
1770 return sim_fpu_status_invalid_sqrt
;
1774 f
->class = sim_fpu_class_infinity
;
1783 return sim_fpu_status_invalid_sqrt
;
1786 /* @(#)e_sqrt.c 5.1 93/09/24 */
1788 * ====================================================
1789 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1791 * Developed at SunPro, a Sun Microsystems, Inc. business.
1792 * Permission to use, copy, modify, and distribute this
1793 * software is freely granted, provided that this notice
1795 * ====================================================
1798 /* __ieee754_sqrt(x)
1799 * Return correctly rounded sqrt.
1800 * ------------------------------------------
1801 * | Use the hardware sqrt if you have one |
1802 * ------------------------------------------
1804 * Bit by bit method using integer arithmetic. (Slow, but portable)
1806 * Scale x to y in [1,4) with even powers of 2:
1807 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1808 * sqrt(x) = 2^k * sqrt(y)
1811 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1812 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1814 - y = ((m even) ? x : 2.x)
1816 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1818 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1820 * 2. Bit by bit computation
1821 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1824 * s = 2*q , and y = 2 * ( y - q ). (1)
1827 * To compute q from q , one checks whether
1831 * (q + 2 ) <= y. (2)
1834 * If (2) is false, then q = q ; otherwise q = q + 2 .
1837 * With some algebraic manipulation, it is not difficult to see
1838 * that (2) is equivalent to
1843 * The advantage of (3) is that s and y can be computed by
1845 * the following recurrence formula:
1848 * s = s , y = y ; (4)
1857 * s = s + 2 , y = y - s - 2 (5)
1862 - NOTE: y = 2 (y - s - 2 )
1865 * One may easily use induction to prove (4) and (5).
1866 * Note. Since the left hand side of (3) contain only i+2 bits,
1867 * it does not necessary to do a full (53-bit) comparison
1870 * After generating the 53 bits result, we compute one more bit.
1871 * Together with the remainder, we can decide whether the
1872 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1873 * (it will never equal to 1/2ulp).
1874 * The rounding mode can be detected by checking whether
1875 * huge + tiny is equal to huge, and whether huge - tiny is
1876 * equal to huge for some floating point number "huge" and "tiny".
1879 * sqrt(+-0) = +-0 ... exact
1881 * sqrt(-ve) = NaN ... with invalid signal
1882 * sqrt(NaN) = NaN ... with invalid signal for signalling NaN
1884 * Other methods : see the appended file at the end of the program below.
1889 /* Generate sqrt(x) bit by bit. */
1895 f
->class = sim_fpu_class_number
;
1898 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1900 /* Odd exp, double x to make it even. */
1901 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1902 if ((r
->normal_exp
& 1))
1906 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1908 /* Let loop determine first value of s (either 1 or 2) */
1926 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1930 f
->fraction
|= 1; /* Stick remaining bits. */
1931 return sim_fpu_status_inexact
;
1939 /* int/long <-> sim_fpu */
1941 INLINE_SIM_FPU (int)
1942 sim_fpu_i32to (sim_fpu
*f
,
1944 sim_fpu_round round
)
1950 INLINE_SIM_FPU (int)
1951 sim_fpu_u32to (sim_fpu
*f
,
1953 sim_fpu_round round
)
1959 INLINE_SIM_FPU (int)
1960 sim_fpu_i64to (sim_fpu
*f
,
1962 sim_fpu_round round
)
1968 INLINE_SIM_FPU (int)
1969 sim_fpu_u64to (sim_fpu
*f
,
1971 sim_fpu_round round
)
1978 INLINE_SIM_FPU (int)
1979 sim_fpu_to32i (int32_t *i
,
1981 sim_fpu_round round
)
1984 int status
= fpu2i (&i64
, f
, 0, round
);
1989 INLINE_SIM_FPU (int)
1990 sim_fpu_to32u (uint32_t *u
,
1992 sim_fpu_round round
)
1995 int status
= fpu2u (&u64
, f
, 0);
2000 INLINE_SIM_FPU (int)
2001 sim_fpu_to64i (int64_t *i
,
2003 sim_fpu_round round
)
2005 return fpu2i (i
, f
, 1, round
);
2009 INLINE_SIM_FPU (int)
2010 sim_fpu_to64u (uint64_t *u
,
2012 sim_fpu_round round
)
2014 return fpu2u (u
, f
, 1);
2019 /* sim_fpu -> host format */
2022 INLINE_SIM_FPU (float)
2023 sim_fpu_2f (const sim_fpu
*f
)
2030 INLINE_SIM_FPU (double)
2031 sim_fpu_2d (const sim_fpu
*s
)
2034 if (sim_fpu_is_snan (s
))
2038 n
.class = sim_fpu_class_qnan
;
2039 val
.i
= pack_fpu (&n
, 1);
2043 val
.i
= pack_fpu (s
, 1);
2050 INLINE_SIM_FPU (void)
2051 sim_fpu_f2 (sim_fpu
*f
,
2056 unpack_fpu (f
, val
.i
, 1);
2061 INLINE_SIM_FPU (void)
2062 sim_fpu_d2 (sim_fpu
*f
,
2067 unpack_fpu (f
, val
.i
, 1);
2073 INLINE_SIM_FPU (int)
2074 sim_fpu_is_nan (const sim_fpu
*d
)
2078 case sim_fpu_class_qnan
:
2079 case sim_fpu_class_snan
:
2086 INLINE_SIM_FPU (int)
2087 sim_fpu_is_qnan (const sim_fpu
*d
)
2091 case sim_fpu_class_qnan
:
2098 INLINE_SIM_FPU (int)
2099 sim_fpu_is_snan (const sim_fpu
*d
)
2103 case sim_fpu_class_snan
:
2110 INLINE_SIM_FPU (int)
2111 sim_fpu_is_zero (const sim_fpu
*d
)
2115 case sim_fpu_class_zero
:
2122 INLINE_SIM_FPU (int)
2123 sim_fpu_is_infinity (const sim_fpu
*d
)
2127 case sim_fpu_class_infinity
:
2134 INLINE_SIM_FPU (int)
2135 sim_fpu_is_number (const sim_fpu
*d
)
2139 case sim_fpu_class_denorm
:
2140 case sim_fpu_class_number
:
2147 INLINE_SIM_FPU (int)
2148 sim_fpu_is_denorm (const sim_fpu
*d
)
2152 case sim_fpu_class_denorm
:
2160 INLINE_SIM_FPU (int)
2161 sim_fpu_sign (const sim_fpu
*d
)
2167 INLINE_SIM_FPU (int)
2168 sim_fpu_exp (const sim_fpu
*d
)
2170 return d
->normal_exp
;
2174 INLINE_SIM_FPU (uint64_t)
2175 sim_fpu_fraction (const sim_fpu
*d
)
2181 INLINE_SIM_FPU (uint64_t)
2182 sim_fpu_guard (const sim_fpu
*d
, int is_double
)
2185 uint64_t guardmask
= LSMASK64 (NR_GUARDS
- 1, 0);
2186 rv
= (d
->fraction
& guardmask
) >> NR_PAD
;
2191 INLINE_SIM_FPU (int)
2192 sim_fpu_is (const sim_fpu
*d
)
2196 case sim_fpu_class_qnan
:
2197 return SIM_FPU_IS_QNAN
;
2198 case sim_fpu_class_snan
:
2199 return SIM_FPU_IS_SNAN
;
2200 case sim_fpu_class_infinity
:
2202 return SIM_FPU_IS_NINF
;
2204 return SIM_FPU_IS_PINF
;
2205 case sim_fpu_class_number
:
2207 return SIM_FPU_IS_NNUMBER
;
2209 return SIM_FPU_IS_PNUMBER
;
2210 case sim_fpu_class_denorm
:
2212 return SIM_FPU_IS_NDENORM
;
2214 return SIM_FPU_IS_PDENORM
;
2215 case sim_fpu_class_zero
:
2217 return SIM_FPU_IS_NZERO
;
2219 return SIM_FPU_IS_PZERO
;
2226 INLINE_SIM_FPU (int)
2227 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2230 sim_fpu_sub (&res
, l
, r
);
2231 return sim_fpu_is (&res
);
2234 INLINE_SIM_FPU (int)
2235 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2238 sim_fpu_lt (&status
, l
, r
);
2242 INLINE_SIM_FPU (int)
2243 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2246 sim_fpu_le (&is
, l
, r
);
2250 INLINE_SIM_FPU (int)
2251 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2254 sim_fpu_eq (&is
, l
, r
);
2258 INLINE_SIM_FPU (int)
2259 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2262 sim_fpu_ne (&is
, l
, r
);
2266 INLINE_SIM_FPU (int)
2267 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2270 sim_fpu_ge (&is
, l
, r
);
2274 INLINE_SIM_FPU (int)
2275 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2278 sim_fpu_gt (&is
, l
, r
);
2282 INLINE_SIM_FPU (int)
2283 sim_fpu_is_un (const sim_fpu
*l
, const sim_fpu
*r
)
2286 sim_fpu_un (&is
, l
, r
);
2290 INLINE_SIM_FPU (int)
2291 sim_fpu_is_or (const sim_fpu
*l
, const sim_fpu
*r
)
2294 sim_fpu_or (&is
, l
, r
);
2298 /* Compare operators */
2300 INLINE_SIM_FPU (int)
2301 sim_fpu_lt (int *is
,
2305 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2309 lval
.i
= pack_fpu (l
, 1);
2310 rval
.i
= pack_fpu (r
, 1);
2311 (*is
) = (lval
.d
< rval
.d
);
2314 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2317 return sim_fpu_status_invalid_snan
;
2322 return sim_fpu_status_invalid_qnan
;
2326 INLINE_SIM_FPU (int)
2327 sim_fpu_le (int *is
,
2331 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2335 lval
.i
= pack_fpu (l
, 1);
2336 rval
.i
= pack_fpu (r
, 1);
2337 *is
= (lval
.d
<= rval
.d
);
2340 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2343 return sim_fpu_status_invalid_snan
;
2348 return sim_fpu_status_invalid_qnan
;
2352 INLINE_SIM_FPU (int)
2353 sim_fpu_eq (int *is
,
2357 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2361 lval
.i
= pack_fpu (l
, 1);
2362 rval
.i
= pack_fpu (r
, 1);
2363 (*is
) = (lval
.d
== rval
.d
);
2366 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2369 return sim_fpu_status_invalid_snan
;
2374 return sim_fpu_status_invalid_qnan
;
2378 INLINE_SIM_FPU (int)
2379 sim_fpu_ne (int *is
,
2383 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2387 lval
.i
= pack_fpu (l
, 1);
2388 rval
.i
= pack_fpu (r
, 1);
2389 (*is
) = (lval
.d
!= rval
.d
);
2392 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2395 return sim_fpu_status_invalid_snan
;
2400 return sim_fpu_status_invalid_qnan
;
2404 INLINE_SIM_FPU (int)
2405 sim_fpu_ge (int *is
,
2409 return sim_fpu_le (is
, r
, l
);
2412 INLINE_SIM_FPU (int)
2413 sim_fpu_gt (int *is
,
2417 return sim_fpu_lt (is
, r
, l
);
2420 INLINE_SIM_FPU (int)
2421 sim_fpu_un (int *is
, const sim_fpu
*l
, const sim_fpu
*r
)
2423 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
2433 INLINE_SIM_FPU (int)
2434 sim_fpu_or (int *is
, const sim_fpu
*l
, const sim_fpu
*r
)
2436 sim_fpu_un (is
, l
, r
);
2438 /* Invert result. */
2444 sim_fpu_classify (const sim_fpu
*f
)
2448 case sim_fpu_class_snan
: return SIM_FPU_IS_SNAN
;
2449 case sim_fpu_class_qnan
: return SIM_FPU_IS_QNAN
;
2450 case sim_fpu_class_infinity
:
2451 return f
->sign
? SIM_FPU_IS_NINF
: SIM_FPU_IS_PINF
;
2452 case sim_fpu_class_zero
:
2453 return f
->sign
? SIM_FPU_IS_NZERO
: SIM_FPU_IS_PZERO
;
2454 case sim_fpu_class_number
:
2455 return f
->sign
? SIM_FPU_IS_NNUMBER
: SIM_FPU_IS_PNUMBER
;
2456 case sim_fpu_class_denorm
:
2457 return f
->sign
? SIM_FPU_IS_NDENORM
: SIM_FPU_IS_PDENORM
;
2459 fprintf (stderr
, "Bad switch\n");
2465 /* A number of useful constants */
2467 #if EXTERN_SIM_FPU_P
2468 sim_fpu_state _sim_fpu
= {
2469 .quiet_nan_inverted
= false,
2470 .current_mode
= sim_fpu_ieee754_1985
,
2473 const sim_fpu sim_fpu_zero
= {
2474 sim_fpu_class_zero
, 0, 0, 0
2476 const sim_fpu sim_fpu_qnan
= {
2477 sim_fpu_class_qnan
, 0, 0, 0
2479 const sim_fpu sim_fpu_one
= {
2480 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2482 const sim_fpu sim_fpu_two
= {
2483 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2485 const sim_fpu sim_fpu_max32
= {
2486 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2488 const sim_fpu sim_fpu_max64
= {
2489 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2493 /* Specification swapping behaviour */
2494 INLINE_SIM_FPU (bool)
2495 sim_fpu_is_ieee754_1985 (void)
2497 return (sim_fpu_current_mode
== sim_fpu_ieee754_1985
);
2500 INLINE_SIM_FPU (bool)
2501 sim_fpu_is_ieee754_2008 (void)
2503 return (sim_fpu_current_mode
== sim_fpu_ieee754_2008
);
2506 INLINE_SIM_FPU (void)
2507 sim_fpu_set_mode (const sim_fpu_mode m
)
2509 sim_fpu_current_mode
= m
;
2514 INLINE_SIM_FPU (void)
2515 sim_fpu_print_fpu (const sim_fpu
*f
,
2516 sim_fpu_print_func
*print
,
2519 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2522 INLINE_SIM_FPU (void)
2523 sim_fpu_printn_fpu (const sim_fpu
*f
,
2524 sim_fpu_print_func
*print
,
2528 print (arg
, "%s", f
->sign
? "-" : "+");
2531 case sim_fpu_class_qnan
:
2533 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2534 print (arg
, "*QuietNaN");
2536 case sim_fpu_class_snan
:
2538 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2539 print (arg
, "*SignalNaN");
2541 case sim_fpu_class_zero
:
2544 case sim_fpu_class_infinity
:
2547 case sim_fpu_class_number
:
2548 case sim_fpu_class_denorm
:
2550 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2551 print (arg
, "*2^%+d", f
->normal_exp
);
2552 ASSERT (f
->fraction
>= IMPLICIT_1
);
2553 ASSERT (f
->fraction
< IMPLICIT_2
);
2558 INLINE_SIM_FPU (void)
2559 sim_fpu_print_status (int status
,
2560 sim_fpu_print_func
*print
,
2564 const char *prefix
= "";
2567 switch ((sim_fpu_status
) (status
& i
))
2569 case sim_fpu_status_denorm
:
2570 print (arg
, "%sD", prefix
);
2572 case sim_fpu_status_invalid_snan
:
2573 print (arg
, "%sSNaN", prefix
);
2575 case sim_fpu_status_invalid_qnan
:
2576 print (arg
, "%sQNaN", prefix
);
2578 case sim_fpu_status_invalid_isi
:
2579 print (arg
, "%sISI", prefix
);
2581 case sim_fpu_status_invalid_idi
:
2582 print (arg
, "%sIDI", prefix
);
2584 case sim_fpu_status_invalid_zdz
:
2585 print (arg
, "%sZDZ", prefix
);
2587 case sim_fpu_status_invalid_imz
:
2588 print (arg
, "%sIMZ", prefix
);
2590 case sim_fpu_status_invalid_cvi
:
2591 print (arg
, "%sCVI", prefix
);
2593 case sim_fpu_status_invalid_cmp
:
2594 print (arg
, "%sCMP", prefix
);
2596 case sim_fpu_status_invalid_sqrt
:
2597 print (arg
, "%sSQRT", prefix
);
2599 case sim_fpu_status_invalid_irx
:
2600 print (arg
, "%sIRX", prefix
);
2602 case sim_fpu_status_inexact
:
2603 print (arg
, "%sX", prefix
);
2605 case sim_fpu_status_overflow
:
2606 print (arg
, "%sO", prefix
);
2608 case sim_fpu_status_underflow
:
2609 print (arg
, "%sU", prefix
);
2611 case sim_fpu_status_invalid_div0
:
2612 print (arg
, "%s/", prefix
);
2614 case sim_fpu_status_rounded
:
2615 print (arg
, "%sR", prefix
);