Home | History | Annotate | Line # | Download | only in common
sim-fpu.c revision 1.1.1.2
      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.  */
      4 
      5 /* Copyright 1994-2015 Free Software Foundation, Inc.
      6 
      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 3 of the License, or
     10 (at your option) any later version.
     11 
     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.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 /* As a special exception, if you link this library with other files,
     21    some of which are compiled with GCC, to produce an executable,
     22    this library does not by itself cause the resulting executable
     23    to be covered by the GNU General Public License.
     24    This exception does not however invalidate any other reasons why
     25    the executable file might be covered by the GNU General Public License.  */
     26 
     27 /* This implements IEEE 754 format arithmetic, but does not provide a
     28    mechanism for setting the rounding mode, or for generating or handling
     29    exceptions.
     30 
     31    The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
     32    Wilson, all of Cygnus Support.  */
     33 
     34 
     35 #ifndef SIM_FPU_C
     36 #define SIM_FPU_C
     37 
     38 #include "sim-basics.h"
     39 #include "sim-fpu.h"
     40 
     41 #include "sim-io.h"
     42 #include "sim-assert.h"
     43 
     44 
     45 /* Debugging support.
     46    If digits is -1, then print all digits.  */
     47 
     48 static void
     49 print_bits (unsigned64 x,
     50 	    int msbit,
     51 	    int digits,
     52 	    sim_fpu_print_func print,
     53 	    void *arg)
     54 {
     55   unsigned64 bit = LSBIT64 (msbit);
     56   int i = 4;
     57   while (bit && digits)
     58     {
     59       if (i == 0)
     60 	print (arg, ",");
     61 
     62       if ((x & bit))
     63 	print (arg, "1");
     64       else
     65 	print (arg, "0");
     66       bit >>= 1;
     67 
     68       if (digits > 0) digits--;
     69       i = (i + 1) % 4;
     70     }
     71 }
     72 
     73 
     74 
     75 /* Quick and dirty conversion between a host double and host 64bit int */
     76 
     77 typedef union {
     78   double d;
     79   unsigned64 i;
     80 } sim_fpu_map;
     81 
     82 
     83 /* A packed IEEE floating point number.
     84 
     85    Form is <SIGN:1><BIASEDEXP:NR_EXPBITS><FRAC:NR_FRACBITS> for both
     86    32 and 64 bit numbers.  This number is interpreted as:
     87 
     88    Normalized (0 < BIASEDEXP && BIASEDEXP < EXPMAX):
     89    (sign ? '-' : '+') 1.<FRAC> x 2 ^ (BIASEDEXP - EXPBIAS)
     90 
     91    Denormalized (0 == BIASEDEXP && FRAC != 0):
     92    (sign ? "-" : "+") 0.<FRAC> x 2 ^ (- EXPBIAS)
     93 
     94    Zero (0 == BIASEDEXP && FRAC == 0):
     95    (sign ? "-" : "+") 0.0
     96 
     97    Infinity (BIASEDEXP == EXPMAX && FRAC == 0):
     98    (sign ? "-" : "+") "infinity"
     99 
    100    SignalingNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC < QUIET_NAN):
    101    SNaN.FRAC
    102 
    103    QuietNaN (BIASEDEXP == EXPMAX && FRAC > 0 && FRAC > QUIET_NAN):
    104    QNaN.FRAC
    105 
    106    */
    107 
    108 #define NR_EXPBITS  (is_double ?   11 :   8)
    109 #define NR_FRACBITS (is_double ?   52 : 23)
    110 #define SIGNBIT     (is_double ? MSBIT64 (0) : MSBIT64 (32))
    111 
    112 #define EXPMAX32    (255)
    113 #define EXMPAX64    (2047)
    114 #define EXPMAX      ((unsigned) (is_double ? EXMPAX64 : EXPMAX32))
    115 
    116 #define EXPBIAS32   (127)
    117 #define EXPBIAS64   (1023)
    118 #define EXPBIAS     (is_double ? EXPBIAS64 : EXPBIAS32)
    119 
    120 #define QUIET_NAN   LSBIT64 (NR_FRACBITS - 1)
    121 
    122 
    123 
    124 /* An unpacked floating point number.
    125 
    126    When unpacked, the fraction of both a 32 and 64 bit floating point
    127    number is stored using the same format:
    128 
    129    64 bit - <IMPLICIT_1:1><FRACBITS:52><GUARDS:8><PAD:00>
    130    32 bit - <IMPLICIT_1:1><FRACBITS:23><GUARDS:7><PAD:30> */
    131 
    132 #define NR_PAD32    (30)
    133 #define NR_PAD64    (0)
    134 #define NR_PAD      (is_double ? NR_PAD64 : NR_PAD32)
    135 #define PADMASK     (is_double ? 0 : LSMASK64 (NR_PAD32 - 1, 0))
    136 
    137 #define NR_GUARDS32 (7 + NR_PAD32)
    138 #define NR_GUARDS64 (8 + NR_PAD64)
    139 #define NR_GUARDS  (is_double ? NR_GUARDS64 : NR_GUARDS32)
    140 #define GUARDMASK  LSMASK64 (NR_GUARDS - 1, 0)
    141 
    142 #define GUARDMSB   LSBIT64  (NR_GUARDS - 1)
    143 #define GUARDLSB   LSBIT64  (NR_PAD)
    144 #define GUARDROUND LSMASK64 (NR_GUARDS - 2, 0)
    145 
    146 #define NR_FRAC_GUARD   (60)
    147 #define IMPLICIT_1 LSBIT64 (NR_FRAC_GUARD)
    148 #define IMPLICIT_2 LSBIT64 (NR_FRAC_GUARD + 1)
    149 #define IMPLICIT_4 LSBIT64 (NR_FRAC_GUARD + 2)
    150 #define NR_SPARE 2
    151 
    152 #define FRAC32MASK LSMASK64 (63, NR_FRAC_GUARD - 32 + 1)
    153 
    154 #define NORMAL_EXPMIN (-(EXPBIAS)+1)
    155 
    156 #define NORMAL_EXPMAX32 (EXPBIAS32)
    157 #define NORMAL_EXPMAX64 (EXPBIAS64)
    158 #define NORMAL_EXPMAX (EXPBIAS)
    159 
    160 
    161 /* Integer constants */
    162 
    163 #define MAX_INT32  ((signed64) LSMASK64 (30, 0))
    164 #define MAX_UINT32 LSMASK64 (31, 0)
    165 #define MIN_INT32  ((signed64) LSMASK64 (63, 31))
    166 
    167 #define MAX_INT64  ((signed64) LSMASK64 (62, 0))
    168 #define MAX_UINT64 LSMASK64 (63, 0)
    169 #define MIN_INT64  ((signed64) LSMASK64 (63, 63))
    170 
    171 #define MAX_INT   (is_64bit ? MAX_INT64  : MAX_INT32)
    172 #define MIN_INT   (is_64bit ? MIN_INT64  : MIN_INT32)
    173 #define MAX_UINT  (is_64bit ? MAX_UINT64 : MAX_UINT32)
    174 #define NR_INTBITS (is_64bit ? 64 : 32)
    175 
    176 /* Squeese an unpacked sim_fpu struct into a 32/64 bit integer */
    177 STATIC_INLINE_SIM_FPU (unsigned64)
    178 pack_fpu (const sim_fpu *src,
    179 	  int is_double)
    180 {
    181   int sign;
    182   unsigned64 exp;
    183   unsigned64 fraction;
    184   unsigned64 packed;
    185 
    186   switch (src->class)
    187     {
    188       /* create a NaN */
    189     case sim_fpu_class_qnan:
    190       sign = src->sign;
    191       exp = EXPMAX;
    192       /* force fraction to correct class */
    193       fraction = src->fraction;
    194       fraction >>= NR_GUARDS;
    195 #ifdef SIM_QUIET_NAN_NEGATED
    196       fraction |= QUIET_NAN - 1;
    197 #else
    198       fraction |= QUIET_NAN;
    199 #endif
    200       break;
    201     case sim_fpu_class_snan:
    202       sign = src->sign;
    203       exp = EXPMAX;
    204       /* force fraction to correct class */
    205       fraction = src->fraction;
    206       fraction >>= NR_GUARDS;
    207 #ifdef SIM_QUIET_NAN_NEGATED
    208       fraction |= QUIET_NAN;
    209 #else
    210       fraction &= ~QUIET_NAN;
    211 #endif
    212       break;
    213     case sim_fpu_class_infinity:
    214       sign = src->sign;
    215       exp = EXPMAX;
    216       fraction = 0;
    217       break;
    218     case sim_fpu_class_zero:
    219       sign = src->sign;
    220       exp = 0;
    221       fraction = 0;
    222       break;
    223     case sim_fpu_class_number:
    224     case sim_fpu_class_denorm:
    225       ASSERT (src->fraction >= IMPLICIT_1);
    226       ASSERT (src->fraction < IMPLICIT_2);
    227       if (src->normal_exp < NORMAL_EXPMIN)
    228 	{
    229 	  /* This number's exponent is too low to fit into the bits
    230 	     available in the number We'll denormalize the number by
    231 	     storing zero in the exponent and shift the fraction to
    232 	     the right to make up for it. */
    233 	  int nr_shift = NORMAL_EXPMIN - src->normal_exp;
    234 	  if (nr_shift > NR_FRACBITS)
    235 	    {
    236 	      /* underflow, just make the number zero */
    237 	      sign = src->sign;
    238 	      exp = 0;
    239 	      fraction = 0;
    240 	    }
    241 	  else
    242 	    {
    243 	      sign = src->sign;
    244 	      exp = 0;
    245 	      /* Shift by the value */
    246 	      fraction = src->fraction;
    247 	      fraction >>= NR_GUARDS;
    248 	      fraction >>= nr_shift;
    249 	    }
    250 	}
    251       else if (src->normal_exp > NORMAL_EXPMAX)
    252 	{
    253 	  /* Infinity */
    254 	  sign = src->sign;
    255 	  exp = EXPMAX;
    256 	  fraction = 0;
    257 	}
    258       else
    259 	{
    260 	  exp = (src->normal_exp + EXPBIAS);
    261 	  sign = src->sign;
    262 	  fraction = src->fraction;
    263 	  /* FIXME: Need to round according to WITH_SIM_FPU_ROUNDING
    264              or some such */
    265 	  /* Round to nearest: If the guard bits are the all zero, but
    266 	     the first, then we're half way between two numbers,
    267 	     choose the one which makes the lsb of the answer 0.  */
    268 	  if ((fraction & GUARDMASK) == GUARDMSB)
    269 	    {
    270 	      if ((fraction & (GUARDMSB << 1)))
    271 		fraction += (GUARDMSB << 1);
    272 	    }
    273 	  else
    274 	    {
    275 	      /* Add a one to the guards to force round to nearest */
    276 	      fraction += GUARDROUND;
    277 	    }
    278 	  if ((fraction & IMPLICIT_2)) /* rounding resulted in carry */
    279 	    {
    280 	      exp += 1;
    281 	      fraction >>= 1;
    282 	    }
    283 	  fraction >>= NR_GUARDS;
    284 	  /* When exp == EXPMAX (overflow from carry) fraction must
    285 	     have been made zero */
    286 	  ASSERT ((exp == EXPMAX) <= ((fraction & ~IMPLICIT_1) == 0));
    287 	}
    288       break;
    289     default:
    290       abort ();
    291     }
    292 
    293   packed = ((sign ? SIGNBIT : 0)
    294 	     | (exp << NR_FRACBITS)
    295 	     | LSMASKED64 (fraction, NR_FRACBITS - 1, 0));
    296 
    297   /* trace operation */
    298 #if 0
    299   if (is_double)
    300     {
    301     }
    302   else
    303     {
    304       printf ("pack_fpu: ");
    305       printf ("-> %c%0lX.%06lX\n",
    306 	      LSMASKED32 (packed, 31, 31) ? '8' : '0',
    307 	      (long) LSEXTRACTED32 (packed, 30, 23),
    308 	      (long) LSEXTRACTED32 (packed, 23 - 1, 0));
    309     }
    310 #endif
    311 
    312   return packed;
    313 }
    314 
    315 
    316 /* Unpack a 32/64 bit integer into a sim_fpu structure */
    317 STATIC_INLINE_SIM_FPU (void)
    318 unpack_fpu (sim_fpu *dst, unsigned64 packed, int is_double)
    319 {
    320   unsigned64 fraction = LSMASKED64 (packed, NR_FRACBITS - 1, 0);
    321   unsigned exp = LSEXTRACTED64 (packed, NR_EXPBITS + NR_FRACBITS - 1, NR_FRACBITS);
    322   int sign = (packed & SIGNBIT) != 0;
    323 
    324   if (exp == 0)
    325     {
    326       /* Hmm.  Looks like 0 */
    327       if (fraction == 0)
    328 	{
    329 	  /* tastes like zero */
    330 	  dst->class = sim_fpu_class_zero;
    331 	  dst->sign = sign;
    332 	  dst->normal_exp = 0;
    333 	}
    334       else
    335 	{
    336 	  /* Zero exponent with non zero fraction - it's denormalized,
    337 	     so there isn't a leading implicit one - we'll shift it so
    338 	     it gets one.  */
    339 	  dst->normal_exp = exp - EXPBIAS + 1;
    340 	  dst->class = sim_fpu_class_denorm;
    341 	  dst->sign = sign;
    342 	  fraction <<= NR_GUARDS;
    343 	  while (fraction < IMPLICIT_1)
    344 	    {
    345 	      fraction <<= 1;
    346 	      dst->normal_exp--;
    347 	    }
    348 	  dst->fraction = fraction;
    349 	}
    350     }
    351   else if (exp == EXPMAX)
    352     {
    353       /* Huge exponent*/
    354       if (fraction == 0)
    355 	{
    356 	  /* Attached to a zero fraction - means infinity */
    357 	  dst->class = sim_fpu_class_infinity;
    358 	  dst->sign = sign;
    359 	  /* dst->normal_exp = EXPBIAS; */
    360 	  /* dst->fraction = 0; */
    361 	}
    362       else
    363 	{
    364 	  int qnan;
    365 
    366 	  /* Non zero fraction, means NaN */
    367 	  dst->sign = sign;
    368 	  dst->fraction = (fraction << NR_GUARDS);
    369 #ifdef SIM_QUIET_NAN_NEGATED
    370 	  qnan = (fraction & QUIET_NAN) == 0;
    371 #else
    372 	  qnan = fraction >= QUIET_NAN;
    373 #endif
    374 	  if (qnan)
    375 	    dst->class = sim_fpu_class_qnan;
    376 	  else
    377 	    dst->class = sim_fpu_class_snan;
    378 	}
    379     }
    380   else
    381     {
    382       /* Nothing strange about this number */
    383       dst->class = sim_fpu_class_number;
    384       dst->sign = sign;
    385       dst->fraction = ((fraction << NR_GUARDS) | IMPLICIT_1);
    386       dst->normal_exp = exp - EXPBIAS;
    387     }
    388 
    389   /* trace operation */
    390 #if 0
    391   if (is_double)
    392     {
    393     }
    394   else
    395     {
    396       printf ("unpack_fpu: %c%02lX.%06lX ->\n",
    397 	      LSMASKED32 (packed, 31, 31) ? '8' : '0',
    398 	      (long) LSEXTRACTED32 (packed, 30, 23),
    399 	      (long) LSEXTRACTED32 (packed, 23 - 1, 0));
    400     }
    401 #endif
    402 
    403   /* sanity checks */
    404   {
    405     sim_fpu_map val;
    406     val.i = pack_fpu (dst, 1);
    407     if (is_double)
    408       {
    409 	ASSERT (val.i == packed);
    410       }
    411     else
    412       {
    413 	unsigned32 val = pack_fpu (dst, 0);
    414 	unsigned32 org = packed;
    415 	ASSERT (val == org);
    416       }
    417   }
    418 }
    419 
    420 
    421 /* Convert a floating point into an integer */
    422 STATIC_INLINE_SIM_FPU (int)
    423 fpu2i (signed64 *i,
    424        const sim_fpu *s,
    425        int is_64bit,
    426        sim_fpu_round round)
    427 {
    428   unsigned64 tmp;
    429   int shift;
    430   int status = 0;
    431   if (sim_fpu_is_zero (s))
    432     {
    433       *i = 0;
    434       return 0;
    435     }
    436   if (sim_fpu_is_snan (s))
    437     {
    438       *i = MIN_INT; /* FIXME */
    439       return sim_fpu_status_invalid_cvi;
    440     }
    441   if (sim_fpu_is_qnan (s))
    442     {
    443       *i = MIN_INT; /* FIXME */
    444       return sim_fpu_status_invalid_cvi;
    445     }
    446   /* map infinity onto MAX_INT... */
    447   if (sim_fpu_is_infinity (s))
    448     {
    449       *i = s->sign ? MIN_INT : MAX_INT;
    450       return sim_fpu_status_invalid_cvi;
    451     }
    452   /* it is a number, but a small one */
    453   if (s->normal_exp < 0)
    454     {
    455       *i = 0;
    456       return sim_fpu_status_inexact;
    457     }
    458   /* Is the floating point MIN_INT or just close? */
    459   if (s->sign && s->normal_exp == (NR_INTBITS - 1))
    460     {
    461       *i = MIN_INT;
    462       ASSERT (s->fraction >= IMPLICIT_1);
    463       if (s->fraction == IMPLICIT_1)
    464 	return 0; /* exact */
    465       if (is_64bit) /* can't round */
    466 	return sim_fpu_status_invalid_cvi; /* must be overflow */
    467       /* For a 32bit with MAX_INT, rounding is possible */
    468       switch (round)
    469 	{
    470 	case sim_fpu_round_default:
    471 	  abort ();
    472 	case sim_fpu_round_zero:
    473 	  if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
    474 	    return sim_fpu_status_invalid_cvi;
    475 	  else
    476 	    return sim_fpu_status_inexact;
    477 	  break;
    478 	case sim_fpu_round_near:
    479 	  {
    480 	    if ((s->fraction & FRAC32MASK) != IMPLICIT_1)
    481 	      return sim_fpu_status_invalid_cvi;
    482 	    else if ((s->fraction & !FRAC32MASK) >= (~FRAC32MASK >> 1))
    483 	      return sim_fpu_status_invalid_cvi;
    484 	    else
    485 	      return sim_fpu_status_inexact;
    486 	  }
    487 	case sim_fpu_round_up:
    488 	  if ((s->fraction & FRAC32MASK) == IMPLICIT_1)
    489 	    return sim_fpu_status_inexact;
    490 	  else
    491 	    return sim_fpu_status_invalid_cvi;
    492 	case sim_fpu_round_down:
    493 	  return sim_fpu_status_invalid_cvi;
    494 	}
    495     }
    496   /* Would right shifting result in the FRAC being shifted into
    497      (through) the integer's sign bit? */
    498   if (s->normal_exp > (NR_INTBITS - 2))
    499     {
    500       *i = s->sign ? MIN_INT : MAX_INT;
    501       return sim_fpu_status_invalid_cvi;
    502     }
    503   /* normal number shift it into place */
    504   tmp = s->fraction;
    505   shift = (s->normal_exp - (NR_FRAC_GUARD));
    506   if (shift > 0)
    507     {
    508       tmp <<= shift;
    509     }
    510   else
    511     {
    512       shift = -shift;
    513       if (tmp & ((SIGNED64 (1) << shift) - 1))
    514 	status |= sim_fpu_status_inexact;
    515       tmp >>= shift;
    516     }
    517   *i = s->sign ? (-tmp) : (tmp);
    518   return status;
    519 }
    520 
    521 /* convert an integer into a floating point */
    522 STATIC_INLINE_SIM_FPU (int)
    523 i2fpu (sim_fpu *f, signed64 i, int is_64bit)
    524 {
    525   int status = 0;
    526   if (i == 0)
    527     {
    528       f->class = sim_fpu_class_zero;
    529       f->sign = 0;
    530       f->normal_exp = 0;
    531     }
    532   else
    533     {
    534       f->class = sim_fpu_class_number;
    535       f->sign = (i < 0);
    536       f->normal_exp = NR_FRAC_GUARD;
    537 
    538       if (f->sign)
    539 	{
    540 	  /* Special case for minint, since there is no corresponding
    541 	     +ve integer representation for it */
    542 	  if (i == MIN_INT)
    543 	    {
    544 	      f->fraction = IMPLICIT_1;
    545 	      f->normal_exp = NR_INTBITS - 1;
    546 	    }
    547 	  else
    548 	    f->fraction = (-i);
    549 	}
    550       else
    551 	f->fraction = i;
    552 
    553       if (f->fraction >= IMPLICIT_2)
    554 	{
    555 	  do
    556 	    {
    557 	      f->fraction = (f->fraction >> 1) | (f->fraction & 1);
    558 	      f->normal_exp += 1;
    559 	    }
    560 	  while (f->fraction >= IMPLICIT_2);
    561 	}
    562       else if (f->fraction < IMPLICIT_1)
    563 	{
    564 	  do
    565 	    {
    566 	      f->fraction <<= 1;
    567 	      f->normal_exp -= 1;
    568 	    }
    569 	  while (f->fraction < IMPLICIT_1);
    570 	}
    571     }
    572 
    573   /* trace operation */
    574 #if 0
    575   {
    576     printf ("i2fpu: 0x%08lX ->\n", (long) i);
    577   }
    578 #endif
    579 
    580   /* sanity check */
    581   {
    582     signed64 val;
    583     fpu2i (&val, f, is_64bit, sim_fpu_round_zero);
    584     if (i >= MIN_INT32 && i <= MAX_INT32)
    585       {
    586 	ASSERT (val == i);
    587       }
    588   }
    589 
    590   return status;
    591 }
    592 
    593 
    594 /* Convert a floating point into an integer */
    595 STATIC_INLINE_SIM_FPU (int)
    596 fpu2u (unsigned64 *u, const sim_fpu *s, int is_64bit)
    597 {
    598   const int is_double = 1;
    599   unsigned64 tmp;
    600   int shift;
    601   if (sim_fpu_is_zero (s))
    602     {
    603       *u = 0;
    604       return 0;
    605     }
    606   if (sim_fpu_is_nan (s))
    607     {
    608       *u = 0;
    609       return 0;
    610     }
    611   /* it is a negative number */
    612   if (s->sign)
    613     {
    614       *u = 0;
    615       return 0;
    616     }
    617   /* get reasonable MAX_USI_INT... */
    618   if (sim_fpu_is_infinity (s))
    619     {
    620       *u = MAX_UINT;
    621       return 0;
    622     }
    623   /* it is a number, but a small one */
    624   if (s->normal_exp < 0)
    625     {
    626       *u = 0;
    627       return 0;
    628     }
    629   /* overflow */
    630   if (s->normal_exp > (NR_INTBITS - 1))
    631     {
    632       *u = MAX_UINT;
    633       return 0;
    634     }
    635   /* normal number */
    636   tmp = (s->fraction & ~PADMASK);
    637   shift = (s->normal_exp - (NR_FRACBITS + NR_GUARDS));
    638   if (shift > 0)
    639     {
    640       tmp <<= shift;
    641     }
    642   else
    643     {
    644       shift = -shift;
    645       tmp >>= shift;
    646     }
    647   *u = tmp;
    648   return 0;
    649 }
    650 
    651 /* Convert an unsigned integer into a floating point */
    652 STATIC_INLINE_SIM_FPU (int)
    653 u2fpu (sim_fpu *f, unsigned64 u, int is_64bit)
    654 {
    655   if (u == 0)
    656     {
    657       f->class = sim_fpu_class_zero;
    658       f->sign = 0;
    659       f->normal_exp = 0;
    660     }
    661   else
    662     {
    663       f->class = sim_fpu_class_number;
    664       f->sign = 0;
    665       f->normal_exp = NR_FRAC_GUARD;
    666       f->fraction = u;
    667 
    668       while (f->fraction < IMPLICIT_1)
    669 	{
    670 	  f->fraction <<= 1;
    671 	  f->normal_exp -= 1;
    672 	}
    673     }
    674   return 0;
    675 }
    676 
    677 
    678 /* register <-> sim_fpu */
    679 
    680 INLINE_SIM_FPU (void)
    681 sim_fpu_32to (sim_fpu *f, unsigned32 s)
    682 {
    683   unpack_fpu (f, s, 0);
    684 }
    685 
    686 
    687 INLINE_SIM_FPU (void)
    688 sim_fpu_232to (sim_fpu *f, unsigned32 h, unsigned32 l)
    689 {
    690   unsigned64 s = h;
    691   s = (s << 32) | l;
    692   unpack_fpu (f, s, 1);
    693 }
    694 
    695 
    696 INLINE_SIM_FPU (void)
    697 sim_fpu_64to (sim_fpu *f, unsigned64 s)
    698 {
    699   unpack_fpu (f, s, 1);
    700 }
    701 
    702 
    703 INLINE_SIM_FPU (void)
    704 sim_fpu_to32 (unsigned32 *s,
    705 	      const sim_fpu *f)
    706 {
    707   *s = pack_fpu (f, 0);
    708 }
    709 
    710 
    711 INLINE_SIM_FPU (void)
    712 sim_fpu_to232 (unsigned32 *h, unsigned32 *l,
    713 	       const sim_fpu *f)
    714 {
    715   unsigned64 s = pack_fpu (f, 1);
    716   *l = s;
    717   *h = (s >> 32);
    718 }
    719 
    720 
    721 INLINE_SIM_FPU (void)
    722 sim_fpu_to64 (unsigned64 *u,
    723 	      const sim_fpu *f)
    724 {
    725   *u = pack_fpu (f, 1);
    726 }
    727 
    728 
    729 INLINE_SIM_FPU (void)
    730 sim_fpu_fractionto (sim_fpu *f,
    731 		    int sign,
    732 		    int normal_exp,
    733 		    unsigned64 fraction,
    734 		    int precision)
    735 {
    736   int shift = (NR_FRAC_GUARD - precision);
    737   f->class = sim_fpu_class_number;
    738   f->sign = sign;
    739   f->normal_exp = normal_exp;
    740   /* shift the fraction to where sim-fpu expects it */
    741   if (shift >= 0)
    742     f->fraction = (fraction << shift);
    743   else
    744     f->fraction = (fraction >> -shift);
    745   f->fraction |= IMPLICIT_1;
    746 }
    747 
    748 
    749 INLINE_SIM_FPU (unsigned64)
    750 sim_fpu_tofraction (const sim_fpu *d,
    751 		    int precision)
    752 {
    753   /* we have NR_FRAC_GUARD bits, we want only PRECISION bits */
    754   int shift = (NR_FRAC_GUARD - precision);
    755   unsigned64 fraction = (d->fraction & ~IMPLICIT_1);
    756   if (shift >= 0)
    757     return fraction >> shift;
    758   else
    759     return fraction << -shift;
    760 }
    761 
    762 
    763 /* Rounding */
    764 
    765 STATIC_INLINE_SIM_FPU (int)
    766 do_normal_overflow (sim_fpu *f,
    767 		    int is_double,
    768 		    sim_fpu_round round)
    769 {
    770   switch (round)
    771     {
    772     case sim_fpu_round_default:
    773       return 0;
    774     case sim_fpu_round_near:
    775       f->class = sim_fpu_class_infinity;
    776       break;
    777     case sim_fpu_round_up:
    778       if (!f->sign)
    779 	f->class = sim_fpu_class_infinity;
    780       break;
    781     case sim_fpu_round_down:
    782       if (f->sign)
    783 	f->class = sim_fpu_class_infinity;
    784       break;
    785     case sim_fpu_round_zero:
    786       break;
    787     }
    788   f->normal_exp = NORMAL_EXPMAX;
    789   f->fraction = LSMASK64 (NR_FRAC_GUARD, NR_GUARDS);
    790   return (sim_fpu_status_overflow | sim_fpu_status_inexact);
    791 }
    792 
    793 STATIC_INLINE_SIM_FPU (int)
    794 do_normal_underflow (sim_fpu *f,
    795 		     int is_double,
    796 		     sim_fpu_round round)
    797 {
    798   switch (round)
    799     {
    800     case sim_fpu_round_default:
    801       return 0;
    802     case sim_fpu_round_near:
    803       f->class = sim_fpu_class_zero;
    804       break;
    805     case sim_fpu_round_up:
    806       if (f->sign)
    807 	f->class = sim_fpu_class_zero;
    808       break;
    809     case sim_fpu_round_down:
    810       if (!f->sign)
    811 	f->class = sim_fpu_class_zero;
    812       break;
    813     case sim_fpu_round_zero:
    814       f->class = sim_fpu_class_zero;
    815       break;
    816     }
    817   f->normal_exp = NORMAL_EXPMIN - NR_FRACBITS;
    818   f->fraction = IMPLICIT_1;
    819   return (sim_fpu_status_inexact | sim_fpu_status_underflow);
    820 }
    821 
    822 
    823 
    824 /* Round a number using NR_GUARDS.
    825    Will return the rounded number or F->FRACTION == 0 when underflow */
    826 
    827 STATIC_INLINE_SIM_FPU (int)
    828 do_normal_round (sim_fpu *f,
    829 		 int nr_guards,
    830 		 sim_fpu_round round)
    831 {
    832   unsigned64 guardmask = LSMASK64 (nr_guards - 1, 0);
    833   unsigned64 guardmsb = LSBIT64 (nr_guards - 1);
    834   unsigned64 fraclsb = guardmsb << 1;
    835   if ((f->fraction & guardmask))
    836     {
    837       int status = sim_fpu_status_inexact;
    838       switch (round)
    839 	{
    840 	case sim_fpu_round_default:
    841 	  return 0;
    842 	case sim_fpu_round_near:
    843 	  if ((f->fraction & guardmsb))
    844 	    {
    845 	      if ((f->fraction & fraclsb))
    846 		{
    847 		  status |= sim_fpu_status_rounded;
    848 		}
    849 	      else if ((f->fraction & (guardmask >> 1)))
    850 		{
    851 		  status |= sim_fpu_status_rounded;
    852 		}
    853 	    }
    854 	  break;
    855 	case sim_fpu_round_up:
    856 	  if (!f->sign)
    857 	    status |= sim_fpu_status_rounded;
    858 	  break;
    859 	case sim_fpu_round_down:
    860 	  if (f->sign)
    861 	    status |= sim_fpu_status_rounded;
    862 	  break;
    863 	case sim_fpu_round_zero:
    864 	  break;
    865 	}
    866       f->fraction &= ~guardmask;
    867       /* round if needed, handle resulting overflow */
    868       if ((status & sim_fpu_status_rounded))
    869 	{
    870 	  f->fraction += fraclsb;
    871 	  if ((f->fraction & IMPLICIT_2))
    872 	    {
    873 	      f->fraction >>= 1;
    874 	      f->normal_exp += 1;
    875 	    }
    876 	}
    877       return status;
    878     }
    879   else
    880     return 0;
    881 }
    882 
    883 
    884 STATIC_INLINE_SIM_FPU (int)
    885 do_round (sim_fpu *f,
    886 	  int is_double,
    887 	  sim_fpu_round round,
    888 	  sim_fpu_denorm denorm)
    889 {
    890   switch (f->class)
    891     {
    892     case sim_fpu_class_qnan:
    893     case sim_fpu_class_zero:
    894     case sim_fpu_class_infinity:
    895       return 0;
    896       break;
    897     case sim_fpu_class_snan:
    898       /* Quieten a SignalingNaN */
    899       f->class = sim_fpu_class_qnan;
    900       return sim_fpu_status_invalid_snan;
    901       break;
    902     case sim_fpu_class_number:
    903     case sim_fpu_class_denorm:
    904       {
    905 	int status;
    906 	ASSERT (f->fraction < IMPLICIT_2);
    907 	ASSERT (f->fraction >= IMPLICIT_1);
    908 	if (f->normal_exp < NORMAL_EXPMIN)
    909 	  {
    910 	    /* This number's exponent is too low to fit into the bits
    911 	       available in the number.  Round off any bits that will be
    912 	       discarded as a result of denormalization.  Edge case is
    913 	       the implicit bit shifted to GUARD0 and then rounded
    914 	       up. */
    915 	    int shift = NORMAL_EXPMIN - f->normal_exp;
    916 	    if (shift + NR_GUARDS <= NR_FRAC_GUARD + 1
    917 		&& !(denorm & sim_fpu_denorm_zero))
    918 	      {
    919 		status = do_normal_round (f, shift + NR_GUARDS, round);
    920 		if (f->fraction == 0) /* rounding underflowed */
    921 		  {
    922 		    status |= do_normal_underflow (f, is_double, round);
    923 		  }
    924 		else if (f->normal_exp < NORMAL_EXPMIN) /* still underflow? */
    925 		  {
    926 		    status |= sim_fpu_status_denorm;
    927 		    /* Any loss of precision when denormalizing is
    928 		       underflow. Some processors check for underflow
    929 		       before rounding, some after! */
    930 		    if (status & sim_fpu_status_inexact)
    931 		      status |= sim_fpu_status_underflow;
    932 		    /* Flag that resultant value has been denormalized */
    933 		    f->class = sim_fpu_class_denorm;
    934 		  }
    935 		else if ((denorm & sim_fpu_denorm_underflow_inexact))
    936 		  {
    937 		    if ((status & sim_fpu_status_inexact))
    938 		      status |= sim_fpu_status_underflow;
    939 		  }
    940 	      }
    941 	    else
    942 	      {
    943 		status = do_normal_underflow (f, is_double, round);
    944 	      }
    945 	  }
    946 	else if (f->normal_exp > NORMAL_EXPMAX)
    947 	  {
    948 	    /* Infinity */
    949 	    status = do_normal_overflow (f, is_double, round);
    950 	  }
    951 	else
    952 	  {
    953 	    status = do_normal_round (f, NR_GUARDS, round);
    954 	    if (f->fraction == 0)
    955 	      /* f->class = sim_fpu_class_zero; */
    956 	      status |= do_normal_underflow (f, is_double, round);
    957 	    else if (f->normal_exp > NORMAL_EXPMAX)
    958 	      /* oops! rounding caused overflow */
    959 	      status |= do_normal_overflow (f, is_double, round);
    960 	  }
    961 	ASSERT ((f->class == sim_fpu_class_number
    962 		 || f->class == sim_fpu_class_denorm)
    963 		<= (f->fraction < IMPLICIT_2 && f->fraction >= IMPLICIT_1));
    964 	return status;
    965       }
    966     }
    967   return 0;
    968 }
    969 
    970 INLINE_SIM_FPU (int)
    971 sim_fpu_round_32 (sim_fpu *f,
    972 		  sim_fpu_round round,
    973 		  sim_fpu_denorm denorm)
    974 {
    975   return do_round (f, 0, round, denorm);
    976 }
    977 
    978 INLINE_SIM_FPU (int)
    979 sim_fpu_round_64 (sim_fpu *f,
    980 		  sim_fpu_round round,
    981 		  sim_fpu_denorm denorm)
    982 {
    983   return do_round (f, 1, round, denorm);
    984 }
    985 
    986 
    987 
    988 /* Arithmetic ops */
    989 
    990 INLINE_SIM_FPU (int)
    991 sim_fpu_add (sim_fpu *f,
    992 	     const sim_fpu *l,
    993 	     const sim_fpu *r)
    994 {
    995   if (sim_fpu_is_snan (l))
    996     {
    997       *f = *l;
    998       f->class = sim_fpu_class_qnan;
    999       return sim_fpu_status_invalid_snan;
   1000     }
   1001   if (sim_fpu_is_snan (r))
   1002     {
   1003       *f = *r;
   1004       f->class = sim_fpu_class_qnan;
   1005       return sim_fpu_status_invalid_snan;
   1006     }
   1007   if (sim_fpu_is_qnan (l))
   1008     {
   1009       *f = *l;
   1010       return 0;
   1011     }
   1012   if (sim_fpu_is_qnan (r))
   1013     {
   1014       *f = *r;
   1015       return 0;
   1016     }
   1017   if (sim_fpu_is_infinity (l))
   1018     {
   1019       if (sim_fpu_is_infinity (r)
   1020 	  && l->sign != r->sign)
   1021 	{
   1022 	  *f = sim_fpu_qnan;
   1023 	  return sim_fpu_status_invalid_isi;
   1024 	}
   1025       *f = *l;
   1026       return 0;
   1027     }
   1028   if (sim_fpu_is_infinity (r))
   1029     {
   1030       *f = *r;
   1031       return 0;
   1032     }
   1033   if (sim_fpu_is_zero (l))
   1034     {
   1035       if (sim_fpu_is_zero (r))
   1036 	{
   1037 	  *f = sim_fpu_zero;
   1038 	  f->sign = l->sign & r->sign;
   1039 	}
   1040       else
   1041 	*f = *r;
   1042       return 0;
   1043     }
   1044   if (sim_fpu_is_zero (r))
   1045     {
   1046       *f = *l;
   1047       return 0;
   1048     }
   1049   {
   1050     int status = 0;
   1051     int shift = l->normal_exp - r->normal_exp;
   1052     unsigned64 lfraction;
   1053     unsigned64 rfraction;
   1054     /* use exp of larger */
   1055     if (shift >= NR_FRAC_GUARD)
   1056       {
   1057 	/* left has much bigger magnitute */
   1058 	*f = *l;
   1059 	return sim_fpu_status_inexact;
   1060       }
   1061     if (shift <= - NR_FRAC_GUARD)
   1062       {
   1063 	/* right has much bigger magnitute */
   1064 	*f = *r;
   1065 	return sim_fpu_status_inexact;
   1066       }
   1067     lfraction = l->fraction;
   1068     rfraction = r->fraction;
   1069     if (shift > 0)
   1070       {
   1071 	f->normal_exp = l->normal_exp;
   1072 	if (rfraction & LSMASK64 (shift - 1, 0))
   1073 	  {
   1074 	    status |= sim_fpu_status_inexact;
   1075 	    rfraction |= LSBIT64 (shift); /* stick LSBit */
   1076 	  }
   1077 	rfraction >>= shift;
   1078       }
   1079     else if (shift < 0)
   1080       {
   1081 	f->normal_exp = r->normal_exp;
   1082 	if (lfraction & LSMASK64 (- shift - 1, 0))
   1083 	  {
   1084 	    status |= sim_fpu_status_inexact;
   1085 	    lfraction |= LSBIT64 (- shift); /* stick LSBit */
   1086 	  }
   1087 	lfraction >>= -shift;
   1088       }
   1089     else
   1090       {
   1091 	f->normal_exp = r->normal_exp;
   1092       }
   1093 
   1094     /* perform the addition */
   1095     if (l->sign)
   1096       lfraction = - lfraction;
   1097     if (r->sign)
   1098       rfraction = - rfraction;
   1099     f->fraction = lfraction + rfraction;
   1100 
   1101     /* zero? */
   1102     if (f->fraction == 0)
   1103       {
   1104 	*f = sim_fpu_zero;
   1105 	return 0;
   1106       }
   1107 
   1108     /* sign? */
   1109     f->class = sim_fpu_class_number;
   1110     if ((signed64) f->fraction >= 0)
   1111       f->sign = 0;
   1112     else
   1113       {
   1114 	f->sign = 1;
   1115 	f->fraction = - f->fraction;
   1116       }
   1117 
   1118     /* normalize it */
   1119     if ((f->fraction & IMPLICIT_2))
   1120       {
   1121 	f->fraction = (f->fraction >> 1) | (f->fraction & 1);
   1122 	f->normal_exp ++;
   1123       }
   1124     else if (f->fraction < IMPLICIT_1)
   1125       {
   1126 	do
   1127 	  {
   1128 	    f->fraction <<= 1;
   1129 	    f->normal_exp --;
   1130 	  }
   1131 	while (f->fraction < IMPLICIT_1);
   1132       }
   1133     ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
   1134     return status;
   1135   }
   1136 }
   1137 
   1138 
   1139 INLINE_SIM_FPU (int)
   1140 sim_fpu_sub (sim_fpu *f,
   1141 	     const sim_fpu *l,
   1142 	     const sim_fpu *r)
   1143 {
   1144   if (sim_fpu_is_snan (l))
   1145     {
   1146       *f = *l;
   1147       f->class = sim_fpu_class_qnan;
   1148       return sim_fpu_status_invalid_snan;
   1149     }
   1150   if (sim_fpu_is_snan (r))
   1151     {
   1152       *f = *r;
   1153       f->class = sim_fpu_class_qnan;
   1154       return sim_fpu_status_invalid_snan;
   1155     }
   1156   if (sim_fpu_is_qnan (l))
   1157     {
   1158       *f = *l;
   1159       return 0;
   1160     }
   1161   if (sim_fpu_is_qnan (r))
   1162     {
   1163       *f = *r;
   1164       return 0;
   1165     }
   1166   if (sim_fpu_is_infinity (l))
   1167     {
   1168       if (sim_fpu_is_infinity (r)
   1169 	  && l->sign == r->sign)
   1170 	{
   1171 	  *f = sim_fpu_qnan;
   1172 	  return sim_fpu_status_invalid_isi;
   1173 	}
   1174       *f = *l;
   1175       return 0;
   1176     }
   1177   if (sim_fpu_is_infinity (r))
   1178     {
   1179       *f = *r;
   1180       f->sign = !r->sign;
   1181       return 0;
   1182     }
   1183   if (sim_fpu_is_zero (l))
   1184     {
   1185       if (sim_fpu_is_zero (r))
   1186 	{
   1187 	  *f = sim_fpu_zero;
   1188 	  f->sign = l->sign & !r->sign;
   1189 	}
   1190       else
   1191 	{
   1192 	  *f = *r;
   1193 	  f->sign = !r->sign;
   1194 	}
   1195       return 0;
   1196     }
   1197   if (sim_fpu_is_zero (r))
   1198     {
   1199       *f = *l;
   1200       return 0;
   1201     }
   1202   {
   1203     int status = 0;
   1204     int shift = l->normal_exp - r->normal_exp;
   1205     unsigned64 lfraction;
   1206     unsigned64 rfraction;
   1207     /* use exp of larger */
   1208     if (shift >= NR_FRAC_GUARD)
   1209       {
   1210 	/* left has much bigger magnitute */
   1211 	*f = *l;
   1212 	return sim_fpu_status_inexact;
   1213       }
   1214     if (shift <= - NR_FRAC_GUARD)
   1215       {
   1216 	/* right has much bigger magnitute */
   1217 	*f = *r;
   1218 	f->sign = !r->sign;
   1219 	return sim_fpu_status_inexact;
   1220       }
   1221     lfraction = l->fraction;
   1222     rfraction = r->fraction;
   1223     if (shift > 0)
   1224       {
   1225 	f->normal_exp = l->normal_exp;
   1226 	if (rfraction & LSMASK64 (shift - 1, 0))
   1227 	  {
   1228 	    status |= sim_fpu_status_inexact;
   1229 	    rfraction |= LSBIT64 (shift); /* stick LSBit */
   1230 	  }
   1231 	rfraction >>= shift;
   1232       }
   1233     else if (shift < 0)
   1234       {
   1235 	f->normal_exp = r->normal_exp;
   1236 	if (lfraction & LSMASK64 (- shift - 1, 0))
   1237 	  {
   1238 	    status |= sim_fpu_status_inexact;
   1239 	    lfraction |= LSBIT64 (- shift); /* stick LSBit */
   1240 	  }
   1241 	lfraction >>= -shift;
   1242       }
   1243     else
   1244       {
   1245 	f->normal_exp = r->normal_exp;
   1246       }
   1247 
   1248     /* perform the subtraction */
   1249     if (l->sign)
   1250       lfraction = - lfraction;
   1251     if (!r->sign)
   1252       rfraction = - rfraction;
   1253     f->fraction = lfraction + rfraction;
   1254 
   1255     /* zero? */
   1256     if (f->fraction == 0)
   1257       {
   1258 	*f = sim_fpu_zero;
   1259 	return 0;
   1260       }
   1261 
   1262     /* sign? */
   1263     f->class = sim_fpu_class_number;
   1264     if ((signed64) f->fraction >= 0)
   1265       f->sign = 0;
   1266     else
   1267       {
   1268 	f->sign = 1;
   1269 	f->fraction = - f->fraction;
   1270       }
   1271 
   1272     /* normalize it */
   1273     if ((f->fraction & IMPLICIT_2))
   1274       {
   1275 	f->fraction = (f->fraction >> 1) | (f->fraction & 1);
   1276 	f->normal_exp ++;
   1277       }
   1278     else if (f->fraction < IMPLICIT_1)
   1279       {
   1280 	do
   1281 	  {
   1282 	    f->fraction <<= 1;
   1283 	    f->normal_exp --;
   1284 	  }
   1285 	while (f->fraction < IMPLICIT_1);
   1286       }
   1287     ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
   1288     return status;
   1289   }
   1290 }
   1291 
   1292 
   1293 INLINE_SIM_FPU (int)
   1294 sim_fpu_mul (sim_fpu *f,
   1295 	     const sim_fpu *l,
   1296 	     const sim_fpu *r)
   1297 {
   1298   if (sim_fpu_is_snan (l))
   1299     {
   1300       *f = *l;
   1301       f->class = sim_fpu_class_qnan;
   1302       return sim_fpu_status_invalid_snan;
   1303     }
   1304   if (sim_fpu_is_snan (r))
   1305     {
   1306       *f = *r;
   1307       f->class = sim_fpu_class_qnan;
   1308       return sim_fpu_status_invalid_snan;
   1309     }
   1310   if (sim_fpu_is_qnan (l))
   1311     {
   1312       *f = *l;
   1313       return 0;
   1314     }
   1315   if (sim_fpu_is_qnan (r))
   1316     {
   1317       *f = *r;
   1318       return 0;
   1319     }
   1320   if (sim_fpu_is_infinity (l))
   1321     {
   1322       if (sim_fpu_is_zero (r))
   1323 	{
   1324 	  *f = sim_fpu_qnan;
   1325 	  return sim_fpu_status_invalid_imz;
   1326 	}
   1327       *f = *l;
   1328       f->sign = l->sign ^ r->sign;
   1329       return 0;
   1330     }
   1331   if (sim_fpu_is_infinity (r))
   1332     {
   1333       if (sim_fpu_is_zero (l))
   1334 	{
   1335 	  *f = sim_fpu_qnan;
   1336 	  return sim_fpu_status_invalid_imz;
   1337 	}
   1338       *f = *r;
   1339       f->sign = l->sign ^ r->sign;
   1340       return 0;
   1341     }
   1342   if (sim_fpu_is_zero (l) || sim_fpu_is_zero (r))
   1343     {
   1344       *f = sim_fpu_zero;
   1345       f->sign = l->sign ^ r->sign;
   1346       return 0;
   1347     }
   1348   /* Calculate the mantissa by multiplying both 64bit numbers to get a
   1349      128 bit number */
   1350   {
   1351     unsigned64 low;
   1352     unsigned64 high;
   1353     unsigned64 nl = l->fraction & 0xffffffff;
   1354     unsigned64 nh = l->fraction >> 32;
   1355     unsigned64 ml = r->fraction & 0xffffffff;
   1356     unsigned64 mh = r->fraction >>32;
   1357     unsigned64 pp_ll = ml * nl;
   1358     unsigned64 pp_hl = mh * nl;
   1359     unsigned64 pp_lh = ml * nh;
   1360     unsigned64 pp_hh = mh * nh;
   1361     unsigned64 res2 = 0;
   1362     unsigned64 res0 = 0;
   1363     unsigned64 ps_hh__ = pp_hl + pp_lh;
   1364     if (ps_hh__ < pp_hl)
   1365       res2 += UNSIGNED64 (0x100000000);
   1366     pp_hl = (ps_hh__ << 32) & UNSIGNED64 (0xffffffff00000000);
   1367     res0 = pp_ll + pp_hl;
   1368     if (res0 < pp_ll)
   1369       res2++;
   1370     res2 += ((ps_hh__ >> 32) & 0xffffffff) + pp_hh;
   1371     high = res2;
   1372     low = res0;
   1373 
   1374     f->normal_exp = l->normal_exp + r->normal_exp;
   1375     f->sign = l->sign ^ r->sign;
   1376     f->class = sim_fpu_class_number;
   1377 
   1378     /* Input is bounded by [1,2)   ;   [2^60,2^61)
   1379        Output is bounded by [1,4)  ;   [2^120,2^122) */
   1380 
   1381     /* Adjust the exponent according to where the decimal point ended
   1382        up in the high 64 bit word.  In the source the decimal point
   1383        was at NR_FRAC_GUARD. */
   1384     f->normal_exp += NR_FRAC_GUARD + 64 - (NR_FRAC_GUARD * 2);
   1385 
   1386     /* The high word is bounded according to the above.  Consequently
   1387        it has never overflowed into IMPLICIT_2. */
   1388     ASSERT (high < LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64));
   1389     ASSERT (high >= LSBIT64 ((NR_FRAC_GUARD * 2) - 64));
   1390     ASSERT (LSBIT64 (((NR_FRAC_GUARD + 1) * 2) - 64) < IMPLICIT_1);
   1391 
   1392     /* normalize */
   1393     do
   1394       {
   1395 	f->normal_exp--;
   1396 	high <<= 1;
   1397 	if (low & LSBIT64 (63))
   1398 	  high |= 1;
   1399 	low <<= 1;
   1400       }
   1401     while (high < IMPLICIT_1);
   1402 
   1403     ASSERT (high >= IMPLICIT_1 && high < IMPLICIT_2);
   1404     if (low != 0)
   1405       {
   1406 	f->fraction = (high | 1); /* sticky */
   1407 	return sim_fpu_status_inexact;
   1408       }
   1409     else
   1410       {
   1411 	f->fraction = high;
   1412 	return 0;
   1413       }
   1414     return 0;
   1415   }
   1416 }
   1417 
   1418 INLINE_SIM_FPU (int)
   1419 sim_fpu_div (sim_fpu *f,
   1420 	     const sim_fpu *l,
   1421 	     const sim_fpu *r)
   1422 {
   1423   if (sim_fpu_is_snan (l))
   1424     {
   1425       *f = *l;
   1426       f->class = sim_fpu_class_qnan;
   1427       return sim_fpu_status_invalid_snan;
   1428     }
   1429   if (sim_fpu_is_snan (r))
   1430     {
   1431       *f = *r;
   1432       f->class = sim_fpu_class_qnan;
   1433       return sim_fpu_status_invalid_snan;
   1434     }
   1435   if (sim_fpu_is_qnan (l))
   1436     {
   1437       *f = *l;
   1438       f->class = sim_fpu_class_qnan;
   1439       return 0;
   1440     }
   1441   if (sim_fpu_is_qnan (r))
   1442     {
   1443       *f = *r;
   1444       f->class = sim_fpu_class_qnan;
   1445       return 0;
   1446     }
   1447   if (sim_fpu_is_infinity (l))
   1448     {
   1449       if (sim_fpu_is_infinity (r))
   1450 	{
   1451 	  *f = sim_fpu_qnan;
   1452 	  return sim_fpu_status_invalid_idi;
   1453 	}
   1454       else
   1455 	{
   1456 	  *f = *l;
   1457 	  f->sign = l->sign ^ r->sign;
   1458 	  return 0;
   1459 	}
   1460     }
   1461   if (sim_fpu_is_zero (l))
   1462     {
   1463       if (sim_fpu_is_zero (r))
   1464 	{
   1465 	  *f = sim_fpu_qnan;
   1466 	  return sim_fpu_status_invalid_zdz;
   1467 	}
   1468       else
   1469 	{
   1470 	  *f = *l;
   1471 	  f->sign = l->sign ^ r->sign;
   1472 	  return 0;
   1473 	}
   1474     }
   1475   if (sim_fpu_is_infinity (r))
   1476     {
   1477       *f = sim_fpu_zero;
   1478       f->sign = l->sign ^ r->sign;
   1479       return 0;
   1480     }
   1481   if (sim_fpu_is_zero (r))
   1482     {
   1483       f->class = sim_fpu_class_infinity;
   1484       f->sign = l->sign ^ r->sign;
   1485       return sim_fpu_status_invalid_div0;
   1486     }
   1487 
   1488   /* Calculate the mantissa by multiplying both 64bit numbers to get a
   1489      128 bit number */
   1490   {
   1491     /* quotient =  ( ( numerator / denominator)
   1492                       x 2^(numerator exponent -  denominator exponent)
   1493      */
   1494     unsigned64 numerator;
   1495     unsigned64 denominator;
   1496     unsigned64 quotient;
   1497     unsigned64 bit;
   1498 
   1499     f->class = sim_fpu_class_number;
   1500     f->sign = l->sign ^ r->sign;
   1501     f->normal_exp = l->normal_exp - r->normal_exp;
   1502 
   1503     numerator = l->fraction;
   1504     denominator = r->fraction;
   1505 
   1506     /* Fraction will be less than 1.0 */
   1507     if (numerator < denominator)
   1508       {
   1509 	numerator <<= 1;
   1510 	f->normal_exp--;
   1511       }
   1512     ASSERT (numerator >= denominator);
   1513 
   1514     /* Gain extra precision, already used one spare bit */
   1515     numerator <<=    NR_SPARE;
   1516     denominator <<=  NR_SPARE;
   1517 
   1518     /* Does divide one bit at a time.  Optimize???  */
   1519     quotient = 0;
   1520     bit = (IMPLICIT_1 << NR_SPARE);
   1521     while (bit)
   1522       {
   1523 	if (numerator >= denominator)
   1524 	  {
   1525 	    quotient |= bit;
   1526 	    numerator -= denominator;
   1527 	  }
   1528 	bit >>= 1;
   1529 	numerator <<= 1;
   1530       }
   1531 
   1532     /* discard (but save) the extra bits */
   1533     if ((quotient & LSMASK64 (NR_SPARE -1, 0)))
   1534       quotient = (quotient >> NR_SPARE) | 1;
   1535     else
   1536       quotient = (quotient >> NR_SPARE);
   1537 
   1538     f->fraction = quotient;
   1539     ASSERT (f->fraction >= IMPLICIT_1 && f->fraction < IMPLICIT_2);
   1540     if (numerator != 0)
   1541       {
   1542 	f->fraction |= 1; /* stick remaining bits */
   1543 	return sim_fpu_status_inexact;
   1544       }
   1545     else
   1546       return 0;
   1547   }
   1548 }
   1549 
   1550 
   1551 INLINE_SIM_FPU (int)
   1552 sim_fpu_max (sim_fpu *f,
   1553 	     const sim_fpu *l,
   1554 	     const sim_fpu *r)
   1555 {
   1556   if (sim_fpu_is_snan (l))
   1557     {
   1558       *f = *l;
   1559       f->class = sim_fpu_class_qnan;
   1560       return sim_fpu_status_invalid_snan;
   1561     }
   1562   if (sim_fpu_is_snan (r))
   1563     {
   1564       *f = *r;
   1565       f->class = sim_fpu_class_qnan;
   1566       return sim_fpu_status_invalid_snan;
   1567     }
   1568   if (sim_fpu_is_qnan (l))
   1569     {
   1570       *f = *l;
   1571       return 0;
   1572     }
   1573   if (sim_fpu_is_qnan (r))
   1574     {
   1575       *f = *r;
   1576       return 0;
   1577     }
   1578   if (sim_fpu_is_infinity (l))
   1579     {
   1580       if (sim_fpu_is_infinity (r)
   1581 	  && l->sign == r->sign)
   1582 	{
   1583 	  *f = sim_fpu_qnan;
   1584 	  return sim_fpu_status_invalid_isi;
   1585 	}
   1586       if (l->sign)
   1587 	*f = *r; /* -inf < anything */
   1588       else
   1589 	*f = *l; /* +inf > anthing */
   1590       return 0;
   1591     }
   1592   if (sim_fpu_is_infinity (r))
   1593     {
   1594       if (r->sign)
   1595 	*f = *l; /* anything > -inf */
   1596       else
   1597 	*f = *r; /* anthing < +inf */
   1598       return 0;
   1599     }
   1600   if (l->sign > r->sign)
   1601     {
   1602       *f = *r; /* -ve < +ve */
   1603       return 0;
   1604     }
   1605   if (l->sign < r->sign)
   1606     {
   1607       *f = *l; /* +ve > -ve */
   1608       return 0;
   1609     }
   1610   ASSERT (l->sign == r->sign);
   1611   if (l->normal_exp > r->normal_exp
   1612       || (l->normal_exp == r->normal_exp &&
   1613 	  l->fraction > r->fraction))
   1614     {
   1615       /* |l| > |r| */
   1616       if (l->sign)
   1617 	*f = *r; /* -ve < -ve */
   1618       else
   1619 	*f = *l; /* +ve > +ve */
   1620       return 0;
   1621     }
   1622   else
   1623     {
   1624       /* |l| <= |r| */
   1625       if (l->sign)
   1626 	*f = *l; /* -ve > -ve */
   1627       else
   1628 	*f = *r; /* +ve < +ve */
   1629       return 0;
   1630     }
   1631 }
   1632 
   1633 
   1634 INLINE_SIM_FPU (int)
   1635 sim_fpu_min (sim_fpu *f,
   1636 	     const sim_fpu *l,
   1637 	     const sim_fpu *r)
   1638 {
   1639   if (sim_fpu_is_snan (l))
   1640     {
   1641       *f = *l;
   1642       f->class = sim_fpu_class_qnan;
   1643       return sim_fpu_status_invalid_snan;
   1644     }
   1645   if (sim_fpu_is_snan (r))
   1646     {
   1647       *f = *r;
   1648       f->class = sim_fpu_class_qnan;
   1649       return sim_fpu_status_invalid_snan;
   1650     }
   1651   if (sim_fpu_is_qnan (l))
   1652     {
   1653       *f = *l;
   1654       return 0;
   1655     }
   1656   if (sim_fpu_is_qnan (r))
   1657     {
   1658       *f = *r;
   1659       return 0;
   1660     }
   1661   if (sim_fpu_is_infinity (l))
   1662     {
   1663       if (sim_fpu_is_infinity (r)
   1664 	  && l->sign == r->sign)
   1665 	{
   1666 	  *f = sim_fpu_qnan;
   1667 	  return sim_fpu_status_invalid_isi;
   1668 	}
   1669       if (l->sign)
   1670 	*f = *l; /* -inf < anything */
   1671       else
   1672 	*f = *r; /* +inf > anthing */
   1673       return 0;
   1674     }
   1675   if (sim_fpu_is_infinity (r))
   1676     {
   1677       if (r->sign)
   1678 	*f = *r; /* anything > -inf */
   1679       else
   1680 	*f = *l; /* anything < +inf */
   1681       return 0;
   1682     }
   1683   if (l->sign > r->sign)
   1684     {
   1685       *f = *l; /* -ve < +ve */
   1686       return 0;
   1687     }
   1688   if (l->sign < r->sign)
   1689     {
   1690       *f = *r; /* +ve > -ve */
   1691       return 0;
   1692     }
   1693   ASSERT (l->sign == r->sign);
   1694   if (l->normal_exp > r->normal_exp
   1695       || (l->normal_exp == r->normal_exp &&
   1696 	  l->fraction > r->fraction))
   1697     {
   1698       /* |l| > |r| */
   1699       if (l->sign)
   1700 	*f = *l; /* -ve < -ve */
   1701       else
   1702 	*f = *r; /* +ve > +ve */
   1703       return 0;
   1704     }
   1705   else
   1706     {
   1707       /* |l| <= |r| */
   1708       if (l->sign)
   1709 	*f = *r; /* -ve > -ve */
   1710       else
   1711 	*f = *l; /* +ve < +ve */
   1712       return 0;
   1713     }
   1714 }
   1715 
   1716 
   1717 INLINE_SIM_FPU (int)
   1718 sim_fpu_neg (sim_fpu *f,
   1719 	     const sim_fpu *r)
   1720 {
   1721   if (sim_fpu_is_snan (r))
   1722     {
   1723       *f = *r;
   1724       f->class = sim_fpu_class_qnan;
   1725       return sim_fpu_status_invalid_snan;
   1726     }
   1727   if (sim_fpu_is_qnan (r))
   1728     {
   1729       *f = *r;
   1730       return 0;
   1731     }
   1732   *f = *r;
   1733   f->sign = !r->sign;
   1734   return 0;
   1735 }
   1736 
   1737 
   1738 INLINE_SIM_FPU (int)
   1739 sim_fpu_abs (sim_fpu *f,
   1740 	     const sim_fpu *r)
   1741 {
   1742   *f = *r;
   1743   f->sign = 0;
   1744   if (sim_fpu_is_snan (r))
   1745     {
   1746       f->class = sim_fpu_class_qnan;
   1747       return sim_fpu_status_invalid_snan;
   1748     }
   1749   return 0;
   1750 }
   1751 
   1752 
   1753 INLINE_SIM_FPU (int)
   1754 sim_fpu_inv (sim_fpu *f,
   1755 	     const sim_fpu *r)
   1756 {
   1757   return sim_fpu_div (f, &sim_fpu_one, r);
   1758 }
   1759 
   1760 
   1761 INLINE_SIM_FPU (int)
   1762 sim_fpu_sqrt (sim_fpu *f,
   1763 	      const sim_fpu *r)
   1764 {
   1765   if (sim_fpu_is_snan (r))
   1766     {
   1767       *f = sim_fpu_qnan;
   1768       return sim_fpu_status_invalid_snan;
   1769     }
   1770   if (sim_fpu_is_qnan (r))
   1771     {
   1772       *f = sim_fpu_qnan;
   1773       return 0;
   1774     }
   1775   if (sim_fpu_is_zero (r))
   1776     {
   1777       f->class = sim_fpu_class_zero;
   1778       f->sign = r->sign;
   1779       f->normal_exp = 0;
   1780       return 0;
   1781     }
   1782   if (sim_fpu_is_infinity (r))
   1783     {
   1784       if (r->sign)
   1785 	{
   1786 	  *f = sim_fpu_qnan;
   1787 	  return sim_fpu_status_invalid_sqrt;
   1788 	}
   1789       else
   1790 	{
   1791 	  f->class = sim_fpu_class_infinity;
   1792 	  f->sign = 0;
   1793 	  f->sign = 0;
   1794 	  return 0;
   1795 	}
   1796     }
   1797   if (r->sign)
   1798     {
   1799       *f = sim_fpu_qnan;
   1800       return sim_fpu_status_invalid_sqrt;
   1801     }
   1802 
   1803   /* @(#)e_sqrt.c 5.1 93/09/24 */
   1804   /*
   1805    * ====================================================
   1806    * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
   1807    *
   1808    * Developed at SunPro, a Sun Microsystems, Inc. business.
   1809    * Permission to use, copy, modify, and distribute this
   1810    * software is freely granted, provided that this notice
   1811    * is preserved.
   1812    * ====================================================
   1813    */
   1814 
   1815   /* __ieee754_sqrt(x)
   1816    * Return correctly rounded sqrt.
   1817    *           ------------------------------------------
   1818    *           |  Use the hardware sqrt if you have one |
   1819    *           ------------------------------------------
   1820    * Method:
   1821    *   Bit by bit method using integer arithmetic. (Slow, but portable)
   1822    *   1. Normalization
   1823    *	Scale x to y in [1,4) with even powers of 2:
   1824    *	find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
   1825    *		sqrt(x) = 2^k * sqrt(y)
   1826    -
   1827    - Since:
   1828    -   sqrt ( x*2^(2m) )     = sqrt(x).2^m    ; m even
   1829    -   sqrt ( x*2^(2m + 1) ) = sqrt(2.x).2^m  ; m odd
   1830    - Define:
   1831    -   y = ((m even) ? x : 2.x)
   1832    - Then:
   1833    -   y in [1, 4)                            ; [IMPLICIT_1,IMPLICIT_4)
   1834    - And:
   1835    -   sqrt (y) in [1, 2)                     ; [IMPLICIT_1,IMPLICIT_2)
   1836    -
   1837    *   2. Bit by bit computation
   1838    *	Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
   1839    *	     i							 0
   1840    *                                     i+1         2
   1841    *	    s  = 2*q , and	y  =  2   * ( y - q  ).		(1)
   1842    *	     i      i            i                 i
   1843    *
   1844    *	To compute q    from q , one checks whether
   1845    *		    i+1       i
   1846    *
   1847    *			      -(i+1) 2
   1848    *			(q + 2      ) <= y.			(2)
   1849    *     			  i
   1850    *							      -(i+1)
   1851    *	If (2) is false, then q   = q ; otherwise q   = q  + 2      .
   1852    *		 	       i+1   i             i+1   i
   1853    *
   1854    *	With some algebric manipulation, it is not difficult to see
   1855    *	that (2) is equivalent to
   1856    *                             -(i+1)
   1857    *			s  +  2       <= y			(3)
   1858    *			 i                i
   1859    *
   1860    *	The advantage of (3) is that s  and y  can be computed by
   1861    *				      i      i
   1862    *	the following recurrence formula:
   1863    *	    if (3) is false
   1864    *
   1865    *	    s     =  s  ,	y    = y   ;			(4)
   1866    *	     i+1      i		 i+1    i
   1867    *
   1868    -
   1869    -                      NOTE: y    = 2*y
   1870    -                             i+1      i
   1871    -
   1872    *	    otherwise,
   1873    *                       -i                      -(i+1)
   1874    *	    s	  =  s  + 2  ,  y    = y  -  s  - 2  		(5)
   1875    *         i+1      i          i+1    i     i
   1876    *
   1877    -
   1878    -                                                   -(i+1)
   1879    -                      NOTE: y    = 2 (y  -  s  -  2      )
   1880    -                             i+1       i     i
   1881    -
   1882    *	One may easily use induction to prove (4) and (5).
   1883    *	Note. Since the left hand side of (3) contain only i+2 bits,
   1884    *	      it does not necessary to do a full (53-bit) comparison
   1885    *	      in (3).
   1886    *   3. Final rounding
   1887    *	After generating the 53 bits result, we compute one more bit.
   1888    *	Together with the remainder, we can decide whether the
   1889    *	result is exact, bigger than 1/2ulp, or less than 1/2ulp
   1890    *	(it will never equal to 1/2ulp).
   1891    *	The rounding mode can be detected by checking whether
   1892    *	huge + tiny is equal to huge, and whether huge - tiny is
   1893    *	equal to huge for some floating point number "huge" and "tiny".
   1894    *
   1895    * Special cases:
   1896    *	sqrt(+-0) = +-0 	... exact
   1897    *	sqrt(inf) = inf
   1898    *	sqrt(-ve) = NaN		... with invalid signal
   1899    *	sqrt(NaN) = NaN		... with invalid signal for signaling NaN
   1900    *
   1901    * Other methods : see the appended file at the end of the program below.
   1902    *---------------
   1903    */
   1904 
   1905   {
   1906     /* generate sqrt(x) bit by bit */
   1907     unsigned64 y;
   1908     unsigned64 q;
   1909     unsigned64 s;
   1910     unsigned64 b;
   1911 
   1912     f->class = sim_fpu_class_number;
   1913     f->sign = 0;
   1914     y = r->fraction;
   1915     f->normal_exp = (r->normal_exp >> 1);	/* exp = [exp/2] */
   1916 
   1917     /* odd exp, double x to make it even */
   1918     ASSERT (y >= IMPLICIT_1 && y < IMPLICIT_4);
   1919     if ((r->normal_exp & 1))
   1920       {
   1921 	y += y;
   1922       }
   1923     ASSERT (y >= IMPLICIT_1 && y < (IMPLICIT_2 << 1));
   1924 
   1925     /* Let loop determine first value of s (either 1 or 2) */
   1926     b = IMPLICIT_1;
   1927     q = 0;
   1928     s = 0;
   1929 
   1930     while (b)
   1931       {
   1932 	unsigned64 t = s + b;
   1933 	if (t <= y)
   1934 	  {
   1935 	    s |= (b << 1);
   1936 	    y -= t;
   1937 	    q |= b;
   1938 	  }
   1939 	y <<= 1;
   1940 	b >>= 1;
   1941       }
   1942 
   1943     ASSERT (q >= IMPLICIT_1 && q < IMPLICIT_2);
   1944     f->fraction = q;
   1945     if (y != 0)
   1946       {
   1947 	f->fraction |= 1; /* stick remaining bits */
   1948 	return sim_fpu_status_inexact;
   1949       }
   1950     else
   1951       return 0;
   1952   }
   1953 }
   1954 
   1955 
   1956 /* int/long <-> sim_fpu */
   1957 
   1958 INLINE_SIM_FPU (int)
   1959 sim_fpu_i32to (sim_fpu *f,
   1960 	       signed32 i,
   1961 	       sim_fpu_round round)
   1962 {
   1963   i2fpu (f, i, 0);
   1964   return 0;
   1965 }
   1966 
   1967 INLINE_SIM_FPU (int)
   1968 sim_fpu_u32to (sim_fpu *f,
   1969 	       unsigned32 u,
   1970 	       sim_fpu_round round)
   1971 {
   1972   u2fpu (f, u, 0);
   1973   return 0;
   1974 }
   1975 
   1976 INLINE_SIM_FPU (int)
   1977 sim_fpu_i64to (sim_fpu *f,
   1978 	       signed64 i,
   1979 	       sim_fpu_round round)
   1980 {
   1981   i2fpu (f, i, 1);
   1982   return 0;
   1983 }
   1984 
   1985 INLINE_SIM_FPU (int)
   1986 sim_fpu_u64to (sim_fpu *f,
   1987 	       unsigned64 u,
   1988 	       sim_fpu_round round)
   1989 {
   1990   u2fpu (f, u, 1);
   1991   return 0;
   1992 }
   1993 
   1994 
   1995 INLINE_SIM_FPU (int)
   1996 sim_fpu_to32i (signed32 *i,
   1997 	       const sim_fpu *f,
   1998 	       sim_fpu_round round)
   1999 {
   2000   signed64 i64;
   2001   int status = fpu2i (&i64, f, 0, round);
   2002   *i = i64;
   2003   return status;
   2004 }
   2005 
   2006 INLINE_SIM_FPU (int)
   2007 sim_fpu_to32u (unsigned32 *u,
   2008 	       const sim_fpu *f,
   2009 	       sim_fpu_round round)
   2010 {
   2011   unsigned64 u64;
   2012   int status = fpu2u (&u64, f, 0);
   2013   *u = u64;
   2014   return status;
   2015 }
   2016 
   2017 INLINE_SIM_FPU (int)
   2018 sim_fpu_to64i (signed64 *i,
   2019 	       const sim_fpu *f,
   2020 	       sim_fpu_round round)
   2021 {
   2022   return fpu2i (i, f, 1, round);
   2023 }
   2024 
   2025 
   2026 INLINE_SIM_FPU (int)
   2027 sim_fpu_to64u (unsigned64 *u,
   2028 	       const sim_fpu *f,
   2029 	       sim_fpu_round round)
   2030 {
   2031   return fpu2u (u, f, 1);
   2032 }
   2033 
   2034 
   2035 
   2036 /* sim_fpu -> host format */
   2037 
   2038 #if 0
   2039 INLINE_SIM_FPU (float)
   2040 sim_fpu_2f (const sim_fpu *f)
   2041 {
   2042   return fval.d;
   2043 }
   2044 #endif
   2045 
   2046 
   2047 INLINE_SIM_FPU (double)
   2048 sim_fpu_2d (const sim_fpu *s)
   2049 {
   2050   sim_fpu_map val;
   2051   if (sim_fpu_is_snan (s))
   2052     {
   2053       /* gag SNaN's */
   2054       sim_fpu n = *s;
   2055       n.class = sim_fpu_class_qnan;
   2056       val.i = pack_fpu (&n, 1);
   2057     }
   2058   else
   2059     {
   2060       val.i = pack_fpu (s, 1);
   2061     }
   2062   return val.d;
   2063 }
   2064 
   2065 
   2066 #if 0
   2067 INLINE_SIM_FPU (void)
   2068 sim_fpu_f2 (sim_fpu *f,
   2069 	    float s)
   2070 {
   2071   sim_fpu_map val;
   2072   val.d = s;
   2073   unpack_fpu (f, val.i, 1);
   2074 }
   2075 #endif
   2076 
   2077 
   2078 INLINE_SIM_FPU (void)
   2079 sim_fpu_d2 (sim_fpu *f,
   2080 	    double d)
   2081 {
   2082   sim_fpu_map val;
   2083   val.d = d;
   2084   unpack_fpu (f, val.i, 1);
   2085 }
   2086 
   2087 
   2088 /* General */
   2089 
   2090 INLINE_SIM_FPU (int)
   2091 sim_fpu_is_nan (const sim_fpu *d)
   2092 {
   2093   switch (d->class)
   2094     {
   2095     case sim_fpu_class_qnan:
   2096     case sim_fpu_class_snan:
   2097       return 1;
   2098     default:
   2099       return 0;
   2100     }
   2101 }
   2102 
   2103 INLINE_SIM_FPU (int)
   2104 sim_fpu_is_qnan (const sim_fpu *d)
   2105 {
   2106   switch (d->class)
   2107     {
   2108     case sim_fpu_class_qnan:
   2109       return 1;
   2110     default:
   2111       return 0;
   2112     }
   2113 }
   2114 
   2115 INLINE_SIM_FPU (int)
   2116 sim_fpu_is_snan (const sim_fpu *d)
   2117 {
   2118   switch (d->class)
   2119     {
   2120     case sim_fpu_class_snan:
   2121       return 1;
   2122     default:
   2123       return 0;
   2124     }
   2125 }
   2126 
   2127 INLINE_SIM_FPU (int)
   2128 sim_fpu_is_zero (const sim_fpu *d)
   2129 {
   2130   switch (d->class)
   2131     {
   2132     case sim_fpu_class_zero:
   2133       return 1;
   2134     default:
   2135       return 0;
   2136     }
   2137 }
   2138 
   2139 INLINE_SIM_FPU (int)
   2140 sim_fpu_is_infinity (const sim_fpu *d)
   2141 {
   2142   switch (d->class)
   2143     {
   2144     case sim_fpu_class_infinity:
   2145       return 1;
   2146     default:
   2147       return 0;
   2148     }
   2149 }
   2150 
   2151 INLINE_SIM_FPU (int)
   2152 sim_fpu_is_number (const sim_fpu *d)
   2153 {
   2154   switch (d->class)
   2155     {
   2156     case sim_fpu_class_denorm:
   2157     case sim_fpu_class_number:
   2158       return 1;
   2159     default:
   2160       return 0;
   2161     }
   2162 }
   2163 
   2164 INLINE_SIM_FPU (int)
   2165 sim_fpu_is_denorm (const sim_fpu *d)
   2166 {
   2167   switch (d->class)
   2168     {
   2169     case sim_fpu_class_denorm:
   2170       return 1;
   2171     default:
   2172       return 0;
   2173     }
   2174 }
   2175 
   2176 
   2177 INLINE_SIM_FPU (int)
   2178 sim_fpu_sign (const sim_fpu *d)
   2179 {
   2180   return d->sign;
   2181 }
   2182 
   2183 
   2184 INLINE_SIM_FPU (int)
   2185 sim_fpu_exp (const sim_fpu *d)
   2186 {
   2187   return d->normal_exp;
   2188 }
   2189 
   2190 
   2191 INLINE_SIM_FPU (unsigned64)
   2192 sim_fpu_fraction (const sim_fpu *d)
   2193 {
   2194   return d->fraction;
   2195 }
   2196 
   2197 
   2198 INLINE_SIM_FPU (unsigned64)
   2199 sim_fpu_guard (const sim_fpu *d, int is_double)
   2200 {
   2201   unsigned64 rv;
   2202   unsigned64 guardmask = LSMASK64 (NR_GUARDS - 1, 0);
   2203   rv = (d->fraction & guardmask) >> NR_PAD;
   2204   return rv;
   2205 }
   2206 
   2207 
   2208 INLINE_SIM_FPU (int)
   2209 sim_fpu_is (const sim_fpu *d)
   2210 {
   2211   switch (d->class)
   2212     {
   2213     case sim_fpu_class_qnan:
   2214       return SIM_FPU_IS_QNAN;
   2215     case sim_fpu_class_snan:
   2216       return SIM_FPU_IS_SNAN;
   2217     case sim_fpu_class_infinity:
   2218       if (d->sign)
   2219 	return SIM_FPU_IS_NINF;
   2220       else
   2221 	return SIM_FPU_IS_PINF;
   2222     case sim_fpu_class_number:
   2223       if (d->sign)
   2224 	return SIM_FPU_IS_NNUMBER;
   2225       else
   2226 	return SIM_FPU_IS_PNUMBER;
   2227     case sim_fpu_class_denorm:
   2228       if (d->sign)
   2229 	return SIM_FPU_IS_NDENORM;
   2230       else
   2231 	return SIM_FPU_IS_PDENORM;
   2232     case sim_fpu_class_zero:
   2233       if (d->sign)
   2234 	return SIM_FPU_IS_NZERO;
   2235       else
   2236 	return SIM_FPU_IS_PZERO;
   2237     default:
   2238       return -1;
   2239       abort ();
   2240     }
   2241 }
   2242 
   2243 INLINE_SIM_FPU (int)
   2244 sim_fpu_cmp (const sim_fpu *l, const sim_fpu *r)
   2245 {
   2246   sim_fpu res;
   2247   sim_fpu_sub (&res, l, r);
   2248   return sim_fpu_is (&res);
   2249 }
   2250 
   2251 INLINE_SIM_FPU (int)
   2252 sim_fpu_is_lt (const sim_fpu *l, const sim_fpu *r)
   2253 {
   2254   int status;
   2255   sim_fpu_lt (&status, l, r);
   2256   return status;
   2257 }
   2258 
   2259 INLINE_SIM_FPU (int)
   2260 sim_fpu_is_le (const sim_fpu *l, const sim_fpu *r)
   2261 {
   2262   int is;
   2263   sim_fpu_le (&is, l, r);
   2264   return is;
   2265 }
   2266 
   2267 INLINE_SIM_FPU (int)
   2268 sim_fpu_is_eq (const sim_fpu *l, const sim_fpu *r)
   2269 {
   2270   int is;
   2271   sim_fpu_eq (&is, l, r);
   2272   return is;
   2273 }
   2274 
   2275 INLINE_SIM_FPU (int)
   2276 sim_fpu_is_ne (const sim_fpu *l, const sim_fpu *r)
   2277 {
   2278   int is;
   2279   sim_fpu_ne (&is, l, r);
   2280   return is;
   2281 }
   2282 
   2283 INLINE_SIM_FPU (int)
   2284 sim_fpu_is_ge (const sim_fpu *l, const sim_fpu *r)
   2285 {
   2286   int is;
   2287   sim_fpu_ge (&is, l, r);
   2288   return is;
   2289 }
   2290 
   2291 INLINE_SIM_FPU (int)
   2292 sim_fpu_is_gt (const sim_fpu *l, const sim_fpu *r)
   2293 {
   2294   int is;
   2295   sim_fpu_gt (&is, l, r);
   2296   return is;
   2297 }
   2298 
   2299 
   2300 /* Compare operators */
   2301 
   2302 INLINE_SIM_FPU (int)
   2303 sim_fpu_lt (int *is,
   2304 	    const sim_fpu *l,
   2305 	    const sim_fpu *r)
   2306 {
   2307   if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
   2308     {
   2309       sim_fpu_map lval;
   2310       sim_fpu_map rval;
   2311       lval.i = pack_fpu (l, 1);
   2312       rval.i = pack_fpu (r, 1);
   2313       (*is) = (lval.d < rval.d);
   2314       return 0;
   2315     }
   2316   else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
   2317     {
   2318       *is = 0;
   2319       return sim_fpu_status_invalid_snan;
   2320     }
   2321   else
   2322     {
   2323       *is = 0;
   2324       return sim_fpu_status_invalid_qnan;
   2325     }
   2326 }
   2327 
   2328 INLINE_SIM_FPU (int)
   2329 sim_fpu_le (int *is,
   2330 	    const sim_fpu *l,
   2331 	    const sim_fpu *r)
   2332 {
   2333   if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
   2334     {
   2335       sim_fpu_map lval;
   2336       sim_fpu_map rval;
   2337       lval.i = pack_fpu (l, 1);
   2338       rval.i = pack_fpu (r, 1);
   2339       *is = (lval.d <= rval.d);
   2340       return 0;
   2341     }
   2342   else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
   2343     {
   2344       *is = 0;
   2345       return sim_fpu_status_invalid_snan;
   2346     }
   2347   else
   2348     {
   2349       *is = 0;
   2350       return sim_fpu_status_invalid_qnan;
   2351     }
   2352 }
   2353 
   2354 INLINE_SIM_FPU (int)
   2355 sim_fpu_eq (int *is,
   2356 	    const sim_fpu *l,
   2357 	    const sim_fpu *r)
   2358 {
   2359   if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
   2360     {
   2361       sim_fpu_map lval;
   2362       sim_fpu_map rval;
   2363       lval.i = pack_fpu (l, 1);
   2364       rval.i = pack_fpu (r, 1);
   2365       (*is) = (lval.d == rval.d);
   2366       return 0;
   2367     }
   2368   else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
   2369     {
   2370       *is = 0;
   2371       return sim_fpu_status_invalid_snan;
   2372     }
   2373   else
   2374     {
   2375       *is = 0;
   2376       return sim_fpu_status_invalid_qnan;
   2377     }
   2378 }
   2379 
   2380 INLINE_SIM_FPU (int)
   2381 sim_fpu_ne (int *is,
   2382 	    const sim_fpu *l,
   2383 	    const sim_fpu *r)
   2384 {
   2385   if (!sim_fpu_is_nan (l) && !sim_fpu_is_nan (r))
   2386     {
   2387       sim_fpu_map lval;
   2388       sim_fpu_map rval;
   2389       lval.i = pack_fpu (l, 1);
   2390       rval.i = pack_fpu (r, 1);
   2391       (*is) = (lval.d != rval.d);
   2392       return 0;
   2393     }
   2394   else if (sim_fpu_is_snan (l) || sim_fpu_is_snan (r))
   2395     {
   2396       *is = 0;
   2397       return sim_fpu_status_invalid_snan;
   2398     }
   2399   else
   2400     {
   2401       *is = 0;
   2402       return sim_fpu_status_invalid_qnan;
   2403     }
   2404 }
   2405 
   2406 INLINE_SIM_FPU (int)
   2407 sim_fpu_ge (int *is,
   2408 	    const sim_fpu *l,
   2409 	    const sim_fpu *r)
   2410 {
   2411   return sim_fpu_le (is, r, l);
   2412 }
   2413 
   2414 INLINE_SIM_FPU (int)
   2415 sim_fpu_gt (int *is,
   2416 	    const sim_fpu *l,
   2417 	    const sim_fpu *r)
   2418 {
   2419   return sim_fpu_lt (is, r, l);
   2420 }
   2421 
   2422 
   2423 /* A number of useful constants */
   2424 
   2425 #if EXTERN_SIM_FPU_P
   2426 const sim_fpu sim_fpu_zero = {
   2427   sim_fpu_class_zero, 0, 0, 0
   2428 };
   2429 const sim_fpu sim_fpu_qnan = {
   2430   sim_fpu_class_qnan, 0, 0, 0
   2431 };
   2432 const sim_fpu sim_fpu_one = {
   2433   sim_fpu_class_number, 0, IMPLICIT_1, 0
   2434 };
   2435 const sim_fpu sim_fpu_two = {
   2436   sim_fpu_class_number, 0, IMPLICIT_1, 1
   2437 };
   2438 const sim_fpu sim_fpu_max32 = {
   2439   sim_fpu_class_number, 0, LSMASK64 (NR_FRAC_GUARD, NR_GUARDS32), NORMAL_EXPMAX32
   2440 };
   2441 const sim_fpu sim_fpu_max64 = {
   2442   sim_fpu_class_number, 0, LSMASK64 (NR_FRAC_GUARD, NR_GUARDS64), NORMAL_EXPMAX64
   2443 };
   2444 #endif
   2445 
   2446 
   2447 /* For debugging */
   2448 
   2449 INLINE_SIM_FPU (void)
   2450 sim_fpu_print_fpu (const sim_fpu *f,
   2451 		   sim_fpu_print_func *print,
   2452 		   void *arg)
   2453 {
   2454   sim_fpu_printn_fpu (f, print, -1, arg);
   2455 }
   2456 
   2457 INLINE_SIM_FPU (void)
   2458 sim_fpu_printn_fpu (const sim_fpu *f,
   2459 		   sim_fpu_print_func *print,
   2460 		   int digits,
   2461 		   void *arg)
   2462 {
   2463   print (arg, "%s", f->sign ? "-" : "+");
   2464   switch (f->class)
   2465     {
   2466     case sim_fpu_class_qnan:
   2467       print (arg, "0.");
   2468       print_bits (f->fraction, NR_FRAC_GUARD - 1, digits, print, arg);
   2469       print (arg, "*QuietNaN");
   2470       break;
   2471     case sim_fpu_class_snan:
   2472       print (arg, "0.");
   2473       print_bits (f->fraction, NR_FRAC_GUARD - 1, digits, print, arg);
   2474       print (arg, "*SignalNaN");
   2475       break;
   2476     case sim_fpu_class_zero:
   2477       print (arg, "0.0");
   2478       break;
   2479     case sim_fpu_class_infinity:
   2480       print (arg, "INF");
   2481       break;
   2482     case sim_fpu_class_number:
   2483     case sim_fpu_class_denorm:
   2484       print (arg, "1.");
   2485       print_bits (f->fraction, NR_FRAC_GUARD - 1, digits, print, arg);
   2486       print (arg, "*2^%+d", f->normal_exp);
   2487       ASSERT (f->fraction >= IMPLICIT_1);
   2488       ASSERT (f->fraction < IMPLICIT_2);
   2489     }
   2490 }
   2491 
   2492 
   2493 INLINE_SIM_FPU (void)
   2494 sim_fpu_print_status (int status,
   2495 		      sim_fpu_print_func *print,
   2496 		      void *arg)
   2497 {
   2498   int i = 1;
   2499   const char *prefix = "";
   2500   while (status >= i)
   2501     {
   2502       switch ((sim_fpu_status) (status & i))
   2503 	{
   2504 	case sim_fpu_status_denorm:
   2505 	  print (arg, "%sD", prefix);
   2506 	  break;
   2507 	case sim_fpu_status_invalid_snan:
   2508 	  print (arg, "%sSNaN", prefix);
   2509 	  break;
   2510 	case sim_fpu_status_invalid_qnan:
   2511 	  print (arg, "%sQNaN", prefix);
   2512 	  break;
   2513 	case sim_fpu_status_invalid_isi:
   2514 	  print (arg, "%sISI", prefix);
   2515 	  break;
   2516 	case sim_fpu_status_invalid_idi:
   2517 	  print (arg, "%sIDI", prefix);
   2518 	  break;
   2519 	case sim_fpu_status_invalid_zdz:
   2520 	  print (arg, "%sZDZ", prefix);
   2521 	  break;
   2522 	case sim_fpu_status_invalid_imz:
   2523 	  print (arg, "%sIMZ", prefix);
   2524 	  break;
   2525 	case sim_fpu_status_invalid_cvi:
   2526 	  print (arg, "%sCVI", prefix);
   2527 	  break;
   2528 	case sim_fpu_status_invalid_cmp:
   2529 	  print (arg, "%sCMP", prefix);
   2530 	  break;
   2531 	case sim_fpu_status_invalid_sqrt:
   2532 	  print (arg, "%sSQRT", prefix);
   2533 	  break;
   2534 	case sim_fpu_status_inexact:
   2535 	  print (arg, "%sX", prefix);
   2536 	  break;
   2537 	case sim_fpu_status_overflow:
   2538 	  print (arg, "%sO", prefix);
   2539 	  break;
   2540 	case sim_fpu_status_underflow:
   2541 	  print (arg, "%sU", prefix);
   2542 	  break;
   2543 	case sim_fpu_status_invalid_div0:
   2544 	  print (arg, "%s/", prefix);
   2545 	  break;
   2546 	case sim_fpu_status_rounded:
   2547 	  print (arg, "%sR", prefix);
   2548 	  break;
   2549 	}
   2550       i <<= 1;
   2551       prefix = ",";
   2552     }
   2553 }
   2554 
   2555 #endif
   2556