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 (C) 1994,1997-1998 Free Software Foundation, Inc.
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file with other programs, and to distribute
15 those programs without any restriction coming from the use of this
16 file. (The General Public License restrictions do apply in other
17 respects; for example, they cover modification of the file, and
18 distribution when not linked into another program.)
20 This file is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; see the file COPYING. If not, write to
27 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 /* As a special exception, if you link this library with other files,
30 some of which are compiled with GCC, to produce an executable,
31 this library does not by itself cause the resulting executable
32 to be covered by the GNU General Public License.
33 This exception does not however invalidate any other reasons why
34 the executable file might be covered by the GNU General Public License. */
36 /* This implements IEEE 754 format arithmetic, but does not provide a
37 mechanism for setting the rounding mode, or for generating or handling
40 The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
41 Wilson, all of Cygnus Support. */
47 #include "sim-basics.h"
51 #include "sim-assert.h"
55 If digits is -1, then print all digits. */
58 print_bits (unsigned64 x
,
61 sim_fpu_print_func print
,
64 unsigned64 bit
= LSBIT64 (msbit
);
77 if (digits
> 0) digits
--;
84 /* Quick and dirty conversion between a host double and host 64bit int */
92 /* A packed IEEE floating point number.
94 Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
95 32 and 64 bit numbers. This number is interpreted as:
97 Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
98 (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
100 Denormalized (0 == BIASEDEXP && FRAC != 0):
101 (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
103 Zero (0 == BIASEDEXP && FRAC == 0):
104 (sign ? "-" : "+") 0.0
106 Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
107 (sign ? "-" : "+") "infinity"
109 SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
112 QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
117 #define NR_EXPBITS (is_double ? 11 : 8)
118 #define NR_FRACBITS (is_double ? 52 : 23)
119 #define SIGNBIT (is_double ? MSBIT64 (0) : MSBIT64 (32))
121 #define EXPMAX32 (255)
122 #define EXMPAX64 (2047)
123 #define EXPMAX ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
125 #define EXPBIAS32 (127)
126 #define EXPBIAS64 (1023)
127 #define EXPBIAS (is_double ? EXPBIAS64 : EXPBIAS32)
129 #define QUIET_NAN LSBIT64 (NR_FRACBITS - 1)
133 /* An unpacked floating point number.
135 When unpacked, the fraction of both a 32 and 64 bit floating point
136 number is stored using the same format:
138 64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
139 32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
141 #define NR_PAD32 (30)
143 #define NR_PAD (is_double ? NR_PAD64 : NR_PAD32)
144 #define PADMASK (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
146 #define NR_GUARDS32 (7 + NR_PAD32)
147 #define NR_GUARDS64 (8 + NR_PAD64)
148 #define NR_GUARDS (is_double ? NR_GUARDS64 : NR_GUARDS32)
149 #define GUARDMASK LSMASK64 (NR_GUARDS - 1, 0)
151 #define GUARDMSB LSBIT64 (NR_GUARDS - 1)
152 #define GUARDLSB LSBIT64 (NR_PAD)
153 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
155 #define NR_FRAC_GUARD (60)
156 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
157 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
158 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
161 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
163 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
165 #define NORMAL_EXPMAX32 (EXPBIAS32)
166 #define NORMAL_EXPMAX64 (EXPBIAS64)
167 #define NORMAL_EXPMAX (EXPBIAS)
170 /* Integer constants */
172 #define MAX_INT32 ((signed64) LSMASK64 (30, 0))
173 #define MAX_UINT32 LSMASK64 (31, 0)
174 #define MIN_INT32 ((signed64) LSMASK64 (63, 31))
176 #define MAX_INT64 ((signed64) LSMASK64 (62, 0))
177 #define MAX_UINT64 LSMASK64 (63, 0)
178 #define MIN_INT64 ((signed64) LSMASK64 (63, 63))
180 #define MAX_INT (is_64bit ? MAX_INT64 : MAX_INT32)
181 #define MIN_INT (is_64bit ? MIN_INT64 : MIN_INT32)
182 #define MAX_UINT (is_64bit ? MAX_UINT64 : MAX_UINT32)
183 #define NR_INTBITS (is_64bit ? 64 : 32)
185 /* Squeese an unpacked sim_fpu struct into a 32/64 bit integer */
186 STATIC_INLINE_SIM_FPU (unsigned64
)
187 pack_fpu (const sim_fpu
*src
,
198 case sim_fpu_class_qnan
:
201 /* force fraction to correct class */
202 fraction
= src
->fraction
;
203 fraction
>>= NR_GUARDS
;
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 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
;
336 /* Zero exponent with non zero fraction - it's denormalized,
337 so there isn't a leading implicit one - we'll shift it so
339 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
340 dst
->class = sim_fpu_class_denorm
;
342 fraction
<<= NR_GUARDS
;
343 while (fraction
< IMPLICIT_1
)
348 dst
->fraction
= fraction
;
351 else if (exp
== EXPMAX
)
356 /* Attached to a zero fraction - means infinity */
357 dst
->class = sim_fpu_class_infinity
;
359 /* dst->normal_exp = EXPBIAS; */
360 /* dst->fraction = 0; */
364 /* Non zero fraction, means NaN */
366 dst
->fraction
= (fraction
<< NR_GUARDS
);
367 if (fraction
>= QUIET_NAN
)
368 dst
->class = sim_fpu_class_qnan
;
370 dst
->class = sim_fpu_class_snan
;
375 /* Nothing strange about this number */
376 dst
->class = sim_fpu_class_number
;
378 dst
->fraction
= ((fraction
<< NR_GUARDS
) | IMPLICIT_1
);
379 dst
->normal_exp
= exp
- EXPBIAS
;
382 /* trace operation */
389 printf ("unpack_fpu: %c%02lX.%06lX ->\n",
390 LSMASKED32 (packed
, 31, 31) ? '8' : '0',
391 (long) LSEXTRACTED32 (packed
, 30, 23),
392 (long) LSEXTRACTED32 (packed
, 23 - 1, 0));
399 val
.i
= pack_fpu (dst
, 1);
402 ASSERT (val
.i
== packed
);
406 unsigned32 val
= pack_fpu (dst
, 0);
407 unsigned32 org
= packed
;
414 /* Convert a floating point into an integer */
415 STATIC_INLINE_SIM_FPU (int)
424 if (sim_fpu_is_zero (s
))
429 if (sim_fpu_is_snan (s
))
431 *i
= MIN_INT
; /* FIXME */
432 return sim_fpu_status_invalid_cvi
;
434 if (sim_fpu_is_qnan (s
))
436 *i
= MIN_INT
; /* FIXME */
437 return sim_fpu_status_invalid_cvi
;
439 /* map infinity onto MAX_INT... */
440 if (sim_fpu_is_infinity (s
))
442 *i
= s
->sign
? MIN_INT
: MAX_INT
;
443 return sim_fpu_status_invalid_cvi
;
445 /* it is a number, but a small one */
446 if (s
->normal_exp
< 0)
449 return sim_fpu_status_inexact
;
451 /* Is the floating point MIN_INT or just close? */
452 if (s
->sign
&& s
->normal_exp
== (NR_INTBITS
- 1))
455 ASSERT (s
->fraction
>= IMPLICIT_1
);
456 if (s
->fraction
== IMPLICIT_1
)
457 return 0; /* exact */
458 if (is_64bit
) /* can't round */
459 return sim_fpu_status_invalid_cvi
; /* must be overflow */
460 /* For a 32bit with MAX_INT, rounding is possible */
463 case sim_fpu_round_default
:
465 case sim_fpu_round_zero
:
466 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
467 return sim_fpu_status_invalid_cvi
;
469 return sim_fpu_status_inexact
;
471 case sim_fpu_round_near
:
473 if ((s
->fraction
& FRAC32MASK
) != IMPLICIT_1
)
474 return sim_fpu_status_invalid_cvi
;
475 else if ((s
->fraction
& !FRAC32MASK
) >= (~FRAC32MASK
>> 1))
476 return sim_fpu_status_invalid_cvi
;
478 return sim_fpu_status_inexact
;
480 case sim_fpu_round_up
:
481 if ((s
->fraction
& FRAC32MASK
) == IMPLICIT_1
)
482 return sim_fpu_status_inexact
;
484 return sim_fpu_status_invalid_cvi
;
485 case sim_fpu_round_down
:
486 return sim_fpu_status_invalid_cvi
;
489 /* Would right shifting result in the FRAC being shifted into
490 (through) the integer's sign bit? */
491 if (s
->normal_exp
> (NR_INTBITS
- 2))
493 *i
= s
->sign
? MIN_INT
: MAX_INT
;
494 return sim_fpu_status_invalid_cvi
;
496 /* normal number shift it into place */
498 shift
= (s
->normal_exp
- (NR_FRAC_GUARD
));
506 if (tmp
& ((SIGNED64 (1) << shift
) - 1))
507 status
|= sim_fpu_status_inexact
;
510 *i
= s
->sign
? (-tmp
) : (tmp
);
514 /* convert an integer into a floating point */
515 STATIC_INLINE_SIM_FPU (int)
516 i2fpu (sim_fpu
*f
, signed64 i
, int is_64bit
)
521 f
->class = sim_fpu_class_zero
;
526 f
->class = sim_fpu_class_number
;
528 f
->normal_exp
= NR_FRAC_GUARD
;
532 /* Special case for minint, since there is no corresponding
533 +ve integer representation for it */
536 f
->fraction
= IMPLICIT_1
;
537 f
->normal_exp
= NR_INTBITS
- 1;
545 if (f
->fraction
>= IMPLICIT_2
)
549 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
552 while (f
->fraction
>= IMPLICIT_2
);
554 else if (f
->fraction
< IMPLICIT_1
)
561 while (f
->fraction
< IMPLICIT_1
);
565 /* trace operation */
568 printf ("i2fpu: 0x%08lX ->\n", (long) i
);
575 fpu2i (&val
, f
, is_64bit
, sim_fpu_round_zero
);
576 if (i
>= MIN_INT32
&& i
<= MAX_INT32
)
586 /* Convert a floating point into an integer */
587 STATIC_INLINE_SIM_FPU (int)
588 fpu2u (unsigned64
*u
, const sim_fpu
*s
, int is_64bit
)
590 const int is_double
= 1;
593 if (sim_fpu_is_zero (s
))
598 if (sim_fpu_is_nan (s
))
603 /* it is a negative number */
609 /* get reasonable MAX_USI_INT... */
610 if (sim_fpu_is_infinity (s
))
615 /* it is a number, but a small one */
616 if (s
->normal_exp
< 0)
622 if (s
->normal_exp
> (NR_INTBITS
- 1))
628 tmp
= (s
->fraction
& ~PADMASK
);
629 shift
= (s
->normal_exp
- (NR_FRACBITS
+ NR_GUARDS
));
643 /* Convert an unsigned integer into a floating point */
644 STATIC_INLINE_SIM_FPU (int)
645 u2fpu (sim_fpu
*f
, unsigned64 u
, int is_64bit
)
649 f
->class = sim_fpu_class_zero
;
654 f
->class = sim_fpu_class_number
;
656 f
->normal_exp
= NR_FRAC_GUARD
;
659 while (f
->fraction
< IMPLICIT_1
)
669 /* register <-> sim_fpu */
671 INLINE_SIM_FPU (void)
672 sim_fpu_32to (sim_fpu
*f
, unsigned32 s
)
674 unpack_fpu (f
, s
, 0);
678 INLINE_SIM_FPU (void)
679 sim_fpu_232to (sim_fpu
*f
, unsigned32 h
, unsigned32 l
)
683 unpack_fpu (f
, s
, 1);
687 INLINE_SIM_FPU (void)
688 sim_fpu_64to (sim_fpu
*f
, unsigned64 s
)
690 unpack_fpu (f
, s
, 1);
694 INLINE_SIM_FPU (void)
695 sim_fpu_to32 (unsigned32
*s
,
698 *s
= pack_fpu (f
, 0);
702 INLINE_SIM_FPU (void)
703 sim_fpu_to232 (unsigned32
*h
, unsigned32
*l
,
706 unsigned64 s
= pack_fpu (f
, 1);
712 INLINE_SIM_FPU (void)
713 sim_fpu_to64 (unsigned64
*u
,
716 *u
= pack_fpu (f
, 1);
720 INLINE_SIM_FPU (void)
721 sim_fpu_fractionto (sim_fpu
*f
,
727 int shift
= (NR_FRAC_GUARD
- precision
);
728 f
->class = sim_fpu_class_number
;
730 f
->normal_exp
= normal_exp
;
731 /* shift the fraction to where sim-fpu expects it */
733 f
->fraction
= (fraction
<< shift
);
735 f
->fraction
= (fraction
>> -shift
);
736 f
->fraction
|= IMPLICIT_1
;
740 INLINE_SIM_FPU (unsigned64
)
741 sim_fpu_tofraction (const sim_fpu
*d
,
744 /* we have NR_FRAC_GUARD bits, we want only PRECISION bits */
745 int shift
= (NR_FRAC_GUARD
- precision
);
746 unsigned64 fraction
= (d
->fraction
& ~IMPLICIT_1
);
748 return fraction
>> shift
;
750 return fraction
<< -shift
;
756 STATIC_INLINE_SIM_FPU (int)
757 do_normal_overflow (sim_fpu
*f
,
763 case sim_fpu_round_default
:
765 case sim_fpu_round_near
:
766 f
->class = sim_fpu_class_infinity
;
768 case sim_fpu_round_up
:
770 f
->class = sim_fpu_class_infinity
;
772 case sim_fpu_round_down
:
774 f
->class = sim_fpu_class_infinity
;
776 case sim_fpu_round_zero
:
779 f
->normal_exp
= NORMAL_EXPMAX
;
780 f
->fraction
= LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS
);
781 return (sim_fpu_status_overflow
| sim_fpu_status_inexact
);
784 STATIC_INLINE_SIM_FPU (int)
785 do_normal_underflow (sim_fpu
*f
,
791 case sim_fpu_round_default
:
793 case sim_fpu_round_near
:
794 f
->class = sim_fpu_class_zero
;
796 case sim_fpu_round_up
:
798 f
->class = sim_fpu_class_zero
;
800 case sim_fpu_round_down
:
802 f
->class = sim_fpu_class_zero
;
804 case sim_fpu_round_zero
:
805 f
->class = sim_fpu_class_zero
;
808 f
->normal_exp
= NORMAL_EXPMIN
- NR_FRACBITS
;
809 f
->fraction
= IMPLICIT_1
;
810 return (sim_fpu_status_inexact
| sim_fpu_status_underflow
);
815 /* Round a number using NR_GUARDS.
816 Will return the rounded number or F->FRACTION == 0 when underflow */
818 STATIC_INLINE_SIM_FPU (int)
819 do_normal_round (sim_fpu
*f
,
823 unsigned64 guardmask
= LSMASK64 (nr_guards
- 1, 0);
824 unsigned64 guardmsb
= LSBIT64 (nr_guards
- 1);
825 unsigned64 fraclsb
= guardmsb
<< 1;
826 if ((f
->fraction
& guardmask
))
828 int status
= sim_fpu_status_inexact
;
831 case sim_fpu_round_default
:
833 case sim_fpu_round_near
:
834 if ((f
->fraction
& guardmsb
))
836 if ((f
->fraction
& fraclsb
))
838 status
|= sim_fpu_status_rounded
;
840 else if ((f
->fraction
& (guardmask
>> 1)))
842 status
|= sim_fpu_status_rounded
;
846 case sim_fpu_round_up
:
848 status
|= sim_fpu_status_rounded
;
850 case sim_fpu_round_down
:
852 status
|= sim_fpu_status_rounded
;
854 case sim_fpu_round_zero
:
857 f
->fraction
&= ~guardmask
;
858 /* round if needed, handle resulting overflow */
859 if ((status
& sim_fpu_status_rounded
))
861 f
->fraction
+= fraclsb
;
862 if ((f
->fraction
& IMPLICIT_2
))
875 STATIC_INLINE_SIM_FPU (int)
876 do_round (sim_fpu
*f
,
879 sim_fpu_denorm denorm
)
883 case sim_fpu_class_qnan
:
884 case sim_fpu_class_zero
:
885 case sim_fpu_class_infinity
:
888 case sim_fpu_class_snan
:
889 /* Quieten a SignalingNaN */
890 f
->class = sim_fpu_class_qnan
;
891 return sim_fpu_status_invalid_snan
;
893 case sim_fpu_class_number
:
894 case sim_fpu_class_denorm
:
897 ASSERT (f
->fraction
< IMPLICIT_2
);
898 ASSERT (f
->fraction
>= IMPLICIT_1
);
899 if (f
->normal_exp
< NORMAL_EXPMIN
)
901 /* This number's exponent is too low to fit into the bits
902 available in the number. Round off any bits that will be
903 discarded as a result of denormalization. Edge case is
904 the implicit bit shifted to GUARD0 and then rounded
906 int shift
= NORMAL_EXPMIN
- f
->normal_exp
;
907 if (shift
+ NR_GUARDS
<= NR_FRAC_GUARD
+ 1
908 && !(denorm
& sim_fpu_denorm_zero
))
910 status
= do_normal_round (f
, shift
+ NR_GUARDS
, round
);
911 if (f
->fraction
== 0) /* rounding underflowed */
913 status
|= do_normal_underflow (f
, is_double
, round
);
915 else if (f
->normal_exp
< NORMAL_EXPMIN
) /* still underflow? */
917 status
|= sim_fpu_status_denorm
;
918 /* Any loss of precision when denormalizing is
919 underflow. Some processors check for underflow
920 before rounding, some after! */
921 if (status
& sim_fpu_status_inexact
)
922 status
|= sim_fpu_status_underflow
;
923 /* Flag that resultant value has been denormalized */
924 f
->class = sim_fpu_class_denorm
;
926 else if ((denorm
& sim_fpu_denorm_underflow_inexact
))
928 if ((status
& sim_fpu_status_inexact
))
929 status
|= sim_fpu_status_underflow
;
934 status
= do_normal_underflow (f
, is_double
, round
);
937 else if (f
->normal_exp
> NORMAL_EXPMAX
)
940 status
= do_normal_overflow (f
, is_double
, round
);
944 status
= do_normal_round (f
, NR_GUARDS
, round
);
945 if (f
->fraction
== 0)
946 /* f->class = sim_fpu_class_zero; */
947 status
|= do_normal_underflow (f
, is_double
, round
);
948 else if (f
->normal_exp
> NORMAL_EXPMAX
)
949 /* oops! rounding caused overflow */
950 status
|= do_normal_overflow (f
, is_double
, round
);
952 ASSERT ((f
->class == sim_fpu_class_number
953 || f
->class == sim_fpu_class_denorm
)
954 <= (f
->fraction
< IMPLICIT_2
&& f
->fraction
>= IMPLICIT_1
));
962 sim_fpu_round_32 (sim_fpu
*f
,
964 sim_fpu_denorm denorm
)
966 return do_round (f
, 0, round
, denorm
);
970 sim_fpu_round_64 (sim_fpu
*f
,
972 sim_fpu_denorm denorm
)
974 return do_round (f
, 1, round
, denorm
);
982 sim_fpu_add (sim_fpu
*f
,
986 if (sim_fpu_is_snan (l
))
989 f
->class = sim_fpu_class_qnan
;
990 return sim_fpu_status_invalid_snan
;
992 if (sim_fpu_is_snan (r
))
995 f
->class = sim_fpu_class_qnan
;
996 return sim_fpu_status_invalid_snan
;
998 if (sim_fpu_is_qnan (l
))
1003 if (sim_fpu_is_qnan (r
))
1008 if (sim_fpu_is_infinity (l
))
1010 if (sim_fpu_is_infinity (r
)
1011 && l
->sign
!= r
->sign
)
1014 return sim_fpu_status_invalid_isi
;
1019 if (sim_fpu_is_infinity (r
))
1024 if (sim_fpu_is_zero (l
))
1026 if (sim_fpu_is_zero (r
))
1029 f
->sign
= l
->sign
& r
->sign
;
1035 if (sim_fpu_is_zero (r
))
1042 int shift
= l
->normal_exp
- r
->normal_exp
;
1043 unsigned64 lfraction
;
1044 unsigned64 rfraction
;
1045 /* use exp of larger */
1046 if (shift
>= NR_FRAC_GUARD
)
1048 /* left has much bigger magnitute */
1050 return sim_fpu_status_inexact
;
1052 if (shift
<= - NR_FRAC_GUARD
)
1054 /* right has much bigger magnitute */
1056 return sim_fpu_status_inexact
;
1058 lfraction
= l
->fraction
;
1059 rfraction
= r
->fraction
;
1062 f
->normal_exp
= l
->normal_exp
;
1063 if (rfraction
& LSMASK64 (shift
- 1, 0))
1065 status
|= sim_fpu_status_inexact
;
1066 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1068 rfraction
>>= shift
;
1072 f
->normal_exp
= r
->normal_exp
;
1073 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1075 status
|= sim_fpu_status_inexact
;
1076 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1078 lfraction
>>= -shift
;
1082 f
->normal_exp
= r
->normal_exp
;
1085 /* perform the addition */
1087 lfraction
= - lfraction
;
1089 rfraction
= - rfraction
;
1090 f
->fraction
= lfraction
+ rfraction
;
1093 if (f
->fraction
== 0)
1100 f
->class = sim_fpu_class_number
;
1101 if ((signed64
) f
->fraction
>= 0)
1106 f
->fraction
= - f
->fraction
;
1110 if ((f
->fraction
& IMPLICIT_2
))
1112 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1115 else if (f
->fraction
< IMPLICIT_1
)
1122 while (f
->fraction
< IMPLICIT_1
);
1124 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1130 INLINE_SIM_FPU (int)
1131 sim_fpu_sub (sim_fpu
*f
,
1135 if (sim_fpu_is_snan (l
))
1138 f
->class = sim_fpu_class_qnan
;
1139 return sim_fpu_status_invalid_snan
;
1141 if (sim_fpu_is_snan (r
))
1144 f
->class = sim_fpu_class_qnan
;
1145 return sim_fpu_status_invalid_snan
;
1147 if (sim_fpu_is_qnan (l
))
1152 if (sim_fpu_is_qnan (r
))
1157 if (sim_fpu_is_infinity (l
))
1159 if (sim_fpu_is_infinity (r
)
1160 && l
->sign
== r
->sign
)
1163 return sim_fpu_status_invalid_isi
;
1168 if (sim_fpu_is_infinity (r
))
1174 if (sim_fpu_is_zero (l
))
1176 if (sim_fpu_is_zero (r
))
1179 f
->sign
= l
->sign
& !r
->sign
;
1188 if (sim_fpu_is_zero (r
))
1195 int shift
= l
->normal_exp
- r
->normal_exp
;
1196 unsigned64 lfraction
;
1197 unsigned64 rfraction
;
1198 /* use exp of larger */
1199 if (shift
>= NR_FRAC_GUARD
)
1201 /* left has much bigger magnitute */
1203 return sim_fpu_status_inexact
;
1205 if (shift
<= - NR_FRAC_GUARD
)
1207 /* right has much bigger magnitute */
1210 return sim_fpu_status_inexact
;
1212 lfraction
= l
->fraction
;
1213 rfraction
= r
->fraction
;
1216 f
->normal_exp
= l
->normal_exp
;
1217 if (rfraction
& LSMASK64 (shift
- 1, 0))
1219 status
|= sim_fpu_status_inexact
;
1220 rfraction
|= LSBIT64 (shift
); /* stick LSBit */
1222 rfraction
>>= shift
;
1226 f
->normal_exp
= r
->normal_exp
;
1227 if (lfraction
& LSMASK64 (- shift
- 1, 0))
1229 status
|= sim_fpu_status_inexact
;
1230 lfraction
|= LSBIT64 (- shift
); /* stick LSBit */
1232 lfraction
>>= -shift
;
1236 f
->normal_exp
= r
->normal_exp
;
1239 /* perform the subtraction */
1241 lfraction
= - lfraction
;
1243 rfraction
= - rfraction
;
1244 f
->fraction
= lfraction
+ rfraction
;
1247 if (f
->fraction
== 0)
1254 f
->class = sim_fpu_class_number
;
1255 if ((signed64
) f
->fraction
>= 0)
1260 f
->fraction
= - f
->fraction
;
1264 if ((f
->fraction
& IMPLICIT_2
))
1266 f
->fraction
= (f
->fraction
>> 1) | (f
->fraction
& 1);
1269 else if (f
->fraction
< IMPLICIT_1
)
1276 while (f
->fraction
< IMPLICIT_1
);
1278 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1284 INLINE_SIM_FPU (int)
1285 sim_fpu_mul (sim_fpu
*f
,
1289 if (sim_fpu_is_snan (l
))
1292 f
->class = sim_fpu_class_qnan
;
1293 return sim_fpu_status_invalid_snan
;
1295 if (sim_fpu_is_snan (r
))
1298 f
->class = sim_fpu_class_qnan
;
1299 return sim_fpu_status_invalid_snan
;
1301 if (sim_fpu_is_qnan (l
))
1306 if (sim_fpu_is_qnan (r
))
1311 if (sim_fpu_is_infinity (l
))
1313 if (sim_fpu_is_zero (r
))
1316 return sim_fpu_status_invalid_imz
;
1319 f
->sign
= l
->sign
^ r
->sign
;
1322 if (sim_fpu_is_infinity (r
))
1324 if (sim_fpu_is_zero (l
))
1327 return sim_fpu_status_invalid_imz
;
1330 f
->sign
= l
->sign
^ r
->sign
;
1333 if (sim_fpu_is_zero (l
) || sim_fpu_is_zero (r
))
1336 f
->sign
= l
->sign
^ r
->sign
;
1339 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1344 unsigned64 nl
= l
->fraction
& 0xffffffff;
1345 unsigned64 nh
= l
->fraction
>> 32;
1346 unsigned64 ml
= r
->fraction
& 0xffffffff;
1347 unsigned64 mh
= r
->fraction
>>32;
1348 unsigned64 pp_ll
= ml
* nl
;
1349 unsigned64 pp_hl
= mh
* nl
;
1350 unsigned64 pp_lh
= ml
* nh
;
1351 unsigned64 pp_hh
= mh
* nh
;
1352 unsigned64 res2
= 0;
1353 unsigned64 res0
= 0;
1354 unsigned64 ps_hh__
= pp_hl
+ pp_lh
;
1355 if (ps_hh__
< pp_hl
)
1356 res2
+= UNSIGNED64 (0x100000000);
1357 pp_hl
= (ps_hh__
<< 32) & UNSIGNED64 (0xffffffff00000000);
1358 res0
= pp_ll
+ pp_hl
;
1361 res2
+= ((ps_hh__
>> 32) & 0xffffffff) + pp_hh
;
1365 f
->normal_exp
= l
->normal_exp
+ r
->normal_exp
;
1366 f
->sign
= l
->sign
^ r
->sign
;
1367 f
->class = sim_fpu_class_number
;
1369 /* Input is bounded by [1,2) ; [2^60,2^61)
1370 Output is bounded by [1,4) ; [2^120,2^122) */
1372 /* Adjust the exponent according to where the decimal point ended
1373 up in the high 64 bit word. In the source the decimal point
1374 was at NR_FRAC_GUARD. */
1375 f
->normal_exp
+= NR_FRAC_GUARD
+ 64 - (NR_FRAC_GUARD
* 2);
1377 /* The high word is bounded according to the above. Consequently
1378 it has never overflowed into IMPLICIT_2. */
1379 ASSERT (high
< LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64));
1380 ASSERT (high
>= LSBIT64 ((NR_FRAC_GUARD
* 2) - 64));
1381 ASSERT (LSBIT64 (((NR_FRAC_GUARD
+ 1) * 2) - 64) < IMPLICIT_1
);
1388 if (low
& LSBIT64 (63))
1392 while (high
< IMPLICIT_1
);
1394 ASSERT (high
>= IMPLICIT_1
&& high
< IMPLICIT_2
);
1397 f
->fraction
= (high
| 1); /* sticky */
1398 return sim_fpu_status_inexact
;
1409 INLINE_SIM_FPU (int)
1410 sim_fpu_div (sim_fpu
*f
,
1414 if (sim_fpu_is_snan (l
))
1417 f
->class = sim_fpu_class_qnan
;
1418 return sim_fpu_status_invalid_snan
;
1420 if (sim_fpu_is_snan (r
))
1423 f
->class = sim_fpu_class_qnan
;
1424 return sim_fpu_status_invalid_snan
;
1426 if (sim_fpu_is_qnan (l
))
1429 f
->class = sim_fpu_class_qnan
;
1432 if (sim_fpu_is_qnan (r
))
1435 f
->class = sim_fpu_class_qnan
;
1438 if (sim_fpu_is_infinity (l
))
1440 if (sim_fpu_is_infinity (r
))
1443 return sim_fpu_status_invalid_idi
;
1448 f
->sign
= l
->sign
^ r
->sign
;
1452 if (sim_fpu_is_zero (l
))
1454 if (sim_fpu_is_zero (r
))
1457 return sim_fpu_status_invalid_zdz
;
1462 f
->sign
= l
->sign
^ r
->sign
;
1466 if (sim_fpu_is_infinity (r
))
1469 f
->sign
= l
->sign
^ r
->sign
;
1472 if (sim_fpu_is_zero (r
))
1474 f
->class = sim_fpu_class_infinity
;
1475 f
->sign
= l
->sign
^ r
->sign
;
1476 return sim_fpu_status_invalid_div0
;
1479 /* Calculate the mantissa by multiplying both 64bit numbers to get a
1482 /* quotient = ( ( numerator / denominator)
1483 x 2^(numerator exponent - denominator exponent)
1485 unsigned64 numerator
;
1486 unsigned64 denominator
;
1487 unsigned64 quotient
;
1490 f
->class = sim_fpu_class_number
;
1491 f
->sign
= l
->sign
^ r
->sign
;
1492 f
->normal_exp
= l
->normal_exp
- r
->normal_exp
;
1494 numerator
= l
->fraction
;
1495 denominator
= r
->fraction
;
1497 /* Fraction will be less than 1.0 */
1498 if (numerator
< denominator
)
1503 ASSERT (numerator
>= denominator
);
1505 /* Gain extra precision, already used one spare bit */
1506 numerator
<<= NR_SPARE
;
1507 denominator
<<= NR_SPARE
;
1509 /* Does divide one bit at a time. Optimize??? */
1511 bit
= (IMPLICIT_1
<< NR_SPARE
);
1514 if (numerator
>= denominator
)
1517 numerator
-= denominator
;
1523 /* discard (but save) the extra bits */
1524 if ((quotient
& LSMASK64 (NR_SPARE
-1, 0)))
1525 quotient
= (quotient
>> NR_SPARE
) | 1;
1527 quotient
= (quotient
>> NR_SPARE
);
1529 f
->fraction
= quotient
;
1530 ASSERT (f
->fraction
>= IMPLICIT_1
&& f
->fraction
< IMPLICIT_2
);
1533 f
->fraction
|= 1; /* stick remaining bits */
1534 return sim_fpu_status_inexact
;
1542 INLINE_SIM_FPU (int)
1543 sim_fpu_max (sim_fpu
*f
,
1547 if (sim_fpu_is_snan (l
))
1550 f
->class = sim_fpu_class_qnan
;
1551 return sim_fpu_status_invalid_snan
;
1553 if (sim_fpu_is_snan (r
))
1556 f
->class = sim_fpu_class_qnan
;
1557 return sim_fpu_status_invalid_snan
;
1559 if (sim_fpu_is_qnan (l
))
1564 if (sim_fpu_is_qnan (r
))
1569 if (sim_fpu_is_infinity (l
))
1571 if (sim_fpu_is_infinity (r
)
1572 && l
->sign
== r
->sign
)
1575 return sim_fpu_status_invalid_isi
;
1578 *f
= *r
; /* -inf < anything */
1580 *f
= *l
; /* +inf > anthing */
1583 if (sim_fpu_is_infinity (r
))
1586 *f
= *l
; /* anything > -inf */
1588 *f
= *r
; /* anthing < +inf */
1591 if (l
->sign
> r
->sign
)
1593 *f
= *r
; /* -ve < +ve */
1596 if (l
->sign
< r
->sign
)
1598 *f
= *l
; /* +ve > -ve */
1601 ASSERT (l
->sign
== r
->sign
);
1602 if (l
->normal_exp
> r
->normal_exp
1603 || (l
->normal_exp
== r
->normal_exp
&&
1604 l
->fraction
> r
->fraction
))
1608 *f
= *r
; /* -ve < -ve */
1610 *f
= *l
; /* +ve > +ve */
1617 *f
= *l
; /* -ve > -ve */
1619 *f
= *r
; /* +ve < +ve */
1625 INLINE_SIM_FPU (int)
1626 sim_fpu_min (sim_fpu
*f
,
1630 if (sim_fpu_is_snan (l
))
1633 f
->class = sim_fpu_class_qnan
;
1634 return sim_fpu_status_invalid_snan
;
1636 if (sim_fpu_is_snan (r
))
1639 f
->class = sim_fpu_class_qnan
;
1640 return sim_fpu_status_invalid_snan
;
1642 if (sim_fpu_is_qnan (l
))
1647 if (sim_fpu_is_qnan (r
))
1652 if (sim_fpu_is_infinity (l
))
1654 if (sim_fpu_is_infinity (r
)
1655 && l
->sign
== r
->sign
)
1658 return sim_fpu_status_invalid_isi
;
1661 *f
= *l
; /* -inf < anything */
1663 *f
= *r
; /* +inf > anthing */
1666 if (sim_fpu_is_infinity (r
))
1669 *f
= *r
; /* anything > -inf */
1671 *f
= *l
; /* anything < +inf */
1674 if (l
->sign
> r
->sign
)
1676 *f
= *l
; /* -ve < +ve */
1679 if (l
->sign
< r
->sign
)
1681 *f
= *r
; /* +ve > -ve */
1684 ASSERT (l
->sign
== r
->sign
);
1685 if (l
->normal_exp
> r
->normal_exp
1686 || (l
->normal_exp
== r
->normal_exp
&&
1687 l
->fraction
> r
->fraction
))
1691 *f
= *l
; /* -ve < -ve */
1693 *f
= *r
; /* +ve > +ve */
1700 *f
= *r
; /* -ve > -ve */
1702 *f
= *l
; /* +ve < +ve */
1708 INLINE_SIM_FPU (int)
1709 sim_fpu_neg (sim_fpu
*f
,
1712 if (sim_fpu_is_snan (r
))
1715 f
->class = sim_fpu_class_qnan
;
1716 return sim_fpu_status_invalid_snan
;
1718 if (sim_fpu_is_qnan (r
))
1729 INLINE_SIM_FPU (int)
1730 sim_fpu_abs (sim_fpu
*f
,
1733 if (sim_fpu_is_snan (r
))
1736 f
->class = sim_fpu_class_qnan
;
1737 return sim_fpu_status_invalid_snan
;
1739 if (sim_fpu_is_qnan (r
))
1750 INLINE_SIM_FPU (int)
1751 sim_fpu_inv (sim_fpu
*f
,
1754 if (sim_fpu_is_snan (r
))
1757 f
->class = sim_fpu_class_qnan
;
1758 return sim_fpu_status_invalid_snan
;
1760 if (sim_fpu_is_qnan (r
))
1763 f
->class = sim_fpu_class_qnan
;
1766 if (sim_fpu_is_infinity (r
))
1772 if (sim_fpu_is_zero (r
))
1774 f
->class = sim_fpu_class_infinity
;
1776 return sim_fpu_status_invalid_div0
;
1779 f
->normal_exp
= - r
->normal_exp
;
1784 INLINE_SIM_FPU (int)
1785 sim_fpu_sqrt (sim_fpu
*f
,
1788 if (sim_fpu_is_snan (r
))
1791 return sim_fpu_status_invalid_snan
;
1793 if (sim_fpu_is_qnan (r
))
1798 if (sim_fpu_is_zero (r
))
1800 f
->class = sim_fpu_class_zero
;
1804 if (sim_fpu_is_infinity (r
))
1809 return sim_fpu_status_invalid_sqrt
;
1813 f
->class = sim_fpu_class_infinity
;
1822 return sim_fpu_status_invalid_sqrt
;
1825 /* @(#)e_sqrt.c 5.1 93/09/24 */
1827 * ====================================================
1828 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1830 * Developed at SunPro, a Sun Microsystems, Inc. business.
1831 * Permission to use, copy, modify, and distribute this
1832 * software is freely granted, provided that this notice
1834 * ====================================================
1837 /* __ieee754_sqrt(x)
1838 * Return correctly rounded sqrt.
1839 * ------------------------------------------
1840 * | Use the hardware sqrt if you have one |
1841 * ------------------------------------------
1843 * Bit by bit method using integer arithmetic. (Slow, but portable)
1845 * Scale x to y in [1,4) with even powers of 2:
1846 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
1847 * sqrt(x) = 2^k * sqrt(y)
1850 - sqrt ( x*2^(2m) ) = sqrt(x).2^m ; m even
1851 - sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m ; m odd
1853 - y = ((m even) ? x : 2.x)
1855 - y in [1, 4) ; [IMPLICIT_1,IMPLICIT_4)
1857 - sqrt (y) in [1, 2) ; [IMPLICIT_1,IMPLICIT_2)
1859 * 2. Bit by bit computation
1860 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
1863 * s = 2*q , and y = 2 * ( y - q ). (1)
1866 * To compute q from q , one checks whether
1870 * (q + 2 ) <= y. (2)
1873 * If (2) is false, then q = q ; otherwise q = q + 2 .
1876 * With some algebric manipulation, it is not difficult to see
1877 * that (2) is equivalent to
1882 * The advantage of (3) is that s and y can be computed by
1884 * the following recurrence formula:
1887 * s = s , y = y ; (4)
1896 * s = s + 2 , y = y - s - 2 (5)
1901 - NOTE: y = 2 (y - s - 2 )
1904 * One may easily use induction to prove (4) and (5).
1905 * Note. Since the left hand side of (3) contain only i+2 bits,
1906 * it does not necessary to do a full (53-bit) comparison
1909 * After generating the 53 bits result, we compute one more bit.
1910 * Together with the remainder, we can decide whether the
1911 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
1912 * (it will never equal to 1/2ulp).
1913 * The rounding mode can be detected by checking whether
1914 * huge + tiny is equal to huge, and whether huge - tiny is
1915 * equal to huge for some floating point number "huge" and "tiny".
1918 * sqrt(+-0) = +-0 ... exact
1920 * sqrt(-ve) = NaN ... with invalid signal
1921 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
1923 * Other methods : see the appended file at the end of the program below.
1928 /* generate sqrt(x) bit by bit */
1934 f
->class = sim_fpu_class_number
;
1937 f
->normal_exp
= (r
->normal_exp
>> 1); /* exp = [exp/2] */
1939 /* odd exp, double x to make it even */
1940 ASSERT (y
>= IMPLICIT_1
&& y
< IMPLICIT_4
);
1941 if ((r
->normal_exp
& 1))
1945 ASSERT (y
>= IMPLICIT_1
&& y
< (IMPLICIT_2
<< 1));
1947 /* Let loop determine first value of s (either 1 or 2) */
1954 unsigned64 t
= s
+ b
;
1965 ASSERT (q
>= IMPLICIT_1
&& q
< IMPLICIT_2
);
1969 f
->fraction
|= 1; /* stick remaining bits */
1970 return sim_fpu_status_inexact
;
1978 /* int/long <-> sim_fpu */
1980 INLINE_SIM_FPU (int)
1981 sim_fpu_i32to (sim_fpu
*f
,
1983 sim_fpu_round round
)
1989 INLINE_SIM_FPU (int)
1990 sim_fpu_u32to (sim_fpu
*f
,
1992 sim_fpu_round round
)
1998 INLINE_SIM_FPU (int)
1999 sim_fpu_i64to (sim_fpu
*f
,
2001 sim_fpu_round round
)
2007 INLINE_SIM_FPU (int)
2008 sim_fpu_u64to (sim_fpu
*f
,
2010 sim_fpu_round round
)
2017 INLINE_SIM_FPU (int)
2018 sim_fpu_to32i (signed32
*i
,
2020 sim_fpu_round round
)
2023 int status
= fpu2i (&i64
, f
, 0, round
);
2028 INLINE_SIM_FPU (int)
2029 sim_fpu_to32u (unsigned32
*u
,
2031 sim_fpu_round round
)
2034 int status
= fpu2u (&u64
, f
, 0);
2039 INLINE_SIM_FPU (int)
2040 sim_fpu_to64i (signed64
*i
,
2042 sim_fpu_round round
)
2044 return fpu2i (i
, f
, 1, round
);
2048 INLINE_SIM_FPU (int)
2049 sim_fpu_to64u (unsigned64
*u
,
2051 sim_fpu_round round
)
2053 return fpu2u (u
, f
, 1);
2058 /* sim_fpu -> host format */
2061 INLINE_SIM_FPU (float)
2062 sim_fpu_2f (const sim_fpu
*f
)
2069 INLINE_SIM_FPU (double)
2070 sim_fpu_2d (const sim_fpu
*s
)
2073 if (sim_fpu_is_snan (s
))
2077 n
.class = sim_fpu_class_qnan
;
2078 val
.i
= pack_fpu (&n
, 1);
2082 val
.i
= pack_fpu (s
, 1);
2089 INLINE_SIM_FPU (void)
2090 sim_fpu_f2 (sim_fpu
*f
,
2095 unpack_fpu (f
, val
.i
, 1);
2100 INLINE_SIM_FPU (void)
2101 sim_fpu_d2 (sim_fpu
*f
,
2106 unpack_fpu (f
, val
.i
, 1);
2112 INLINE_SIM_FPU (int)
2113 sim_fpu_is_nan (const sim_fpu
*d
)
2117 case sim_fpu_class_qnan
:
2118 case sim_fpu_class_snan
:
2125 INLINE_SIM_FPU (int)
2126 sim_fpu_is_qnan (const sim_fpu
*d
)
2130 case sim_fpu_class_qnan
:
2137 INLINE_SIM_FPU (int)
2138 sim_fpu_is_snan (const sim_fpu
*d
)
2142 case sim_fpu_class_snan
:
2149 INLINE_SIM_FPU (int)
2150 sim_fpu_is_zero (const sim_fpu
*d
)
2154 case sim_fpu_class_zero
:
2161 INLINE_SIM_FPU (int)
2162 sim_fpu_is_infinity (const sim_fpu
*d
)
2166 case sim_fpu_class_infinity
:
2173 INLINE_SIM_FPU (int)
2174 sim_fpu_is_number (const sim_fpu
*d
)
2178 case sim_fpu_class_denorm
:
2179 case sim_fpu_class_number
:
2186 INLINE_SIM_FPU (int)
2187 sim_fpu_is_denorm (const sim_fpu
*d
)
2191 case sim_fpu_class_denorm
:
2199 INLINE_SIM_FPU (int)
2200 sim_fpu_sign (const sim_fpu
*d
)
2206 INLINE_SIM_FPU (int)
2207 sim_fpu_exp (const sim_fpu
*d
)
2209 return d
->normal_exp
;
2214 INLINE_SIM_FPU (int)
2215 sim_fpu_is (const sim_fpu
*d
)
2219 case sim_fpu_class_qnan
:
2220 return SIM_FPU_IS_QNAN
;
2221 case sim_fpu_class_snan
:
2222 return SIM_FPU_IS_SNAN
;
2223 case sim_fpu_class_infinity
:
2225 return SIM_FPU_IS_NINF
;
2227 return SIM_FPU_IS_PINF
;
2228 case sim_fpu_class_number
:
2230 return SIM_FPU_IS_NNUMBER
;
2232 return SIM_FPU_IS_PNUMBER
;
2233 case sim_fpu_class_denorm
:
2235 return SIM_FPU_IS_NDENORM
;
2237 return SIM_FPU_IS_PDENORM
;
2238 case sim_fpu_class_zero
:
2240 return SIM_FPU_IS_NZERO
;
2242 return SIM_FPU_IS_PZERO
;
2249 INLINE_SIM_FPU (int)
2250 sim_fpu_cmp (const sim_fpu
*l
, const sim_fpu
*r
)
2253 sim_fpu_sub (&res
, l
, r
);
2254 return sim_fpu_is (&res
);
2257 INLINE_SIM_FPU (int)
2258 sim_fpu_is_lt (const sim_fpu
*l
, const sim_fpu
*r
)
2261 sim_fpu_lt (&status
, l
, r
);
2265 INLINE_SIM_FPU (int)
2266 sim_fpu_is_le (const sim_fpu
*l
, const sim_fpu
*r
)
2269 sim_fpu_le (&is
, l
, r
);
2273 INLINE_SIM_FPU (int)
2274 sim_fpu_is_eq (const sim_fpu
*l
, const sim_fpu
*r
)
2277 sim_fpu_eq (&is
, l
, r
);
2281 INLINE_SIM_FPU (int)
2282 sim_fpu_is_ne (const sim_fpu
*l
, const sim_fpu
*r
)
2285 sim_fpu_ne (&is
, l
, r
);
2289 INLINE_SIM_FPU (int)
2290 sim_fpu_is_ge (const sim_fpu
*l
, const sim_fpu
*r
)
2293 sim_fpu_ge (&is
, l
, r
);
2297 INLINE_SIM_FPU (int)
2298 sim_fpu_is_gt (const sim_fpu
*l
, const sim_fpu
*r
)
2301 sim_fpu_gt (&is
, l
, r
);
2306 /* Compare operators */
2308 INLINE_SIM_FPU (int)
2309 sim_fpu_lt (int *is
,
2313 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2317 lval
.i
= pack_fpu (l
, 1);
2318 rval
.i
= pack_fpu (r
, 1);
2319 (*is
) = (lval
.d
< rval
.d
);
2322 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2325 return sim_fpu_status_invalid_snan
;
2330 return sim_fpu_status_invalid_qnan
;
2334 INLINE_SIM_FPU (int)
2335 sim_fpu_le (int *is
,
2339 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2343 lval
.i
= pack_fpu (l
, 1);
2344 rval
.i
= pack_fpu (r
, 1);
2345 *is
= (lval
.d
<= rval
.d
);
2348 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2351 return sim_fpu_status_invalid_snan
;
2356 return sim_fpu_status_invalid_qnan
;
2360 INLINE_SIM_FPU (int)
2361 sim_fpu_eq (int *is
,
2365 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2369 lval
.i
= pack_fpu (l
, 1);
2370 rval
.i
= pack_fpu (r
, 1);
2371 (*is
) = (lval
.d
== rval
.d
);
2374 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2377 return sim_fpu_status_invalid_snan
;
2382 return sim_fpu_status_invalid_qnan
;
2386 INLINE_SIM_FPU (int)
2387 sim_fpu_ne (int *is
,
2391 if (!sim_fpu_is_nan (l
) && !sim_fpu_is_nan (r
))
2395 lval
.i
= pack_fpu (l
, 1);
2396 rval
.i
= pack_fpu (r
, 1);
2397 (*is
) = (lval
.d
!= rval
.d
);
2400 else if (sim_fpu_is_snan (l
) || sim_fpu_is_snan (r
))
2403 return sim_fpu_status_invalid_snan
;
2408 return sim_fpu_status_invalid_qnan
;
2412 INLINE_SIM_FPU (int)
2413 sim_fpu_ge (int *is
,
2417 return sim_fpu_le (is
, r
, l
);
2420 INLINE_SIM_FPU (int)
2421 sim_fpu_gt (int *is
,
2425 return sim_fpu_lt (is
, r
, l
);
2429 /* A number of useful constants */
2431 #if EXTERN_SIM_FPU_P
2432 const sim_fpu sim_fpu_zero
= {
2435 const sim_fpu sim_fpu_qnan
= {
2438 const sim_fpu sim_fpu_one
= {
2439 sim_fpu_class_number
, 0, IMPLICIT_1
, 0
2441 const sim_fpu sim_fpu_two
= {
2442 sim_fpu_class_number
, 0, IMPLICIT_1
, 1
2444 const sim_fpu sim_fpu_max32
= {
2445 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS32
), NORMAL_EXPMAX32
2447 const sim_fpu sim_fpu_max64
= {
2448 sim_fpu_class_number
, 0, LSMASK64 (NR_FRAC_GUARD
, NR_GUARDS64
), NORMAL_EXPMAX64
2455 INLINE_SIM_FPU (void)
2456 sim_fpu_print_fpu (const sim_fpu
*f
,
2457 sim_fpu_print_func
*print
,
2460 sim_fpu_printn_fpu (f
, print
, -1, arg
);
2463 INLINE_SIM_FPU (void)
2464 sim_fpu_printn_fpu (const sim_fpu
*f
,
2465 sim_fpu_print_func
*print
,
2469 print (arg
, "%s", f
->sign
? "-" : "+");
2472 case sim_fpu_class_qnan
:
2474 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2475 print (arg
, "*QuietNaN");
2477 case sim_fpu_class_snan
:
2479 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2480 print (arg
, "*SignalNaN");
2482 case sim_fpu_class_zero
:
2485 case sim_fpu_class_infinity
:
2488 case sim_fpu_class_number
:
2489 case sim_fpu_class_denorm
:
2491 print_bits (f
->fraction
, NR_FRAC_GUARD
- 1, digits
, print
, arg
);
2492 print (arg
, "*2^%+d", f
->normal_exp
);
2493 ASSERT (f
->fraction
>= IMPLICIT_1
);
2494 ASSERT (f
->fraction
< IMPLICIT_2
);
2499 INLINE_SIM_FPU (void)
2500 sim_fpu_print_status (int status
,
2501 sim_fpu_print_func
*print
,
2508 switch ((sim_fpu_status
) (status
& i
))
2510 case sim_fpu_status_denorm
:
2511 print (arg
, "%sD", prefix
);
2513 case sim_fpu_status_invalid_snan
:
2514 print (arg
, "%sSNaN", prefix
);
2516 case sim_fpu_status_invalid_qnan
:
2517 print (arg
, "%sQNaN", prefix
);
2519 case sim_fpu_status_invalid_isi
:
2520 print (arg
, "%sISI", prefix
);
2522 case sim_fpu_status_invalid_idi
:
2523 print (arg
, "%sIDI", prefix
);
2525 case sim_fpu_status_invalid_zdz
:
2526 print (arg
, "%sZDZ", prefix
);
2528 case sim_fpu_status_invalid_imz
:
2529 print (arg
, "%sIMZ", prefix
);
2531 case sim_fpu_status_invalid_cvi
:
2532 print (arg
, "%sCVI", prefix
);
2534 case sim_fpu_status_invalid_cmp
:
2535 print (arg
, "%sCMP", prefix
);
2537 case sim_fpu_status_invalid_sqrt
:
2538 print (arg
, "%sSQRT", prefix
);
2541 case sim_fpu_status_inexact
:
2542 print (arg
, "%sX", prefix
);
2545 case sim_fpu_status_overflow
:
2546 print (arg
, "%sO", prefix
);
2549 case sim_fpu_status_underflow
:
2550 print (arg
, "%sU", prefix
);
2553 case sim_fpu_status_invalid_div0
:
2554 print (arg
, "%s/", prefix
);
2557 case sim_fpu_status_rounded
:
2558 print (arg
, "%sR", prefix
);