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, 1997, 1998, 2003, 2007, 2008, 2009, 2010
6 Free Software Foundation, Inc.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* As a special exception, if you link this library with other files,
22 some of which are compiled with GCC, to produce an executable,
23 this library does not by itself cause the resulting executable
24 to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
28 /* This implements IEEE 754 format arithmetic, but does not provide a
29 mechanism for setting the rounding mode, or for generating or handling
32 The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
33 Wilson, all of Cygnus Support. */
39 #include "sim-basics.h"
43 #include "sim-assert.h"
47 If digits is -1, then print all digits. */
50 print_bits (unsigned64 x
,
53 sim_fpu_print_func print
,
56 unsigned64 bit
= LSBIT64 (msbit
);
69 if (digits
> 0) digits
--;
76 /* Quick and dirty conversion between a host double and host 64bit int */
84 /* A packed IEEE floating point number.
86 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
87 32 and 64 bit numbers. This number is interpreted as:
89 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
90 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
92 Denormalized (0 == BIASEDEXP && FRAC != 0):
93 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
95 Zero (0 == BIASEDEXP && FRAC == 0):
96 (sign ? "-" : "+") 0.0
98 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
99 (sign ? "-" : "+") "infinity"
101 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
104 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
109 #define NR_EXPBITS (is_double ? 11 : 8)
110 #define NR_FRACBITS (is_double ? 52 : 23)
111 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
113 #define EXPMAX32 (255)
114 #define EXMPAX64 (2047)
115 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
117 #define EXPBIAS32 (127)
118 #define EXPBIAS64 (1023)
119 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
121 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
125 /* An unpacked floating point number.
127 When unpacked, the fraction of both a 32 and 64 bit floating point
128 number is stored using the same format:
130 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
131 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
133 #define NR_PAD32 (30)
135 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
136 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
138 #define NR_GUARDS32 (7 + NR_PAD32)
139 #define NR_GUARDS64 (8 + NR_PAD64)
140 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
141 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
143 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
144 #define GUARDLSB LSBIT64 (NR_PAD)
145 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
147 #define NR_FRAC_GUARD (60)
148 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
149 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
150 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
153 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
155 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
157 #define NORMAL_EXPMAX32 (EXPBIAS32)
158 #define NORMAL_EXPMAX64 (EXPBIAS64)
159 #define NORMAL_EXPMAX (EXPBIAS)
162 /* Integer constants */
164 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
165 #define MAX_UINT32 LSMASK64 (31, 0)
166 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
168 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
169 #define MAX_UINT64 LSMASK64 (63, 0)
170 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
172 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
173 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
174 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
175 #define NR_INTBITS (is_64bit ? 64 : 32)
177 /* Squeese an unpacked sim_fpu struct into a 32/64 bit integer */
178 STATIC_INLINE_SIM_FPU (unsigned64
)
179 pack_fpu (const sim_fpu
*src
,
190 case sim_fpu_class_qnan
:
193 /* force fraction to correct class */
194 fraction
= src
->fraction
;
195 fraction
>>= NR_GUARDS
;
196 #ifdef SIM_QUIET_NAN_NEGATED
197 fraction
|= QUIET_NAN
- 1;
199 fraction
|= QUIET_NAN
;
202 case sim_fpu_class_snan
:
205 /* force fraction to correct class */
206 fraction
= src
->fraction
;
207 fraction
>>= NR_GUARDS
;
208 #ifdef SIM_QUIET_NAN_NEGATED
209 fraction
|= QUIET_NAN
;
211 fraction
&= ~QUIET_NAN
;
214 case sim_fpu_class_infinity
:
219 case sim_fpu_class_zero
:
224 case sim_fpu_class_number
:
225 case sim_fpu_class_denorm
:
226 ASSERT (src
->fraction
>= IMPLICIT_1
);
227 ASSERT (src
->fraction
< IMPLICIT_2
);
228 if (src
->normal_exp
< NORMAL_EXPMIN
)
230 /* This number's exponent is too low to fit into the bits
231 available in the number We'll denormalize the number by
232 storing zero in the exponent and shift the fraction to
233 the right to make up for it. */
234 int nr_shift
= NORMAL_EXPMIN
- src
->normal_exp
;
235 if (nr_shift
> NR_FRACBITS
)
237 /* underflow, just make the number zero */
246 /* Shift by the value */
247 fraction
= src
->fraction
;
248 fraction
>>= NR_GUARDS
;
249 fraction
>>= nr_shift
;
252 else if (src
->normal_exp
> NORMAL_EXPMAX
)
261 exp
= (src
->normal_exp
+ EXPBIAS
);
263 fraction
= src
->fraction
;
264 /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
266 /* Round to nearest: If the guard bits are the all zero, but
267 the first, then we're half way between two numbers,
268 choose the one which makes the lsb of the answer 0. */
269 if ((fraction
& GUARDMASK
) == GUARDMSB
)
271 if ((fraction
& (GUARDMSB
<< 1)))
272 fraction
+= (GUARDMSB
<< 1);
276 /* Add a one to the guards to force round to nearest */
277 fraction
+= GUARDROUND
;
279 if ((fraction
& IMPLICIT_2
)) /* rounding resulted in carry */
284 fraction
>>= NR_GUARDS
;
285 /* When exp == EXPMAX (overflow from carry) fraction must
286 have been made zero */
287 ASSERT ((exp
== EXPMAX
) <= ((fraction
& ~IMPLICIT_1
) == 0));
294 packed
= ((sign
? SIGNBIT
: 0)
295 | (exp
<< NR_FRACBITS
)
296 | LSMASKED64 (fraction
, NR_FRACBITS
- 1, 0));
298 /* trace operation */
305 printf ("pack_fpu: ");
306 printf ("-> %c%0lX.%06lX\n",
307 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
308 (long) LSEXTRACTED32 (packed
, 30, 23),
309 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
317 /* Unpack a 32/64 bit integer into a sim_fpu structure */
318 STATIC_INLINE_SIM_FPU (void)
319 unpack_fpu (sim_fpu
*dst
, unsigned64 packed
, int is_double
)
321 unsigned64 fraction
= LSMASKED64 (packed
, NR_FRACBITS
- 1, 0);
322 unsigned exp
= LSEXTRACTED64 (packed
, NR_EXPBITS
+ NR_FRACBITS
- 1, NR_FRACBITS
);
323 int sign
= (packed
& SIGNBIT
) != 0;
327 /* Hmm. Looks like 0 */
330 /* tastes like zero */
331 dst
->class = sim_fpu_class_zero
;
337 /* Zero exponent with non zero fraction - it's denormalized,
338 so there isn't a leading implicit one - we'll shift it so
340 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
341 dst
->class = sim_fpu_class_denorm
;
343 fraction
<<= NR_GUARDS
;
344 while (fraction
< IMPLICIT_1
)
349 dst
->fraction
= fraction
;
352 else if (exp
== EXPMAX
)
357 /* Attached to a zero fraction - means infinity */
358 dst
->class = sim_fpu_class_infinity
;
360 /* dst->normal_exp = EXPBIAS; */
361 /* dst->fraction = 0; */
367 /* Non zero fraction, means NaN */
369 dst
->fraction
= (fraction
<< NR_GUARDS
);
370 #ifdef SIM_QUIET_NAN_NEGATED
371 qnan
= (fraction
& QUIET_NAN
) == 0;
373 qnan
= fraction
>= QUIET_NAN
;
376 dst
->class = sim_fpu_class_qnan
;
378 dst
->class = sim_fpu_class_snan
;
383 /* Nothing strange about this number */
384 dst
->class = sim_fpu_class_number
;
386 dst
->fraction
= ((fraction
<< NR_GUARDS
) | IMPLICIT_1
);
387 dst
->normal_exp
= exp
- EXPBIAS
;
390 /* trace operation */
397 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
398 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
399 (long) LSEXTRACTED32 (packed
, 30, 23),
400 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
407 val
.i
= pack_fpu (dst
, 1);
410 ASSERT (val
.i
== packed
);
414 unsigned32 val
= pack_fpu (dst
, 0);
415 unsigned32 org
= packed
;
422 /* Convert a floating point into an integer */
423 STATIC_INLINE_SIM_FPU (int)
432 if (sim_fpu_is_zero (s
))
437 if (sim_fpu_is_snan (s
))
439 *i
= MIN_INT
; /* FIXME */
440 return sim_fpu_status_invalid_cvi
;
442 if (sim_fpu_is_qnan (s
))
444 *i
= MIN_INT
; /* FIXME */
445 return sim_fpu_status_invalid_cvi
;
447 /* map infinity onto MAX_INT... */
448 if (sim_fpu_is_infinity (s
))
450 *i
= s
->sign
? MIN_INT
: MAX_INT
;
451 return sim_fpu_status_invalid_cvi
;
453 /* it is a number, but a small one */
454 if (s
->normal_exp
< 0)
457 return sim_fpu_status_inexact
;
459 /* Is the floating point MIN_INT or just close? */
460 if (s
->sign
&& s
->normal_exp
== (NR_INTBITS
- 1))
463 ASSERT (s
->fraction
>= IMPLICIT_1
);
464 if (s
->fraction
== IMPLICIT_1
)
465 return 0; /* exact */
466 if (is_64bit
) /* can't round */
467 return sim_fpu_status_invalid_cvi
; /* must be overflow */
468 /* For a 32bit with MAX_INT, rounding is possible */
471 case sim_fpu_round_default
:
473 case sim_fpu_round_zero
:
474 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
475 return sim_fpu_status_invalid_cvi
;
477 return sim_fpu_status_inexact
;
479 case sim_fpu_round_near
:
481 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
482 return sim_fpu_status_invalid_cvi
;
483 else if ((s
->fraction
& !FRAC32MASK
) >= (~FRAC32MASK
>> 1))
484 return sim_fpu_status_invalid_cvi
;
486 return sim_fpu_status_inexact
;
488 case sim_fpu_round_up
:
489 if ((s
->fraction
& FRAC32MASK
) == IMPLICIT_1
)
490 return sim_fpu_status_inexact
;
492 return sim_fpu_status_invalid_cvi
;
493 case sim_fpu_round_down
:
494 return sim_fpu_status_invalid_cvi
;
497 /* Would right shifting result in the FRAC being shifted into
498 (through) the integer's sign bit? */
499 if (s
->normal_exp
> (NR_INTBITS
- 2))
501 *i
= s
->sign
? MIN_INT
: MAX_INT
;
502 return sim_fpu_status_invalid_cvi
;
504 /* normal number shift it into place */
506 shift
= (s
->normal_exp
- (NR_FRAC_GUARD
));
514 if (tmp
& ((SIGNED64 (1) << shift
) - 1))
515 status
|= sim_fpu_status_inexact
;
518 *i
= s
->sign
? (-tmp
) : (tmp
);
522 /* convert an integer into a floating point */
523 STATIC_INLINE_SIM_FPU (int)
524 i2fpu (sim_fpu
*f
, signed64 i
, int is_64bit
)
529 f
->class = sim_fpu_class_zero
;
535 f
->class = sim_fpu_class_number
;
537 f
->normal_exp
= NR_FRAC_GUARD
;
541 /* Special case for minint, since there is no corresponding
542 +ve integer representation for it */
545 f
->fraction
= IMPLICIT_1
;
546 f
->normal_exp
= NR_INTBITS
- 1;
554 if (f
->fraction
>= IMPLICIT_2
)
558 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
561 while (f
->fraction
>= IMPLICIT_2
);
563 else if (f
->fraction
< IMPLICIT_1
)
570 while (f
->fraction
< IMPLICIT_1
);
574 /* trace operation */
577 printf ("i2fpu: 0x%08lX ->\n", (long) i
);
584 fpu2i (&val
, f
, is_64bit
, sim_fpu_round_zero
);
585 if (i
>= MIN_INT32
&& i
<= MAX_INT32
)
595 /* Convert a floating point into an integer */
596 STATIC_INLINE_SIM_FPU (int)
597 fpu2u (unsigned64
*u
, const sim_fpu
*s
, int is_64bit
)
599 const int is_double
= 1;
602 if (sim_fpu_is_zero (s
))
607 if (sim_fpu_is_nan (s
))
612 /* it is a negative number */
618 /* get reasonable MAX_USI_INT... */
619 if (sim_fpu_is_infinity (s
))
624 /* it is a number, but a small one */
625 if (s
->normal_exp
< 0)
631 if (s
->normal_exp
> (NR_INTBITS
- 1))
637 tmp
= (s
->fraction
& ~PADMASK
);
638 shift
= (s
->normal_exp
- (NR_FRACBITS
+ NR_GUARDS
));
652 /* Convert an unsigned integer into a floating point */
653 STATIC_INLINE_SIM_FPU (int)
654 u2fpu (sim_fpu
*f
, unsigned64 u
, int is_64bit
)
658 f
->class = sim_fpu_class_zero
;
664 f
->class = sim_fpu_class_number
;
666 f
->normal_exp
= NR_FRAC_GUARD
;
669 while (f
->fraction
< IMPLICIT_1
)
679 /* register <-> sim_fpu */
681 INLINE_SIM_FPU (void)
682 sim_fpu_32to (sim_fpu
*f
, unsigned32 s
)
684 unpack_fpu (f
, s
, 0);
688 INLINE_SIM_FPU (void)
689 sim_fpu_232to (sim_fpu
*f
, unsigned32 h
, unsigned32 l
)
693 unpack_fpu (f
, s
, 1);
697 INLINE_SIM_FPU (void)
698 sim_fpu_64to (sim_fpu
*f
, unsigned64 s
)
700 unpack_fpu (f
, s
, 1);
704 INLINE_SIM_FPU (void)
705 sim_fpu_to32 (unsigned32
*s
,
708 *s
= pack_fpu (f
, 0);
712 INLINE_SIM_FPU (void)
713 sim_fpu_to232 (unsigned32
*h
, unsigned32
*l
,
716 unsigned64 s
= pack_fpu (f
, 1);
722 INLINE_SIM_FPU (void)
723 sim_fpu_to64 (unsigned64
*u
,
726 *u
= pack_fpu (f
, 1);
730 INLINE_SIM_FPU (void)
731 sim_fpu_fractionto (sim_fpu
*f
,
737 int shift
= (NR_FRAC_GUARD
- precision
);
738 f
->class = sim_fpu_class_number
;
740 f
->normal_exp
= normal_exp
;
741 /* shift the fraction to where sim-fpu expects it */
743 f
->fraction
= (fraction
<< shift
);
745 f
->fraction
= (fraction
>> -shift
);
746 f
->fraction
|= IMPLICIT_1
;
750 INLINE_SIM_FPU (unsigned64
)
751 sim_fpu_tofraction (const sim_fpu
*d
,
754 /* we have NR_FRAC_GUARD bits, we want only PRECISION bits */
755 int shift
= (NR_FRAC_GUARD
- precision
);
756 unsigned64 fraction
= (d
->fraction
& ~IMPLICIT_1
);
758 return fraction
>> shift
;
760 return fraction
<< -shift
;
766 STATIC_INLINE_SIM_FPU (int)
767 do_normal_overflow (sim_fpu
*f
,
773 case sim_fpu_round_default
:
775 case sim_fpu_round_near
:
776 f
->class = sim_fpu_class_infinity
;
778 case sim_fpu_round_up
:
780 f
->class = sim_fpu_class_infinity
;
782 case sim_fpu_round_down
:
784 f
->class = sim_fpu_class_infinity
;
786 case sim_fpu_round_zero
:
789 f
->normal_exp
= NORMAL_EXPMAX
;
790 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
791 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
794 STATIC_INLINE_SIM_FPU (int)
795 do_normal_underflow (sim_fpu
*f
,
801 case sim_fpu_round_default
:
803 case sim_fpu_round_near
:
804 f
->class = sim_fpu_class_zero
;
806 case sim_fpu_round_up
:
808 f
->class = sim_fpu_class_zero
;
810 case sim_fpu_round_down
:
812 f
->class = sim_fpu_class_zero
;
814 case sim_fpu_round_zero
:
815 f
->class = sim_fpu_class_zero
;
818 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
819 f
->fraction
= IMPLICIT_1
;
820 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
825 /* Round a number using NR_GUARDS.
826 Will return the rounded number or F->FRACTION == 0 when underflow */
828 STATIC_INLINE_SIM_FPU (int)
829 do_normal_round (sim_fpu
*f
,
833 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
834 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
835 unsigned64 fraclsb
= guardmsb
<< 1;
836 if ((f
->fraction
& guardmask
))
838 int status
= sim_fpu_status_inexact
;
841 case sim_fpu_round_default
:
843 case sim_fpu_round_near
:
844 if ((f
->fraction
& guardmsb
))
846 if ((f
->fraction
& fraclsb
))
848 status
|= sim_fpu_status_rounded
;
850 else if ((f
->fraction
& (guardmask
>> 1)))
852 status
|= sim_fpu_status_rounded
;
856 case sim_fpu_round_up
:
858 status
|= sim_fpu_status_rounded
;
860 case sim_fpu_round_down
:
862 status
|= sim_fpu_status_rounded
;
864 case sim_fpu_round_zero
:
867 f
->fraction
&= ~guardmask
;
868 /* round if needed, handle resulting overflow */
869 if ((status
& sim_fpu_status_rounded
))
871 f
->fraction
+= fraclsb
;
872 if ((f
->fraction
& IMPLICIT_2
))
885 STATIC_INLINE_SIM_FPU (int)
886 do_round (sim_fpu
*f
,
889 sim_fpu_denorm denorm
)
893 case sim_fpu_class_qnan
:
894 case sim_fpu_class_zero
:
895 case sim_fpu_class_infinity
:
898 case sim_fpu_class_snan
:
899 /* Quieten a SignalingNaN */
900 f
->class = sim_fpu_class_qnan
;
901 return sim_fpu_status_invalid_snan
;
903 case sim_fpu_class_number
:
904 case sim_fpu_class_denorm
:
907 ASSERT (f
->fraction
< IMPLICIT_2
);
908 ASSERT (f
->fraction
>= IMPLICIT_1
);
909 if (f
->normal_exp
< NORMAL_EXPMIN
)
911 /* This number's exponent is too low to fit into the bits
912 available in the number. Round off any bits that will be
913 discarded as a result of denormalization. Edge case is
914 the implicit bit shifted to GUARD0 and then rounded
916 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
917 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
918 && !(denorm
& sim_fpu_denorm_zero
))
920 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
921 if (f
->fraction
== 0) /* rounding underflowed */
923 status
|= do_normal_underflow (f
, is_double
, round
);
925 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
927 status
|= sim_fpu_status_denorm
;
928 /* Any loss of precision when denormalizing is
929 underflow. Some processors check for underflow
930 before rounding, some after! */
931 if (status
& sim_fpu_status_inexact
)
932 status
|= sim_fpu_status_underflow
;
933 /* Flag that resultant value has been denormalized */
934 f
->class = sim_fpu_class_denorm
;
936 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
938 if ((status
& sim_fpu_status_inexact
))
939 status
|= sim_fpu_status_underflow
;
944 status
= do_normal_underflow (f
, is_double
, round
);
947 else if (f
->normal_exp
> NORMAL_EXPMAX
)
950 status
= do_normal_overflow (f
, is_double
, round
);
954 status
= do_normal_round (f
, NR_GUARDS
, round
);
955 if (f
->fraction
== 0)
956 /* f->class = sim_fpu_class_zero; */
957 status
|= do_normal_underflow (f
, is_double
, round
);
958 else if (f
->normal_exp
> NORMAL_EXPMAX
)
959 /* oops! rounding caused overflow */
960 status
|= do_normal_overflow (f
, is_double
, round
);
962 ASSERT ((f
->class == sim_fpu_class_number
963 || f
->class == sim_fpu_class_denorm
)
964 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
972 sim_fpu_round_32 (sim_fpu
*f
,
974 sim_fpu_denorm denorm
)
976 return do_round (f
, 0, round
, denorm
);
980 sim_fpu_round_64 (sim_fpu
*f
,
982 sim_fpu_denorm denorm
)
984 return do_round (f
, 1, round
, denorm
);
992 sim_fpu_add (sim_fpu
*f
,
996 if (sim_fpu_is_snan (l
))
999 f
->class = sim_fpu_class_qnan
;
1000 return sim_fpu_status_invalid_snan
;
1002 if (sim_fpu_is_snan (r
))
1005 f
->class = sim_fpu_class_qnan
;
1006 return sim_fpu_status_invalid_snan
;
1008 if (sim_fpu_is_qnan (l
))
1013 if (sim_fpu_is_qnan (r
))
1018 if (sim_fpu_is_infinity (l
))
1020 if (sim_fpu_is_infinity (r
)
1021 && l
->sign
!= r
->sign
)
1024 return sim_fpu_status_invalid_isi
;
1029 if (sim_fpu_is_infinity (r
))
1034 if (sim_fpu_is_zero (l
))
1036 if (sim_fpu_is_zero (r
))
1039 f
->sign
= l
->sign
& r
->sign
;
1045 if (sim_fpu_is_zero (r
))
1052 int shift
= l
->normal_exp
- r
->normal_exp
;
1053 unsigned64 lfraction
;
1054 unsigned64 rfraction
;
1055 /* use exp of larger */
1056 if (shift
>= NR_FRAC_GUARD
)
1058 /* left has much bigger magnitute */
1060 return sim_fpu_status_inexact
;
1062 if (shift
<= - NR_FRAC_GUARD
)
1064 /* right has much bigger magnitute */
1066 return sim_fpu_status_inexact
;
1068 lfraction
= l
->fraction
;
1069 rfraction
= r
->fraction
;
1072 f
->normal_exp
= l
->normal_exp
;
1073 if (rfraction
& LSMASK64 (shift
- 1, 0))
1075 status
|= sim_fpu_status_inexact
;
1076 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1078 rfraction
>>= shift
;
1082 f
->normal_exp
= r
->normal_exp
;
1083 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1085 status
|= sim_fpu_status_inexact
;
1086 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1088 lfraction
>>= -shift
;
1092 f
->normal_exp
= r
->normal_exp
;
1095 /* perform the addition */
1097 lfraction
= - lfraction
;
1099 rfraction
= - rfraction
;
1100 f
->fraction
= lfraction
+ rfraction
;
1103 if (f
->fraction
== 0)
1110 f
->class = sim_fpu_class_number
;
1111 if ((signed64
) f
->fraction
>= 0)
1116 f
->fraction
= - f
->fraction
;
1120 if ((f
->fraction
& IMPLICIT_2
))
1122 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1125 else if (f
->fraction
< IMPLICIT_1
)
1132 while (f
->fraction
< IMPLICIT_1
);
1134 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1140 INLINE_SIM_FPU (int)
1141 sim_fpu_sub (sim_fpu
*f
,
1145 if (sim_fpu_is_snan (l
))
1148 f
->class = sim_fpu_class_qnan
;
1149 return sim_fpu_status_invalid_snan
;
1151 if (sim_fpu_is_snan (r
))
1154 f
->class = sim_fpu_class_qnan
;
1155 return sim_fpu_status_invalid_snan
;
1157 if (sim_fpu_is_qnan (l
))
1162 if (sim_fpu_is_qnan (r
))
1167 if (sim_fpu_is_infinity (l
))
1169 if (sim_fpu_is_infinity (r
)
1170 && l
->sign
== r
->sign
)
1173 return sim_fpu_status_invalid_isi
;
1178 if (sim_fpu_is_infinity (r
))
1184 if (sim_fpu_is_zero (l
))
1186 if (sim_fpu_is_zero (r
))
1189 f
->sign
= l
->sign
& !r
->sign
;
1198 if (sim_fpu_is_zero (r
))
1205 int shift
= l
->normal_exp
- r
->normal_exp
;
1206 unsigned64 lfraction
;
1207 unsigned64 rfraction
;
1208 /* use exp of larger */
1209 if (shift
>= NR_FRAC_GUARD
)
1211 /* left has much bigger magnitute */
1213 return sim_fpu_status_inexact
;
1215 if (shift
<= - NR_FRAC_GUARD
)
1217 /* right has much bigger magnitute */
1220 return sim_fpu_status_inexact
;
1222 lfraction
= l
->fraction
;
1223 rfraction
= r
->fraction
;
1226 f
->normal_exp
= l
->normal_exp
;
1227 if (rfraction
& LSMASK64 (shift
- 1, 0))
1229 status
|= sim_fpu_status_inexact
;
1230 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1232 rfraction
>>= shift
;
1236 f
->normal_exp
= r
->normal_exp
;
1237 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1239 status
|= sim_fpu_status_inexact
;
1240 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1242 lfraction
>>= -shift
;
1246 f
->normal_exp
= r
->normal_exp
;
1249 /* perform the subtraction */
1251 lfraction
= - lfraction
;
1253 rfraction
= - rfraction
;
1254 f
->fraction
= lfraction
+ rfraction
;
1257 if (f
->fraction
== 0)
1264 f
->class = sim_fpu_class_number
;
1265 if ((signed64
) f
->fraction
>= 0)
1270 f
->fraction
= - f
->fraction
;
1274 if ((f
->fraction
& IMPLICIT_2
))
1276 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1279 else if (f
->fraction
< IMPLICIT_1
)
1286 while (f
->fraction
< IMPLICIT_1
);
1288 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1294 INLINE_SIM_FPU (int)
1295 sim_fpu_mul (sim_fpu
*f
,
1299 if (sim_fpu_is_snan (l
))
1302 f
->class = sim_fpu_class_qnan
;
1303 return sim_fpu_status_invalid_snan
;
1305 if (sim_fpu_is_snan (r
))
1308 f
->class = sim_fpu_class_qnan
;
1309 return sim_fpu_status_invalid_snan
;
1311 if (sim_fpu_is_qnan (l
))
1316 if (sim_fpu_is_qnan (r
))
1321 if (sim_fpu_is_infinity (l
))
1323 if (sim_fpu_is_zero (r
))
1326 return sim_fpu_status_invalid_imz
;
1329 f
->sign
= l
->sign
^ r
->sign
;
1332 if (sim_fpu_is_infinity (r
))
1334 if (sim_fpu_is_zero (l
))
1337 return sim_fpu_status_invalid_imz
;
1340 f
->sign
= l
->sign
^ r
->sign
;
1343 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1346 f
->sign
= l
->sign
^ r
->sign
;
1349 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1354 unsigned64 nl
= l
->fraction
& 0xffffffff;
1355 unsigned64 nh
= l
->fraction
>> 32;
1356 unsigned64 ml
= r
->fraction
& 0xffffffff;
1357 unsigned64 mh
= r
->fraction
>>32;
1358 unsigned64 pp_ll
= ml
* nl
;
1359 unsigned64 pp_hl
= mh
* nl
;
1360 unsigned64 pp_lh
= ml
* nh
;
1361 unsigned64 pp_hh
= mh
* nh
;
1362 unsigned64 res2
= 0;
1363 unsigned64 res0
= 0;
1364 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1365 if (ps_hh__
< pp_hl
)
1366 res2
+= UNSIGNED64 (0x100000000);
1367 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1368 res0
= pp_ll
+ pp_hl
;
1371 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1375 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1376 f
->sign
= l
->sign
^ r
->sign
;
1377 f
->class = sim_fpu_class_number
;
1379 /* Input is bounded by [1,2) ; [2^60,2^61)
1380 Output is bounded by [1,4) ; [2^120,2^122) */
1382 /* Adjust the exponent according to where the decimal point ended
1383 up in the high 64 bit word. In the source the decimal point
1384 was at NR_FRAC_GUARD. */
1385 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1387 /* The high word is bounded according to the above. Consequently
1388 it has never overflowed into IMPLICIT_2. */
1389 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1390 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1391 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1398 if (low
& LSBIT64 (63))
1402 while (high
< IMPLICIT_1
);
1404 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1407 f
->fraction
= (high
| 1); /* sticky */
1408 return sim_fpu_status_inexact
;
1419 INLINE_SIM_FPU (int)
1420 sim_fpu_div (sim_fpu
*f
,
1424 if (sim_fpu_is_snan (l
))
1427 f
->class = sim_fpu_class_qnan
;
1428 return sim_fpu_status_invalid_snan
;
1430 if (sim_fpu_is_snan (r
))
1433 f
->class = sim_fpu_class_qnan
;
1434 return sim_fpu_status_invalid_snan
;
1436 if (sim_fpu_is_qnan (l
))
1439 f
->class = sim_fpu_class_qnan
;
1442 if (sim_fpu_is_qnan (r
))
1445 f
->class = sim_fpu_class_qnan
;
1448 if (sim_fpu_is_infinity (l
))
1450 if (sim_fpu_is_infinity (r
))
1453 return sim_fpu_status_invalid_idi
;
1458 f
->sign
= l
->sign
^ r
->sign
;
1462 if (sim_fpu_is_zero (l
))
1464 if (sim_fpu_is_zero (r
))
1467 return sim_fpu_status_invalid_zdz
;
1472 f
->sign
= l
->sign
^ r
->sign
;
1476 if (sim_fpu_is_infinity (r
))
1479 f
->sign
= l
->sign
^ r
->sign
;
1482 if (sim_fpu_is_zero (r
))
1484 f
->class = sim_fpu_class_infinity
;
1485 f
->sign
= l
->sign
^ r
->sign
;
1486 return sim_fpu_status_invalid_div0
;
1489 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1492 /* quotient = ( ( numerator / denominator)
1493 x 2^(numerator exponent - denominator exponent)
1495 unsigned64 numerator
;
1496 unsigned64 denominator
;
1497 unsigned64 quotient
;
1500 f
->class = sim_fpu_class_number
;
1501 f
->sign
= l
->sign
^ r
->sign
;
1502 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1504 numerator
= l
->fraction
;
1505 denominator
= r
->fraction
;
1507 /* Fraction will be less than 1.0 */
1508 if (numerator
< denominator
)
1513 ASSERT (numerator
>= denominator
);
1515 /* Gain extra precision, already used one spare bit */
1516 numerator
<<= NR_SPARE
;
1517 denominator
<<= NR_SPARE
;
1519 /* Does divide one bit at a time. Optimize??? */
1521 bit
= (IMPLICIT_1
<< NR_SPARE
);
1524 if (numerator
>= denominator
)
1527 numerator
-= denominator
;
1533 /* discard (but save) the extra bits */
1534 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1535 quotient
= (quotient
>> NR_SPARE
) | 1;
1537 quotient
= (quotient
>> NR_SPARE
);
1539 f
->fraction
= quotient
;
1540 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1543 f
->fraction
|= 1; /* stick remaining bits */
1544 return sim_fpu_status_inexact
;
1552 INLINE_SIM_FPU (int)
1553 sim_fpu_max (sim_fpu
*f
,
1557 if (sim_fpu_is_snan (l
))
1560 f
->class = sim_fpu_class_qnan
;
1561 return sim_fpu_status_invalid_snan
;
1563 if (sim_fpu_is_snan (r
))
1566 f
->class = sim_fpu_class_qnan
;
1567 return sim_fpu_status_invalid_snan
;
1569 if (sim_fpu_is_qnan (l
))
1574 if (sim_fpu_is_qnan (r
))
1579 if (sim_fpu_is_infinity (l
))
1581 if (sim_fpu_is_infinity (r
)
1582 && l
->sign
== r
->sign
)
1585 return sim_fpu_status_invalid_isi
;
1588 *f
= *r
; /* -inf < anything */
1590 *f
= *l
; /* +inf > anthing */
1593 if (sim_fpu_is_infinity (r
))
1596 *f
= *l
; /* anything > -inf */
1598 *f
= *r
; /* anthing < +inf */
1601 if (l
->sign
> r
->sign
)
1603 *f
= *r
; /* -ve < +ve */
1606 if (l
->sign
< r
->sign
)
1608 *f
= *l
; /* +ve > -ve */
1611 ASSERT (l
->sign
== r
->sign
);
1612 if (l
->normal_exp
> r
->normal_exp
1613 || (l
->normal_exp
== r
->normal_exp
&&
1614 l
->fraction
> r
->fraction
))
1618 *f
= *r
; /* -ve < -ve */
1620 *f
= *l
; /* +ve > +ve */
1627 *f
= *l
; /* -ve > -ve */
1629 *f
= *r
; /* +ve < +ve */
1635 INLINE_SIM_FPU (int)
1636 sim_fpu_min (sim_fpu
*f
,
1640 if (sim_fpu_is_snan (l
))
1643 f
->class = sim_fpu_class_qnan
;
1644 return sim_fpu_status_invalid_snan
;
1646 if (sim_fpu_is_snan (r
))
1649 f
->class = sim_fpu_class_qnan
;
1650 return sim_fpu_status_invalid_snan
;
1652 if (sim_fpu_is_qnan (l
))
1657 if (sim_fpu_is_qnan (r
))
1662 if (sim_fpu_is_infinity (l
))
1664 if (sim_fpu_is_infinity (r
)
1665 && l
->sign
== r
->sign
)
1668 return sim_fpu_status_invalid_isi
;
1671 *f
= *l
; /* -inf < anything */
1673 *f
= *r
; /* +inf > anthing */
1676 if (sim_fpu_is_infinity (r
))
1679 *f
= *r
; /* anything > -inf */
1681 *f
= *l
; /* anything < +inf */
1684 if (l
->sign
> r
->sign
)
1686 *f
= *l
; /* -ve < +ve */
1689 if (l
->sign
< r
->sign
)
1691 *f
= *r
; /* +ve > -ve */
1694 ASSERT (l
->sign
== r
->sign
);
1695 if (l
->normal_exp
> r
->normal_exp
1696 || (l
->normal_exp
== r
->normal_exp
&&
1697 l
->fraction
> r
->fraction
))
1701 *f
= *l
; /* -ve < -ve */
1703 *f
= *r
; /* +ve > +ve */
1710 *f
= *r
; /* -ve > -ve */
1712 *f
= *l
; /* +ve < +ve */
1718 INLINE_SIM_FPU (int)
1719 sim_fpu_neg (sim_fpu
*f
,
1722 if (sim_fpu_is_snan (r
))
1725 f
->class = sim_fpu_class_qnan
;
1726 return sim_fpu_status_invalid_snan
;
1728 if (sim_fpu_is_qnan (r
))
1739 INLINE_SIM_FPU (int)
1740 sim_fpu_abs (sim_fpu
*f
,
1745 if (sim_fpu_is_snan (r
))
1747 f
->class = sim_fpu_class_qnan
;
1748 return sim_fpu_status_invalid_snan
;
1754 INLINE_SIM_FPU (int)
1755 sim_fpu_inv (sim_fpu
*f
,
1758 return sim_fpu_div (f
, &sim_fpu_one
, r
);
1762 INLINE_SIM_FPU (int)
1763 sim_fpu_sqrt (sim_fpu
*f
,
1766 if (sim_fpu_is_snan (r
))
1769 return sim_fpu_status_invalid_snan
;
1771 if (sim_fpu_is_qnan (r
))
1776 if (sim_fpu_is_zero (r
))
1778 f
->class = sim_fpu_class_zero
;
1783 if (sim_fpu_is_infinity (r
))
1788 return sim_fpu_status_invalid_sqrt
;
1792 f
->class = sim_fpu_class_infinity
;
1801 return sim_fpu_status_invalid_sqrt
;
1804 /* @(#)e_sqrt.c 5.1 93/09/24 */
1806 * ====================================================
1807 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1809 * Developed at SunPro, a Sun Microsystems, Inc. business.
1810 * Permission to use, copy, modify, and distribute this
1811 * software is freely granted, provided that this notice
1813 * ====================================================
1816 /* __ieee754_sqrt(x)
1817 * Return correctly rounded sqrt.
1818 * ------------------------------------------
1819 * | Use the hardware sqrt if you have one |
1820 * ------------------------------------------
1822 * Bit by bit method using integer arithmetic. (Slow, but portable)
1824 * Scale x to y in [1,4) with even powers of 2:
1825 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1826 * sqrt(x) = 2^k * sqrt(y)
1829 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1830 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1832 - y = ((m even) ? x : 2.x)
1834 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1836 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1838 * 2. Bit by bit computation
1839 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1842 * s = 2*q , and y = 2 * ( y - q ). (1)
1845 * To compute q from q , one checks whether
1849 * (q + 2 ) <= y. (2)
1852 * If (2) is false, then q = q ; otherwise q = q + 2 .
1855 * With some algebric manipulation, it is not difficult to see
1856 * that (2) is equivalent to
1861 * The advantage of (3) is that s and y can be computed by
1863 * the following recurrence formula:
1866 * s = s , y = y ; (4)
1875 * s = s + 2 , y = y - s - 2 (5)
1880 - NOTE: y = 2 (y - s - 2 )
1883 * One may easily use induction to prove (4) and (5).
1884 * Note. Since the left hand side of (3) contain only i+2 bits,
1885 * it does not necessary to do a full (53-bit) comparison
1888 * After generating the 53 bits result, we compute one more bit.
1889 * Together with the remainder, we can decide whether the
1890 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1891 * (it will never equal to 1/2ulp).
1892 * The rounding mode can be detected by checking whether
1893 * huge + tiny is equal to huge, and whether huge - tiny is
1894 * equal to huge for some floating point number "huge" and "tiny".
1897 * sqrt(+-0) = +-0 ... exact
1899 * sqrt(-ve) = NaN ... with invalid signal
1900 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1902 * Other methods : see the appended file at the end of the program below.
1907 /* generate sqrt(x) bit by bit */
1913 f
->class = sim_fpu_class_number
;
1916 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1918 /* odd exp, double x to make it even */
1919 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1920 if ((r
->normal_exp
& 1))
1924 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1926 /* Let loop determine first value of s (either 1 or 2) */
1933 unsigned64 t
= s
+ b
;
1944 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1948 f
->fraction
|= 1; /* stick remaining bits */
1949 return sim_fpu_status_inexact
;
1957 /* int/long <-> sim_fpu */
1959 INLINE_SIM_FPU (int)
1960 sim_fpu_i32to (sim_fpu
*f
,
1962 sim_fpu_round round
)
1968 INLINE_SIM_FPU (int)
1969 sim_fpu_u32to (sim_fpu
*f
,
1971 sim_fpu_round round
)
1977 INLINE_SIM_FPU (int)
1978 sim_fpu_i64to (sim_fpu
*f
,
1980 sim_fpu_round round
)
1986 INLINE_SIM_FPU (int)
1987 sim_fpu_u64to (sim_fpu
*f
,
1989 sim_fpu_round round
)
1996 INLINE_SIM_FPU (int)
1997 sim_fpu_to32i (signed32
*i
,
1999 sim_fpu_round round
)
2002 int status
= fpu2i (&i64
, f
, 0, round
);
2007 INLINE_SIM_FPU (int)
2008 sim_fpu_to32u (unsigned32
*u
,
2010 sim_fpu_round round
)
2013 int status
= fpu2u (&u64
, f
, 0);
2018 INLINE_SIM_FPU (int)
2019 sim_fpu_to64i (signed64
*i
,
2021 sim_fpu_round round
)
2023 return fpu2i (i
, f
, 1, round
);
2027 INLINE_SIM_FPU (int)
2028 sim_fpu_to64u (unsigned64
*u
,
2030 sim_fpu_round round
)
2032 return fpu2u (u
, f
, 1);
2037 /* sim_fpu -> host format */
2040 INLINE_SIM_FPU (float)
2041 sim_fpu_2f (const sim_fpu
*f
)
2048 INLINE_SIM_FPU (double)
2049 sim_fpu_2d (const sim_fpu
*s
)
2052 if (sim_fpu_is_snan (s
))
2056 n
.class = sim_fpu_class_qnan
;
2057 val
.i
= pack_fpu (&n
, 1);
2061 val
.i
= pack_fpu (s
, 1);
2068 INLINE_SIM_FPU (void)
2069 sim_fpu_f2 (sim_fpu
*f
,
2074 unpack_fpu (f
, val
.i
, 1);
2079 INLINE_SIM_FPU (void)
2080 sim_fpu_d2 (sim_fpu
*f
,
2085 unpack_fpu (f
, val
.i
, 1);
2091 INLINE_SIM_FPU (int)
2092 sim_fpu_is_nan (const sim_fpu
*d
)
2096 case sim_fpu_class_qnan
:
2097 case sim_fpu_class_snan
:
2104 INLINE_SIM_FPU (int)
2105 sim_fpu_is_qnan (const sim_fpu
*d
)
2109 case sim_fpu_class_qnan
:
2116 INLINE_SIM_FPU (int)
2117 sim_fpu_is_snan (const sim_fpu
*d
)
2121 case sim_fpu_class_snan
:
2128 INLINE_SIM_FPU (int)
2129 sim_fpu_is_zero (const sim_fpu
*d
)
2133 case sim_fpu_class_zero
:
2140 INLINE_SIM_FPU (int)
2141 sim_fpu_is_infinity (const sim_fpu
*d
)
2145 case sim_fpu_class_infinity
:
2152 INLINE_SIM_FPU (int)
2153 sim_fpu_is_number (const sim_fpu
*d
)
2157 case sim_fpu_class_denorm
:
2158 case sim_fpu_class_number
:
2165 INLINE_SIM_FPU (int)
2166 sim_fpu_is_denorm (const sim_fpu
*d
)
2170 case sim_fpu_class_denorm
:
2178 INLINE_SIM_FPU (int)
2179 sim_fpu_sign (const sim_fpu
*d
)
2185 INLINE_SIM_FPU (int)
2186 sim_fpu_exp (const sim_fpu
*d
)
2188 return d
->normal_exp
;
2192 INLINE_SIM_FPU (unsigned64
)
2193 sim_fpu_fraction (const sim_fpu
*d
)
2199 INLINE_SIM_FPU (unsigned64
)
2200 sim_fpu_guard (const sim_fpu
*d
, int is_double
)
2203 unsigned64 guardmask
= LSMASK64 (NR_GUARDS
- 1, 0);
2204 rv
= (d
->fraction
& guardmask
) >> NR_PAD
;
2209 INLINE_SIM_FPU (int)
2210 sim_fpu_is (const sim_fpu
*d
)
2214 case sim_fpu_class_qnan
:
2215 return SIM_FPU_IS_QNAN
;
2216 case sim_fpu_class_snan
:
2217 return SIM_FPU_IS_SNAN
;
2218 case sim_fpu_class_infinity
:
2220 return SIM_FPU_IS_NINF
;
2222 return SIM_FPU_IS_PINF
;
2223 case sim_fpu_class_number
:
2225 return SIM_FPU_IS_NNUMBER
;
2227 return SIM_FPU_IS_PNUMBER
;
2228 case sim_fpu_class_denorm
:
2230 return SIM_FPU_IS_NDENORM
;
2232 return SIM_FPU_IS_PDENORM
;
2233 case sim_fpu_class_zero
:
2235 return SIM_FPU_IS_NZERO
;
2237 return SIM_FPU_IS_PZERO
;
2244 INLINE_SIM_FPU (int)
2245 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2248 sim_fpu_sub (&res
, l
, r
);
2249 return sim_fpu_is (&res
);
2252 INLINE_SIM_FPU (int)
2253 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2256 sim_fpu_lt (&status
, l
, r
);
2260 INLINE_SIM_FPU (int)
2261 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2264 sim_fpu_le (&is
, l
, r
);
2268 INLINE_SIM_FPU (int)
2269 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2272 sim_fpu_eq (&is
, l
, r
);
2276 INLINE_SIM_FPU (int)
2277 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2280 sim_fpu_ne (&is
, l
, r
);
2284 INLINE_SIM_FPU (int)
2285 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2288 sim_fpu_ge (&is
, l
, r
);
2292 INLINE_SIM_FPU (int)
2293 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2296 sim_fpu_gt (&is
, l
, r
);
2301 /* Compare operators */
2303 INLINE_SIM_FPU (int)
2304 sim_fpu_lt (int *is
,
2308 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2312 lval
.i
= pack_fpu (l
, 1);
2313 rval
.i
= pack_fpu (r
, 1);
2314 (*is
) = (lval
.d
< rval
.d
);
2317 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2320 return sim_fpu_status_invalid_snan
;
2325 return sim_fpu_status_invalid_qnan
;
2329 INLINE_SIM_FPU (int)
2330 sim_fpu_le (int *is
,
2334 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2338 lval
.i
= pack_fpu (l
, 1);
2339 rval
.i
= pack_fpu (r
, 1);
2340 *is
= (lval
.d
<= rval
.d
);
2343 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2346 return sim_fpu_status_invalid_snan
;
2351 return sim_fpu_status_invalid_qnan
;
2355 INLINE_SIM_FPU (int)
2356 sim_fpu_eq (int *is
,
2360 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2364 lval
.i
= pack_fpu (l
, 1);
2365 rval
.i
= pack_fpu (r
, 1);
2366 (*is
) = (lval
.d
== rval
.d
);
2369 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2372 return sim_fpu_status_invalid_snan
;
2377 return sim_fpu_status_invalid_qnan
;
2381 INLINE_SIM_FPU (int)
2382 sim_fpu_ne (int *is
,
2386 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2390 lval
.i
= pack_fpu (l
, 1);
2391 rval
.i
= pack_fpu (r
, 1);
2392 (*is
) = (lval
.d
!= rval
.d
);
2395 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2398 return sim_fpu_status_invalid_snan
;
2403 return sim_fpu_status_invalid_qnan
;
2407 INLINE_SIM_FPU (int)
2408 sim_fpu_ge (int *is
,
2412 return sim_fpu_le (is
, r
, l
);
2415 INLINE_SIM_FPU (int)
2416 sim_fpu_gt (int *is
,
2420 return sim_fpu_lt (is
, r
, l
);
2424 /* A number of useful constants */
2426 #if EXTERN_SIM_FPU_P
2427 const sim_fpu sim_fpu_zero
= {
2430 const sim_fpu sim_fpu_qnan
= {
2433 const sim_fpu sim_fpu_one
= {
2434 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2436 const sim_fpu sim_fpu_two
= {
2437 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2439 const sim_fpu sim_fpu_max32
= {
2440 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2442 const sim_fpu sim_fpu_max64
= {
2443 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2450 INLINE_SIM_FPU (void)
2451 sim_fpu_print_fpu (const sim_fpu
*f
,
2452 sim_fpu_print_func
*print
,
2455 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2458 INLINE_SIM_FPU (void)
2459 sim_fpu_printn_fpu (const sim_fpu
*f
,
2460 sim_fpu_print_func
*print
,
2464 print (arg
, "%s", f
->sign
? "-" : "+");
2467 case sim_fpu_class_qnan
:
2469 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2470 print (arg
, "*QuietNaN");
2472 case sim_fpu_class_snan
:
2474 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2475 print (arg
, "*SignalNaN");
2477 case sim_fpu_class_zero
:
2480 case sim_fpu_class_infinity
:
2483 case sim_fpu_class_number
:
2484 case sim_fpu_class_denorm
:
2486 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2487 print (arg
, "*2^%+d", f
->normal_exp
);
2488 ASSERT (f
->fraction
>= IMPLICIT_1
);
2489 ASSERT (f
->fraction
< IMPLICIT_2
);
2494 INLINE_SIM_FPU (void)
2495 sim_fpu_print_status (int status
,
2496 sim_fpu_print_func
*print
,
2503 switch ((sim_fpu_status
) (status
& i
))
2505 case sim_fpu_status_denorm
:
2506 print (arg
, "%sD", prefix
);
2508 case sim_fpu_status_invalid_snan
:
2509 print (arg
, "%sSNaN", prefix
);
2511 case sim_fpu_status_invalid_qnan
:
2512 print (arg
, "%sQNaN", prefix
);
2514 case sim_fpu_status_invalid_isi
:
2515 print (arg
, "%sISI", prefix
);
2517 case sim_fpu_status_invalid_idi
:
2518 print (arg
, "%sIDI", prefix
);
2520 case sim_fpu_status_invalid_zdz
:
2521 print (arg
, "%sZDZ", prefix
);
2523 case sim_fpu_status_invalid_imz
:
2524 print (arg
, "%sIMZ", prefix
);
2526 case sim_fpu_status_invalid_cvi
:
2527 print (arg
, "%sCVI", prefix
);
2529 case sim_fpu_status_invalid_cmp
:
2530 print (arg
, "%sCMP", prefix
);
2532 case sim_fpu_status_invalid_sqrt
:
2533 print (arg
, "%sSQRT", prefix
);
2536 case sim_fpu_status_inexact
:
2537 print (arg
, "%sX", prefix
);
2540 case sim_fpu_status_overflow
:
2541 print (arg
, "%sO", prefix
);
2544 case sim_fpu_status_underflow
:
2545 print (arg
, "%sU", prefix
);
2548 case sim_fpu_status_invalid_div0
:
2549 print (arg
, "%s/", prefix
);
2552 case sim_fpu_status_rounded
:
2553 print (arg
, "%sR", prefix
);