1 /* This is a software floating point library which can be used instead of
2 the floating point routines in libgcc1.c for targets without hardware
5 /* Copyright (C) 1994,1997 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. */
49 #include "sim-assert.h"
54 /* Floating point number is <SIGN:1><EXP:EXPBITS><FRAC:FRACBITS> */
57 #define SP_GARDROUND 0x3f
58 #define SP_GARDMASK ((unsigned) 0x7f)
59 #define SP_GARDMSB ((unsigned) 0x40)
61 #define SP_EXPBIAS 127
62 #define SP_FRACBITS 23
63 #define SP_EXPMAX ((unsigned) 0xff)
64 #define SP_QUIET_NAN 0x100000L
65 #define SP_FRAC_NBITS 32
66 #define SP_FRACHIGH 0x80000000L
67 #define SP_FRACHIGH2 0xc0000000L
70 #define DP_GARDROUND 0x7f
71 #define DP_GARDMASK ((unsigned) 0xff)
72 #define DP_GARDMSB ((unsigned) 0x80)
74 #define DP_EXPBIAS 1023
75 #define DP_FRACBITS 52
76 #define DP_EXPMAX ((unsigned) 0x7ff)
77 #define DP_QUIET_NAN MSBIT64 (12) /* 0x0008000000000000LL */
78 #define DP_FRAC_NBITS 64
79 #define DP_FRACHIGH MSMASK64 (1) /* 0x8000000000000000LL */
80 #define DP_FRACHIGH2 MSMASK64 (2) /* 0xc000000000000000LL */
82 #define EXPMAX (is_double ? DP_EXPMAX : SP_EXPMAX)
83 #define EXPBITS (is_double ? DP_EXPBITS : SP_EXPBITS)
84 #define EXPBIAS (is_double ? DP_EXPBIAS : SP_EXPBIAS)
85 #define FRACBITS (is_double ? DP_FRACBITS : SP_FRACBITS)
86 #define NGARDS (is_double ? DP_NGARDS : (SP_NGARDS ))
87 #define SIGNBIT ((unsigned64)1 << (EXPBITS + FRACBITS))
88 #define FRAC_NBITS (is_double ? DP_FRAC_NBITS : SP_FRAC_NBITS)
89 #define GARDMASK (is_double ? DP_GARDMASK : SP_GARDMASK)
90 #define GARDMSB (is_double ? DP_GARDMSB : SP_GARDMSB)
91 #define GARDROUND (is_double ? DP_GARDROUND : SP_GARDROUND)
93 /* F_D_BITOFF is the number of bits offset between the MSB of the mantissa
94 of a float and of a double. Assumes there are only two float types.
95 (double::FRAC_BITS+double::NGARGS-(float::FRAC_BITS-float::NGARDS))
97 #define F_D_BITOFF (is_double ? 0 : (52+8-(23+7)))
101 #define (is_double ? DP_ : SP_)
104 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
106 #define IMPLICIT_1 ((unsigned64)1 << (FRACBITS+NGARDS))
107 #define IMPLICIT_2 ((unsigned64)1 << (FRACBITS+1+NGARDS))
109 #define MAX_SI_INT (is_double ? LSMASK64 (63) : LSMASK64 (31))
110 #define MAX_USI_INT (is_double ? LSMASK64 (64) : LSMASK64 (32))
118 sim_fpu_class_number,
119 sim_fpu_class_infinity,
122 typedef struct _sim_ufpu {
134 STATIC_INLINE_SIM_FPU (unsigned64)
135 pack_fpu (const sim_ufpu *src, int is_double)
145 case sim_fpu_class_qnan:
146 case sim_fpu_class_snan:
147 sign = 1; /* fixme - always a qNaN */
149 fraction = src->fraction;
151 case sim_fpu_class_infinity:
156 case sim_fpu_class_zero:
161 case sim_fpu_class_number:
162 if (src->normal_exp < NORMAL_EXPMIN)
164 /* This number's exponent is too low to fit into the bits
165 available in the number, so we'll store 0 in the exponent and
166 shift the fraction to the right to make up for it. */
168 int shift = NORMAL_EXPMIN - src->normal_exp;
173 if (shift > (FRAC_NBITS - NGARDS))
175 /* No point shifting, since it's more that 64 out. */
180 /* Shift by the value */
181 fraction = src->fraction >> F_D_BITOFF;
186 else if (src->normal_exp > EXPBIAS)
196 exp = (src->normal_exp + EXPBIAS);
197 fraction = src->fraction >> F_D_BITOFF;
198 /* IF the gard bits are the all zero, but the first, then we're
199 half way between two numbers, choose the one which makes the
200 lsb of the answer 0. */
201 if ((fraction & GARDMASK) == GARDMSB)
203 if (fraction & (1 << NGARDS))
204 fraction += GARDROUND + 1;
208 /* Add a one to the guards to round up */
209 fraction += GARDROUND;
211 if (fraction >= IMPLICIT_2)
220 return ((sign ? SIGNBIT : 0)
222 | LSMASKED64 (fraction, FRACBITS));
226 STATIC_INLINE_SIM_FPU (void)
227 unpack_fpu (sim_ufpu *dst, unsigned64 s, int is_double)
229 unsigned64 fraction = LSMASKED64 (s, FRACBITS);
230 unsigned exp = LSMASKED64 (s >> FRACBITS, EXPBITS);
232 dst->sign = (s & SIGNBIT) != 0;
236 /* Hmm. Looks like 0 */
239 /* tastes like zero */
240 dst->class = sim_fpu_class_zero;
244 /* Zero exponent with non zero fraction - it's denormalized,
245 so there isn't a leading implicit one - we'll shift it so
247 dst->normal_exp = exp - EXPBIAS + 1;
250 dst->class = sim_fpu_class_number;
251 while (fraction < IMPLICIT_1)
256 dst->fraction = fraction << F_D_BITOFF;
259 else if (exp == EXPMAX)
264 /* Attached to a zero fraction - means infinity */
265 dst->class = sim_fpu_class_infinity;
269 /* Non zero fraction, means nan */
272 dst->class = sim_fpu_class_snan;
276 dst->class = sim_fpu_class_qnan;
278 /* Keep the fraction part as the nan number */
279 dst->fraction = fraction << F_D_BITOFF;
284 /* Nothing strange about this number */
285 dst->normal_exp = exp - EXPBIAS;
286 dst->class = sim_fpu_class_number;
287 dst->fraction = ((fraction << NGARDS) | IMPLICIT_1) << F_D_BITOFF;
292 dst->val.i = pack_fpu (dst, 1);
296 ASSERT (dst->val.i == s);
300 unsigned32 val = pack_fpu (dst, 0);
307 STATIC_INLINE_SIM_FPU (sim_fpu)
308 ufpu2fpu (const sim_ufpu *d)
311 ans.val.i = pack_fpu (d, 1);
316 STATIC_INLINE_SIM_FPU (sim_ufpu)
317 fpu2ufpu (const sim_fpu *d)
320 unpack_fpu (&ans, d->val.i, 1);
325 STATIC_INLINE_SIM_FPU (int)
326 is_ufpu_number (const sim_ufpu *d)
330 case sim_fpu_class_zero:
331 case sim_fpu_class_number:
340 STATIC_INLINE_SIM_FPU (int)
341 is_ufpu_nan (const sim_ufpu *d)
345 case sim_fpu_class_qnan:
346 case sim_fpu_class_snan:
354 STATIC_INLINE_SIM_FPU (int)
355 is_ufpu_zero (const sim_ufpu *d)
359 case sim_fpu_class_zero:
367 STATIC_INLINE_SIM_FPU (int)
368 is_ufpu_inf (const sim_ufpu *d)
372 case sim_fpu_class_infinity:
380 STATIC_INLINE_SIM_FPU (sim_fpu)
384 tmp.class = sim_fpu_class_snan;
388 return ufpu2fpu (&tmp);
392 STATIC_INLINE_SIM_FPU (signed64)
393 fpu2i (sim_fpu s, int is_double)
395 sim_ufpu a = fpu2ufpu (&s);
397 if (is_ufpu_zero (&a))
399 if (is_ufpu_nan (&a))
401 /* get reasonable MAX_SI_INT... */
402 if (is_ufpu_inf (&a))
403 return a.sign ? MAX_SI_INT : (-MAX_SI_INT)-1;
404 /* it is a number, but a small one */
405 if (a.normal_exp < 0)
407 if (a.normal_exp > (FRAC_NBITS - 2))
408 return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
409 if (a.normal_exp > (FRACBITS + NGARDS + F_D_BITOFF))
410 tmp = (a.fraction << (a.normal_exp - (FRACBITS + NGARDS)));
412 tmp = (a.fraction >> ((FRACBITS + NGARDS + F_D_BITOFF) - a.normal_exp));
413 return a.sign ? (-tmp) : (tmp);
416 STATIC_INLINE_SIM_FPU (unsigned64)
417 fpu2u (sim_fpu s, int is_double)
419 sim_ufpu a = fpu2ufpu (&s);
421 if (is_ufpu_zero (&a))
423 if (is_ufpu_nan (&a))
425 /* get reasonable MAX_USI_INT... */
426 if (is_ufpu_inf (&a))
427 return a.sign ? MAX_USI_INT : 0;
428 /* it is a negative number */
431 /* it is a number, but a small one */
432 if (a.normal_exp < 0)
434 if (a.normal_exp > (FRAC_NBITS - 1))
436 if (a.normal_exp > (FRACBITS + NGARDS + F_D_BITOFF))
437 tmp = (a.fraction << (a.normal_exp - (FRACBITS + NGARDS + F_D_BITOFF)));
439 tmp = (a.fraction >> ((FRACBITS + NGARDS + F_D_BITOFF) - a.normal_exp));
444 /* register <-> sim_fpu */
446 INLINE_SIM_FPU (sim_fpu)
447 sim_fpu_32to (unsigned32 s)
450 unpack_fpu (&tmp, s, 0);
451 return ufpu2fpu (&tmp);
455 INLINE_SIM_FPU (sim_fpu)
456 sim_fpu_64to (unsigned64 s)
464 INLINE_SIM_FPU (unsigned32)
465 sim_fpu_to32 (sim_fpu l)
467 /* convert to single safely */
468 sim_ufpu tmp = fpu2ufpu (&l);
469 return pack_fpu (&tmp, 0);
473 INLINE_SIM_FPU (unsigned64)
474 sim_fpu_to64 (sim_fpu s)
482 INLINE_SIM_FPU (sim_fpu)
483 sim_fpu_add (sim_fpu l,
487 ans.val.d = l.val.d + r.val.d;
492 INLINE_SIM_FPU (sim_fpu)
493 sim_fpu_sub (sim_fpu l,
497 ans.val.d = l.val.d - r.val.d;
502 INLINE_SIM_FPU (sim_fpu)
503 sim_fpu_mul (sim_fpu l,
507 ans.val.d = l.val.d * r.val.d;
512 INLINE_SIM_FPU (sim_fpu)
513 sim_fpu_div (sim_fpu l,
516 const int is_double = 1;
517 sim_ufpu a = fpu2ufpu (&l);
518 sim_ufpu b = fpu2ufpu (&r);
520 unsigned64 numerator;
521 unsigned64 denominator;
524 if (is_ufpu_nan (&a))
526 return ufpu2fpu (&a);
528 if (is_ufpu_nan (&b))
530 return ufpu2fpu (&b);
532 if (is_ufpu_inf (&a) || is_ufpu_zero (&a))
534 if (a.class == b.class)
538 a.sign = a.sign ^ b.sign;
540 if (is_ufpu_inf (&b))
544 return ufpu2fpu (&a);
546 if (is_ufpu_zero (&b))
548 a.class = sim_fpu_class_infinity;
549 return ufpu2fpu (&a);
552 /* Calculate the mantissa by multiplying both 64bit numbers to get a
556 ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
559 a.normal_exp = a.normal_exp - b.normal_exp;
560 numerator = a.fraction;
561 denominator = b.fraction;
563 if (numerator < denominator)
565 /* Fraction will be less than 1.0 */
571 /* ??? Does divide one bit at a time. Optimize. */
574 if (numerator >= denominator)
577 numerator -= denominator;
583 if ((quotient & GARDMASK) == GARDMSB)
585 if (quotient & (1 << NGARDS))
587 /* half way, so round to even */
588 quotient += GARDROUND + 1;
592 /* but we really weren't half way, more bits exist */
593 quotient += GARDROUND + 1;
597 a.fraction = quotient;
598 return ufpu2fpu (&a);
603 INLINE_SIM_FPU (sim_fpu)
604 sim_fpu_inv (sim_fpu r)
607 ans.val.d = 1 / r.val.d;
612 INLINE_SIM_FPU (sim_fpu)
613 sim_fpu_sqrt (sim_fpu r)
616 ans.val.d = sqrt (r.val.d);
621 /* int/long -> sim_fpu */
623 INLINE_SIM_FPU (sim_fpu)
624 sim_fpu_i32to (signed32 s)
632 INLINE_SIM_FPU (signed32)
633 sim_fpu_to32i (sim_fpu s)
639 INLINE_SIM_FPU (sim_fpu)
640 sim_fpu_u32to (unsigned32 s)
648 INLINE_SIM_FPU (unsigned32)
649 sim_fpu_to32u (sim_fpu s)
655 INLINE_SIM_FPU (sim_fpu)
656 sim_fpu_i64to (signed64 s)
664 INLINE_SIM_FPU (signed64)
665 sim_fpu_to64i (sim_fpu s)
671 INLINE_SIM_FPU (sim_fpu)
672 sim_fpu_u64to (unsigned64 s)
680 INLINE_SIM_FPU (unsigned64)
681 sim_fpu_to64u (sim_fpu s)
687 /* sim_fpu -> host format */
689 INLINE_SIM_FPU (float)
690 sim_fpu_2f (sim_fpu f)
696 INLINE_SIM_FPU (double)
697 sim_fpu_2d (sim_fpu s)
703 INLINE_SIM_FPU (sim_fpu)
712 INLINE_SIM_FPU (sim_fpu)
713 sim_fpu_d2 (double d)
724 sim_fpu_is_nan (sim_fpu d)
726 sim_ufpu tmp = fpu2ufpu (&d);
727 return is_ufpu_nan (&tmp);
731 /* Compare operators */
734 sim_fpu_is_lt (sim_fpu l,
737 sim_ufpu tl = fpu2ufpu (&l);
738 sim_ufpu tr = fpu2ufpu (&r);
739 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
740 return (l.val.d < r.val.d);
746 sim_fpu_is_le (sim_fpu l,
749 sim_ufpu tl = fpu2ufpu (&l);
750 sim_ufpu tr = fpu2ufpu (&r);
751 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
752 return (l.val.d <= r.val.d);
758 sim_fpu_is_eq (sim_fpu l,
761 sim_ufpu tl = fpu2ufpu (&l);
762 sim_ufpu tr = fpu2ufpu (&r);
763 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
764 return (l.val.d == r.val.d);
770 sim_fpu_is_ne (sim_fpu l,
773 sim_ufpu tl = fpu2ufpu (&l);
774 sim_ufpu tr = fpu2ufpu (&r);
775 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
776 return (l.val.d != r.val.d);
782 sim_fpu_is_ge (sim_fpu l,
785 sim_ufpu tl = fpu2ufpu (&l);
786 sim_ufpu tr = fpu2ufpu (&r);
787 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
788 return (l.val.d >= r.val.d);
794 sim_fpu_is_gt (sim_fpu l,
797 sim_ufpu tl = fpu2ufpu (&l);
798 sim_ufpu tr = fpu2ufpu (&r);
799 if (!is_ufpu_nan (&tl) && !is_ufpu_nan (&tr))
800 return (l.val.d > r.val.d);