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