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-2022 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 /* Arithmetic ops */
1010 INLINE_SIM_FPU (int)
1011 sim_fpu_add (sim_fpu
*f
,
1015 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1016 return sim_fpu_op_nan (f
, l
, r
);
1017 if (sim_fpu_is_infinity (l
))
1019 if (sim_fpu_is_infinity (r
)
1020 && l
->sign
!= r
->sign
)
1023 return sim_fpu_status_invalid_isi
;
1028 if (sim_fpu_is_infinity (r
))
1033 if (sim_fpu_is_zero (l
))
1035 if (sim_fpu_is_zero (r
))
1038 f
->sign
= l
->sign
& r
->sign
;
1044 if (sim_fpu_is_zero (r
))
1051 int shift
= l
->normal_exp
- r
->normal_exp
;
1054 /* use exp of larger */
1055 if (shift
>= NR_FRAC_GUARD
)
1057 /* left has much bigger magnitude */
1059 return sim_fpu_status_inexact
;
1061 if (shift
<= - NR_FRAC_GUARD
)
1063 /* right has much bigger magnitude */
1065 return sim_fpu_status_inexact
;
1067 lfraction
= l
->fraction
;
1068 rfraction
= r
->fraction
;
1071 f
->normal_exp
= l
->normal_exp
;
1072 if (rfraction
& LSMASK64 (shift
- 1, 0))
1074 status
|= sim_fpu_status_inexact
;
1075 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1077 rfraction
>>= shift
;
1081 f
->normal_exp
= r
->normal_exp
;
1082 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1084 status
|= sim_fpu_status_inexact
;
1085 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1087 lfraction
>>= -shift
;
1091 f
->normal_exp
= r
->normal_exp
;
1094 /* Perform the addition. */
1096 lfraction
= - lfraction
;
1098 rfraction
= - rfraction
;
1099 f
->fraction
= lfraction
+ rfraction
;
1102 if (f
->fraction
== 0)
1109 f
->class = sim_fpu_class_number
;
1110 if (((int64_t) f
->fraction
) >= 0)
1115 f
->fraction
= - f
->fraction
;
1119 if ((f
->fraction
& IMPLICIT_2
))
1121 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1124 else if (f
->fraction
< IMPLICIT_1
)
1131 while (f
->fraction
< IMPLICIT_1
);
1133 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1139 INLINE_SIM_FPU (int)
1140 sim_fpu_sub (sim_fpu
*f
,
1144 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1145 return sim_fpu_op_nan (f
, l
, r
);
1146 if (sim_fpu_is_infinity (l
))
1148 if (sim_fpu_is_infinity (r
)
1149 && l
->sign
== r
->sign
)
1152 return sim_fpu_status_invalid_isi
;
1157 if (sim_fpu_is_infinity (r
))
1163 if (sim_fpu_is_zero (l
))
1165 if (sim_fpu_is_zero (r
))
1168 f
->sign
= l
->sign
& !r
->sign
;
1177 if (sim_fpu_is_zero (r
))
1184 int shift
= l
->normal_exp
- r
->normal_exp
;
1187 /* use exp of larger */
1188 if (shift
>= NR_FRAC_GUARD
)
1190 /* left has much bigger magnitude */
1192 return sim_fpu_status_inexact
;
1194 if (shift
<= - NR_FRAC_GUARD
)
1196 /* right has much bigger magnitude */
1199 return sim_fpu_status_inexact
;
1201 lfraction
= l
->fraction
;
1202 rfraction
= r
->fraction
;
1205 f
->normal_exp
= l
->normal_exp
;
1206 if (rfraction
& LSMASK64 (shift
- 1, 0))
1208 status
|= sim_fpu_status_inexact
;
1209 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1211 rfraction
>>= shift
;
1215 f
->normal_exp
= r
->normal_exp
;
1216 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1218 status
|= sim_fpu_status_inexact
;
1219 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1221 lfraction
>>= -shift
;
1225 f
->normal_exp
= r
->normal_exp
;
1228 /* Perform the subtraction. */
1230 lfraction
= - lfraction
;
1232 rfraction
= - rfraction
;
1233 f
->fraction
= lfraction
+ rfraction
;
1236 if (f
->fraction
== 0)
1243 f
->class = sim_fpu_class_number
;
1244 if (((int64_t) f
->fraction
) >= 0)
1249 f
->fraction
= - f
->fraction
;
1253 if ((f
->fraction
& IMPLICIT_2
))
1255 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1258 else if (f
->fraction
< IMPLICIT_1
)
1265 while (f
->fraction
< IMPLICIT_1
);
1267 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1273 INLINE_SIM_FPU (int)
1274 sim_fpu_mul (sim_fpu
*f
,
1278 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1279 return sim_fpu_op_nan (f
, l
, r
);
1280 if (sim_fpu_is_infinity (l
))
1282 if (sim_fpu_is_zero (r
))
1285 return sim_fpu_status_invalid_imz
;
1288 f
->sign
= l
->sign
^ r
->sign
;
1291 if (sim_fpu_is_infinity (r
))
1293 if (sim_fpu_is_zero (l
))
1296 return sim_fpu_status_invalid_imz
;
1299 f
->sign
= l
->sign
^ r
->sign
;
1302 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1305 f
->sign
= l
->sign
^ r
->sign
;
1308 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1313 uint64_t nl
= l
->fraction
& 0xffffffff;
1314 uint64_t nh
= l
->fraction
>> 32;
1315 uint64_t ml
= r
->fraction
& 0xffffffff;
1316 uint64_t mh
= r
->fraction
>>32;
1317 uint64_t pp_ll
= ml
* nl
;
1318 uint64_t pp_hl
= mh
* nl
;
1319 uint64_t pp_lh
= ml
* nh
;
1320 uint64_t pp_hh
= mh
* nh
;
1323 uint64_t ps_hh__
= pp_hl
+ pp_lh
;
1324 if (ps_hh__
< pp_hl
)
1325 res2
+= UNSIGNED64 (0x100000000);
1326 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1327 res0
= pp_ll
+ pp_hl
;
1330 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1334 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1335 f
->sign
= l
->sign
^ r
->sign
;
1336 f
->class = sim_fpu_class_number
;
1338 /* Input is bounded by [1,2) ; [2^60,2^61)
1339 Output is bounded by [1,4) ; [2^120,2^122) */
1341 /* Adjust the exponent according to where the decimal point ended
1342 up in the high 64 bit word. In the source the decimal point
1343 was at NR_FRAC_GUARD. */
1344 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1346 /* The high word is bounded according to the above. Consequently
1347 it has never overflowed into IMPLICIT_2. */
1348 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1349 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1350 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1357 if (low
& LSBIT64 (63))
1361 while (high
< IMPLICIT_1
);
1363 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1366 f
->fraction
= (high
| 1); /* sticky */
1367 return sim_fpu_status_inexact
;
1378 INLINE_SIM_FPU (int)
1379 sim_fpu_div (sim_fpu
*f
,
1383 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1384 return sim_fpu_op_nan (f
, l
, r
);
1385 if (sim_fpu_is_infinity (l
))
1387 if (sim_fpu_is_infinity (r
))
1390 return sim_fpu_status_invalid_idi
;
1395 f
->sign
= l
->sign
^ r
->sign
;
1399 if (sim_fpu_is_zero (l
))
1401 if (sim_fpu_is_zero (r
))
1404 return sim_fpu_status_invalid_zdz
;
1409 f
->sign
= l
->sign
^ r
->sign
;
1413 if (sim_fpu_is_infinity (r
))
1416 f
->sign
= l
->sign
^ r
->sign
;
1419 if (sim_fpu_is_zero (r
))
1421 f
->class = sim_fpu_class_infinity
;
1422 f
->sign
= l
->sign
^ r
->sign
;
1423 return sim_fpu_status_invalid_div0
;
1426 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1429 /* quotient = ( ( numerator / denominator)
1430 x 2^(numerator exponent - denominator exponent)
1433 uint64_t denominator
;
1437 f
->class = sim_fpu_class_number
;
1438 f
->sign
= l
->sign
^ r
->sign
;
1439 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1441 numerator
= l
->fraction
;
1442 denominator
= r
->fraction
;
1444 /* Fraction will be less than 1.0 */
1445 if (numerator
< denominator
)
1450 ASSERT (numerator
>= denominator
);
1452 /* Gain extra precision, already used one spare bit. */
1453 numerator
<<= NR_SPARE
;
1454 denominator
<<= NR_SPARE
;
1456 /* Does divide one bit at a time. Optimize??? */
1458 bit
= (IMPLICIT_1
<< NR_SPARE
);
1461 if (numerator
>= denominator
)
1464 numerator
-= denominator
;
1470 /* Discard (but save) the extra bits. */
1471 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1472 quotient
= (quotient
>> NR_SPARE
) | 1;
1474 quotient
= (quotient
>> NR_SPARE
);
1476 f
->fraction
= quotient
;
1477 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1480 f
->fraction
|= 1; /* Stick remaining bits. */
1481 return sim_fpu_status_inexact
;
1489 INLINE_SIM_FPU (int)
1490 sim_fpu_rem (sim_fpu
*f
,
1494 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1495 return sim_fpu_op_nan (f
, l
, r
);
1496 if (sim_fpu_is_infinity (l
))
1499 return sim_fpu_status_invalid_irx
;
1501 if (sim_fpu_is_zero (r
))
1504 return sim_fpu_status_invalid_div0
;
1506 if (sim_fpu_is_zero (l
))
1511 if (sim_fpu_is_infinity (r
))
1519 /* Remainder is calculated as l-n*r, where n is l/r rounded to the
1520 nearest integer. The variable n is rounded half even. */
1522 sim_fpu_div (&n
, l
, r
);
1523 sim_fpu_round_64 (&n
, 0, 0);
1525 if (n
.normal_exp
< -1) /* If n looks like zero just return l. */
1530 else if (n
.class == sim_fpu_class_number
1531 && n
.normal_exp
<= (NR_FRAC_GUARD
)) /* If not too large round. */
1532 do_normal_round (&n
, (NR_FRAC_GUARD
) - n
.normal_exp
, sim_fpu_round_near
);
1534 /* Mark 0's as zero so multiply can detect zero. */
1535 if (n
.fraction
== 0)
1536 n
.class = sim_fpu_class_zero
;
1538 /* Calculate n*r. */
1539 sim_fpu_mul (&tmp
, &n
, r
);
1540 sim_fpu_round_64 (&tmp
, 0, 0);
1542 /* Finally calculate l-n*r. */
1543 sim_fpu_sub (f
, l
, &tmp
);
1550 INLINE_SIM_FPU (int)
1551 sim_fpu_max (sim_fpu
*f
,
1555 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1556 return sim_fpu_op_nan (f
, l
, r
);
1557 if (sim_fpu_is_infinity (l
))
1559 if (sim_fpu_is_infinity (r
)
1560 && l
->sign
== r
->sign
)
1563 return sim_fpu_status_invalid_isi
;
1566 *f
= *r
; /* -inf < anything */
1568 *f
= *l
; /* +inf > anything */
1571 if (sim_fpu_is_infinity (r
))
1574 *f
= *l
; /* anything > -inf */
1576 *f
= *r
; /* anything < +inf */
1579 if (l
->sign
> r
->sign
)
1581 *f
= *r
; /* -ve < +ve */
1584 if (l
->sign
< r
->sign
)
1586 *f
= *l
; /* +ve > -ve */
1589 ASSERT (l
->sign
== r
->sign
);
1590 if (l
->normal_exp
> r
->normal_exp
1591 || (l
->normal_exp
== r
->normal_exp
1592 && l
->fraction
> r
->fraction
))
1596 *f
= *r
; /* -ve < -ve */
1598 *f
= *l
; /* +ve > +ve */
1605 *f
= *l
; /* -ve > -ve */
1607 *f
= *r
; /* +ve < +ve */
1613 INLINE_SIM_FPU (int)
1614 sim_fpu_min (sim_fpu
*f
,
1618 if (sim_fpu_is_nan (l
) || sim_fpu_is_nan (r
))
1619 return sim_fpu_op_nan (f
, l
, r
);
1620 if (sim_fpu_is_infinity (l
))
1622 if (sim_fpu_is_infinity (r
)
1623 && l
->sign
== r
->sign
)
1626 return sim_fpu_status_invalid_isi
;
1629 *f
= *l
; /* -inf < anything */
1631 *f
= *r
; /* +inf > anthing */
1634 if (sim_fpu_is_infinity (r
))
1637 *f
= *r
; /* anything > -inf */
1639 *f
= *l
; /* anything < +inf */
1642 if (l
->sign
> r
->sign
)
1644 *f
= *l
; /* -ve < +ve */
1647 if (l
->sign
< r
->sign
)
1649 *f
= *r
; /* +ve > -ve */
1652 ASSERT (l
->sign
== r
->sign
);
1653 if (l
->normal_exp
> r
->normal_exp
1654 || (l
->normal_exp
== r
->normal_exp
1655 && l
->fraction
> r
->fraction
))
1659 *f
= *l
; /* -ve < -ve */
1661 *f
= *r
; /* +ve > +ve */
1668 *f
= *r
; /* -ve > -ve */
1670 *f
= *l
; /* +ve < +ve */
1676 INLINE_SIM_FPU (int)
1677 sim_fpu_neg (sim_fpu
*f
,
1680 if (sim_fpu_is_snan (r
))
1683 f
->class = sim_fpu_class_qnan
;
1684 return sim_fpu_status_invalid_snan
;
1686 if (sim_fpu_is_qnan (r
))
1697 INLINE_SIM_FPU (int)
1698 sim_fpu_abs (sim_fpu
*f
,
1703 if (sim_fpu_is_snan (r
))
1705 f
->class = sim_fpu_class_qnan
;
1706 return sim_fpu_status_invalid_snan
;
1712 INLINE_SIM_FPU (int)
1713 sim_fpu_inv (sim_fpu
*f
,
1716 return sim_fpu_div (f
, &sim_fpu_one
, r
);
1720 INLINE_SIM_FPU (int)
1721 sim_fpu_sqrt (sim_fpu
*f
,
1724 if (sim_fpu_is_snan (r
))
1727 return sim_fpu_status_invalid_snan
;
1729 if (sim_fpu_is_qnan (r
))
1734 if (sim_fpu_is_zero (r
))
1736 f
->class = sim_fpu_class_zero
;
1741 if (sim_fpu_is_infinity (r
))
1746 return sim_fpu_status_invalid_sqrt
;
1750 f
->class = sim_fpu_class_infinity
;
1759 return sim_fpu_status_invalid_sqrt
;
1762 /* @(#)e_sqrt.c 5.1 93/09/24 */
1764 * ====================================================
1765 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1767 * Developed at SunPro, a Sun Microsystems, Inc. business.
1768 * Permission to use, copy, modify, and distribute this
1769 * software is freely granted, provided that this notice
1771 * ====================================================
1774 /* __ieee754_sqrt(x)
1775 * Return correctly rounded sqrt.
1776 * ------------------------------------------
1777 * | Use the hardware sqrt if you have one |
1778 * ------------------------------------------
1780 * Bit by bit method using integer arithmetic. (Slow, but portable)
1782 * Scale x to y in [1,4) with even powers of 2:
1783 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1784 * sqrt(x) = 2^k * sqrt(y)
1787 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1788 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1790 - y = ((m even) ? x : 2.x)
1792 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1794 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1796 * 2. Bit by bit computation
1797 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1800 * s = 2*q , and y = 2 * ( y - q ). (1)
1803 * To compute q from q , one checks whether
1807 * (q + 2 ) <= y. (2)
1810 * If (2) is false, then q = q ; otherwise q = q + 2 .
1813 * With some algebraic manipulation, it is not difficult to see
1814 * that (2) is equivalent to
1819 * The advantage of (3) is that s and y can be computed by
1821 * the following recurrence formula:
1824 * s = s , y = y ; (4)
1833 * s = s + 2 , y = y - s - 2 (5)
1838 - NOTE: y = 2 (y - s - 2 )
1841 * One may easily use induction to prove (4) and (5).
1842 * Note. Since the left hand side of (3) contain only i+2 bits,
1843 * it does not necessary to do a full (53-bit) comparison
1846 * After generating the 53 bits result, we compute one more bit.
1847 * Together with the remainder, we can decide whether the
1848 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1849 * (it will never equal to 1/2ulp).
1850 * The rounding mode can be detected by checking whether
1851 * huge + tiny is equal to huge, and whether huge - tiny is
1852 * equal to huge for some floating point number "huge" and "tiny".
1855 * sqrt(+-0) = +-0 ... exact
1857 * sqrt(-ve) = NaN ... with invalid signal
1858 * sqrt(NaN) = NaN ... with invalid signal for signalling NaN
1860 * Other methods : see the appended file at the end of the program below.
1865 /* Generate sqrt(x) bit by bit. */
1871 f
->class = sim_fpu_class_number
;
1874 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1876 /* Odd exp, double x to make it even. */
1877 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1878 if ((r
->normal_exp
& 1))
1882 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1884 /* Let loop determine first value of s (either 1 or 2) */
1902 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1906 f
->fraction
|= 1; /* Stick remaining bits. */
1907 return sim_fpu_status_inexact
;
1915 /* int/long <-> sim_fpu */
1917 INLINE_SIM_FPU (int)
1918 sim_fpu_i32to (sim_fpu
*f
,
1920 sim_fpu_round round
)
1926 INLINE_SIM_FPU (int)
1927 sim_fpu_u32to (sim_fpu
*f
,
1929 sim_fpu_round round
)
1935 INLINE_SIM_FPU (int)
1936 sim_fpu_i64to (sim_fpu
*f
,
1938 sim_fpu_round round
)
1944 INLINE_SIM_FPU (int)
1945 sim_fpu_u64to (sim_fpu
*f
,
1947 sim_fpu_round round
)
1954 INLINE_SIM_FPU (int)
1955 sim_fpu_to32i (int32_t *i
,
1957 sim_fpu_round round
)
1960 int status
= fpu2i (&i64
, f
, 0, round
);
1965 INLINE_SIM_FPU (int)
1966 sim_fpu_to32u (uint32_t *u
,
1968 sim_fpu_round round
)
1971 int status
= fpu2u (&u64
, f
, 0);
1976 INLINE_SIM_FPU (int)
1977 sim_fpu_to64i (int64_t *i
,
1979 sim_fpu_round round
)
1981 return fpu2i (i
, f
, 1, round
);
1985 INLINE_SIM_FPU (int)
1986 sim_fpu_to64u (uint64_t *u
,
1988 sim_fpu_round round
)
1990 return fpu2u (u
, f
, 1);
1995 /* sim_fpu -> host format */
1998 INLINE_SIM_FPU (float)
1999 sim_fpu_2f (const sim_fpu
*f
)
2006 INLINE_SIM_FPU (double)
2007 sim_fpu_2d (const sim_fpu
*s
)
2010 if (sim_fpu_is_snan (s
))
2014 n
.class = sim_fpu_class_qnan
;
2015 val
.i
= pack_fpu (&n
, 1);
2019 val
.i
= pack_fpu (s
, 1);
2026 INLINE_SIM_FPU (void)
2027 sim_fpu_f2 (sim_fpu
*f
,
2032 unpack_fpu (f
, val
.i
, 1);
2037 INLINE_SIM_FPU (void)
2038 sim_fpu_d2 (sim_fpu
*f
,
2043 unpack_fpu (f
, val
.i
, 1);
2049 INLINE_SIM_FPU (int)
2050 sim_fpu_is_nan (const sim_fpu
*d
)
2054 case sim_fpu_class_qnan
:
2055 case sim_fpu_class_snan
:
2062 INLINE_SIM_FPU (int)
2063 sim_fpu_is_qnan (const sim_fpu
*d
)
2067 case sim_fpu_class_qnan
:
2074 INLINE_SIM_FPU (int)
2075 sim_fpu_is_snan (const sim_fpu
*d
)
2079 case sim_fpu_class_snan
:
2086 INLINE_SIM_FPU (int)
2087 sim_fpu_is_zero (const sim_fpu
*d
)
2091 case sim_fpu_class_zero
:
2098 INLINE_SIM_FPU (int)
2099 sim_fpu_is_infinity (const sim_fpu
*d
)
2103 case sim_fpu_class_infinity
:
2110 INLINE_SIM_FPU (int)
2111 sim_fpu_is_number (const sim_fpu
*d
)
2115 case sim_fpu_class_denorm
:
2116 case sim_fpu_class_number
:
2123 INLINE_SIM_FPU (int)
2124 sim_fpu_is_denorm (const sim_fpu
*d
)
2128 case sim_fpu_class_denorm
:
2136 INLINE_SIM_FPU (int)
2137 sim_fpu_sign (const sim_fpu
*d
)
2143 INLINE_SIM_FPU (int)
2144 sim_fpu_exp (const sim_fpu
*d
)
2146 return d
->normal_exp
;
2150 INLINE_SIM_FPU (uint64_t)
2151 sim_fpu_fraction (const sim_fpu
*d
)
2157 INLINE_SIM_FPU (uint64_t)
2158 sim_fpu_guard (const sim_fpu
*d
, int is_double
)
2161 uint64_t guardmask
= LSMASK64 (NR_GUARDS
- 1, 0);
2162 rv
= (d
->fraction
& guardmask
) >> NR_PAD
;
2167 INLINE_SIM_FPU (int)
2168 sim_fpu_is (const sim_fpu
*d
)
2172 case sim_fpu_class_qnan
:
2173 return SIM_FPU_IS_QNAN
;
2174 case sim_fpu_class_snan
:
2175 return SIM_FPU_IS_SNAN
;
2176 case sim_fpu_class_infinity
:
2178 return SIM_FPU_IS_NINF
;
2180 return SIM_FPU_IS_PINF
;
2181 case sim_fpu_class_number
:
2183 return SIM_FPU_IS_NNUMBER
;
2185 return SIM_FPU_IS_PNUMBER
;
2186 case sim_fpu_class_denorm
:
2188 return SIM_FPU_IS_NDENORM
;
2190 return SIM_FPU_IS_PDENORM
;
2191 case sim_fpu_class_zero
:
2193 return SIM_FPU_IS_NZERO
;
2195 return SIM_FPU_IS_PZERO
;
2202 INLINE_SIM_FPU (int)
2203 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2206 sim_fpu_sub (&res
, l
, r
);
2207 return sim_fpu_is (&res
);
2210 INLINE_SIM_FPU (int)
2211 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2214 sim_fpu_lt (&status
, l
, r
);
2218 INLINE_SIM_FPU (int)
2219 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2222 sim_fpu_le (&is
, l
, r
);
2226 INLINE_SIM_FPU (int)
2227 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2230 sim_fpu_eq (&is
, l
, r
);
2234 INLINE_SIM_FPU (int)
2235 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2238 sim_fpu_ne (&is
, l
, r
);
2242 INLINE_SIM_FPU (int)
2243 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2246 sim_fpu_ge (&is
, l
, r
);
2250 INLINE_SIM_FPU (int)
2251 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2254 sim_fpu_gt (&is
, l
, r
);
2259 /* Compare operators */
2261 INLINE_SIM_FPU (int)
2262 sim_fpu_lt (int *is
,
2266 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2270 lval
.i
= pack_fpu (l
, 1);
2271 rval
.i
= pack_fpu (r
, 1);
2272 (*is
) = (lval
.d
< rval
.d
);
2275 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2278 return sim_fpu_status_invalid_snan
;
2283 return sim_fpu_status_invalid_qnan
;
2287 INLINE_SIM_FPU (int)
2288 sim_fpu_le (int *is
,
2292 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2296 lval
.i
= pack_fpu (l
, 1);
2297 rval
.i
= pack_fpu (r
, 1);
2298 *is
= (lval
.d
<= rval
.d
);
2301 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2304 return sim_fpu_status_invalid_snan
;
2309 return sim_fpu_status_invalid_qnan
;
2313 INLINE_SIM_FPU (int)
2314 sim_fpu_eq (int *is
,
2318 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2322 lval
.i
= pack_fpu (l
, 1);
2323 rval
.i
= pack_fpu (r
, 1);
2324 (*is
) = (lval
.d
== rval
.d
);
2327 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2330 return sim_fpu_status_invalid_snan
;
2335 return sim_fpu_status_invalid_qnan
;
2339 INLINE_SIM_FPU (int)
2340 sim_fpu_ne (int *is
,
2344 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2348 lval
.i
= pack_fpu (l
, 1);
2349 rval
.i
= pack_fpu (r
, 1);
2350 (*is
) = (lval
.d
!= rval
.d
);
2353 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2356 return sim_fpu_status_invalid_snan
;
2361 return sim_fpu_status_invalid_qnan
;
2365 INLINE_SIM_FPU (int)
2366 sim_fpu_ge (int *is
,
2370 return sim_fpu_le (is
, r
, l
);
2373 INLINE_SIM_FPU (int)
2374 sim_fpu_gt (int *is
,
2378 return sim_fpu_lt (is
, r
, l
);
2382 /* A number of useful constants */
2384 #if EXTERN_SIM_FPU_P
2385 sim_fpu_state _sim_fpu
= {
2386 .quiet_nan_inverted
= false,
2389 const sim_fpu sim_fpu_zero
= {
2390 sim_fpu_class_zero
, 0, 0, 0
2392 const sim_fpu sim_fpu_qnan
= {
2393 sim_fpu_class_qnan
, 0, 0, 0
2395 const sim_fpu sim_fpu_one
= {
2396 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2398 const sim_fpu sim_fpu_two
= {
2399 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2401 const sim_fpu sim_fpu_max32
= {
2402 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2404 const sim_fpu sim_fpu_max64
= {
2405 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2412 INLINE_SIM_FPU (void)
2413 sim_fpu_print_fpu (const sim_fpu
*f
,
2414 sim_fpu_print_func
*print
,
2417 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2420 INLINE_SIM_FPU (void)
2421 sim_fpu_printn_fpu (const sim_fpu
*f
,
2422 sim_fpu_print_func
*print
,
2426 print (arg
, "%s", f
->sign
? "-" : "+");
2429 case sim_fpu_class_qnan
:
2431 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2432 print (arg
, "*QuietNaN");
2434 case sim_fpu_class_snan
:
2436 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2437 print (arg
, "*SignalNaN");
2439 case sim_fpu_class_zero
:
2442 case sim_fpu_class_infinity
:
2445 case sim_fpu_class_number
:
2446 case sim_fpu_class_denorm
:
2448 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2449 print (arg
, "*2^%+d", f
->normal_exp
);
2450 ASSERT (f
->fraction
>= IMPLICIT_1
);
2451 ASSERT (f
->fraction
< IMPLICIT_2
);
2456 INLINE_SIM_FPU (void)
2457 sim_fpu_print_status (int status
,
2458 sim_fpu_print_func
*print
,
2462 const char *prefix
= "";
2465 switch ((sim_fpu_status
) (status
& i
))
2467 case sim_fpu_status_denorm
:
2468 print (arg
, "%sD", prefix
);
2470 case sim_fpu_status_invalid_snan
:
2471 print (arg
, "%sSNaN", prefix
);
2473 case sim_fpu_status_invalid_qnan
:
2474 print (arg
, "%sQNaN", prefix
);
2476 case sim_fpu_status_invalid_isi
:
2477 print (arg
, "%sISI", prefix
);
2479 case sim_fpu_status_invalid_idi
:
2480 print (arg
, "%sIDI", prefix
);
2482 case sim_fpu_status_invalid_zdz
:
2483 print (arg
, "%sZDZ", prefix
);
2485 case sim_fpu_status_invalid_imz
:
2486 print (arg
, "%sIMZ", prefix
);
2488 case sim_fpu_status_invalid_cvi
:
2489 print (arg
, "%sCVI", prefix
);
2491 case sim_fpu_status_invalid_cmp
:
2492 print (arg
, "%sCMP", prefix
);
2494 case sim_fpu_status_invalid_sqrt
:
2495 print (arg
, "%sSQRT", prefix
);
2497 case sim_fpu_status_invalid_irx
:
2498 print (arg
, "%sIRX", prefix
);
2500 case sim_fpu_status_inexact
:
2501 print (arg
, "%sX", prefix
);
2503 case sim_fpu_status_overflow
:
2504 print (arg
, "%sO", prefix
);
2506 case sim_fpu_status_underflow
:
2507 print (arg
, "%sU", prefix
);
2509 case sim_fpu_status_invalid_div0
:
2510 print (arg
, "%s/", prefix
);
2512 case sim_fpu_status_rounded
:
2513 print (arg
, "%sR", prefix
);