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);