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