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