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-2018 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"
46 If digits is -1, then print all digits. */
49 print_bits (unsigned64 x
,
52 sim_fpu_print_func print
,
55 unsigned64 bit
= LSBIT64 (msbit
);
76 /* Quick and dirty conversion between a host double and host 64bit int. */
85 /* A packed IEEE floating point number.
87 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
88 32 and 64 bit numbers. This number is interpreted as:
90 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
91 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
93 Denormalized (0 == BIASEDEXP && FRAC != 0):
94 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
96 Zero (0 == BIASEDEXP && FRAC == 0):
97 (sign ? "-" : "+") 0.0
99 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
100 (sign ? "-" : "+") "infinity"
102 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
105 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
110 #define NR_EXPBITS (is_double ? 11 : 8)
111 #define NR_FRACBITS (is_double ? 52 : 23)
112 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
114 #define EXPMAX32 (255)
115 #define EXMPAX64 (2047)
116 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
118 #define EXPBIAS32 (127)
119 #define EXPBIAS64 (1023)
120 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
122 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
126 /* An unpacked floating point number.
128 When unpacked, the fraction of both a 32 and 64 bit floating point
129 number is stored using the same format:
131 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
132 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
134 #define NR_PAD32 (30)
136 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
137 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
139 #define NR_GUARDS32 (7 + NR_PAD32)
140 #define NR_GUARDS64 (8 + NR_PAD64)
141 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
142 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
144 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
145 #define GUARDLSB LSBIT64 (NR_PAD)
146 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
148 #define NR_FRAC_GUARD (60)
149 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
150 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
151 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
154 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
156 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
158 #define NORMAL_EXPMAX32 (EXPBIAS32)
159 #define NORMAL_EXPMAX64 (EXPBIAS64)
160 #define NORMAL_EXPMAX (EXPBIAS)
163 /* Integer constants */
165 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
166 #define MAX_UINT32 LSMASK64 (31, 0)
167 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
169 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
170 #define MAX_UINT64 LSMASK64 (63, 0)
171 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
173 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
174 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
175 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
176 #define NR_INTBITS (is_64bit ? 64 : 32)
178 /* Squeeze an unpacked sim_fpu struct into a 32/64 bit integer. */
179 STATIC_INLINE_SIM_FPU (unsigned64
)
180 pack_fpu (const sim_fpu
*src
,
191 case sim_fpu_class_qnan
:
194 /* Force fraction to correct class. */
195 fraction
= src
->fraction
;
196 fraction
>>= NR_GUARDS
;
197 #ifdef SIM_QUIET_NAN_NEGATED
198 fraction
|= QUIET_NAN
- 1;
200 fraction
|= QUIET_NAN
;
203 case sim_fpu_class_snan
:
206 /* Force fraction to correct class. */
207 fraction
= src
->fraction
;
208 fraction
>>= NR_GUARDS
;
209 #ifdef SIM_QUIET_NAN_NEGATED
210 fraction
|= QUIET_NAN
;
212 fraction
&= ~QUIET_NAN
;
215 case sim_fpu_class_infinity
:
220 case sim_fpu_class_zero
:
225 case sim_fpu_class_number
:
226 case sim_fpu_class_denorm
:
227 ASSERT (src
->fraction
>= IMPLICIT_1
);
228 ASSERT (src
->fraction
< IMPLICIT_2
);
229 if (src
->normal_exp
< NORMAL_EXPMIN
)
231 /* This number's exponent is too low to fit into the bits
232 available in the number We'll denormalize the number by
233 storing zero in the exponent and shift the fraction to
234 the right to make up for it. */
235 int nr_shift
= NORMAL_EXPMIN
- src
->normal_exp
;
236 if (nr_shift
> NR_FRACBITS
)
238 /* Underflow, just make the number zero. */
247 /* Shift by the value. */
248 fraction
= src
->fraction
;
249 fraction
>>= NR_GUARDS
;
250 fraction
>>= nr_shift
;
253 else if (src
->normal_exp
> NORMAL_EXPMAX
)
262 exp
= (src
->normal_exp
+ EXPBIAS
);
264 fraction
= src
->fraction
;
265 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
267 /* Round to nearest: If the guard bits are the all zero, but
268 the first, then we're half way between two numbers,
269 choose the one which makes the lsb of the answer 0. */
270 if ((fraction
& GUARDMASK
) == GUARDMSB
)
272 if ((fraction
& (GUARDMSB
<< 1)))
273 fraction
+= (GUARDMSB
<< 1);
277 /* Add a one to the guards to force round to nearest. */
278 fraction
+= GUARDROUND
;
280 if ((fraction
& IMPLICIT_2
)) /* Rounding resulted in carry. */
285 fraction
>>= NR_GUARDS
;
286 /* When exp == EXPMAX (overflow from carry) fraction must
287 have been made zero. */
288 ASSERT ((exp
== EXPMAX
) <= ((fraction
& ~IMPLICIT_1
) == 0));
295 packed
= ((sign
? SIGNBIT
: 0)
296 | (exp
<< NR_FRACBITS
)
297 | LSMASKED64 (fraction
, NR_FRACBITS
- 1, 0));
299 /* Trace operation. */
306 printf ("pack_fpu: ");
307 printf ("-> %c%0lX.%06lX\n",
308 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
309 (long) LSEXTRACTED32 (packed
, 30, 23),
310 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
318 /* Unpack a 32/64 bit integer into a sim_fpu structure. */
319 STATIC_INLINE_SIM_FPU (void)
320 unpack_fpu (sim_fpu
*dst
, unsigned64 packed
, int is_double
)
322 unsigned64 fraction
= LSMASKED64 (packed
, NR_FRACBITS
- 1, 0);
323 unsigned exp
= LSEXTRACTED64 (packed
, NR_EXPBITS
+ NR_FRACBITS
- 1, NR_FRACBITS
);
324 int sign
= (packed
& SIGNBIT
) != 0;
328 /* Hmm. Looks like 0 */
331 /* Tastes like zero. */
332 dst
->class = sim_fpu_class_zero
;
338 /* Zero exponent with non zero fraction - it's denormalized,
339 so there isn't a leading implicit one - we'll shift it so
341 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
342 dst
->class = sim_fpu_class_denorm
;
344 fraction
<<= NR_GUARDS
;
345 while (fraction
< IMPLICIT_1
)
350 dst
->fraction
= fraction
;
353 else if (exp
== EXPMAX
)
358 /* Attached to a zero fraction - means infinity. */
359 dst
->class = sim_fpu_class_infinity
;
361 /* dst->normal_exp = EXPBIAS; */
362 /* dst->fraction = 0; */
368 /* Non zero fraction, means NaN. */
370 dst
->fraction
= (fraction
<< NR_GUARDS
);
371 #ifdef SIM_QUIET_NAN_NEGATED
372 qnan
= (fraction
& QUIET_NAN
) == 0;
374 qnan
= fraction
>= QUIET_NAN
;
377 dst
->class = sim_fpu_class_qnan
;
379 dst
->class = sim_fpu_class_snan
;
384 /* Nothing strange about this number. */
385 dst
->class = sim_fpu_class_number
;
387 dst
->fraction
= ((fraction
<< NR_GUARDS
) | IMPLICIT_1
);
388 dst
->normal_exp
= exp
- EXPBIAS
;
391 /* Trace operation. */
398 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
399 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
400 (long) LSEXTRACTED32 (packed
, 30, 23),
401 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
408 val
.i
= pack_fpu (dst
, 1);
411 ASSERT (val
.i
== packed
);
415 unsigned32 val
= pack_fpu (dst
, 0);
416 unsigned32 org
= packed
;
423 /* Convert a floating point into an integer. */
424 STATIC_INLINE_SIM_FPU (int)
433 if (sim_fpu_is_zero (s
))
438 if (sim_fpu_is_snan (s
))
440 *i
= MIN_INT
; /* FIXME */
441 return sim_fpu_status_invalid_cvi
;
443 if (sim_fpu_is_qnan (s
))
445 *i
= MIN_INT
; /* FIXME */
446 return sim_fpu_status_invalid_cvi
;
448 /* Map infinity onto MAX_INT... */
449 if (sim_fpu_is_infinity (s
))
451 *i
= s
->sign
? MIN_INT
: MAX_INT
;
452 return sim_fpu_status_invalid_cvi
;
454 /* It is a number, but a small one. */
455 if (s
->normal_exp
< 0)
458 return sim_fpu_status_inexact
;
460 /* Is the floating point MIN_INT or just close? */
461 if (s
->sign
&& s
->normal_exp
== (NR_INTBITS
- 1))
464 ASSERT (s
->fraction
>= IMPLICIT_1
);
465 if (s
->fraction
== IMPLICIT_1
)
466 return 0; /* exact */
467 if (is_64bit
) /* can't round */
468 return sim_fpu_status_invalid_cvi
; /* must be overflow */
469 /* For a 32bit with MAX_INT, rounding is possible. */
472 case sim_fpu_round_default
:
474 case sim_fpu_round_zero
:
475 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
476 return sim_fpu_status_invalid_cvi
;
478 return sim_fpu_status_inexact
;
480 case sim_fpu_round_near
:
482 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
483 return sim_fpu_status_invalid_cvi
;
484 else if ((s
->fraction
& !FRAC32MASK
) >= (~FRAC32MASK
>> 1))
485 return sim_fpu_status_invalid_cvi
;
487 return sim_fpu_status_inexact
;
489 case sim_fpu_round_up
:
490 if ((s
->fraction
& FRAC32MASK
) == IMPLICIT_1
)
491 return sim_fpu_status_inexact
;
493 return sim_fpu_status_invalid_cvi
;
494 case sim_fpu_round_down
:
495 return sim_fpu_status_invalid_cvi
;
498 /* Would right shifting result in the FRAC being shifted into
499 (through) the integer's sign bit? */
500 if (s
->normal_exp
> (NR_INTBITS
- 2))
502 *i
= s
->sign
? MIN_INT
: MAX_INT
;
503 return sim_fpu_status_invalid_cvi
;
505 /* Normal number, shift it into place. */
507 shift
= (s
->normal_exp
- (NR_FRAC_GUARD
));
515 if (tmp
& ((SIGNED64 (1) << shift
) - 1))
516 status
|= sim_fpu_status_inexact
;
519 *i
= s
->sign
? (-tmp
) : (tmp
);
523 /* Convert an integer into a floating point. */
524 STATIC_INLINE_SIM_FPU (int)
525 i2fpu (sim_fpu
*f
, signed64 i
, int is_64bit
)
530 f
->class = sim_fpu_class_zero
;
536 f
->class = sim_fpu_class_number
;
538 f
->normal_exp
= NR_FRAC_GUARD
;
542 /* Special case for minint, since there is no corresponding
543 +ve integer representation for it. */
546 f
->fraction
= IMPLICIT_1
;
547 f
->normal_exp
= NR_INTBITS
- 1;
555 if (f
->fraction
>= IMPLICIT_2
)
559 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
562 while (f
->fraction
>= IMPLICIT_2
);
564 else if (f
->fraction
< IMPLICIT_1
)
571 while (f
->fraction
< IMPLICIT_1
);
575 /* trace operation */
578 printf ("i2fpu: 0x%08lX ->\n", (long) i
);
585 fpu2i (&val
, f
, is_64bit
, sim_fpu_round_zero
);
586 if (i
>= MIN_INT32
&& i
<= MAX_INT32
)
596 /* Convert a floating point into an integer. */
597 STATIC_INLINE_SIM_FPU (int)
598 fpu2u (unsigned64
*u
, const sim_fpu
*s
, int is_64bit
)
600 const int is_double
= 1;
603 if (sim_fpu_is_zero (s
))
608 if (sim_fpu_is_nan (s
))
613 /* It is a negative number. */
619 /* Get reasonable MAX_USI_INT... */
620 if (sim_fpu_is_infinity (s
))
625 /* It is a number, but a small one. */
626 if (s
->normal_exp
< 0)
632 if (s
->normal_exp
> (NR_INTBITS
- 1))
638 tmp
= (s
->fraction
& ~PADMASK
);
639 shift
= (s
->normal_exp
- (NR_FRACBITS
+ NR_GUARDS
));
653 /* Convert an unsigned integer into a floating point. */
654 STATIC_INLINE_SIM_FPU (int)
655 u2fpu (sim_fpu
*f
, unsigned64 u
, int is_64bit
)
659 f
->class = sim_fpu_class_zero
;
665 f
->class = sim_fpu_class_number
;
667 f
->normal_exp
= NR_FRAC_GUARD
;
670 while (f
->fraction
< IMPLICIT_1
)
680 /* register <-> sim_fpu */
682 INLINE_SIM_FPU (void)
683 sim_fpu_32to (sim_fpu
*f
, unsigned32 s
)
685 unpack_fpu (f
, s
, 0);
689 INLINE_SIM_FPU (void)
690 sim_fpu_232to (sim_fpu
*f
, unsigned32 h
, unsigned32 l
)
694 unpack_fpu (f
, s
, 1);
698 INLINE_SIM_FPU (void)
699 sim_fpu_64to (sim_fpu
*f
, unsigned64 s
)
701 unpack_fpu (f
, s
, 1);
705 INLINE_SIM_FPU (void)
706 sim_fpu_to32 (unsigned32
*s
,
709 *s
= pack_fpu (f
, 0);
713 INLINE_SIM_FPU (void)
714 sim_fpu_to232 (unsigned32
*h
, unsigned32
*l
,
717 unsigned64 s
= pack_fpu (f
, 1);
723 INLINE_SIM_FPU (void)
724 sim_fpu_to64 (unsigned64
*u
,
727 *u
= pack_fpu (f
, 1);
731 INLINE_SIM_FPU (void)
732 sim_fpu_fractionto (sim_fpu
*f
,
738 int shift
= (NR_FRAC_GUARD
- precision
);
739 f
->class = sim_fpu_class_number
;
741 f
->normal_exp
= normal_exp
;
742 /* Shift the fraction to where sim-fpu expects it. */
744 f
->fraction
= (fraction
<< shift
);
746 f
->fraction
= (fraction
>> -shift
);
747 f
->fraction
|= IMPLICIT_1
;
751 INLINE_SIM_FPU (unsigned64
)
752 sim_fpu_tofraction (const sim_fpu
*d
,
755 /* We have NR_FRAC_GUARD bits, we want only PRECISION bits. */
756 int shift
= (NR_FRAC_GUARD
- precision
);
757 unsigned64 fraction
= (d
->fraction
& ~IMPLICIT_1
);
759 return fraction
>> shift
;
761 return fraction
<< -shift
;
767 STATIC_INLINE_SIM_FPU (int)
768 do_normal_overflow (sim_fpu
*f
,
774 case sim_fpu_round_default
:
776 case sim_fpu_round_near
:
777 f
->class = sim_fpu_class_infinity
;
779 case sim_fpu_round_up
:
781 f
->class = sim_fpu_class_infinity
;
783 case sim_fpu_round_down
:
785 f
->class = sim_fpu_class_infinity
;
787 case sim_fpu_round_zero
:
790 f
->normal_exp
= NORMAL_EXPMAX
;
791 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
792 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
795 STATIC_INLINE_SIM_FPU (int)
796 do_normal_underflow (sim_fpu
*f
,
802 case sim_fpu_round_default
:
804 case sim_fpu_round_near
:
805 f
->class = sim_fpu_class_zero
;
807 case sim_fpu_round_up
:
809 f
->class = sim_fpu_class_zero
;
811 case sim_fpu_round_down
:
813 f
->class = sim_fpu_class_zero
;
815 case sim_fpu_round_zero
:
816 f
->class = sim_fpu_class_zero
;
819 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
820 f
->fraction
= IMPLICIT_1
;
821 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
826 /* Round a number using NR_GUARDS.
827 Will return the rounded number or F->FRACTION == 0 when underflow. */
829 STATIC_INLINE_SIM_FPU (int)
830 do_normal_round (sim_fpu
*f
,
834 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
835 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
836 unsigned64 fraclsb
= guardmsb
<< 1;
837 if ((f
->fraction
& guardmask
))
839 int status
= sim_fpu_status_inexact
;
842 case sim_fpu_round_default
:
844 case sim_fpu_round_near
:
845 if ((f
->fraction
& guardmsb
))
847 if ((f
->fraction
& fraclsb
))
849 status
|= sim_fpu_status_rounded
;
851 else if ((f
->fraction
& (guardmask
>> 1)))
853 status
|= sim_fpu_status_rounded
;
857 case sim_fpu_round_up
:
859 status
|= sim_fpu_status_rounded
;
861 case sim_fpu_round_down
:
863 status
|= sim_fpu_status_rounded
;
865 case sim_fpu_round_zero
:
868 f
->fraction
&= ~guardmask
;
869 /* Round if needed, handle resulting overflow. */
870 if ((status
& sim_fpu_status_rounded
))
872 f
->fraction
+= fraclsb
;
873 if ((f
->fraction
& IMPLICIT_2
))
886 STATIC_INLINE_SIM_FPU (int)
887 do_round (sim_fpu
*f
,
890 sim_fpu_denorm denorm
)
894 case sim_fpu_class_qnan
:
895 case sim_fpu_class_zero
:
896 case sim_fpu_class_infinity
:
899 case sim_fpu_class_snan
:
900 /* Quieten a SignalingNaN. */
901 f
->class = sim_fpu_class_qnan
;
902 return sim_fpu_status_invalid_snan
;
904 case sim_fpu_class_number
:
905 case sim_fpu_class_denorm
:
908 ASSERT (f
->fraction
< IMPLICIT_2
);
909 ASSERT (f
->fraction
>= IMPLICIT_1
);
910 if (f
->normal_exp
< NORMAL_EXPMIN
)
912 /* This number's exponent is too low to fit into the bits
913 available in the number. Round off any bits that will be
914 discarded as a result of denormalization. Edge case is
915 the implicit bit shifted to GUARD0 and then rounded
917 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
918 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
919 && !(denorm
& sim_fpu_denorm_zero
))
921 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
922 if (f
->fraction
== 0) /* Rounding underflowed. */
924 status
|= do_normal_underflow (f
, is_double
, round
);
926 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
928 status
|= sim_fpu_status_denorm
;
929 /* Any loss of precision when denormalizing is
930 underflow. Some processors check for underflow
931 before rounding, some after! */
932 if (status
& sim_fpu_status_inexact
)
933 status
|= sim_fpu_status_underflow
;
934 /* Flag that resultant value has been denormalized. */
935 f
->class = sim_fpu_class_denorm
;
937 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
939 if ((status
& sim_fpu_status_inexact
))
940 status
|= sim_fpu_status_underflow
;
945 status
= do_normal_underflow (f
, is_double
, round
);
948 else if (f
->normal_exp
> NORMAL_EXPMAX
)
951 status
= do_normal_overflow (f
, is_double
, round
);
955 status
= do_normal_round (f
, NR_GUARDS
, round
);
956 if (f
->fraction
== 0)
957 /* f->class = sim_fpu_class_zero; */
958 status
|= do_normal_underflow (f
, is_double
, round
);
959 else if (f
->normal_exp
> NORMAL_EXPMAX
)
960 /* Oops! rounding caused overflow. */
961 status
|= do_normal_overflow (f
, is_double
, round
);
963 ASSERT ((f
->class == sim_fpu_class_number
964 || f
->class == sim_fpu_class_denorm
)
965 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
973 sim_fpu_round_32 (sim_fpu
*f
,
975 sim_fpu_denorm denorm
)
977 return do_round (f
, 0, round
, denorm
);
981 sim_fpu_round_64 (sim_fpu
*f
,
983 sim_fpu_denorm denorm
)
985 return do_round (f
, 1, round
, denorm
);
993 sim_fpu_add (sim_fpu
*f
,
997 if (sim_fpu_is_snan (l
))
1000 f
->class = sim_fpu_class_qnan
;
1001 return sim_fpu_status_invalid_snan
;
1003 if (sim_fpu_is_snan (r
))
1006 f
->class = sim_fpu_class_qnan
;
1007 return sim_fpu_status_invalid_snan
;
1009 if (sim_fpu_is_qnan (l
))
1014 if (sim_fpu_is_qnan (r
))
1019 if (sim_fpu_is_infinity (l
))
1021 if (sim_fpu_is_infinity (r
)
1022 && l
->sign
!= r
->sign
)
1025 return sim_fpu_status_invalid_isi
;
1030 if (sim_fpu_is_infinity (r
))
1035 if (sim_fpu_is_zero (l
))
1037 if (sim_fpu_is_zero (r
))
1040 f
->sign
= l
->sign
& r
->sign
;
1046 if (sim_fpu_is_zero (r
))
1053 int shift
= l
->normal_exp
- r
->normal_exp
;
1054 unsigned64 lfraction
;
1055 unsigned64 rfraction
;
1056 /* use exp of larger */
1057 if (shift
>= NR_FRAC_GUARD
)
1059 /* left has much bigger magnitude */
1061 return sim_fpu_status_inexact
;
1063 if (shift
<= - NR_FRAC_GUARD
)
1065 /* right has much bigger magnitude */
1067 return sim_fpu_status_inexact
;
1069 lfraction
= l
->fraction
;
1070 rfraction
= r
->fraction
;
1073 f
->normal_exp
= l
->normal_exp
;
1074 if (rfraction
& LSMASK64 (shift
- 1, 0))
1076 status
|= sim_fpu_status_inexact
;
1077 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1079 rfraction
>>= shift
;
1083 f
->normal_exp
= r
->normal_exp
;
1084 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1086 status
|= sim_fpu_status_inexact
;
1087 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1089 lfraction
>>= -shift
;
1093 f
->normal_exp
= r
->normal_exp
;
1096 /* Perform the addition. */
1098 lfraction
= - lfraction
;
1100 rfraction
= - rfraction
;
1101 f
->fraction
= lfraction
+ rfraction
;
1104 if (f
->fraction
== 0)
1111 f
->class = sim_fpu_class_number
;
1112 if (((signed64
) f
->fraction
) >= 0)
1117 f
->fraction
= - f
->fraction
;
1121 if ((f
->fraction
& IMPLICIT_2
))
1123 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1126 else if (f
->fraction
< IMPLICIT_1
)
1133 while (f
->fraction
< IMPLICIT_1
);
1135 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1141 INLINE_SIM_FPU (int)
1142 sim_fpu_sub (sim_fpu
*f
,
1146 if (sim_fpu_is_snan (l
))
1149 f
->class = sim_fpu_class_qnan
;
1150 return sim_fpu_status_invalid_snan
;
1152 if (sim_fpu_is_snan (r
))
1155 f
->class = sim_fpu_class_qnan
;
1156 return sim_fpu_status_invalid_snan
;
1158 if (sim_fpu_is_qnan (l
))
1163 if (sim_fpu_is_qnan (r
))
1168 if (sim_fpu_is_infinity (l
))
1170 if (sim_fpu_is_infinity (r
)
1171 && l
->sign
== r
->sign
)
1174 return sim_fpu_status_invalid_isi
;
1179 if (sim_fpu_is_infinity (r
))
1185 if (sim_fpu_is_zero (l
))
1187 if (sim_fpu_is_zero (r
))
1190 f
->sign
= l
->sign
& !r
->sign
;
1199 if (sim_fpu_is_zero (r
))
1206 int shift
= l
->normal_exp
- r
->normal_exp
;
1207 unsigned64 lfraction
;
1208 unsigned64 rfraction
;
1209 /* use exp of larger */
1210 if (shift
>= NR_FRAC_GUARD
)
1212 /* left has much bigger magnitude */
1214 return sim_fpu_status_inexact
;
1216 if (shift
<= - NR_FRAC_GUARD
)
1218 /* right has much bigger magnitude */
1221 return sim_fpu_status_inexact
;
1223 lfraction
= l
->fraction
;
1224 rfraction
= r
->fraction
;
1227 f
->normal_exp
= l
->normal_exp
;
1228 if (rfraction
& LSMASK64 (shift
- 1, 0))
1230 status
|= sim_fpu_status_inexact
;
1231 rfraction
|= LSBIT64 (shift
); /* Stick LSBit. */
1233 rfraction
>>= shift
;
1237 f
->normal_exp
= r
->normal_exp
;
1238 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1240 status
|= sim_fpu_status_inexact
;
1241 lfraction
|= LSBIT64 (- shift
); /* Stick LSBit. */
1243 lfraction
>>= -shift
;
1247 f
->normal_exp
= r
->normal_exp
;
1250 /* Perform the subtraction. */
1252 lfraction
= - lfraction
;
1254 rfraction
= - rfraction
;
1255 f
->fraction
= lfraction
+ rfraction
;
1258 if (f
->fraction
== 0)
1265 f
->class = sim_fpu_class_number
;
1266 if (((signed64
) f
->fraction
) >= 0)
1271 f
->fraction
= - f
->fraction
;
1275 if ((f
->fraction
& IMPLICIT_2
))
1277 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1280 else if (f
->fraction
< IMPLICIT_1
)
1287 while (f
->fraction
< IMPLICIT_1
);
1289 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1295 INLINE_SIM_FPU (int)
1296 sim_fpu_mul (sim_fpu
*f
,
1300 if (sim_fpu_is_snan (l
))
1303 f
->class = sim_fpu_class_qnan
;
1304 return sim_fpu_status_invalid_snan
;
1306 if (sim_fpu_is_snan (r
))
1309 f
->class = sim_fpu_class_qnan
;
1310 return sim_fpu_status_invalid_snan
;
1312 if (sim_fpu_is_qnan (l
))
1317 if (sim_fpu_is_qnan (r
))
1322 if (sim_fpu_is_infinity (l
))
1324 if (sim_fpu_is_zero (r
))
1327 return sim_fpu_status_invalid_imz
;
1330 f
->sign
= l
->sign
^ r
->sign
;
1333 if (sim_fpu_is_infinity (r
))
1335 if (sim_fpu_is_zero (l
))
1338 return sim_fpu_status_invalid_imz
;
1341 f
->sign
= l
->sign
^ r
->sign
;
1344 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1347 f
->sign
= l
->sign
^ r
->sign
;
1350 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1355 unsigned64 nl
= l
->fraction
& 0xffffffff;
1356 unsigned64 nh
= l
->fraction
>> 32;
1357 unsigned64 ml
= r
->fraction
& 0xffffffff;
1358 unsigned64 mh
= r
->fraction
>>32;
1359 unsigned64 pp_ll
= ml
* nl
;
1360 unsigned64 pp_hl
= mh
* nl
;
1361 unsigned64 pp_lh
= ml
* nh
;
1362 unsigned64 pp_hh
= mh
* nh
;
1363 unsigned64 res2
= 0;
1364 unsigned64 res0
= 0;
1365 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1366 if (ps_hh__
< pp_hl
)
1367 res2
+= UNSIGNED64 (0x100000000);
1368 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1369 res0
= pp_ll
+ pp_hl
;
1372 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1376 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1377 f
->sign
= l
->sign
^ r
->sign
;
1378 f
->class = sim_fpu_class_number
;
1380 /* Input is bounded by [1,2) ; [2^60,2^61)
1381 Output is bounded by [1,4) ; [2^120,2^122) */
1383 /* Adjust the exponent according to where the decimal point ended
1384 up in the high 64 bit word. In the source the decimal point
1385 was at NR_FRAC_GUARD. */
1386 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1388 /* The high word is bounded according to the above. Consequently
1389 it has never overflowed into IMPLICIT_2. */
1390 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1391 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1392 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1399 if (low
& LSBIT64 (63))
1403 while (high
< IMPLICIT_1
);
1405 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1408 f
->fraction
= (high
| 1); /* sticky */
1409 return sim_fpu_status_inexact
;
1420 INLINE_SIM_FPU (int)
1421 sim_fpu_div (sim_fpu
*f
,
1425 if (sim_fpu_is_snan (l
))
1428 f
->class = sim_fpu_class_qnan
;
1429 return sim_fpu_status_invalid_snan
;
1431 if (sim_fpu_is_snan (r
))
1434 f
->class = sim_fpu_class_qnan
;
1435 return sim_fpu_status_invalid_snan
;
1437 if (sim_fpu_is_qnan (l
))
1440 f
->class = sim_fpu_class_qnan
;
1443 if (sim_fpu_is_qnan (r
))
1446 f
->class = sim_fpu_class_qnan
;
1449 if (sim_fpu_is_infinity (l
))
1451 if (sim_fpu_is_infinity (r
))
1454 return sim_fpu_status_invalid_idi
;
1459 f
->sign
= l
->sign
^ r
->sign
;
1463 if (sim_fpu_is_zero (l
))
1465 if (sim_fpu_is_zero (r
))
1468 return sim_fpu_status_invalid_zdz
;
1473 f
->sign
= l
->sign
^ r
->sign
;
1477 if (sim_fpu_is_infinity (r
))
1480 f
->sign
= l
->sign
^ r
->sign
;
1483 if (sim_fpu_is_zero (r
))
1485 f
->class = sim_fpu_class_infinity
;
1486 f
->sign
= l
->sign
^ r
->sign
;
1487 return sim_fpu_status_invalid_div0
;
1490 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1493 /* quotient = ( ( numerator / denominator)
1494 x 2^(numerator exponent - denominator exponent)
1496 unsigned64 numerator
;
1497 unsigned64 denominator
;
1498 unsigned64 quotient
;
1501 f
->class = sim_fpu_class_number
;
1502 f
->sign
= l
->sign
^ r
->sign
;
1503 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1505 numerator
= l
->fraction
;
1506 denominator
= r
->fraction
;
1508 /* Fraction will be less than 1.0 */
1509 if (numerator
< denominator
)
1514 ASSERT (numerator
>= denominator
);
1516 /* Gain extra precision, already used one spare bit. */
1517 numerator
<<= NR_SPARE
;
1518 denominator
<<= NR_SPARE
;
1520 /* Does divide one bit at a time. Optimize??? */
1522 bit
= (IMPLICIT_1
<< NR_SPARE
);
1525 if (numerator
>= denominator
)
1528 numerator
-= denominator
;
1534 /* Discard (but save) the extra bits. */
1535 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1536 quotient
= (quotient
>> NR_SPARE
) | 1;
1538 quotient
= (quotient
>> NR_SPARE
);
1540 f
->fraction
= quotient
;
1541 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1544 f
->fraction
|= 1; /* Stick remaining bits. */
1545 return sim_fpu_status_inexact
;
1553 INLINE_SIM_FPU (int)
1554 sim_fpu_rem (sim_fpu
*f
,
1558 if (sim_fpu_is_snan (l
))
1561 f
->class = sim_fpu_class_qnan
;
1562 return sim_fpu_status_invalid_snan
;
1564 if (sim_fpu_is_snan (r
))
1567 f
->class = sim_fpu_class_qnan
;
1568 return sim_fpu_status_invalid_snan
;
1570 if (sim_fpu_is_qnan (l
))
1573 f
->class = sim_fpu_class_qnan
;
1576 if (sim_fpu_is_qnan (r
))
1579 f
->class = sim_fpu_class_qnan
;
1582 if (sim_fpu_is_infinity (l
))
1585 return sim_fpu_status_invalid_irx
;
1587 if (sim_fpu_is_zero (r
))
1590 return sim_fpu_status_invalid_div0
;
1592 if (sim_fpu_is_zero (l
))
1597 if (sim_fpu_is_infinity (r
))
1605 /* Remainder is calculated as l-n*r, where n is l/r rounded to the
1606 nearest integer. The variable n is rounded half even. */
1608 sim_fpu_div (&n
, l
, r
);
1609 sim_fpu_round_64 (&n
, 0, 0);
1611 if (n
.normal_exp
< -1) /* If n looks like zero just return l. */
1616 else if (n
.class == sim_fpu_class_number
1617 && n
.normal_exp
<= (NR_FRAC_GUARD
)) /* If not too large round. */
1618 do_normal_round (&n
, (NR_FRAC_GUARD
) - n
.normal_exp
, sim_fpu_round_near
);
1620 /* Mark 0's as zero so multiply can detect zero. */
1621 if (n
.fraction
== 0)
1622 n
.class = sim_fpu_class_zero
;
1624 /* Calculate n*r. */
1625 sim_fpu_mul (&tmp
, &n
, r
);
1626 sim_fpu_round_64 (&tmp
, 0, 0);
1628 /* Finally calculate l-n*r. */
1629 sim_fpu_sub (f
, l
, &tmp
);
1636 INLINE_SIM_FPU (int)
1637 sim_fpu_max (sim_fpu
*f
,
1641 if (sim_fpu_is_snan (l
))
1644 f
->class = sim_fpu_class_qnan
;
1645 return sim_fpu_status_invalid_snan
;
1647 if (sim_fpu_is_snan (r
))
1650 f
->class = sim_fpu_class_qnan
;
1651 return sim_fpu_status_invalid_snan
;
1653 if (sim_fpu_is_qnan (l
))
1658 if (sim_fpu_is_qnan (r
))
1663 if (sim_fpu_is_infinity (l
))
1665 if (sim_fpu_is_infinity (r
)
1666 && l
->sign
== r
->sign
)
1669 return sim_fpu_status_invalid_isi
;
1672 *f
= *r
; /* -inf < anything */
1674 *f
= *l
; /* +inf > anything */
1677 if (sim_fpu_is_infinity (r
))
1680 *f
= *l
; /* anything > -inf */
1682 *f
= *r
; /* anything < +inf */
1685 if (l
->sign
> r
->sign
)
1687 *f
= *r
; /* -ve < +ve */
1690 if (l
->sign
< r
->sign
)
1692 *f
= *l
; /* +ve > -ve */
1695 ASSERT (l
->sign
== r
->sign
);
1696 if (l
->normal_exp
> r
->normal_exp
1697 || (l
->normal_exp
== r
->normal_exp
1698 && l
->fraction
> r
->fraction
))
1702 *f
= *r
; /* -ve < -ve */
1704 *f
= *l
; /* +ve > +ve */
1711 *f
= *l
; /* -ve > -ve */
1713 *f
= *r
; /* +ve < +ve */
1719 INLINE_SIM_FPU (int)
1720 sim_fpu_min (sim_fpu
*f
,
1724 if (sim_fpu_is_snan (l
))
1727 f
->class = sim_fpu_class_qnan
;
1728 return sim_fpu_status_invalid_snan
;
1730 if (sim_fpu_is_snan (r
))
1733 f
->class = sim_fpu_class_qnan
;
1734 return sim_fpu_status_invalid_snan
;
1736 if (sim_fpu_is_qnan (l
))
1741 if (sim_fpu_is_qnan (r
))
1746 if (sim_fpu_is_infinity (l
))
1748 if (sim_fpu_is_infinity (r
)
1749 && l
->sign
== r
->sign
)
1752 return sim_fpu_status_invalid_isi
;
1755 *f
= *l
; /* -inf < anything */
1757 *f
= *r
; /* +inf > anthing */
1760 if (sim_fpu_is_infinity (r
))
1763 *f
= *r
; /* anything > -inf */
1765 *f
= *l
; /* anything < +inf */
1768 if (l
->sign
> r
->sign
)
1770 *f
= *l
; /* -ve < +ve */
1773 if (l
->sign
< r
->sign
)
1775 *f
= *r
; /* +ve > -ve */
1778 ASSERT (l
->sign
== r
->sign
);
1779 if (l
->normal_exp
> r
->normal_exp
1780 || (l
->normal_exp
== r
->normal_exp
1781 && l
->fraction
> r
->fraction
))
1785 *f
= *l
; /* -ve < -ve */
1787 *f
= *r
; /* +ve > +ve */
1794 *f
= *r
; /* -ve > -ve */
1796 *f
= *l
; /* +ve < +ve */
1802 INLINE_SIM_FPU (int)
1803 sim_fpu_neg (sim_fpu
*f
,
1806 if (sim_fpu_is_snan (r
))
1809 f
->class = sim_fpu_class_qnan
;
1810 return sim_fpu_status_invalid_snan
;
1812 if (sim_fpu_is_qnan (r
))
1823 INLINE_SIM_FPU (int)
1824 sim_fpu_abs (sim_fpu
*f
,
1829 if (sim_fpu_is_snan (r
))
1831 f
->class = sim_fpu_class_qnan
;
1832 return sim_fpu_status_invalid_snan
;
1838 INLINE_SIM_FPU (int)
1839 sim_fpu_inv (sim_fpu
*f
,
1842 return sim_fpu_div (f
, &sim_fpu_one
, r
);
1846 INLINE_SIM_FPU (int)
1847 sim_fpu_sqrt (sim_fpu
*f
,
1850 if (sim_fpu_is_snan (r
))
1853 return sim_fpu_status_invalid_snan
;
1855 if (sim_fpu_is_qnan (r
))
1860 if (sim_fpu_is_zero (r
))
1862 f
->class = sim_fpu_class_zero
;
1867 if (sim_fpu_is_infinity (r
))
1872 return sim_fpu_status_invalid_sqrt
;
1876 f
->class = sim_fpu_class_infinity
;
1885 return sim_fpu_status_invalid_sqrt
;
1888 /* @(#)e_sqrt.c 5.1 93/09/24 */
1890 * ====================================================
1891 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1893 * Developed at SunPro, a Sun Microsystems, Inc. business.
1894 * Permission to use, copy, modify, and distribute this
1895 * software is freely granted, provided that this notice
1897 * ====================================================
1900 /* __ieee754_sqrt(x)
1901 * Return correctly rounded sqrt.
1902 * ------------------------------------------
1903 * | Use the hardware sqrt if you have one |
1904 * ------------------------------------------
1906 * Bit by bit method using integer arithmetic. (Slow, but portable)
1908 * Scale x to y in [1,4) with even powers of 2:
1909 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1910 * sqrt(x) = 2^k * sqrt(y)
1913 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1914 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1916 - y = ((m even) ? x : 2.x)
1918 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1920 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1922 * 2. Bit by bit computation
1923 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1926 * s = 2*q , and y = 2 * ( y - q ). (1)
1929 * To compute q from q , one checks whether
1933 * (q + 2 ) <= y. (2)
1936 * If (2) is false, then q = q ; otherwise q = q + 2 .
1939 * With some algebraic manipulation, it is not difficult to see
1940 * that (2) is equivalent to
1945 * The advantage of (3) is that s and y can be computed by
1947 * the following recurrence formula:
1950 * s = s , y = y ; (4)
1959 * s = s + 2 , y = y - s - 2 (5)
1964 - NOTE: y = 2 (y - s - 2 )
1967 * One may easily use induction to prove (4) and (5).
1968 * Note. Since the left hand side of (3) contain only i+2 bits,
1969 * it does not necessary to do a full (53-bit) comparison
1972 * After generating the 53 bits result, we compute one more bit.
1973 * Together with the remainder, we can decide whether the
1974 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1975 * (it will never equal to 1/2ulp).
1976 * The rounding mode can be detected by checking whether
1977 * huge + tiny is equal to huge, and whether huge - tiny is
1978 * equal to huge for some floating point number "huge" and "tiny".
1981 * sqrt(+-0) = +-0 ... exact
1983 * sqrt(-ve) = NaN ... with invalid signal
1984 * sqrt(NaN) = NaN ... with invalid signal for signalling NaN
1986 * Other methods : see the appended file at the end of the program below.
1991 /* Generate sqrt(x) bit by bit. */
1997 f
->class = sim_fpu_class_number
;
2000 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
2002 /* Odd exp, double x to make it even. */
2003 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
2004 if ((r
->normal_exp
& 1))
2008 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
2010 /* Let loop determine first value of s (either 1 or 2) */
2017 unsigned64 t
= s
+ b
;
2028 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
2032 f
->fraction
|= 1; /* Stick remaining bits. */
2033 return sim_fpu_status_inexact
;
2041 /* int/long <-> sim_fpu */
2043 INLINE_SIM_FPU (int)
2044 sim_fpu_i32to (sim_fpu
*f
,
2046 sim_fpu_round round
)
2052 INLINE_SIM_FPU (int)
2053 sim_fpu_u32to (sim_fpu
*f
,
2055 sim_fpu_round round
)
2061 INLINE_SIM_FPU (int)
2062 sim_fpu_i64to (sim_fpu
*f
,
2064 sim_fpu_round round
)
2070 INLINE_SIM_FPU (int)
2071 sim_fpu_u64to (sim_fpu
*f
,
2073 sim_fpu_round round
)
2080 INLINE_SIM_FPU (int)
2081 sim_fpu_to32i (signed32
*i
,
2083 sim_fpu_round round
)
2086 int status
= fpu2i (&i64
, f
, 0, round
);
2091 INLINE_SIM_FPU (int)
2092 sim_fpu_to32u (unsigned32
*u
,
2094 sim_fpu_round round
)
2097 int status
= fpu2u (&u64
, f
, 0);
2102 INLINE_SIM_FPU (int)
2103 sim_fpu_to64i (signed64
*i
,
2105 sim_fpu_round round
)
2107 return fpu2i (i
, f
, 1, round
);
2111 INLINE_SIM_FPU (int)
2112 sim_fpu_to64u (unsigned64
*u
,
2114 sim_fpu_round round
)
2116 return fpu2u (u
, f
, 1);
2121 /* sim_fpu -> host format */
2124 INLINE_SIM_FPU (float)
2125 sim_fpu_2f (const sim_fpu
*f
)
2132 INLINE_SIM_FPU (double)
2133 sim_fpu_2d (const sim_fpu
*s
)
2136 if (sim_fpu_is_snan (s
))
2140 n
.class = sim_fpu_class_qnan
;
2141 val
.i
= pack_fpu (&n
, 1);
2145 val
.i
= pack_fpu (s
, 1);
2152 INLINE_SIM_FPU (void)
2153 sim_fpu_f2 (sim_fpu
*f
,
2158 unpack_fpu (f
, val
.i
, 1);
2163 INLINE_SIM_FPU (void)
2164 sim_fpu_d2 (sim_fpu
*f
,
2169 unpack_fpu (f
, val
.i
, 1);
2175 INLINE_SIM_FPU (int)
2176 sim_fpu_is_nan (const sim_fpu
*d
)
2180 case sim_fpu_class_qnan
:
2181 case sim_fpu_class_snan
:
2188 INLINE_SIM_FPU (int)
2189 sim_fpu_is_qnan (const sim_fpu
*d
)
2193 case sim_fpu_class_qnan
:
2200 INLINE_SIM_FPU (int)
2201 sim_fpu_is_snan (const sim_fpu
*d
)
2205 case sim_fpu_class_snan
:
2212 INLINE_SIM_FPU (int)
2213 sim_fpu_is_zero (const sim_fpu
*d
)
2217 case sim_fpu_class_zero
:
2224 INLINE_SIM_FPU (int)
2225 sim_fpu_is_infinity (const sim_fpu
*d
)
2229 case sim_fpu_class_infinity
:
2236 INLINE_SIM_FPU (int)
2237 sim_fpu_is_number (const sim_fpu
*d
)
2241 case sim_fpu_class_denorm
:
2242 case sim_fpu_class_number
:
2249 INLINE_SIM_FPU (int)
2250 sim_fpu_is_denorm (const sim_fpu
*d
)
2254 case sim_fpu_class_denorm
:
2262 INLINE_SIM_FPU (int)
2263 sim_fpu_sign (const sim_fpu
*d
)
2269 INLINE_SIM_FPU (int)
2270 sim_fpu_exp (const sim_fpu
*d
)
2272 return d
->normal_exp
;
2276 INLINE_SIM_FPU (unsigned64
)
2277 sim_fpu_fraction (const sim_fpu
*d
)
2283 INLINE_SIM_FPU (unsigned64
)
2284 sim_fpu_guard (const sim_fpu
*d
, int is_double
)
2287 unsigned64 guardmask
= LSMASK64 (NR_GUARDS
- 1, 0);
2288 rv
= (d
->fraction
& guardmask
) >> NR_PAD
;
2293 INLINE_SIM_FPU (int)
2294 sim_fpu_is (const sim_fpu
*d
)
2298 case sim_fpu_class_qnan
:
2299 return SIM_FPU_IS_QNAN
;
2300 case sim_fpu_class_snan
:
2301 return SIM_FPU_IS_SNAN
;
2302 case sim_fpu_class_infinity
:
2304 return SIM_FPU_IS_NINF
;
2306 return SIM_FPU_IS_PINF
;
2307 case sim_fpu_class_number
:
2309 return SIM_FPU_IS_NNUMBER
;
2311 return SIM_FPU_IS_PNUMBER
;
2312 case sim_fpu_class_denorm
:
2314 return SIM_FPU_IS_NDENORM
;
2316 return SIM_FPU_IS_PDENORM
;
2317 case sim_fpu_class_zero
:
2319 return SIM_FPU_IS_NZERO
;
2321 return SIM_FPU_IS_PZERO
;
2328 INLINE_SIM_FPU (int)
2329 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2332 sim_fpu_sub (&res
, l
, r
);
2333 return sim_fpu_is (&res
);
2336 INLINE_SIM_FPU (int)
2337 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2340 sim_fpu_lt (&status
, l
, r
);
2344 INLINE_SIM_FPU (int)
2345 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2348 sim_fpu_le (&is
, l
, r
);
2352 INLINE_SIM_FPU (int)
2353 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2356 sim_fpu_eq (&is
, l
, r
);
2360 INLINE_SIM_FPU (int)
2361 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2364 sim_fpu_ne (&is
, l
, r
);
2368 INLINE_SIM_FPU (int)
2369 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2372 sim_fpu_ge (&is
, l
, r
);
2376 INLINE_SIM_FPU (int)
2377 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2380 sim_fpu_gt (&is
, l
, r
);
2385 /* Compare operators */
2387 INLINE_SIM_FPU (int)
2388 sim_fpu_lt (int *is
,
2392 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2396 lval
.i
= pack_fpu (l
, 1);
2397 rval
.i
= pack_fpu (r
, 1);
2398 (*is
) = (lval
.d
< rval
.d
);
2401 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2404 return sim_fpu_status_invalid_snan
;
2409 return sim_fpu_status_invalid_qnan
;
2413 INLINE_SIM_FPU (int)
2414 sim_fpu_le (int *is
,
2418 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2422 lval
.i
= pack_fpu (l
, 1);
2423 rval
.i
= pack_fpu (r
, 1);
2424 *is
= (lval
.d
<= rval
.d
);
2427 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2430 return sim_fpu_status_invalid_snan
;
2435 return sim_fpu_status_invalid_qnan
;
2439 INLINE_SIM_FPU (int)
2440 sim_fpu_eq (int *is
,
2444 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2448 lval
.i
= pack_fpu (l
, 1);
2449 rval
.i
= pack_fpu (r
, 1);
2450 (*is
) = (lval
.d
== rval
.d
);
2453 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2456 return sim_fpu_status_invalid_snan
;
2461 return sim_fpu_status_invalid_qnan
;
2465 INLINE_SIM_FPU (int)
2466 sim_fpu_ne (int *is
,
2470 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2474 lval
.i
= pack_fpu (l
, 1);
2475 rval
.i
= pack_fpu (r
, 1);
2476 (*is
) = (lval
.d
!= rval
.d
);
2479 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2482 return sim_fpu_status_invalid_snan
;
2487 return sim_fpu_status_invalid_qnan
;
2491 INLINE_SIM_FPU (int)
2492 sim_fpu_ge (int *is
,
2496 return sim_fpu_le (is
, r
, l
);
2499 INLINE_SIM_FPU (int)
2500 sim_fpu_gt (int *is
,
2504 return sim_fpu_lt (is
, r
, l
);
2508 /* A number of useful constants */
2510 #if EXTERN_SIM_FPU_P
2511 const sim_fpu sim_fpu_zero
= {
2512 sim_fpu_class_zero
, 0, 0, 0
2514 const sim_fpu sim_fpu_qnan
= {
2515 sim_fpu_class_qnan
, 0, 0, 0
2517 const sim_fpu sim_fpu_one
= {
2518 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2520 const sim_fpu sim_fpu_two
= {
2521 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2523 const sim_fpu sim_fpu_max32
= {
2524 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2526 const sim_fpu sim_fpu_max64
= {
2527 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2534 INLINE_SIM_FPU (void)
2535 sim_fpu_print_fpu (const sim_fpu
*f
,
2536 sim_fpu_print_func
*print
,
2539 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2542 INLINE_SIM_FPU (void)
2543 sim_fpu_printn_fpu (const sim_fpu
*f
,
2544 sim_fpu_print_func
*print
,
2548 print (arg
, "%s", f
->sign
? "-" : "+");
2551 case sim_fpu_class_qnan
:
2553 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2554 print (arg
, "*QuietNaN");
2556 case sim_fpu_class_snan
:
2558 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2559 print (arg
, "*SignalNaN");
2561 case sim_fpu_class_zero
:
2564 case sim_fpu_class_infinity
:
2567 case sim_fpu_class_number
:
2568 case sim_fpu_class_denorm
:
2570 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2571 print (arg
, "*2^%+d", f
->normal_exp
);
2572 ASSERT (f
->fraction
>= IMPLICIT_1
);
2573 ASSERT (f
->fraction
< IMPLICIT_2
);
2578 INLINE_SIM_FPU (void)
2579 sim_fpu_print_status (int status
,
2580 sim_fpu_print_func
*print
,
2584 const char *prefix
= "";
2587 switch ((sim_fpu_status
) (status
& i
))
2589 case sim_fpu_status_denorm
:
2590 print (arg
, "%sD", prefix
);
2592 case sim_fpu_status_invalid_snan
:
2593 print (arg
, "%sSNaN", prefix
);
2595 case sim_fpu_status_invalid_qnan
:
2596 print (arg
, "%sQNaN", prefix
);
2598 case sim_fpu_status_invalid_isi
:
2599 print (arg
, "%sISI", prefix
);
2601 case sim_fpu_status_invalid_idi
:
2602 print (arg
, "%sIDI", prefix
);
2604 case sim_fpu_status_invalid_zdz
:
2605 print (arg
, "%sZDZ", prefix
);
2607 case sim_fpu_status_invalid_imz
:
2608 print (arg
, "%sIMZ", prefix
);
2610 case sim_fpu_status_invalid_cvi
:
2611 print (arg
, "%sCVI", prefix
);
2613 case sim_fpu_status_invalid_cmp
:
2614 print (arg
, "%sCMP", prefix
);
2616 case sim_fpu_status_invalid_sqrt
:
2617 print (arg
, "%sSQRT", prefix
);
2619 case sim_fpu_status_invalid_irx
:
2620 print (arg
, "%sIRX", prefix
);
2622 case sim_fpu_status_inexact
:
2623 print (arg
, "%sX", prefix
);
2625 case sim_fpu_status_overflow
:
2626 print (arg
, "%sO", prefix
);
2628 case sim_fpu_status_underflow
:
2629 print (arg
, "%sU", prefix
);
2631 case sim_fpu_status_invalid_div0
:
2632 print (arg
, "%s/", prefix
);
2634 case sim_fpu_status_rounded
:
2635 print (arg
, "%sR", prefix
);