1 /* Simulator Floating-point support.
2 Copyright (C) 1994, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 #include "sim-assert.h"
33 /* Floating point number is <SIGN:1><EXP:EXPBITS><FRAC:FRACBITS> */
36 #define SP_GARDROUND 0x3f
37 #define SP_GARDMASK 0x7f
38 #define SP_GARDMSB 0x40
40 #define SP_EXPBIAS 127
41 #define SP_FRACBITS 23
42 #define SP_EXPMAX (0xff)
43 #define SP_QUIET_NAN 0x100000L
44 #define SP_FRAC_NBITS 32
45 #define SP_FRACHIGH 0x80000000L
46 #define SP_FRACHIGH2 0xc0000000L
49 #define DP_GARDROUND 0x7f
50 #define DP_GARDMASK 0xff
51 #define DP_GARDMSB 0x80
53 #define DP_EXPBIAS 1023
54 #define DP_FRACBITS 52
55 #define DP_EXPMAX (0x7ff)
56 #define DP_QUIET_NAN 0x8000000000000LL
57 #define DP_FRAC_NBITS 64
58 #define DP_FRACHIGH 0x8000000000000000LL
59 #define DP_FRACHIGH2 0xc000000000000000LL
61 #define EXPMAX (is_double ? DP_EXPMAX : SP_EXPMAX)
62 #define EXPBITS (is_double ? DP_EXPBITS : SP_EXPBITS)
63 #define EXPBIAS (is_double ? DP_EXPBIAS : SP_EXPBIAS)
64 #define FRACBITS (is_double ? DP_FRACBITS : SP_FRACBITS)
65 #define NGARDS (is_double ? DP_NGARDS : (SP_NGARDS ))
66 #define SIGNBIT (1LL << (EXPBITS + FRACBITS))
67 #define FRAC_NBITS (is_double ? DP_FRAC_NBITS : SP_FRAC_NBITS)
68 #define GARDMASK (is_double ? DP_GARDMASK : SP_GARDMASK)
69 #define GARDMSB (is_double ? DP_GARDMSB : SP_GARDMSB)
70 #define GARDROUND (is_double ? DP_GARDROUND : SP_GARDROUND)
72 /* F_D_BITOFF is the number of bits offset between the MSB of the mantissa
73 of a float and of a double. Assumes there are only two float types.
74 (double::FRAC_BITS+double::NGARGS-(float::FRAC_BITS-float::NGARDS))
76 #define F_D_BITOFF (is_double ? 0 : (52+8-(23+7)))
80 #define (is_double ? DP_ : SP_)
83 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
85 #define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS))
86 #define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS))
88 #define MAX_SI_INT (is_double ? LSMASK64 (63) : LSMASK64 (31))
89 #define MAX_USI_INT (is_double ? LSMASK64 (64) : LSMASK64 (32))
98 sim_fpu_class_infinity
,
101 typedef struct _sim_ufpu
{
113 STATIC_INLINE_SIM_FPU (unsigned64
)
114 pack_fpu (const sim_ufpu
*src
, int is_double
)
124 case sim_fpu_class_qnan
:
125 case sim_fpu_class_snan
:
126 sign
= 1; /* fixme - always a qNaN */
128 fraction
= src
->fraction
;
130 case sim_fpu_class_infinity
:
135 case sim_fpu_class_zero
:
140 case sim_fpu_class_number
:
141 if (src
->normal_exp
< NORMAL_EXPMIN
)
143 /* This number's exponent is too low to fit into the bits
144 available in the number, so we'll store 0 in the exponent and
145 shift the fraction to the right to make up for it. */
147 int shift
= NORMAL_EXPMIN
- src
->normal_exp
;
152 if (shift
> (FRAC_NBITS
- NGARDS
))
154 /* No point shifting, since it's more that 64 out. */
159 /* Shift by the value */
160 fraction
= src
->fraction
>> F_D_BITOFF
;
165 else if (src
->normal_exp
> EXPBIAS
)
175 exp
= (src
->normal_exp
+ EXPBIAS
);
176 fraction
= src
->fraction
>> F_D_BITOFF
;
177 /* IF the gard bits are the all zero, but the first, then we're
178 half way between two numbers, choose the one which makes the
179 lsb of the answer 0. */
180 if ((fraction
& GARDMASK
) == GARDMSB
)
182 if (fraction
& (1 << NGARDS
))
183 fraction
+= GARDROUND
+ 1;
187 /* Add a one to the guards to round up */
188 fraction
+= GARDROUND
;
190 if (fraction
>= IMPLICIT_2
)
199 return ((sign
? SIGNBIT
: 0)
201 | LSMASKED64 (fraction
, FRACBITS
));
205 STATIC_INLINE_SIM_FPU (void)
206 unpack_fpu (sim_ufpu
*dst
, unsigned64 s
, int is_double
)
208 unsigned64 fraction
= LSMASKED64 (s
, FRACBITS
);
209 unsigned exp
= LSMASKED64 (s
>> FRACBITS
, EXPBITS
);
211 dst
->sign
= (s
& SIGNBIT
) != 0;
215 /* Hmm. Looks like 0 */
218 /* tastes like zero */
219 dst
->class = sim_fpu_class_zero
;
223 /* Zero exponent with non zero fraction - it's denormalized,
224 so there isn't a leading implicit one - we'll shift it so
226 dst
->normal_exp
= exp
- EXPBIAS
+ 1;
229 dst
->class = sim_fpu_class_number
;
230 while (fraction
< IMPLICIT_1
)
235 dst
->fraction
= fraction
<< F_D_BITOFF
;
238 else if (exp
== EXPMAX
)
243 /* Attached to a zero fraction - means infinity */
244 dst
->class = sim_fpu_class_infinity
;
248 /* Non zero fraction, means nan */
251 dst
->class = sim_fpu_class_snan
;
255 dst
->class = sim_fpu_class_qnan
;
257 /* Keep the fraction part as the nan number */
258 dst
->fraction
= fraction
<< F_D_BITOFF
;
263 /* Nothing strange about this number */
264 dst
->normal_exp
= exp
- EXPBIAS
;
265 dst
->class = sim_fpu_class_number
;
266 dst
->fraction
= ((fraction
<< NGARDS
) | IMPLICIT_1
) << F_D_BITOFF
;
271 dst
->val
.i
= pack_fpu (dst
, 1);
275 ASSERT (dst
->val
.i
== s
);
279 unsigned32 val
= pack_fpu (dst
, 0);
286 STATIC_INLINE_SIM_FPU (sim_fpu
)
287 ufpu2fpu (const sim_ufpu
*d
)
290 ans
.val
.i
= pack_fpu (d
, 1);
295 STATIC_INLINE_SIM_FPU (sim_ufpu
)
296 fpu2ufpu (const sim_fpu
*d
)
299 unpack_fpu (&ans
, d
->val
.i
, 1);
303 STATIC_INLINE_SIM_FPU (int)
304 is_ufpu_number (const sim_ufpu
*d
)
308 case sim_fpu_class_zero
:
309 case sim_fpu_class_number
:
317 STATIC_INLINE_SIM_FPU (int)
318 is_ufpu_nan (const sim_ufpu
*d
)
322 case sim_fpu_class_qnan
:
323 case sim_fpu_class_snan
:
331 STATIC_INLINE_SIM_FPU (int)
332 is_ufpu_zero (const sim_ufpu
*d
)
336 case sim_fpu_class_zero
:
344 STATIC_INLINE_SIM_FPU (int)
345 is_ufpu_inf (const sim_ufpu
*d
)
349 case sim_fpu_class_infinity
:
357 STATIC_INLINE_SIM_FPU (sim_fpu
)
361 tmp
.class = sim_fpu_class_snan
;
365 return ufpu2fpu (&tmp
);
369 STATIC_INLINE_SIM_FPU (signed64
)
370 fpu2i (sim_fpu s
, int is_double
)
372 sim_ufpu a
= fpu2ufpu (&s
);
374 if (is_ufpu_zero (&a
))
376 if (is_ufpu_nan (&a
))
378 /* get reasonable MAX_SI_INT... */
379 if (is_ufpu_inf (&a
))
380 return a
.sign
? MAX_SI_INT
: (-MAX_SI_INT
)-1;
381 /* it is a number, but a small one */
382 if (a
.normal_exp
< 0)
384 if (a
.normal_exp
> (FRAC_NBITS
- 2))
385 return a
.sign
? (-MAX_SI_INT
)-1 : MAX_SI_INT
;
386 if (a
.normal_exp
> (FRACBITS
+ NGARDS
+ F_D_BITOFF
))
387 tmp
= (a
.fraction
<< (a
.normal_exp
- (FRACBITS
+ NGARDS
)));
389 tmp
= (a
.fraction
>> ((FRACBITS
+ NGARDS
+ F_D_BITOFF
) - a
.normal_exp
));
390 return a
.sign
? (-tmp
) : (tmp
);
393 STATIC_INLINE_SIM_FPU (unsigned64
)
394 fpu2u (sim_fpu s
, int is_double
)
396 sim_ufpu a
= fpu2ufpu (&s
);
398 if (is_ufpu_zero (&a
))
400 if (is_ufpu_nan (&a
))
402 /* get reasonable MAX_USI_INT... */
403 if (is_ufpu_inf (&a
))
404 return a
.sign
? MAX_USI_INT
: 0;
405 /* it is a negative number */
408 /* it is a number, but a small one */
409 if (a
.normal_exp
< 0)
411 if (a
.normal_exp
> (FRAC_NBITS
- 1))
413 if (a
.normal_exp
> (FRACBITS
+ NGARDS
+ F_D_BITOFF
))
414 tmp
= (a
.fraction
<< (a
.normal_exp
- (FRACBITS
+ NGARDS
+ F_D_BITOFF
)));
416 tmp
= (a
.fraction
>> ((FRACBITS
+ NGARDS
+ F_D_BITOFF
) - a
.normal_exp
));
421 /* register <-> sim_fpu */
423 INLINE_SIM_FPU (sim_fpu
)
424 sim_fpu_32to (unsigned32 s
)
427 unpack_fpu (&tmp
, s
, 0);
428 return ufpu2fpu (&tmp
);
432 INLINE_SIM_FPU (sim_fpu
)
433 sim_fpu_64to (unsigned64 s
)
441 INLINE_SIM_FPU (unsigned32
)
442 sim_fpu_to32 (sim_fpu l
)
444 /* convert to single safely */
445 sim_ufpu tmp
= fpu2ufpu (&l
);
446 return pack_fpu (&tmp
, 0);
450 INLINE_SIM_FPU (unsigned64
)
451 sim_fpu_to64 (sim_fpu s
)
459 INLINE_SIM_FPU (sim_fpu
)
460 sim_fpu_add (sim_fpu l
,
464 ans
.val
.d
= l
.val
.d
+ r
.val
.d
;
469 INLINE_SIM_FPU (sim_fpu
)
470 sim_fpu_sub (sim_fpu l
,
474 ans
.val
.d
= l
.val
.d
- r
.val
.d
;
479 INLINE_SIM_FPU (sim_fpu
)
480 sim_fpu_mul (sim_fpu l
,
484 ans
.val
.d
= l
.val
.d
* r
.val
.d
;
489 INLINE_SIM_FPU (sim_fpu
)
490 sim_fpu_div (sim_fpu l
,
493 const int is_double
= 1;
494 sim_ufpu a
= fpu2ufpu (&l
);
495 sim_ufpu b
= fpu2ufpu (&r
);
497 unsigned64 numerator
;
498 unsigned64 denominator
;
501 if (is_ufpu_nan (&a
))
503 return ufpu2fpu (&a
);
505 if (is_ufpu_nan (&b
))
507 return ufpu2fpu (&b
);
509 if (is_ufpu_inf (&a
) || is_ufpu_zero (&a
))
511 if (a
.class == b
.class)
515 a
.sign
= a
.sign
^ b
.sign
;
517 if (is_ufpu_inf (&b
))
521 return ufpu2fpu (&a
);
523 if (is_ufpu_zero (&b
))
525 a
.class = sim_fpu_class_infinity
;
526 return ufpu2fpu (&a
);
529 /* Calculate the mantissa by multiplying both 64bit numbers to get a
533 ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
536 a
.normal_exp
= a
.normal_exp
- b
.normal_exp
;
537 numerator
= a
.fraction
;
538 denominator
= b
.fraction
;
540 if (numerator
< denominator
)
542 /* Fraction will be less than 1.0 */
548 /* ??? Does divide one bit at a time. Optimize. */
551 if (numerator
>= denominator
)
554 numerator
-= denominator
;
560 if ((quotient
& GARDMASK
) == GARDMSB
)
562 if (quotient
& (1 << NGARDS
))
564 /* half way, so round to even */
565 quotient
+= GARDROUND
+ 1;
569 /* but we really weren't half way, more bits exist */
570 quotient
+= GARDROUND
+ 1;
574 a
.fraction
= quotient
;
575 return ufpu2fpu (&a
);
580 INLINE_SIM_FPU (sim_fpu
)
581 sim_fpu_inv (sim_fpu r
)
584 ans
.val
.d
= 1 / r
.val
.d
;
589 INLINE_SIM_FPU (sim_fpu
)
590 sim_fpu_sqrt (sim_fpu r
)
593 ans
.val
.d
= sqrt (r
.val
.d
);
598 /* int/long -> sim_fpu */
600 INLINE_SIM_FPU (sim_fpu
)
601 sim_fpu_i32to (signed32 s
)
609 INLINE_SIM_FPU (signed32
)
610 sim_fpu_to32i (sim_fpu s
)
616 INLINE_SIM_FPU (sim_fpu
)
617 sim_fpu_u32to (unsigned32 s
)
625 INLINE_SIM_FPU (unsigned32
)
626 sim_fpu_to32u (sim_fpu s
)
632 INLINE_SIM_FPU (sim_fpu
)
633 sim_fpu_i64to (signed64 s
)
641 INLINE_SIM_FPU (signed64
)
642 sim_fpu_to64i (sim_fpu s
)
648 INLINE_SIM_FPU (sim_fpu
)
649 sim_fpu_u64to (unsigned64 s
)
657 INLINE_SIM_FPU (unsigned64
)
658 sim_fpu_to64u (sim_fpu s
)
664 /* sim_fpu -> host format */
666 INLINE_SIM_FPU (float)
667 sim_fpu_2f (sim_fpu f
)
673 INLINE_SIM_FPU (double)
674 sim_fpu_2d (sim_fpu s
)
680 INLINE_SIM_FPU (sim_fpu
)
689 INLINE_SIM_FPU (sim_fpu
)
690 sim_fpu_d2 (double d
)
701 sim_fpu_is_nan (sim_fpu d
)
703 sim_ufpu tmp
= fpu2ufpu (&d
);
704 return is_ufpu_nan (&tmp
);
708 /* Compare operators */
711 sim_fpu_is_lt (sim_fpu l
,
714 sim_ufpu tl
= fpu2ufpu (&l
);
715 sim_ufpu tr
= fpu2ufpu (&r
);
716 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
717 return (l
.val
.d
< r
.val
.d
);
723 sim_fpu_is_le (sim_fpu l
,
726 sim_ufpu tl
= fpu2ufpu (&l
);
727 sim_ufpu tr
= fpu2ufpu (&r
);
728 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
729 return (l
.val
.d
<= r
.val
.d
);
735 sim_fpu_is_eq (sim_fpu l
,
738 sim_ufpu tl
= fpu2ufpu (&l
);
739 sim_ufpu tr
= fpu2ufpu (&r
);
740 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
741 return (l
.val
.d
== r
.val
.d
);
747 sim_fpu_is_ne (sim_fpu l
,
750 sim_ufpu tl
= fpu2ufpu (&l
);
751 sim_ufpu tr
= fpu2ufpu (&r
);
752 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
753 return (l
.val
.d
!= r
.val
.d
);
759 sim_fpu_is_ge (sim_fpu l
,
762 sim_ufpu tl
= fpu2ufpu (&l
);
763 sim_ufpu tr
= fpu2ufpu (&r
);
764 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
765 return (l
.val
.d
>= r
.val
.d
);
771 sim_fpu_is_gt (sim_fpu l
,
774 sim_ufpu tl
= fpu2ufpu (&l
);
775 sim_ufpu tr
= fpu2ufpu (&r
);
776 if (is_ufpu_number (&tl
) && is_ufpu_number (&tr
))
777 return (l
.val
.d
> r
.val
.d
);
This page took 0.064161 seconds and 5 git commands to generate.