1/* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)fp.s 7.2 (Berkeley) 05/25/92 11 */ 12 13/* 14 * Standard header stuff. 15 */ 16 17#include "machine/regdef.h" 18#include "machine/machAsmDefs.h" 19#include "machine/machConst.h" 20#include "assym.h" 21 22#define SEXP_INF 0xff 23#define DEXP_INF 0x7ff 24#define SEXP_BIAS 127 25#define DEXP_BIAS 1023 26#define SEXP_MIN -126 27#define DEXP_MIN -1022 28#define SEXP_MAX 127 29#define DEXP_MAX 1023 30#define WEXP_MAX 30 /* maximum unbiased exponent for int */ 31#define WEXP_MIN -1 /* minimum unbiased exponent for int */ 32#define SFRAC_BITS 23 33#define DFRAC_BITS 52 34#define SIMPL_ONE 0x00800000 35#define DIMPL_ONE 0x00100000 36#define SLEAD_ZEROS 31 - 23 37#define DLEAD_ZEROS 31 - 20 38#define STICKYBIT 1 39#define GUARDBIT 0x80000000 40#define SSIGNAL_NAN 0x00400000 41#define DSIGNAL_NAN 0x00080000 42#define SQUIET_NAN 0x003fffff 43#define DQUIET_NAN0 0x0007ffff 44#define DQUIET_NAN1 0xffffffff 45#define INT_MIN 0x80000000 46#define INT_MAX 0x7fffffff 47 48#define COND_UNORDERED 0x1 49#define COND_EQUAL 0x2 50#define COND_LESS 0x4 51#define COND_SIGNAL 0x8 52 53/*---------------------------------------------------------------------------- 54 * 55 * MachEmulateFP -- 56 * 57 * Emulate unimplemented floating point operations. 58 * This routine should only be called by MachFPInterrupt(). 59 * 60 * MachEmulateFP(instr) 61 * unsigned instr; 62 * 63 * Results: 64 * None. 65 * 66 * Side effects: 67 * Floating point registers are modified according to instruction. 68 * 69 *---------------------------------------------------------------------------- 70 */ 71NON_LEAF(MachEmulateFP, STAND_FRAME_SIZE, ra) 72 subu sp, sp, STAND_FRAME_SIZE 73 sw ra, STAND_RA_OFFSET(sp) 74/* 75 * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0). 76 */ 77 srl v0, a0, 21 - 2 # get FMT field 78 and v0, v0, 0xF << 2 # mask FMT field 79 and v1, a0, 0x3F # mask FUNC field 80 sll v1, v1, 5 # align for table lookup 81 bgt v0, 4 << 2, ill # illegal format 82 83 or v1, v1, v0 84 cfc1 a1, MACH_FPC_CSR # get exception register 85 lw a3, func_fmt_tbl(v1) # switch on FUNC & FMT 86 and a1, a1, ~MACH_FPC_EXCEPTION_UNIMPL # clear exception 87 ctc1 a1, MACH_FPC_CSR 88 j a3 89 90 .rdata 91func_fmt_tbl: 92 .word add_s # 0 93 .word add_d # 0 94 .word ill # 0 95 .word ill # 0 96 .word ill # 0 97 .word ill # 0 98 .word ill # 0 99 .word ill # 0 100 .word sub_s # 1 101 .word sub_d # 1 102 .word ill # 1 103 .word ill # 1 104 .word ill # 1 105 .word ill # 1 106 .word ill # 1 107 .word ill # 1 108 .word mul_s # 2 109 .word mul_d # 2 110 .word ill # 2 111 .word ill # 2 112 .word ill # 2 113 .word ill # 2 114 .word ill # 2 115 .word ill # 2 116 .word div_s # 3 117 .word div_d # 3 118 .word ill # 3 119 .word ill # 3 120 .word ill # 3 121 .word ill # 3 122 .word ill # 3 123 .word ill # 3 124 .word ill # 4 125 .word ill # 4 126 .word ill # 4 127 .word ill # 4 128 .word ill # 4 129 .word ill # 4 130 .word ill # 4 131 .word ill # 4 132 .word abs_s # 5 133 .word abs_d # 5 134 .word ill # 5 135 .word ill # 5 136 .word ill # 5 137 .word ill # 5 138 .word ill # 5 139 .word ill # 5 140 .word mov_s # 6 141 .word mov_d # 6 142 .word ill # 6 143 .word ill # 6 144 .word ill # 6 145 .word ill # 6 146 .word ill # 6 147 .word ill # 6 148 .word neg_s # 7 149 .word neg_d # 7 150 .word ill # 7 151 .word ill # 7 152 .word ill # 7 153 .word ill # 7 154 .word ill # 7 155 .word ill # 7 156 .word ill # 8 157 .word ill # 8 158 .word ill # 8 159 .word ill # 8 160 .word ill # 8 161 .word ill # 8 162 .word ill # 8 163 .word ill # 8 164 .word ill # 9 165 .word ill # 9 166 .word ill # 9 167 .word ill # 9 168 .word ill # 9 169 .word ill # 9 170 .word ill # 9 171 .word ill # 9 172 .word ill # 10 173 .word ill # 10 174 .word ill # 10 175 .word ill # 10 176 .word ill # 10 177 .word ill # 10 178 .word ill # 10 179 .word ill # 10 180 .word ill # 11 181 .word ill # 11 182 .word ill # 11 183 .word ill # 11 184 .word ill # 11 185 .word ill # 11 186 .word ill # 11 187 .word ill # 11 188 .word ill # 12 189 .word ill # 12 190 .word ill # 12 191 .word ill # 12 192 .word ill # 12 193 .word ill # 12 194 .word ill # 12 195 .word ill # 12 196 .word ill # 13 197 .word ill # 13 198 .word ill # 13 199 .word ill # 13 200 .word ill # 13 201 .word ill # 13 202 .word ill # 13 203 .word ill # 13 204 .word ill # 14 205 .word ill # 14 206 .word ill # 14 207 .word ill # 14 208 .word ill # 14 209 .word ill # 14 210 .word ill # 14 211 .word ill # 14 212 .word ill # 15 213 .word ill # 15 214 .word ill # 15 215 .word ill # 15 216 .word ill # 15 217 .word ill # 15 218 .word ill # 15 219 .word ill # 15 220 .word ill # 16 221 .word ill # 16 222 .word ill # 16 223 .word ill # 16 224 .word ill # 16 225 .word ill # 16 226 .word ill # 16 227 .word ill # 16 228 .word ill # 17 229 .word ill # 17 230 .word ill # 17 231 .word ill # 17 232 .word ill # 17 233 .word ill # 17 234 .word ill # 17 235 .word ill # 17 236 .word ill # 18 237 .word ill # 18 238 .word ill # 18 239 .word ill # 18 240 .word ill # 18 241 .word ill # 18 242 .word ill # 18 243 .word ill # 18 244 .word ill # 19 245 .word ill # 19 246 .word ill # 19 247 .word ill # 19 248 .word ill # 19 249 .word ill # 19 250 .word ill # 19 251 .word ill # 19 252 .word ill # 20 253 .word ill # 20 254 .word ill # 20 255 .word ill # 20 256 .word ill # 20 257 .word ill # 20 258 .word ill # 20 259 .word ill # 20 260 .word ill # 21 261 .word ill # 21 262 .word ill # 21 263 .word ill # 21 264 .word ill # 21 265 .word ill # 21 266 .word ill # 21 267 .word ill # 21 268 .word ill # 22 269 .word ill # 22 270 .word ill # 22 271 .word ill # 22 272 .word ill # 22 273 .word ill # 22 274 .word ill # 22 275 .word ill # 22 276 .word ill # 23 277 .word ill # 23 278 .word ill # 23 279 .word ill # 23 280 .word ill # 23 281 .word ill # 23 282 .word ill # 23 283 .word ill # 23 284 .word ill # 24 285 .word ill # 24 286 .word ill # 24 287 .word ill # 24 288 .word ill # 24 289 .word ill # 24 290 .word ill # 24 291 .word ill # 24 292 .word ill # 25 293 .word ill # 25 294 .word ill # 25 295 .word ill # 25 296 .word ill # 25 297 .word ill # 25 298 .word ill # 25 299 .word ill # 25 300 .word ill # 26 301 .word ill # 26 302 .word ill # 26 303 .word ill # 26 304 .word ill # 26 305 .word ill # 26 306 .word ill # 26 307 .word ill # 26 308 .word ill # 27 309 .word ill # 27 310 .word ill # 27 311 .word ill # 27 312 .word ill # 27 313 .word ill # 27 314 .word ill # 27 315 .word ill # 27 316 .word ill # 28 317 .word ill # 28 318 .word ill # 28 319 .word ill # 28 320 .word ill # 28 321 .word ill # 28 322 .word ill # 28 323 .word ill # 28 324 .word ill # 29 325 .word ill # 29 326 .word ill # 29 327 .word ill # 29 328 .word ill # 29 329 .word ill # 29 330 .word ill # 29 331 .word ill # 29 332 .word ill # 30 333 .word ill # 30 334 .word ill # 30 335 .word ill # 30 336 .word ill # 30 337 .word ill # 30 338 .word ill # 30 339 .word ill # 30 340 .word ill # 31 341 .word ill # 31 342 .word ill # 31 343 .word ill # 31 344 .word ill # 31 345 .word ill # 31 346 .word ill # 31 347 .word ill # 31 348 .word ill # 32 349 .word cvt_s_d # 32 350 .word ill # 32 351 .word ill # 32 352 .word cvt_s_w # 32 353 .word ill # 32 354 .word ill # 32 355 .word ill # 32 356 .word cvt_d_s # 33 357 .word ill # 33 358 .word ill # 33 359 .word ill # 33 360 .word cvt_d_w # 33 361 .word ill # 33 362 .word ill # 33 363 .word ill # 33 364 .word ill # 34 365 .word ill # 34 366 .word ill # 34 367 .word ill # 34 368 .word ill # 34 369 .word ill # 34 370 .word ill # 34 371 .word ill # 34 372 .word ill # 35 373 .word ill # 35 374 .word ill # 35 375 .word ill # 35 376 .word ill # 35 377 .word ill # 35 378 .word ill # 35 379 .word ill # 35 380 .word cvt_w_s # 36 381 .word cvt_w_d # 36 382 .word ill # 36 383 .word ill # 36 384 .word ill # 36 385 .word ill # 36 386 .word ill # 36 387 .word ill # 36 388 .word ill # 37 389 .word ill # 37 390 .word ill # 37 391 .word ill # 37 392 .word ill # 37 393 .word ill # 37 394 .word ill # 37 395 .word ill # 37 396 .word ill # 38 397 .word ill # 38 398 .word ill # 38 399 .word ill # 38 400 .word ill # 38 401 .word ill # 38 402 .word ill # 38 403 .word ill # 38 404 .word ill # 39 405 .word ill # 39 406 .word ill # 39 407 .word ill # 39 408 .word ill # 39 409 .word ill # 39 410 .word ill # 39 411 .word ill # 39 412 .word ill # 40 413 .word ill # 40 414 .word ill # 40 415 .word ill # 40 416 .word ill # 40 417 .word ill # 40 418 .word ill # 40 419 .word ill # 40 420 .word ill # 41 421 .word ill # 41 422 .word ill # 41 423 .word ill # 41 424 .word ill # 41 425 .word ill # 41 426 .word ill # 41 427 .word ill # 41 428 .word ill # 42 429 .word ill # 42 430 .word ill # 42 431 .word ill # 42 432 .word ill # 42 433 .word ill # 42 434 .word ill # 42 435 .word ill # 42 436 .word ill # 43 437 .word ill # 43 438 .word ill # 43 439 .word ill # 43 440 .word ill # 43 441 .word ill # 43 442 .word ill # 43 443 .word ill # 43 444 .word ill # 44 445 .word ill # 44 446 .word ill # 44 447 .word ill # 44 448 .word ill # 44 449 .word ill # 44 450 .word ill # 44 451 .word ill # 44 452 .word ill # 45 453 .word ill # 45 454 .word ill # 45 455 .word ill # 45 456 .word ill # 45 457 .word ill # 45 458 .word ill # 45 459 .word ill # 45 460 .word ill # 46 461 .word ill # 46 462 .word ill # 46 463 .word ill # 46 464 .word ill # 46 465 .word ill # 46 466 .word ill # 46 467 .word ill # 46 468 .word ill # 47 469 .word ill # 47 470 .word ill # 47 471 .word ill # 47 472 .word ill # 47 473 .word ill # 47 474 .word ill # 47 475 .word ill # 47 476 .word cmp_s # 48 477 .word cmp_d # 48 478 .word ill # 48 479 .word ill # 48 480 .word ill # 48 481 .word ill # 48 482 .word ill # 48 483 .word ill # 48 484 .word cmp_s # 49 485 .word cmp_d # 49 486 .word ill # 49 487 .word ill # 49 488 .word ill # 49 489 .word ill # 49 490 .word ill # 49 491 .word ill # 49 492 .word cmp_s # 50 493 .word cmp_d # 50 494 .word ill # 50 495 .word ill # 50 496 .word ill # 50 497 .word ill # 50 498 .word ill # 50 499 .word ill # 50 500 .word cmp_s # 51 501 .word cmp_d # 51 502 .word ill # 51 503 .word ill # 51 504 .word ill # 51 505 .word ill # 51 506 .word ill # 51 507 .word ill # 51 508 .word cmp_s # 52 509 .word cmp_d # 52 510 .word ill # 52 511 .word ill # 52 512 .word ill # 52 513 .word ill # 52 514 .word ill # 52 515 .word ill # 52 516 .word cmp_s # 53 517 .word cmp_d # 53 518 .word ill # 53 519 .word ill # 53 520 .word ill # 53 521 .word ill # 53 522 .word ill # 53 523 .word ill # 53 524 .word cmp_s # 54 525 .word cmp_d # 54 526 .word ill # 54 527 .word ill # 54 528 .word ill # 54 529 .word ill # 54 530 .word ill # 54 531 .word ill # 54 532 .word cmp_s # 55 533 .word cmp_d # 55 534 .word ill # 55 535 .word ill # 55 536 .word ill # 55 537 .word ill # 55 538 .word ill # 55 539 .word ill # 55 540 .word cmp_s # 56 541 .word cmp_d # 56 542 .word ill # 56 543 .word ill # 56 544 .word ill # 56 545 .word ill # 56 546 .word ill # 56 547 .word ill # 56 548 .word cmp_s # 57 549 .word cmp_d # 57 550 .word ill # 57 551 .word ill # 57 552 .word ill # 57 553 .word ill # 57 554 .word ill # 57 555 .word ill # 57 556 .word cmp_s # 58 557 .word cmp_d # 58 558 .word ill # 58 559 .word ill # 58 560 .word ill # 58 561 .word ill # 58 562 .word ill # 58 563 .word ill # 58 564 .word cmp_s # 59 565 .word cmp_d # 59 566 .word ill # 59 567 .word ill # 59 568 .word ill # 59 569 .word ill # 59 570 .word ill # 59 571 .word ill # 59 572 .word cmp_s # 60 573 .word cmp_d # 60 574 .word ill # 60 575 .word ill # 60 576 .word ill # 60 577 .word ill # 60 578 .word ill # 60 579 .word ill # 60 580 .word cmp_s # 61 581 .word cmp_d # 61 582 .word ill # 61 583 .word ill # 61 584 .word ill # 61 585 .word ill # 61 586 .word ill # 61 587 .word ill # 61 588 .word cmp_s # 62 589 .word cmp_d # 62 590 .word ill # 62 591 .word ill # 62 592 .word ill # 62 593 .word ill # 62 594 .word ill # 62 595 .word ill # 62 596 .word cmp_s # 63 597 .word cmp_d # 63 598 .word ill # 63 599 .word ill # 63 600 .word ill # 63 601 .word ill # 63 602 .word ill # 63 603 .word ill # 63 604 .text 605 606/* 607 * Single precision subtract. 608 */ 609sub_s: 610 jal get_ft_fs_s 611 xor t4, t4, 1 # negate FT sign bit 612 b add_sub_s 613/* 614 * Single precision add. 615 */ 616add_s: 617 jal get_ft_fs_s 618add_sub_s: 619 bne t1, SEXP_INF, 1f # is FS an infinity? 620 bne t5, SEXP_INF, result_fs_s # if FT is not inf, result=FS 621 bne t2, zero, result_fs_s # if FS is NAN, result is FS 622 bne t6, zero, result_ft_s # if FT is NAN, result is FT 623 bne t0, t4, invalid_s # both infinities same sign? 624 b result_fs_s # result is in FS 6251: 626 beq t5, SEXP_INF, result_ft_s # if FT is inf, result=FT 627 bne t1, zero, 4f # is FS a denormalized num? 628 beq t2, zero, 3f # is FS zero? 629 bne t5, zero, 2f # is FT a denormalized num? 630 beq t6, zero, result_fs_s # FT is zero, result=FS 631 jal renorm_fs_s 632 jal renorm_ft_s 633 b 5f 6342: 635 jal renorm_fs_s 636 subu t5, t5, SEXP_BIAS # unbias FT exponent 637 or t6, t6, SIMPL_ONE # set implied one bit 638 b 5f 6393: 640 bne t5, zero, result_ft_s # if FT != 0, result=FT 641 bne t6, zero, result_ft_s 642 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 643 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 644 or t0, t0, t4 # compute result sign 645 b result_fs_s 6461: 647 and t0, t0, t4 # compute result sign 648 b result_fs_s 6494: 650 bne t5, zero, 2f # is FT a denormalized num? 651 beq t6, zero, result_fs_s # FT is zero, result=FS 652 subu t1, t1, SEXP_BIAS # unbias FS exponent 653 or t2, t2, SIMPL_ONE # set implied one bit 654 jal renorm_ft_s 655 b 5f 6562: 657 subu t1, t1, SEXP_BIAS # unbias FS exponent 658 or t2, t2, SIMPL_ONE # set implied one bit 659 subu t5, t5, SEXP_BIAS # unbias FT exponent 660 or t6, t6, SIMPL_ONE # set implied one bit 661/* 662 * Perform the addition. 663 */ 6645: 665 move t8, zero # no shifted bits (sticky reg) 666 beq t1, t5, 4f # no shift needed 667 subu v0, t1, t5 # v0 = difference of exponents 668 move v1, v0 # v1 = abs(difference) 669 bge v0, zero, 1f 670 negu v1 6711: 672 ble v1, SFRAC_BITS+2, 2f # is difference too great? 673 li t8, STICKYBIT # set the sticky bit 674 bge v0, zero, 1f # check which exp is larger 675 move t1, t5 # result exp is FT's 676 move t2, zero # FS's fraction shifted is zero 677 b 4f 6781: 679 move t6, zero # FT's fraction shifted is zero 680 b 4f 6812: 682 li t9, 32 # compute 32 - abs(exp diff) 683 subu t9, t9, v1 684 bgt v0, zero, 3f # if FS > FT, shift FT's frac 685 move t1, t5 # FT > FS, result exp is FT's 686 sll t8, t2, t9 # save bits shifted out 687 srl t2, t2, v1 # shift FS's fraction 688 b 4f 6893: 690 sll t8, t6, t9 # save bits shifted out 691 srl t6, t6, v1 # shift FT's fraction 6924: 693 bne t0, t4, 1f # if signs differ, subtract 694 addu t2, t2, t6 # add fractions 695 b norm_s 6961: 697 blt t2, t6, 3f # subtract larger from smaller 698 bne t2, t6, 2f # if same, result=0 699 move t1, zero # result=0 700 move t2, zero 701 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 702 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 703 or t0, t0, t4 # compute result sign 704 b result_fs_s 7051: 706 and t0, t0, t4 # compute result sign 707 b result_fs_s 7082: 709 sltu t9, zero, t8 # compute t2:zero - t6:t8 710 subu t8, zero, t8 711 subu t2, t2, t6 # subtract fractions 712 subu t2, t2, t9 # subtract barrow 713 b norm_s 7143: 715 move t0, t4 # sign of result = FT's 716 sltu t9, zero, t8 # compute t6:zero - t2:t8 717 subu t8, zero, t8 718 subu t2, t6, t2 # subtract fractions 719 subu t2, t2, t9 # subtract barrow 720 b norm_s 721 722/* 723 * Double precision subtract. 724 */ 725sub_d: 726 jal get_ft_fs_d 727 xor t4, t4, 1 # negate sign bit 728 b add_sub_d 729/* 730 * Double precision add. 731 */ 732add_d: 733 jal get_ft_fs_d 734add_sub_d: 735 bne t1, DEXP_INF, 1f # is FS an infinity? 736 bne t5, DEXP_INF, result_fs_d # if FT is not inf, result=FS 737 bne t2, zero, result_fs_d # if FS is NAN, result is FS 738 bne t3, zero, result_fs_d 739 bne t6, zero, result_ft_d # if FT is NAN, result is FT 740 bne t7, zero, result_ft_d 741 bne t0, t4, invalid_d # both infinities same sign? 742 b result_fs_d # result is in FS 7431: 744 beq t5, DEXP_INF, result_ft_d # if FT is inf, result=FT 745 bne t1, zero, 4f # is FS a denormalized num? 746 bne t2, zero, 1f # is FS zero? 747 beq t3, zero, 3f 7481: 749 bne t5, zero, 2f # is FT a denormalized num? 750 bne t6, zero, 1f 751 beq t7, zero, result_fs_d # FT is zero, result=FS 7521: 753 jal renorm_fs_d 754 jal renorm_ft_d 755 b 5f 7562: 757 jal renorm_fs_d 758 subu t5, t5, DEXP_BIAS # unbias FT exponent 759 or t6, t6, DIMPL_ONE # set implied one bit 760 b 5f 7613: 762 bne t5, zero, result_ft_d # if FT != 0, result=FT 763 bne t6, zero, result_ft_d 764 bne t7, zero, result_ft_d 765 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 766 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 767 or t0, t0, t4 # compute result sign 768 b result_fs_d 7691: 770 and t0, t0, t4 # compute result sign 771 b result_fs_d 7724: 773 bne t5, zero, 2f # is FT a denormalized num? 774 bne t6, zero, 1f 775 beq t7, zero, result_fs_d # FT is zero, result=FS 7761: 777 subu t1, t1, DEXP_BIAS # unbias FS exponent 778 or t2, t2, DIMPL_ONE # set implied one bit 779 jal renorm_ft_d 780 b 5f 7812: 782 subu t1, t1, DEXP_BIAS # unbias FS exponent 783 or t2, t2, DIMPL_ONE # set implied one bit 784 subu t5, t5, DEXP_BIAS # unbias FT exponent 785 or t6, t6, DIMPL_ONE # set implied one bit 786/* 787 * Perform the addition. 788 */ 7895: 790 move t8, zero # no shifted bits (sticky reg) 791 beq t1, t5, 4f # no shift needed 792 subu v0, t1, t5 # v0 = difference of exponents 793 move v1, v0 # v1 = abs(difference) 794 bge v0, zero, 1f 795 negu v1 7961: 797 ble v1, DFRAC_BITS+2, 2f # is difference too great? 798 li t8, STICKYBIT # set the sticky bit 799 bge v0, zero, 1f # check which exp is larger 800 move t1, t5 # result exp is FT's 801 move t2, zero # FS's fraction shifted is zero 802 move t3, zero 803 b 4f 8041: 805 move t6, zero # FT's fraction shifted is zero 806 move t7, zero 807 b 4f 8082: 809 li t9, 32 810 bge v0, zero, 3f # if FS > FT, shift FT's frac 811 move t1, t5 # FT > FS, result exp is FT's 812 blt v1, t9, 1f # shift right by < 32? 813 subu v1, v1, t9 814 subu t9, t9, v1 815 sll t8, t2, t9 # save bits shifted out 816 sltu t9, zero, t3 # don't lose any one bits 817 or t8, t8, t9 # save sticky bit 818 srl t3, t2, v1 # shift FS's fraction 819 move t2, zero 820 b 4f 8211: 822 subu t9, t9, v1 823 sll t8, t3, t9 # save bits shifted out 824 srl t3, t3, v1 # shift FS's fraction 825 sll t9, t2, t9 # save bits shifted out of t2 826 or t3, t3, t9 # and put into t3 827 srl t2, t2, v1 828 b 4f 8293: 830 blt v1, t9, 1f # shift right by < 32? 831 subu v1, v1, t9 832 subu t9, t9, v1 833 sll t8, t6, t9 # save bits shifted out 834 srl t7, t6, v1 # shift FT's fraction 835 move t6, zero 836 b 4f 8371: 838 subu t9, t9, v1 839 sll t8, t7, t9 # save bits shifted out 840 srl t7, t7, v1 # shift FT's fraction 841 sll t9, t6, t9 # save bits shifted out of t2 842 or t7, t7, t9 # and put into t3 843 srl t6, t6, v1 8444: 845 bne t0, t4, 1f # if signs differ, subtract 846 addu t3, t3, t7 # add fractions 847 sltu t9, t3, t7 # compute carry 848 addu t2, t2, t6 # add fractions 849 addu t2, t2, t9 # add carry 850 b norm_d 8511: 852 blt t2, t6, 3f # subtract larger from smaller 853 bne t2, t6, 2f 854 bltu t3, t7, 3f 855 bne t3, t7, 2f # if same, result=0 856 move t1, zero # result=0 857 move t2, zero 858 move t3, zero 859 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 860 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 861 or t0, t0, t4 # compute result sign 862 b result_fs_d 8631: 864 and t0, t0, t4 # compute result sign 865 b result_fs_d 8662: 867 beq t8, zero, 1f # compute t2:t3:zero - t6:t7:t8 868 subu t8, zero, t8 869 sltu v0, t3, 1 # compute barrow out 870 subu t3, t3, 1 # subtract barrow 871 subu t2, t2, v0 8721: 873 sltu v0, t3, t7 874 subu t3, t3, t7 # subtract fractions 875 subu t2, t2, t6 # subtract fractions 876 subu t2, t2, v0 # subtract barrow 877 b norm_d 8783: 879 move t0, t4 # sign of result = FT's 880 beq t8, zero, 1f # compute t6:t7:zero - t2:t3:t8 881 subu t8, zero, t8 882 sltu v0, t7, 1 # compute barrow out 883 subu t7, t7, 1 # subtract barrow 884 subu t6, t6, v0 8851: 886 sltu v0, t7, t3 887 subu t3, t7, t3 # subtract fractions 888 subu t2, t6, t2 # subtract fractions 889 subu t2, t2, v0 # subtract barrow 890 b norm_d 891 892/* 893 * Single precision multiply. 894 */ 895mul_s: 896 jal get_ft_fs_s 897 xor t0, t0, t4 # compute sign of result 898 move t4, t0 899 bne t1, SEXP_INF, 2f # is FS an infinity? 900 bne t2, zero, result_fs_s # if FS is a NAN, result=FS 901 bne t5, SEXP_INF, 1f # FS is inf, is FT an infinity? 902 bne t6, zero, result_ft_s # if FT is a NAN, result=FT 903 b result_fs_s # result is infinity 9041: 905 bne t5, zero, result_fs_s # inf * zero? if no, result=FS 906 bne t6, zero, result_fs_s 907 b invalid_s # infinity * zero is invalid 9082: 909 bne t5, SEXP_INF, 1f # FS != inf, is FT an infinity? 910 bne t1, zero, result_ft_s # zero * inf? if no, result=FT 911 bne t2, zero, result_ft_s 912 bne t6, zero, result_ft_s # if FT is a NAN, result=FT 913 b invalid_s # zero * infinity is invalid 9141: 915 bne t1, zero, 1f # is FS zero? 916 beq t2, zero, result_fs_s # result is zero 917 jal renorm_fs_s 918 b 2f 9191: 920 subu t1, t1, SEXP_BIAS # unbias FS exponent 921 or t2, t2, SIMPL_ONE # set implied one bit 9222: 923 bne t5, zero, 1f # is FT zero? 924 beq t6, zero, result_ft_s # result is zero 925 jal renorm_ft_s 926 b 2f 9271: 928 subu t5, t5, SEXP_BIAS # unbias FT exponent 929 or t6, t6, SIMPL_ONE # set implied one bit 9302: 931 addu t1, t1, t5 # compute result exponent 932 addu t1, t1, 9 # account for binary point 933 multu t2, t6 # multiply fractions 934 mflo t8 935 mfhi t2 936 b norm_s 937 938/* 939 * Double precision multiply. 940 */ 941mul_d: 942 jal get_ft_fs_d 943 xor t0, t0, t4 # compute sign of result 944 move t4, t0 945 bne t1, DEXP_INF, 2f # is FS an infinity? 946 bne t2, zero, result_fs_d # if FS is a NAN, result=FS 947 bne t3, zero, result_fs_d 948 bne t5, DEXP_INF, 1f # FS is inf, is FT an infinity? 949 bne t6, zero, result_ft_d # if FT is a NAN, result=FT 950 bne t7, zero, result_ft_d 951 b result_fs_d # result is infinity 9521: 953 bne t5, zero, result_fs_d # inf * zero? if no, result=FS 954 bne t6, zero, result_fs_d 955 bne t7, zero, result_fs_d 956 b invalid_d # infinity * zero is invalid 9572: 958 bne t5, DEXP_INF, 1f # FS != inf, is FT an infinity? 959 bne t1, zero, result_ft_d # zero * inf? if no, result=FT 960 bne t2, zero, result_ft_d # if FS is a NAN, result=FS 961 bne t3, zero, result_ft_d 962 bne t6, zero, result_ft_d # if FT is a NAN, result=FT 963 bne t7, zero, result_ft_d 964 b invalid_d # zero * infinity is invalid 9651: 966 bne t1, zero, 2f # is FS zero? 967 bne t2, zero, 1f 968 beq t3, zero, result_fs_d # result is zero 9691: 970 jal renorm_fs_d 971 b 3f 9722: 973 subu t1, t1, DEXP_BIAS # unbias FS exponent 974 or t2, t2, DIMPL_ONE # set implied one bit 9753: 976 bne t5, zero, 2f # is FT zero? 977 bne t6, zero, 1f 978 beq t7, zero, result_ft_d # result is zero 9791: 980 jal renorm_ft_d 981 b 3f 9822: 983 subu t5, t5, DEXP_BIAS # unbias FT exponent 984 or t6, t6, DIMPL_ONE # set implied one bit 9853: 986 addu t1, t1, t5 # compute result exponent 987 addu t1, t1, 12 # ??? 988 multu t3, t7 # multiply fractions (low * low) 989 move t4, t2 # free up t2,t3 for result 990 move t5, t3 991 mflo a3 # save low order bits 992 mfhi t8 993 not v0, t8 994 multu t4, t7 # multiply FS(high) * FT(low) 995 mflo v1 996 mfhi t3 # init low result 997 sltu v0, v0, v1 # compute carry 998 addu t8, v1 999 multu t5, t6 # multiply FS(low) * FT(high) 1000 addu t3, t3, v0 # add carry 1001 not v0, t8 1002 mflo v1 1003 mfhi t2 1004 sltu v0, v0, v1 1005 addu t8, v1 1006 multu t4, t6 # multiply FS(high) * FT(high) 1007 addu t3, v0 1008 not v1, t3 1009 sltu v1, v1, t2 1010 addu t3, t2 1011 not v0, t3 1012 mfhi t2 1013 addu t2, v1 1014 mflo v1 1015 sltu v0, v0, v1 1016 addu t2, v0 1017 addu t3, v1 1018 sltu a3, zero, a3 # reduce t8,a3 to just t8 1019 or t8, a3 1020 b norm_d 1021 1022/* 1023 * Single precision divide. 1024 */ 1025div_s: 1026 jal get_ft_fs_s 1027 xor t0, t0, t4 # compute sign of result 1028 move t4, t0 1029 bne t1, SEXP_INF, 1f # is FS an infinity? 1030 bne t2, zero, result_fs_s # if FS is NAN, result is FS 1031 bne t5, SEXP_INF, result_fs_s # is FT an infinity? 1032 bne t6, zero, result_ft_s # if FT is NAN, result is FT 1033 b invalid_s # infinity/infinity is invalid 10341: 1035 bne t5, SEXP_INF, 1f # is FT an infinity? 1036 bne t6, zero, result_ft_s # if FT is NAN, result is FT 1037 move t1, zero # x / infinity is zero 1038 move t2, zero 1039 b result_fs_s 10401: 1041 bne t1, zero, 2f # is FS zero? 1042 bne t2, zero, 1f 1043 bne t5, zero, result_fs_s # FS=zero, is FT zero? 1044 beq t6, zero, invalid_s # 0 / 0 1045 b result_fs_s # result = zero 10461: 1047 jal renorm_fs_s 1048 b 3f 10492: 1050 subu t1, t1, SEXP_BIAS # unbias FS exponent 1051 or t2, t2, SIMPL_ONE # set implied one bit 10523: 1053 bne t5, zero, 2f # is FT zero? 1054 bne t6, zero, 1f 1055 or a1, a1, MACH_FPC_EXCEPTION_DIV0 | MACH_FPC_STICKY_DIV0 1056 and v0, a1, MACH_FPC_ENABLE_DIV0 # trap enabled? 1057 bne v0, zero, fpe_trap 1058 ctc1 a1, MACH_FPC_CSR # save exceptions 1059 li t1, SEXP_INF # result is infinity 1060 move t2, zero 1061 b result_fs_s 10621: 1063 jal renorm_ft_s 1064 b 3f 10652: 1066 subu t5, t5, SEXP_BIAS # unbias FT exponent 1067 or t6, t6, SIMPL_ONE # set implied one bit 10683: 1069 subu t1, t1, t5 # compute exponent 1070 subu t1, t1, 3 # compensate for result position 1071 li v0, SFRAC_BITS+3 # number of bits to divide 1072 move t8, t2 # init dividend 1073 move t2, zero # init result 10741: 1075 bltu t8, t6, 3f # is dividend >= divisor? 10762: 1077 subu t8, t8, t6 # subtract divisor from dividend 1078 or t2, t2, 1 # remember that we did 1079 bne t8, zero, 3f # if not done, continue 1080 sll t2, t2, v0 # shift result to final position 1081 b norm_s 10823: 1083 sll t8, t8, 1 # shift dividend 1084 sll t2, t2, 1 # shift result 1085 subu v0, v0, 1 # are we done? 1086 bne v0, zero, 1b # no, continue 1087 b norm_s 1088 1089/* 1090 * Double precision divide. 1091 */ 1092div_d: 1093 jal get_ft_fs_d 1094 xor t0, t0, t4 # compute sign of result 1095 move t4, t0 1096 bne t1, DEXP_INF, 1f # is FS an infinity? 1097 bne t2, zero, result_fs_d # if FS is NAN, result is FS 1098 bne t3, zero, result_fs_d 1099 bne t5, DEXP_INF, result_fs_d # is FT an infinity? 1100 bne t6, zero, result_ft_d # if FT is NAN, result is FT 1101 bne t7, zero, result_ft_d 1102 b invalid_d # infinity/infinity is invalid 11031: 1104 bne t5, DEXP_INF, 1f # is FT an infinity? 1105 bne t6, zero, result_ft_d # if FT is NAN, result is FT 1106 bne t7, zero, result_ft_d 1107 move t1, zero # x / infinity is zero 1108 move t2, zero 1109 move t3, zero 1110 b result_fs_d 11111: 1112 bne t1, zero, 2f # is FS zero? 1113 bne t2, zero, 1f 1114 bne t3, zero, 1f 1115 bne t5, zero, result_fs_d # FS=zero, is FT zero? 1116 bne t6, zero, result_fs_d 1117 beq t7, zero, invalid_d # 0 / 0 1118 b result_fs_d # result = zero 11191: 1120 jal renorm_fs_d 1121 b 3f 11222: 1123 subu t1, t1, DEXP_BIAS # unbias FS exponent 1124 or t2, t2, DIMPL_ONE # set implied one bit 11253: 1126 bne t5, zero, 2f # is FT zero? 1127 bne t6, zero, 1f 1128 bne t7, zero, 1f 1129 or a1, a1, MACH_FPC_EXCEPTION_DIV0 | MACH_FPC_STICKY_DIV0 1130 and v0, a1, MACH_FPC_ENABLE_DIV0 # trap enabled? 1131 bne v0, zero, fpe_trap 1132 ctc1 a1, MACH_FPC_CSR # Save exceptions 1133 li t1, DEXP_INF # result is infinity 1134 move t2, zero 1135 move t3, zero 1136 b result_fs_d 11371: 1138 jal renorm_ft_d 1139 b 3f 11402: 1141 subu t5, t5, DEXP_BIAS # unbias FT exponent 1142 or t6, t6, DIMPL_ONE # set implied one bit 11433: 1144 subu t1, t1, t5 # compute exponent 1145 subu t1, t1, 3 # compensate for result position 1146 li v0, DFRAC_BITS+3 # number of bits to divide 1147 move t8, t2 # init dividend 1148 move t9, t3 1149 move t2, zero # init result 1150 move t3, zero 11511: 1152 bltu t8, t6, 3f # is dividend >= divisor? 1153 bne t8, t6, 2f 1154 bltu t9, t7, 3f 11552: 1156 sltu v1, t9, t7 # subtract divisor from dividend 1157 subu t9, t9, t7 1158 subu t8, t8, t6 1159 subu t8, t8, v1 1160 or t3, t3, 1 # remember that we did 1161 bne t8, zero, 3f # if not done, continue 1162 bne t9, zero, 3f 1163 li v1, 32 # shift result to final position 1164 blt v0, v1, 2f # shift < 32 bits? 1165 subu v0, v0, v1 # shift by > 32 bits 1166 sll t2, t3, v0 # shift upper part 1167 move t3, zero 1168 b norm_d 11692: 1170 subu v1, v1, v0 # shift by < 32 bits 1171 sll t2, t2, v0 # shift upper part 1172 srl t9, t3, v1 # save bits shifted out 1173 or t2, t2, t9 # and put into upper part 1174 sll t3, t3, v0 1175 b norm_d 11763: 1177 sll t8, t8, 1 # shift dividend 1178 srl v1, t9, 31 # save bit shifted out 1179 or t8, t8, v1 # and put into upper part 1180 sll t9, t9, 1 1181 sll t2, t2, 1 # shift result 1182 srl v1, t3, 31 # save bit shifted out 1183 or t2, t2, v1 # and put into upper part 1184 sll t3, t3, 1 1185 subu v0, v0, 1 # are we done? 1186 bne v0, zero, 1b # no, continue 1187 sltu v0, zero, t9 # be sure to save any one bits 1188 or t8, t8, v0 # from the lower remainder 1189 b norm_d 1190 1191/* 1192 * Single precision absolute value. 1193 */ 1194abs_s: 1195 jal get_fs_s 1196 move t0, zero # set sign positive 1197 b result_fs_s 1198 1199/* 1200 * Double precision absolute value. 1201 */ 1202abs_d: 1203 jal get_fs_d 1204 move t0, zero # set sign positive 1205 b result_fs_d 1206 1207/* 1208 * Single precision move. 1209 */ 1210mov_s: 1211 jal get_fs_s 1212 b result_fs_s 1213 1214/* 1215 * Double precision move. 1216 */ 1217mov_d: 1218 jal get_fs_d 1219 b result_fs_d 1220 1221/* 1222 * Single precision negate. 1223 */ 1224neg_s: 1225 jal get_fs_s 1226 xor t0, t0, 1 # reverse sign 1227 b result_fs_s 1228 1229/* 1230 * Double precision negate. 1231 */ 1232neg_d: 1233 jal get_fs_d 1234 xor t0, t0, 1 # reverse sign 1235 b result_fs_d 1236 1237/* 1238 * Convert double to single. 1239 */ 1240cvt_s_d: 1241 jal get_fs_d 1242 bne t1, DEXP_INF, 1f # is FS an infinity? 1243 li t1, SEXP_INF # convert to single 1244 sll t2, t2, 3 # convert D fraction to S 1245 srl t8, t3, 32 - 3 1246 or t2, t2, t8 1247 b result_fs_s 12481: 1249 bne t1, zero, 2f # is FS zero? 1250 bne t2, zero, 1f 1251 beq t3, zero, result_fs_s # result=0 12521: 1253 jal renorm_fs_d 1254 subu t1, t1, 3 # correct exp for shift below 1255 b 3f 12562: 1257 subu t1, t1, DEXP_BIAS # unbias exponent 1258 or t2, t2, DIMPL_ONE # add implied one bit 12593: 1260 sll t2, t2, 3 # convert D fraction to S 1261 srl t8, t3, 32 - 3 1262 or t2, t2, t8 1263 sll t8, t3, 3 1264 b norm_noshift_s 1265 1266/* 1267 * Convert integer to single. 1268 */ 1269cvt_s_w: 1270 jal get_fs_int 1271 bne t2, zero, 1f # check for zero 1272 move t1, zero 1273 b result_fs_s 1274/* 1275 * Find out how many leading zero bits are in t2 and put in t9. 1276 */ 12771: 1278 move v0, t2 1279 move t9, zero 1280 srl v1, v0, 16 1281 bne v1, zero, 1f 1282 addu t9, 16 1283 sll v0, 16 12841: 1285 srl v1, v0, 24 1286 bne v1, zero, 1f 1287 addu t9, 8 1288 sll v0, 8 12891: 1290 srl v1, v0, 28 1291 bne v1, zero, 1f 1292 addu t9, 4 1293 sll v0, 4 12941: 1295 srl v1, v0, 30 1296 bne v1, zero, 1f 1297 addu t9, 2 1298 sll v0, 2 12991: 1300 srl v1, v0, 31 1301 bne v1, zero, 1f 1302 addu t9, 1 1303/* 1304 * Now shift t2 the correct number of bits. 1305 */ 13061: 1307 subu t9, t9, SLEAD_ZEROS # don't count leading zeros 1308 li t1, 23 # init exponent 1309 subu t1, t1, t9 # compute exponent 1310 beq t9, zero, 1f 1311 li v0, 32 1312 blt t9, zero, 2f # if shift < 0, shift right 1313 subu v0, v0, t9 1314 sll t2, t2, t9 # shift left 13151: 1316 add t1, t1, SEXP_BIAS # bias exponent 1317 and t2, t2, ~SIMPL_ONE # clear implied one bit 1318 b result_fs_s 13192: 1320 negu t9 # shift right by t9 1321 subu v0, v0, t9 1322 sll t8, t2, v0 # save bits shifted out 1323 srl t2, t2, t9 1324 b norm_noshift_s 1325 1326/* 1327 * Convert single to double. 1328 */ 1329cvt_d_s: 1330 jal get_fs_s 1331 bne t1, SEXP_INF, 1f # is FS an infinity? 1332 li t1, DEXP_INF # convert to double 1333 b 2f 13341: 1335 bne t1, zero, 2f # is FS denormalized or zero? 1336 beq t2, zero, result_fs_d # is FS zero? 1337 jal renorm_fs_s 1338 move t8, zero 1339 b norm_d 13402: 1341 addu t1, t1, DEXP_BIAS - SEXP_BIAS # bias exponent correctly 1342 sll t3, t2, 32 - 3 # convert S fraction to D 1343 srl t2, t2, 3 1344 b result_fs_d 1345 1346/* 1347 * Convert integer to double. 1348 */ 1349cvt_d_w: 1350 jal get_fs_int 1351 bne t2, zero, 1f # check for zero 1352 move t1, zero # result=0 1353 move t3, zero 1354 b result_fs_d 1355/* 1356 * Find out how many leading zero bits are in t2 and put in t9. 1357 */ 13581: 1359 move v0, t2 1360 move t9, zero 1361 srl v1, v0, 16 1362 bne v1, zero, 1f 1363 addu t9, 16 1364 sll v0, 16 13651: 1366 srl v1, v0, 24 1367 bne v1, zero, 1f 1368 addu t9, 8 1369 sll v0, 8 13701: 1371 srl v1, v0, 28 1372 bne v1, zero, 1f 1373 addu t9, 4 1374 sll v0, 4 13751: 1376 srl v1, v0, 30 1377 bne v1, zero, 1f 1378 addu t9, 2 1379 sll v0, 2 13801: 1381 srl v1, v0, 31 1382 bne v1, zero, 1f 1383 addu t9, 1 1384/* 1385 * Now shift t2 the correct number of bits. 1386 */ 13871: 1388 subu t9, t9, DLEAD_ZEROS # don't count leading zeros 1389 li t1, DEXP_BIAS + 23 # init exponent 1390 subu t1, t1, t9 # compute exponent 1391 beq t9, zero, 1f 1392 li v0, 32 1393 blt t9, zero, 2f # if shift < 0, shift right 1394 subu v0, v0, t9 1395 sll t2, t2, t9 # shift left 13961: 1397 and t2, t2, ~DIMPL_ONE # clear implied one bit 1398 b result_fs_d 13992: 1400 negu t9 # shift right by t9 1401 subu v0, v0, t9 1402 sll t3, t2, v0 1403 srl t2, t2, t9 1404 and t2, t2, ~DIMPL_ONE # clear implied one bit 1405 b result_fs_d 1406 1407/* 1408 * Convert single to integer. 1409 */ 1410cvt_w_s: 1411 jal get_fs_s 1412 bne t1, SEXP_INF, 1f # is FS an infinity? 1413 bne t2, zero, invalid_w # invalid conversion 14141: 1415 bne t1, zero, 1f # is FS zero? 1416 beq t2, zero, result_fs_w # result is zero 1417 move t2, zero # result is an inexact zero 1418 b inexact_w 14191: 1420 subu t1, t1, SEXP_BIAS # unbias exponent 1421 or t2, t2, SIMPL_ONE # add implied one bit 1422 sll t3, t2, 32 - 3 # convert S fraction to D 1423 srl t2, t2, 3 1424 b cvt_w 1425 1426/* 1427 * Convert double to integer. 1428 */ 1429cvt_w_d: 1430 jal get_fs_d 1431 bne t1, DEXP_INF, 1f # is FS an infinity? 1432 bne t2, zero, invalid_w # invalid conversion 1433 bne t3, zero, invalid_w # invalid conversion 14341: 1435 bne t1, zero, 2f # is FS zero? 1436 bne t2, zero, 1f 1437 beq t3, zero, result_fs_w # result is zero 14381: 1439 move t2, zero # result is an inexact zero 1440 b inexact_w 14412: 1442 subu t1, t1, DEXP_BIAS # unbias exponent 1443 or t2, t2, DIMPL_ONE # add implied one bit 1444cvt_w: 1445 blt t1, WEXP_MIN, underflow_w # is exponent too small? 1446 li v0, WEXP_MAX+1 1447 bgt t1, v0, overflow_w # is exponent too large? 1448 bne t1, v0, 1f # special check for INT_MIN 1449 beq t0, zero, overflow_w # if positive, overflow 1450 bne t2, DIMPL_ONE, overflow_w 1451 bne t3, zero, overflow_w 1452 li t2, INT_MIN # result is INT_MIN 1453 b result_fs_w 14541: 1455 subu v0, t1, 20 # compute amount to shift 1456 beq v0, zero, 2f # is shift needed? 1457 li v1, 32 1458 blt v0, zero, 1f # if shift < 0, shift right 1459 subu v1, v1, v0 # shift left 1460 sll t2, t2, v0 1461 srl t9, t3, v1 # save bits shifted out of t3 1462 or t2, t2, t9 # and put into t2 1463 sll t3, t3, v0 # shift FS's fraction 1464 b 2f 14651: 1466 negu v0 # shift right by v0 1467 subu v1, v1, v0 1468 sll t8, t3, v1 # save bits shifted out 1469 sltu t8, zero, t8 # don't lose any one's 1470 srl t3, t3, v0 # shift FS's fraction 1471 or t3, t3, t8 1472 sll t9, t2, v1 # save bits shifted out of t2 1473 or t3, t3, t9 # and put into t3 1474 srl t2, t2, v0 1475/* 1476 * round result (t0 is sign, t2 is integer part, t3 is fractional part). 1477 */ 14782: 1479 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1480 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1481 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1482 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1483 beq t0, zero, 5f # if sign is positive, truncate 1484 b 2f 14851: 1486 bne t0, zero, 5f # if sign is negative, truncate 14872: 1488 beq t3, zero, 5f # if no fraction bits, continue 1489 addu t2, t2, 1 # add rounding bit 1490 blt t2, zero, overflow_w # overflow? 1491 b 5f 14923: 1493 li v0, GUARDBIT # load guard bit for rounding 1494 addu v0, v0, t3 # add remainder 1495 sltu v1, v0, t3 # compute carry out 1496 beq v1, zero, 4f # if no carry, continue 1497 addu t2, t2, 1 # add carry to result 1498 blt t2, zero, overflow_w # overflow? 14994: 1500 bne v0, zero, 5f # if rounded remainder is zero 1501 and t2, t2, ~1 # clear LSB (round to nearest) 15025: 1503 beq t0, zero, 1f # result positive? 1504 negu t2 # convert to negative integer 15051: 1506 beq t3, zero, result_fs_w # is result exact? 1507/* 1508 * Handle inexact exception. 1509 */ 1510inexact_w: 1511 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1512 and v0, a1, MACH_FPC_ENABLE_INEXACT 1513 bne v0, zero, fpe_trap 1514 ctc1 a1, MACH_FPC_CSR # save exceptions 1515 b result_fs_w 1516 1517/* 1518 * Conversions to integer which overflow will trap (if enabled), 1519 * or generate an inexact trap (if enabled), 1520 * or generate an invalid exception. 1521 */ 1522overflow_w: 1523 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1524 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1525 bne v0, zero, fpe_trap 1526 and v0, a1, MACH_FPC_ENABLE_INEXACT 1527 bne v0, zero, inexact_w # inexact traps enabled? 1528 b invalid_w 1529 1530/* 1531 * Conversions to integer which underflow will trap (if enabled), 1532 * or generate an inexact trap (if enabled), 1533 * or generate an invalid exception. 1534 */ 1535underflow_w: 1536 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1537 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1538 bne v0, zero, fpe_trap 1539 and v0, a1, MACH_FPC_ENABLE_INEXACT 1540 bne v0, zero, inexact_w # inexact traps enabled? 1541 b invalid_w 1542 1543/* 1544 * Compare single. 1545 */ 1546cmp_s: 1547 jal get_cmp_s 1548 bne t1, SEXP_INF, 1f # is FS an infinity? 1549 bne t2, zero, unordered # FS is a NAN 15501: 1551 bne t5, SEXP_INF, 2f # is FT an infinity? 1552 bne t6, zero, unordered # FT is a NAN 15532: 1554 sll t1, t1, 23 # reassemble exp & frac 1555 or t1, t1, t2 1556 sll t5, t5, 23 # reassemble exp & frac 1557 or t5, t5, t6 1558 beq t0, zero, 1f # is FS positive? 1559 negu t1 15601: 1561 beq t4, zero, 1f # is FT positive? 1562 negu t5 15631: 1564 li v0, COND_LESS 1565 blt t1, t5, test_cond # is FS < FT? 1566 li v0, COND_EQUAL 1567 beq t1, t5, test_cond # is FS == FT? 1568 move v0, zero # FS > FT 1569 b test_cond 1570 1571/* 1572 * Compare double. 1573 */ 1574cmp_d: 1575 jal get_cmp_d 1576 bne t1, DEXP_INF, 1f # is FS an infinity? 1577 bne t2, zero, unordered 1578 bne t3, zero, unordered # FS is a NAN 15791: 1580 bne t5, DEXP_INF, 2f # is FT an infinity? 1581 bne t6, zero, unordered 1582 bne t7, zero, unordered # FT is a NAN 15832: 1584 sll t1, t1, 20 # reassemble exp & frac 1585 or t1, t1, t2 1586 sll t5, t5, 20 # reassemble exp & frac 1587 or t5, t5, t6 1588 beq t0, zero, 1f # is FS positive? 1589 not t3 # negate t1,t3 1590 not t1 1591 addu t3, t3, 1 1592 seq v0, t3, zero # compute carry 1593 addu t1, t1, v0 15941: 1595 beq t4, zero, 1f # is FT positive? 1596 not t7 # negate t5,t7 1597 not t5 1598 addu t7, t7, 1 1599 seq v0, t7, zero # compute carry 1600 addu t5, t5, v0 16011: 1602 li v0, COND_LESS 1603 blt t1, t5, test_cond # is FS(MSW) < FT(MSW)? 1604 move v0, zero 1605 bne t1, t5, test_cond # is FS(MSW) > FT(MSW)? 1606 li v0, COND_LESS 1607 bltu t3, t7, test_cond # is FS(LSW) < FT(LSW)? 1608 li v0, COND_EQUAL 1609 beq t3, t7, test_cond # is FS(LSW) == FT(LSW)? 1610 move v0, zero # FS > FT 1611test_cond: 1612 and v0, v0, a0 # condition match instruction? 1613set_cond: 1614 bne v0, zero, 1f 1615 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1616 b 2f 16171: 1618 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16192: 1620 ctc1 a1, MACH_FPC_CSR # save condition bit 1621 b done 1622 1623unordered: 1624 and v0, a0, COND_UNORDERED # this cmp match unordered? 1625 bne v0, zero, 1f 1626 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1627 b 2f 16281: 1629 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16302: 1631 and v0, a0, COND_SIGNAL 1632 beq v0, zero, 1f # is this a signaling cmp? 1633 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 1634 and v0, a1, MACH_FPC_ENABLE_INVALID 1635 bne v0, zero, fpe_trap 16361: 1637 ctc1 a1, MACH_FPC_CSR # save condition bit 1638 b done 1639 1640/* 1641 * Determine the amount to shift the fraction in order to restore the 1642 * normalized position. After that, round and handle exceptions. 1643 */ 1644norm_s: 1645 move v0, t2 1646 move t9, zero # t9 = num of leading zeros 1647 bne t2, zero, 1f 1648 move v0, t8 1649 addu t9, 32 16501: 1651 srl v1, v0, 16 1652 bne v1, zero, 1f 1653 addu t9, 16 1654 sll v0, 16 16551: 1656 srl v1, v0, 24 1657 bne v1, zero, 1f 1658 addu t9, 8 1659 sll v0, 8 16601: 1661 srl v1, v0, 28 1662 bne v1, zero, 1f 1663 addu t9, 4 1664 sll v0, 4 16651: 1666 srl v1, v0, 30 1667 bne v1, zero, 1f 1668 addu t9, 2 1669 sll v0, 2 16701: 1671 srl v1, v0, 31 1672 bne v1, zero, 1f 1673 addu t9, 1 1674/* 1675 * Now shift t2,t8 the correct number of bits. 1676 */ 16771: 1678 subu t9, t9, SLEAD_ZEROS # don't count leading zeros 1679 subu t1, t1, t9 # adjust the exponent 1680 beq t9, zero, norm_noshift_s 1681 li v1, 32 1682 blt t9, zero, 1f # if shift < 0, shift right 1683 subu v1, v1, t9 1684 sll t2, t2, t9 # shift t2,t8 left 1685 srl v0, t8, v1 # save bits shifted out 1686 or t2, t2, v0 1687 sll t8, t8, t9 1688 b norm_noshift_s 16891: 1690 negu t9 # shift t2,t8 right by t9 1691 subu v1, v1, t9 1692 sll v0, t8, v1 # save bits shifted out 1693 sltu v0, zero, v0 # be sure to save any one bits 1694 srl t8, t8, t9 1695 or t8, t8, v0 1696 sll v0, t2, v1 # save bits shifted out 1697 or t8, t8, v0 1698 srl t2, t2, t9 1699norm_noshift_s: 1700 move t5, t1 # save unrounded exponent 1701 move t6, t2 # save unrounded fraction 1702 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1703 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1704 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1705 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1706 beq t0, zero, 5f # if sign is positive, truncate 1707 b 2f 17081: 1709 bne t0, zero, 5f # if sign is negative, truncate 17102: 1711 beq t8, zero, 5f # if exact, continue 1712 addu t2, t2, 1 # add rounding bit 1713 bne t2, SIMPL_ONE<<1, 5f # need to adjust exponent? 1714 addu t1, t1, 1 # adjust exponent 1715 srl t2, t2, 1 # renormalize fraction 1716 b 5f 17173: 1718 li v0, GUARDBIT # load guard bit for rounding 1719 addu v0, v0, t8 # add remainder 1720 sltu v1, v0, t8 # compute carry out 1721 beq v1, zero, 4f # if no carry, continue 1722 addu t2, t2, 1 # add carry to result 1723 bne t2, SIMPL_ONE<<1, 4f # need to adjust exponent? 1724 addu t1, t1, 1 # adjust exponent 1725 srl t2, t2, 1 # renormalize fraction 17264: 1727 bne v0, zero, 5f # if rounded remainder is zero 1728 and t2, t2, ~1 # clear LSB (round to nearest) 17295: 1730 bgt t1, SEXP_MAX, overflow_s # overflow? 1731 blt t1, SEXP_MIN, underflow_s # underflow? 1732 bne t8, zero, inexact_s # is result inexact? 1733 addu t1, t1, SEXP_BIAS # bias exponent 1734 and t2, t2, ~SIMPL_ONE # clear implied one bit 1735 b result_fs_s 1736 1737/* 1738 * Handle inexact exception. 1739 */ 1740inexact_s: 1741 addu t1, t1, SEXP_BIAS # bias exponent 1742 and t2, t2, ~SIMPL_ONE # clear implied one bit 1743inexact_nobias_s: 1744 jal set_fd_s # save result 1745 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1746 and v0, a1, MACH_FPC_ENABLE_INEXACT 1747 bne v0, zero, fpe_trap 1748 ctc1 a1, MACH_FPC_CSR # save exceptions 1749 b done 1750 1751/* 1752 * Overflow will trap (if enabled), 1753 * or generate an inexact trap (if enabled), 1754 * or generate an infinity. 1755 */ 1756overflow_s: 1757 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1758 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1759 beq v0, zero, 1f 1760 subu t1, t1, 192 # bias exponent 1761 and t2, t2, ~SIMPL_ONE # clear implied one bit 1762 jal set_fd_s # save result 1763 b fpe_trap 17641: 1765 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1766 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1767 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 1768 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 1769 bne t0, zero, 3f 17701: 1771 li t1, SEXP_MAX # result is max finite 1772 li t2, 0x007fffff 1773 b inexact_s 17742: 1775 bne t0, zero, 1b 17763: 1777 li t1, SEXP_MAX + 1 # result is infinity 1778 move t2, zero 1779 b inexact_s 1780 1781/* 1782 * In this implementation, "tininess" is detected "after rounding" and 1783 * "loss of accuracy" is detected as "an inexact result". 1784 */ 1785underflow_s: 1786 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1787 beq v0, zero, 1f 1788/* 1789 * Underflow is enabled so compute the result and trap. 1790 */ 1791 addu t1, t1, 192 # bias exponent 1792 and t2, t2, ~SIMPL_ONE # clear implied one bit 1793 jal set_fd_s # save result 1794 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1795 b fpe_trap 1796/* 1797 * Underflow is not enabled so compute the result, 1798 * signal inexact result (if it is) and trap (if enabled). 1799 */ 18001: 1801 move t1, t5 # get unrounded exponent 1802 move t2, t6 # get unrounded fraction 1803 li t9, SEXP_MIN # compute shift amount 1804 subu t9, t9, t1 # shift t2,t8 right by t9 1805 blt t9, SFRAC_BITS+2, 3f # shift all the bits out? 1806 move t1, zero # result is inexact zero 1807 move t2, zero 1808 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1809/* 1810 * Now round the zero result. 1811 * Only need to worry about rounding to +- infinity when the sign matches. 1812 */ 1813 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1814 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_s # round to nearest 1815 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_s # round to zero 1816 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1817 beq t0, zero, inexact_nobias_s # if sign is positive, truncate 1818 b 2f 18191: 1820 bne t0, zero, inexact_nobias_s # if sign is negative, truncate 18212: 1822 addu t2, t2, 1 # add rounding bit 1823 b inexact_nobias_s 18243: 1825 li v1, 32 1826 subu v1, v1, t9 1827 sltu v0, zero, t8 # be sure to save any one bits 1828 sll t8, t2, v1 # save bits shifted out 1829 or t8, t8, v0 # include sticky bits 1830 srl t2, t2, t9 1831/* 1832 * Now round the denormalized result. 1833 */ 1834 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1835 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1836 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1837 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1838 beq t0, zero, 5f # if sign is positive, truncate 1839 b 2f 18401: 1841 bne t0, zero, 5f # if sign is negative, truncate 18422: 1843 beq t8, zero, 5f # if exact, continue 1844 addu t2, t2, 1 # add rounding bit 1845 b 5f 18463: 1847 li v0, GUARDBIT # load guard bit for rounding 1848 addu v0, v0, t8 # add remainder 1849 sltu v1, v0, t8 # compute carry out 1850 beq v1, zero, 4f # if no carry, continue 1851 addu t2, t2, 1 # add carry to result 18524: 1853 bne v0, zero, 5f # if rounded remainder is zero 1854 and t2, t2, ~1 # clear LSB (round to nearest) 18555: 1856 move t1, zero # denorm or zero exponent 1857 jal set_fd_s # save result 1858 beq t8, zero, done # check for exact result 1859 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1860 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1861 and v0, a1, MACH_FPC_ENABLE_INEXACT 1862 bne v0, zero, fpe_trap 1863 ctc1 a1, MACH_FPC_CSR # save exceptions 1864 b done 1865 1866/* 1867 * Determine the amount to shift the fraction in order to restore the 1868 * normalized position. After that, round and handle exceptions. 1869 */ 1870norm_d: 1871 move v0, t2 1872 move t9, zero # t9 = num of leading zeros 1873 bne t2, zero, 1f 1874 move v0, t3 1875 addu t9, 32 1876 bne t3, zero, 1f 1877 move v0, t8 1878 addu t9, 32 18791: 1880 srl v1, v0, 16 1881 bne v1, zero, 1f 1882 addu t9, 16 1883 sll v0, 16 18841: 1885 srl v1, v0, 24 1886 bne v1, zero, 1f 1887 addu t9, 8 1888 sll v0, 8 18891: 1890 srl v1, v0, 28 1891 bne v1, zero, 1f 1892 addu t9, 4 1893 sll v0, 4 18941: 1895 srl v1, v0, 30 1896 bne v1, zero, 1f 1897 addu t9, 2 1898 sll v0, 2 18991: 1900 srl v1, v0, 31 1901 bne v1, zero, 1f 1902 addu t9, 1 1903/* 1904 * Now shift t2,t3,t8 the correct number of bits. 1905 */ 19061: 1907 subu t9, t9, DLEAD_ZEROS # don't count leading zeros 1908 subu t1, t1, t9 # adjust the exponent 1909 beq t9, zero, norm_noshift_d 1910 li v1, 32 1911 blt t9, zero, 2f # if shift < 0, shift right 1912 blt t9, v1, 1f # shift by < 32? 1913 subu t9, t9, v1 # shift by >= 32 1914 subu v1, v1, t9 1915 sll t2, t3, t9 # shift left by t9 1916 srl v0, t8, v1 # save bits shifted out 1917 or t2, t2, v0 1918 sll t3, t8, t9 1919 move t8, zero 1920 b norm_noshift_d 19211: 1922 subu v1, v1, t9 1923 sll t2, t2, t9 # shift left by t9 1924 srl v0, t3, v1 # save bits shifted out 1925 or t2, t2, v0 1926 sll t3, t3, t9 1927 srl v0, t8, v1 # save bits shifted out 1928 or t3, t3, v0 1929 sll t8, t8, t9 1930 b norm_noshift_d 19312: 1932 negu t9 # shift right by t9 1933 subu v1, v1, t9 # (known to be < 32 bits) 1934 sll v0, t8, v1 # save bits shifted out 1935 sltu v0, zero, v0 # be sure to save any one bits 1936 srl t8, t8, t9 1937 or t8, t8, v0 1938 sll v0, t3, v1 # save bits shifted out 1939 or t8, t8, v0 1940 srl t3, t3, t9 1941 sll v0, t2, v1 # save bits shifted out 1942 or t3, t3, v0 1943 srl t2, t2, t9 1944norm_noshift_d: 1945 move t5, t1 # save unrounded exponent 1946 move t6, t2 # save unrounded fraction (MS) 1947 move t7, t3 # save unrounded fraction (LS) 1948 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1949 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1950 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1951 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1952 beq t0, zero, 5f # if sign is positive, truncate 1953 b 2f 19541: 1955 bne t0, zero, 5f # if sign is negative, truncate 19562: 1957 beq t8, zero, 5f # if exact, continue 1958 addu t3, t3, 1 # add rounding bit 1959 bne t3, zero, 5f # branch if no carry 1960 addu t2, t2, 1 # add carry 1961 bne t2, DIMPL_ONE<<1, 5f # need to adjust exponent? 1962 addu t1, t1, 1 # adjust exponent 1963 srl t2, t2, 1 # renormalize fraction 1964 b 5f 19653: 1966 li v0, GUARDBIT # load guard bit for rounding 1967 addu v0, v0, t8 # add remainder 1968 sltu v1, v0, t8 # compute carry out 1969 beq v1, zero, 4f # branch if no carry 1970 addu t3, t3, 1 # add carry 1971 bne t3, zero, 4f # branch if no carry 1972 addu t2, t2, 1 # add carry to result 1973 bne t2, DIMPL_ONE<<1, 4f # need to adjust exponent? 1974 addu t1, t1, 1 # adjust exponent 1975 srl t2, t2, 1 # renormalize fraction 19764: 1977 bne v0, zero, 5f # if rounded remainder is zero 1978 and t3, t3, ~1 # clear LSB (round to nearest) 19795: 1980 bgt t1, DEXP_MAX, overflow_d # overflow? 1981 blt t1, DEXP_MIN, underflow_d # underflow? 1982 bne t8, zero, inexact_d # is result inexact? 1983 addu t1, t1, DEXP_BIAS # bias exponent 1984 and t2, t2, ~DIMPL_ONE # clear implied one bit 1985 b result_fs_d 1986 1987/* 1988 * Handle inexact exception. 1989 */ 1990inexact_d: 1991 addu t1, t1, DEXP_BIAS # bias exponent 1992 and t2, t2, ~DIMPL_ONE # clear implied one bit 1993inexact_nobias_d: 1994 jal set_fd_d # save result 1995 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1996 and v0, a1, MACH_FPC_ENABLE_INEXACT 1997 bne v0, zero, fpe_trap 1998 ctc1 a1, MACH_FPC_CSR # save exceptions 1999 b done 2000 2001/* 2002 * Overflow will trap (if enabled), 2003 * or generate an inexact trap (if enabled), 2004 * or generate an infinity. 2005 */ 2006overflow_d: 2007 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 2008 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 2009 beq v0, zero, 1f 2010 subu t1, t1, 1536 # bias exponent 2011 and t2, t2, ~DIMPL_ONE # clear implied one bit 2012 jal set_fd_d # save result 2013 b fpe_trap 20141: 2015 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2016 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2017 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 2018 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 2019 bne t0, zero, 3f 20201: 2021 li t1, DEXP_MAX # result is max finite 2022 li t2, 0x000fffff 2023 li t3, 0xffffffff 2024 b inexact_d 20252: 2026 bne t0, zero, 1b 20273: 2028 li t1, DEXP_MAX + 1 # result is infinity 2029 move t2, zero 2030 move t3, zero 2031 b inexact_d 2032 2033/* 2034 * In this implementation, "tininess" is detected "after rounding" and 2035 * "loss of accuracy" is detected as "an inexact result". 2036 */ 2037underflow_d: 2038 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 2039 beq v0, zero, 1f 2040/* 2041 * Underflow is enabled so compute the result and trap. 2042 */ 2043 addu t1, t1, 1536 # bias exponent 2044 and t2, t2, ~DIMPL_ONE # clear implied one bit 2045 jal set_fd_d # save result 2046 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2047 b fpe_trap 2048/* 2049 * Underflow is not enabled so compute the result, 2050 * signal inexact result (if it is) and trap (if enabled). 2051 */ 20521: 2053 move t1, t5 # get unrounded exponent 2054 move t2, t6 # get unrounded fraction (MS) 2055 move t3, t7 # get unrounded fraction (LS) 2056 li t9, DEXP_MIN # compute shift amount 2057 subu t9, t9, t1 # shift t2,t8 right by t9 2058 blt t9, DFRAC_BITS+2, 3f # shift all the bits out? 2059 move t1, zero # result is inexact zero 2060 move t2, zero 2061 move t3, zero 2062 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2063/* 2064 * Now round the zero result. 2065 * Only need to worry about rounding to +- infinity when the sign matches. 2066 */ 2067 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2068 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_d # round to nearest 2069 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_d # round to zero 2070 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2071 beq t0, zero, inexact_nobias_d # if sign is positive, truncate 2072 b 2f 20731: 2074 bne t0, zero, inexact_nobias_d # if sign is negative, truncate 20752: 2076 addu t3, t3, 1 # add rounding bit 2077 b inexact_nobias_d 20783: 2079 li v1, 32 2080 blt t9, v1, 1f # shift by < 32? 2081 subu t9, t9, v1 # shift right by >= 32 2082 subu v1, v1, t9 2083 sltu v0, zero, t8 # be sure to save any one bits 2084 sll t8, t2, v1 # save bits shifted out 2085 or t8, t8, v0 # include sticky bits 2086 srl t3, t2, t9 2087 move t2, zero 2088 b 2f 20891: 2090 subu v1, v1, t9 # shift right by t9 2091 sltu v0, zero, t8 # be sure to save any one bits 2092 sll t8, t3, v1 # save bits shifted out 2093 or t8, t8, v0 # include sticky bits 2094 srl t3, t3, t9 2095 sll v0, t2, v1 # save bits shifted out 2096 or t3, t3, v0 2097 srl t2, t2, t9 2098/* 2099 * Now round the denormalized result. 2100 */ 21012: 2102 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2103 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2104 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 2105 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2106 beq t0, zero, 5f # if sign is positive, truncate 2107 b 2f 21081: 2109 bne t0, zero, 5f # if sign is negative, truncate 21102: 2111 beq t8, zero, 5f # if exact, continue 2112 addu t3, t3, 1 # add rounding bit 2113 bne t3, zero, 5f # if no carry, continue 2114 addu t2, t2, 1 # add carry 2115 b 5f 21163: 2117 li v0, GUARDBIT # load guard bit for rounding 2118 addu v0, v0, t8 # add remainder 2119 sltu v1, v0, t8 # compute carry out 2120 beq v1, zero, 4f # if no carry, continue 2121 addu t3, t3, 1 # add rounding bit 2122 bne t3, zero, 4f # if no carry, continue 2123 addu t2, t2, 1 # add carry 21244: 2125 bne v0, zero, 5f # if rounded remainder is zero 2126 and t3, t3, ~1 # clear LSB (round to nearest) 21275: 2128 move t1, zero # denorm or zero exponent 2129 jal set_fd_d # save result 2130 beq t8, zero, done # check for exact result 2131 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2132 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 2133 and v0, a1, MACH_FPC_ENABLE_INEXACT 2134 bne v0, zero, fpe_trap 2135 ctc1 a1, MACH_FPC_CSR # save exceptions 2136 b done 2137 2138/* 2139 * Signal an invalid operation if the trap is enabled; otherwise, 2140 * the result is a quiet NAN. 2141 */ 2142invalid_s: # trap invalid operation 2143 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2144 and v0, a1, MACH_FPC_ENABLE_INVALID 2145 bne v0, zero, fpe_trap 2146 ctc1 a1, MACH_FPC_CSR # save exceptions 2147 move t0, zero # result is a quiet NAN 2148 li t1, SEXP_INF 2149 li t2, SQUIET_NAN 2150 jal set_fd_s # save result (in t0,t1,t2) 2151 b done 2152 2153/* 2154 * Signal an invalid operation if the trap is enabled; otherwise, 2155 * the result is a quiet NAN. 2156 */ 2157invalid_d: # trap invalid operation 2158 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2159 and v0, a1, MACH_FPC_ENABLE_INVALID 2160 bne v0, zero, fpe_trap 2161 ctc1 a1, MACH_FPC_CSR # save exceptions 2162 move t0, zero # result is a quiet NAN 2163 li t1, DEXP_INF 2164 li t2, DQUIET_NAN0 2165 li t3, DQUIET_NAN1 2166 jal set_fd_d # save result (in t0,t1,t2,t3) 2167 b done 2168 2169/* 2170 * Signal an invalid operation if the trap is enabled; otherwise, 2171 * the result is INT_MAX or INT_MIN. 2172 */ 2173invalid_w: # trap invalid operation 2174 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2175 and v0, a1, MACH_FPC_ENABLE_INVALID 2176 bne v0, zero, fpe_trap 2177 ctc1 a1, MACH_FPC_CSR # save exceptions 2178 bne t0, zero, 1f 2179 li t2, INT_MAX # result is INT_MAX 2180 b result_fs_w 21811: 2182 li t2, INT_MIN # result is INT_MIN 2183 b result_fs_w 2184 2185/* 2186 * Trap if the hardware should have handled this case. 2187 */ 2188fpe_trap: 2189 move a2, a1 # code = FP CSR 2190 ctc1 a1, MACH_FPC_CSR # save exceptions 2191 break 0 2192 2193/* 2194 * Send an illegal instruction signal to the current process. 2195 */ 2196ill: 2197 ctc1 a1, MACH_FPC_CSR # save exceptions 2198 move a2, a0 # code = FP instruction 2199 break 0 2200 2201result_ft_s: 2202 move t0, t4 # result is FT 2203 move t1, t5 2204 move t2, t6 2205result_fs_s: # result is FS 2206 jal set_fd_s # save result (in t0,t1,t2) 2207 b done 2208 2209result_fs_w: 2210 jal set_fd_word # save result (in t2) 2211 b done 2212 2213result_ft_d: 2214 move t0, t4 # result is FT 2215 move t1, t5 2216 move t2, t6 2217 move t3, t7 2218result_fs_d: # result is FS 2219 jal set_fd_d # save result (in t0,t1,t2,t3) 2220 2221done: 2222 lw ra, STAND_RA_OFFSET(sp) 2223 addu sp, sp, STAND_FRAME_SIZE 2224 j ra 2225END(MachEmulateFP) 2226 2227/*---------------------------------------------------------------------------- 2228 * get_fs_int -- 2229 * 2230 * Read (integer) the FS register (bits 15-11). 2231 * This is an internal routine used by MachEmulateFP only. 2232 * 2233 * Results: 2234 * t0 contains the sign 2235 * t2 contains the fraction 2236 * 2237 *---------------------------------------------------------------------------- 2238 */ 2239LEAF(get_fs_int) 2240 srl a3, a0, 12 - 2 # get FS field (even regs only) 2241 and a3, a3, 0xF << 2 # mask FS field 2242 lw a3, get_fs_int_tbl(a3) # switch on register number 2243 j a3 2244 2245 .rdata 2246get_fs_int_tbl: 2247 .word get_fs_int_f0 2248 .word get_fs_int_f2 2249 .word get_fs_int_f4 2250 .word get_fs_int_f6 2251 .word get_fs_int_f8 2252 .word get_fs_int_f10 2253 .word get_fs_int_f12 2254 .word get_fs_int_f14 2255 .word get_fs_int_f16 2256 .word get_fs_int_f18 2257 .word get_fs_int_f20 2258 .word get_fs_int_f22 2259 .word get_fs_int_f24 2260 .word get_fs_int_f26 2261 .word get_fs_int_f28 2262 .word get_fs_int_f30 2263 .text 2264 2265get_fs_int_f0: 2266 mfc1 t2, $f0 2267 b get_fs_int_done 2268get_fs_int_f2: 2269 mfc1 t2, $f2 2270 b get_fs_int_done 2271get_fs_int_f4: 2272 mfc1 t2, $f4 2273 b get_fs_int_done 2274get_fs_int_f6: 2275 mfc1 t2, $f6 2276 b get_fs_int_done 2277get_fs_int_f8: 2278 mfc1 t2, $f8 2279 b get_fs_int_done 2280get_fs_int_f10: 2281 mfc1 t2, $f10 2282 b get_fs_int_done 2283get_fs_int_f12: 2284 mfc1 t2, $f12 2285 b get_fs_int_done 2286get_fs_int_f14: 2287 mfc1 t2, $f14 2288 b get_fs_int_done 2289get_fs_int_f16: 2290 mfc1 t2, $f16 2291 b get_fs_int_done 2292get_fs_int_f18: 2293 mfc1 t2, $f18 2294 b get_fs_int_done 2295get_fs_int_f20: 2296 mfc1 t2, $f20 2297 b get_fs_int_done 2298get_fs_int_f22: 2299 mfc1 t2, $f22 2300 b get_fs_int_done 2301get_fs_int_f24: 2302 mfc1 t2, $f24 2303 b get_fs_int_done 2304get_fs_int_f26: 2305 mfc1 t2, $f26 2306 b get_fs_int_done 2307get_fs_int_f28: 2308 mfc1 t2, $f28 2309 b get_fs_int_done 2310get_fs_int_f30: 2311 mfc1 t2, $f30 2312get_fs_int_done: 2313 srl t0, t2, 31 # init the sign bit 2314 bge t2, zero, 1f 2315 negu t2 23161: 2317 j ra 2318END(get_fs_int) 2319 2320/*---------------------------------------------------------------------------- 2321 * get_ft_fs_s -- 2322 * 2323 * Read (single precision) the FT register (bits 20-16) and 2324 * the FS register (bits 15-11) and break up into fields. 2325 * This is an internal routine used by MachEmulateFP only. 2326 * 2327 * Results: 2328 * t0 contains the FS sign 2329 * t1 contains the FS (biased) exponent 2330 * t2 contains the FS fraction 2331 * t4 contains the FT sign 2332 * t5 contains the FT (biased) exponent 2333 * t6 contains the FT fraction 2334 * 2335 *---------------------------------------------------------------------------- 2336 */ 2337LEAF(get_ft_fs_s) 2338 srl a3, a0, 17 - 2 # get FT field (even regs only) 2339 and a3, a3, 0xF << 2 # mask FT field 2340 lw a3, get_ft_s_tbl(a3) # switch on register number 2341 j a3 2342 2343 .rdata 2344get_ft_s_tbl: 2345 .word get_ft_s_f0 2346 .word get_ft_s_f2 2347 .word get_ft_s_f4 2348 .word get_ft_s_f6 2349 .word get_ft_s_f8 2350 .word get_ft_s_f10 2351 .word get_ft_s_f12 2352 .word get_ft_s_f14 2353 .word get_ft_s_f16 2354 .word get_ft_s_f18 2355 .word get_ft_s_f20 2356 .word get_ft_s_f22 2357 .word get_ft_s_f24 2358 .word get_ft_s_f26 2359 .word get_ft_s_f28 2360 .word get_ft_s_f30 2361 .text 2362 2363get_ft_s_f0: 2364 mfc1 t4, $f0 2365 b get_ft_s_done 2366get_ft_s_f2: 2367 mfc1 t4, $f2 2368 b get_ft_s_done 2369get_ft_s_f4: 2370 mfc1 t4, $f4 2371 b get_ft_s_done 2372get_ft_s_f6: 2373 mfc1 t4, $f6 2374 b get_ft_s_done 2375get_ft_s_f8: 2376 mfc1 t4, $f8 2377 b get_ft_s_done 2378get_ft_s_f10: 2379 mfc1 t4, $f10 2380 b get_ft_s_done 2381get_ft_s_f12: 2382 mfc1 t4, $f12 2383 b get_ft_s_done 2384get_ft_s_f14: 2385 mfc1 t4, $f14 2386 b get_ft_s_done 2387get_ft_s_f16: 2388 mfc1 t4, $f16 2389 b get_ft_s_done 2390get_ft_s_f18: 2391 mfc1 t4, $f18 2392 b get_ft_s_done 2393get_ft_s_f20: 2394 mfc1 t4, $f20 2395 b get_ft_s_done 2396get_ft_s_f22: 2397 mfc1 t4, $f22 2398 b get_ft_s_done 2399get_ft_s_f24: 2400 mfc1 t4, $f24 2401 b get_ft_s_done 2402get_ft_s_f26: 2403 mfc1 t4, $f26 2404 b get_ft_s_done 2405get_ft_s_f28: 2406 mfc1 t4, $f28 2407 b get_ft_s_done 2408get_ft_s_f30: 2409 mfc1 t4, $f30 2410get_ft_s_done: 2411 srl t5, t4, 23 # get exponent 2412 and t5, t5, 0xFF 2413 and t6, t4, 0x7FFFFF # get fraction 2414 srl t4, t4, 31 # get sign 2415 bne t5, SEXP_INF, 1f # is it a signaling NAN? 2416 and v0, t6, SSIGNAL_NAN 2417 bne v0, zero, invalid_s 24181: 2419 /* fall through to get FS */ 2420 2421/*---------------------------------------------------------------------------- 2422 * get_fs_s -- 2423 * 2424 * Read (single precision) the FS register (bits 15-11) and 2425 * break up into fields. 2426 * This is an internal routine used by MachEmulateFP only. 2427 * 2428 * Results: 2429 * t0 contains the sign 2430 * t1 contains the (biased) exponent 2431 * t2 contains the fraction 2432 * 2433 *---------------------------------------------------------------------------- 2434 */ 2435ALEAF(get_fs_s) 2436 srl a3, a0, 12 - 2 # get FS field (even regs only) 2437 and a3, a3, 0xF << 2 # mask FS field 2438 lw a3, get_fs_s_tbl(a3) # switch on register number 2439 j a3 2440 2441 .rdata 2442get_fs_s_tbl: 2443 .word get_fs_s_f0 2444 .word get_fs_s_f2 2445 .word get_fs_s_f4 2446 .word get_fs_s_f6 2447 .word get_fs_s_f8 2448 .word get_fs_s_f10 2449 .word get_fs_s_f12 2450 .word get_fs_s_f14 2451 .word get_fs_s_f16 2452 .word get_fs_s_f18 2453 .word get_fs_s_f20 2454 .word get_fs_s_f22 2455 .word get_fs_s_f24 2456 .word get_fs_s_f26 2457 .word get_fs_s_f28 2458 .word get_fs_s_f30 2459 .text 2460 2461get_fs_s_f0: 2462 mfc1 t0, $f0 2463 b get_fs_s_done 2464get_fs_s_f2: 2465 mfc1 t0, $f2 2466 b get_fs_s_done 2467get_fs_s_f4: 2468 mfc1 t0, $f4 2469 b get_fs_s_done 2470get_fs_s_f6: 2471 mfc1 t0, $f6 2472 b get_fs_s_done 2473get_fs_s_f8: 2474 mfc1 t0, $f8 2475 b get_fs_s_done 2476get_fs_s_f10: 2477 mfc1 t0, $f10 2478 b get_fs_s_done 2479get_fs_s_f12: 2480 mfc1 t0, $f12 2481 b get_fs_s_done 2482get_fs_s_f14: 2483 mfc1 t0, $f14 2484 b get_fs_s_done 2485get_fs_s_f16: 2486 mfc1 t0, $f16 2487 b get_fs_s_done 2488get_fs_s_f18: 2489 mfc1 t0, $f18 2490 b get_fs_s_done 2491get_fs_s_f20: 2492 mfc1 t0, $f20 2493 b get_fs_s_done 2494get_fs_s_f22: 2495 mfc1 t0, $f22 2496 b get_fs_s_done 2497get_fs_s_f24: 2498 mfc1 t0, $f24 2499 b get_fs_s_done 2500get_fs_s_f26: 2501 mfc1 t0, $f26 2502 b get_fs_s_done 2503get_fs_s_f28: 2504 mfc1 t0, $f28 2505 b get_fs_s_done 2506get_fs_s_f30: 2507 mfc1 t0, $f30 2508get_fs_s_done: 2509 srl t1, t0, 23 # get exponent 2510 and t1, t1, 0xFF 2511 and t2, t0, 0x7FFFFF # get fraction 2512 srl t0, t0, 31 # get sign 2513 bne t1, SEXP_INF, 1f # is it a signaling NAN? 2514 and v0, t2, SSIGNAL_NAN 2515 bne v0, zero, invalid_s 25161: 2517 j ra 2518END(get_ft_fs_s) 2519 2520/*---------------------------------------------------------------------------- 2521 * get_ft_fs_d -- 2522 * 2523 * Read (double precision) the FT register (bits 20-16) and 2524 * the FS register (bits 15-11) and break up into fields. 2525 * This is an internal routine used by MachEmulateFP only. 2526 * 2527 * Results: 2528 * t0 contains the FS sign 2529 * t1 contains the FS (biased) exponent 2530 * t2 contains the FS fraction 2531 * t3 contains the FS remaining fraction 2532 * t4 contains the FT sign 2533 * t5 contains the FT (biased) exponent 2534 * t6 contains the FT fraction 2535 * t7 contains the FT remaining fraction 2536 * 2537 *---------------------------------------------------------------------------- 2538 */ 2539LEAF(get_ft_fs_d) 2540 srl a3, a0, 17 - 2 # get FT field (even regs only) 2541 and a3, a3, 0xF << 2 # mask FT field 2542 lw a3, get_ft_d_tbl(a3) # switch on register number 2543 j a3 2544 2545 .rdata 2546get_ft_d_tbl: 2547 .word get_ft_d_f0 2548 .word get_ft_d_f2 2549 .word get_ft_d_f4 2550 .word get_ft_d_f6 2551 .word get_ft_d_f8 2552 .word get_ft_d_f10 2553 .word get_ft_d_f12 2554 .word get_ft_d_f14 2555 .word get_ft_d_f16 2556 .word get_ft_d_f18 2557 .word get_ft_d_f20 2558 .word get_ft_d_f22 2559 .word get_ft_d_f24 2560 .word get_ft_d_f26 2561 .word get_ft_d_f28 2562 .word get_ft_d_f30 2563 .text 2564 2565get_ft_d_f0: 2566 mfc1 t7, $f0 2567 mfc1 t4, $f1 2568 b get_ft_d_done 2569get_ft_d_f2: 2570 mfc1 t7, $f2 2571 mfc1 t4, $f3 2572 b get_ft_d_done 2573get_ft_d_f4: 2574 mfc1 t7, $f4 2575 mfc1 t4, $f5 2576 b get_ft_d_done 2577get_ft_d_f6: 2578 mfc1 t7, $f6 2579 mfc1 t4, $f7 2580 b get_ft_d_done 2581get_ft_d_f8: 2582 mfc1 t7, $f8 2583 mfc1 t4, $f9 2584 b get_ft_d_done 2585get_ft_d_f10: 2586 mfc1 t7, $f10 2587 mfc1 t4, $f11 2588 b get_ft_d_done 2589get_ft_d_f12: 2590 mfc1 t7, $f12 2591 mfc1 t4, $f13 2592 b get_ft_d_done 2593get_ft_d_f14: 2594 mfc1 t7, $f14 2595 mfc1 t4, $f15 2596 b get_ft_d_done 2597get_ft_d_f16: 2598 mfc1 t7, $f16 2599 mfc1 t4, $f17 2600 b get_ft_d_done 2601get_ft_d_f18: 2602 mfc1 t7, $f18 2603 mfc1 t4, $f19 2604 b get_ft_d_done 2605get_ft_d_f20: 2606 mfc1 t7, $f20 2607 mfc1 t4, $f21 2608 b get_ft_d_done 2609get_ft_d_f22: 2610 mfc1 t7, $f22 2611 mfc1 t4, $f23 2612 b get_ft_d_done 2613get_ft_d_f24: 2614 mfc1 t7, $f24 2615 mfc1 t4, $f25 2616 b get_ft_d_done 2617get_ft_d_f26: 2618 mfc1 t7, $f26 2619 mfc1 t4, $f27 2620 b get_ft_d_done 2621get_ft_d_f28: 2622 mfc1 t7, $f28 2623 mfc1 t4, $f29 2624 b get_ft_d_done 2625get_ft_d_f30: 2626 mfc1 t7, $f30 2627 mfc1 t4, $f31 2628get_ft_d_done: 2629 srl t5, t4, 20 # get exponent 2630 and t5, t5, 0x7FF 2631 and t6, t4, 0xFFFFF # get fraction 2632 srl t4, t4, 31 # get sign 2633 bne t5, DEXP_INF, 1f # is it a signaling NAN? 2634 and v0, t6, DSIGNAL_NAN 2635 bne v0, zero, invalid_d 26361: 2637 /* fall through to get FS */ 2638 2639/*---------------------------------------------------------------------------- 2640 * get_fs_d -- 2641 * 2642 * Read (double precision) the FS register (bits 15-11) and 2643 * break up into fields. 2644 * This is an internal routine used by MachEmulateFP only. 2645 * 2646 * Results: 2647 * t0 contains the sign 2648 * t1 contains the (biased) exponent 2649 * t2 contains the fraction 2650 * t3 contains the remaining fraction 2651 * 2652 *---------------------------------------------------------------------------- 2653 */ 2654ALEAF(get_fs_d) 2655 srl a3, a0, 12 - 2 # get FS field (even regs only) 2656 and a3, a3, 0xF << 2 # mask FS field 2657 lw a3, get_fs_d_tbl(a3) # switch on register number 2658 j a3 2659 2660 .rdata 2661get_fs_d_tbl: 2662 .word get_fs_d_f0 2663 .word get_fs_d_f2 2664 .word get_fs_d_f4 2665 .word get_fs_d_f6 2666 .word get_fs_d_f8 2667 .word get_fs_d_f10 2668 .word get_fs_d_f12 2669 .word get_fs_d_f14 2670 .word get_fs_d_f16 2671 .word get_fs_d_f18 2672 .word get_fs_d_f20 2673 .word get_fs_d_f22 2674 .word get_fs_d_f24 2675 .word get_fs_d_f26 2676 .word get_fs_d_f28 2677 .word get_fs_d_f30 2678 .text 2679 2680get_fs_d_f0: 2681 mfc1 t3, $f0 2682 mfc1 t0, $f1 2683 b get_fs_d_done 2684get_fs_d_f2: 2685 mfc1 t3, $f2 2686 mfc1 t0, $f3 2687 b get_fs_d_done 2688get_fs_d_f4: 2689 mfc1 t3, $f4 2690 mfc1 t0, $f5 2691 b get_fs_d_done 2692get_fs_d_f6: 2693 mfc1 t3, $f6 2694 mfc1 t0, $f7 2695 b get_fs_d_done 2696get_fs_d_f8: 2697 mfc1 t3, $f8 2698 mfc1 t0, $f9 2699 b get_fs_d_done 2700get_fs_d_f10: 2701 mfc1 t3, $f10 2702 mfc1 t0, $f11 2703 b get_fs_d_done 2704get_fs_d_f12: 2705 mfc1 t3, $f12 2706 mfc1 t0, $f13 2707 b get_fs_d_done 2708get_fs_d_f14: 2709 mfc1 t3, $f14 2710 mfc1 t0, $f15 2711 b get_fs_d_done 2712get_fs_d_f16: 2713 mfc1 t3, $f16 2714 mfc1 t0, $f17 2715 b get_fs_d_done 2716get_fs_d_f18: 2717 mfc1 t3, $f18 2718 mfc1 t0, $f19 2719 b get_fs_d_done 2720get_fs_d_f20: 2721 mfc1 t3, $f20 2722 mfc1 t0, $f21 2723 b get_fs_d_done 2724get_fs_d_f22: 2725 mfc1 t3, $f22 2726 mfc1 t0, $f23 2727 b get_fs_d_done 2728get_fs_d_f24: 2729 mfc1 t3, $f24 2730 mfc1 t0, $f25 2731 b get_fs_d_done 2732get_fs_d_f26: 2733 mfc1 t3, $f26 2734 mfc1 t0, $f27 2735 b get_fs_d_done 2736get_fs_d_f28: 2737 mfc1 t3, $f28 2738 mfc1 t0, $f29 2739 b get_fs_d_done 2740get_fs_d_f30: 2741 mfc1 t3, $f30 2742 mfc1 t0, $f31 2743get_fs_d_done: 2744 srl t1, t0, 20 # get exponent 2745 and t1, t1, 0x7FF 2746 and t2, t0, 0xFFFFF # get fraction 2747 srl t0, t0, 31 # get sign 2748 bne t1, DEXP_INF, 1f # is it a signaling NAN? 2749 and v0, t2, DSIGNAL_NAN 2750 bne v0, zero, invalid_d 27511: 2752 j ra 2753END(get_ft_fs_d) 2754 2755/*---------------------------------------------------------------------------- 2756 * get_cmp_s -- 2757 * 2758 * Read (single precision) the FS register (bits 15-11) and 2759 * the FT register (bits 20-16) and break up into fields. 2760 * This is an internal routine used by MachEmulateFP only. 2761 * 2762 * Results: 2763 * t0 contains the sign 2764 * t1 contains the (biased) exponent 2765 * t2 contains the fraction 2766 * t4 contains the sign 2767 * t5 contains the (biased) exponent 2768 * t6 contains the fraction 2769 * 2770 *---------------------------------------------------------------------------- 2771 */ 2772LEAF(get_cmp_s) 2773 srl a3, a0, 12 - 2 # get FS field (even regs only) 2774 and a3, a3, 0xF << 2 # mask FS field 2775 lw a3, cmp_fs_s_tbl(a3) # switch on register number 2776 j a3 2777 2778 .rdata 2779cmp_fs_s_tbl: 2780 .word cmp_fs_s_f0 2781 .word cmp_fs_s_f2 2782 .word cmp_fs_s_f4 2783 .word cmp_fs_s_f6 2784 .word cmp_fs_s_f8 2785 .word cmp_fs_s_f10 2786 .word cmp_fs_s_f12 2787 .word cmp_fs_s_f14 2788 .word cmp_fs_s_f16 2789 .word cmp_fs_s_f18 2790 .word cmp_fs_s_f20 2791 .word cmp_fs_s_f22 2792 .word cmp_fs_s_f24 2793 .word cmp_fs_s_f26 2794 .word cmp_fs_s_f28 2795 .word cmp_fs_s_f30 2796 .text 2797 2798cmp_fs_s_f0: 2799 mfc1 t0, $f0 2800 b cmp_fs_s_done 2801cmp_fs_s_f2: 2802 mfc1 t0, $f2 2803 b cmp_fs_s_done 2804cmp_fs_s_f4: 2805 mfc1 t0, $f4 2806 b cmp_fs_s_done 2807cmp_fs_s_f6: 2808 mfc1 t0, $f6 2809 b cmp_fs_s_done 2810cmp_fs_s_f8: 2811 mfc1 t0, $f8 2812 b cmp_fs_s_done 2813cmp_fs_s_f10: 2814 mfc1 t0, $f10 2815 b cmp_fs_s_done 2816cmp_fs_s_f12: 2817 mfc1 t0, $f12 2818 b cmp_fs_s_done 2819cmp_fs_s_f14: 2820 mfc1 t0, $f14 2821 b cmp_fs_s_done 2822cmp_fs_s_f16: 2823 mfc1 t0, $f16 2824 b cmp_fs_s_done 2825cmp_fs_s_f18: 2826 mfc1 t0, $f18 2827 b cmp_fs_s_done 2828cmp_fs_s_f20: 2829 mfc1 t0, $f20 2830 b cmp_fs_s_done 2831cmp_fs_s_f22: 2832 mfc1 t0, $f22 2833 b cmp_fs_s_done 2834cmp_fs_s_f24: 2835 mfc1 t0, $f24 2836 b cmp_fs_s_done 2837cmp_fs_s_f26: 2838 mfc1 t0, $f26 2839 b cmp_fs_s_done 2840cmp_fs_s_f28: 2841 mfc1 t0, $f28 2842 b cmp_fs_s_done 2843cmp_fs_s_f30: 2844 mfc1 t0, $f30 2845cmp_fs_s_done: 2846 srl t1, t0, 23 # get exponent 2847 and t1, t1, 0xFF 2848 and t2, t0, 0x7FFFFF # get fraction 2849 srl t0, t0, 31 # get sign 2850 2851 srl a3, a0, 17 - 2 # get FT field (even regs only) 2852 and a3, a3, 0xF << 2 # mask FT field 2853 lw a3, cmp_ft_s_tbl(a3) # switch on register number 2854 j a3 2855 2856 .rdata 2857cmp_ft_s_tbl: 2858 .word cmp_ft_s_f0 2859 .word cmp_ft_s_f2 2860 .word cmp_ft_s_f4 2861 .word cmp_ft_s_f6 2862 .word cmp_ft_s_f8 2863 .word cmp_ft_s_f10 2864 .word cmp_ft_s_f12 2865 .word cmp_ft_s_f14 2866 .word cmp_ft_s_f16 2867 .word cmp_ft_s_f18 2868 .word cmp_ft_s_f20 2869 .word cmp_ft_s_f22 2870 .word cmp_ft_s_f24 2871 .word cmp_ft_s_f26 2872 .word cmp_ft_s_f28 2873 .word cmp_ft_s_f30 2874 .text 2875 2876cmp_ft_s_f0: 2877 mfc1 t4, $f0 2878 b cmp_ft_s_done 2879cmp_ft_s_f2: 2880 mfc1 t4, $f2 2881 b cmp_ft_s_done 2882cmp_ft_s_f4: 2883 mfc1 t4, $f4 2884 b cmp_ft_s_done 2885cmp_ft_s_f6: 2886 mfc1 t4, $f6 2887 b cmp_ft_s_done 2888cmp_ft_s_f8: 2889 mfc1 t4, $f8 2890 b cmp_ft_s_done 2891cmp_ft_s_f10: 2892 mfc1 t4, $f10 2893 b cmp_ft_s_done 2894cmp_ft_s_f12: 2895 mfc1 t4, $f12 2896 b cmp_ft_s_done 2897cmp_ft_s_f14: 2898 mfc1 t4, $f14 2899 b cmp_ft_s_done 2900cmp_ft_s_f16: 2901 mfc1 t4, $f16 2902 b cmp_ft_s_done 2903cmp_ft_s_f18: 2904 mfc1 t4, $f18 2905 b cmp_ft_s_done 2906cmp_ft_s_f20: 2907 mfc1 t4, $f20 2908 b cmp_ft_s_done 2909cmp_ft_s_f22: 2910 mfc1 t4, $f22 2911 b cmp_ft_s_done 2912cmp_ft_s_f24: 2913 mfc1 t4, $f24 2914 b cmp_ft_s_done 2915cmp_ft_s_f26: 2916 mfc1 t4, $f26 2917 b cmp_ft_s_done 2918cmp_ft_s_f28: 2919 mfc1 t4, $f28 2920 b cmp_ft_s_done 2921cmp_ft_s_f30: 2922 mfc1 t4, $f30 2923cmp_ft_s_done: 2924 srl t5, t4, 23 # get exponent 2925 and t5, t5, 0xFF 2926 and t6, t4, 0x7FFFFF # get fraction 2927 srl t4, t4, 31 # get sign 2928 j ra 2929END(get_cmp_s) 2930 2931/*---------------------------------------------------------------------------- 2932 * get_cmp_d -- 2933 * 2934 * Read (double precision) the FS register (bits 15-11) and 2935 * the FT register (bits 20-16) and break up into fields. 2936 * This is an internal routine used by MachEmulateFP only. 2937 * 2938 * Results: 2939 * t0 contains the sign 2940 * t1 contains the (biased) exponent 2941 * t2 contains the fraction 2942 * t3 contains the remaining fraction 2943 * t4 contains the sign 2944 * t5 contains the (biased) exponent 2945 * t6 contains the fraction 2946 * t7 contains the remaining fraction 2947 * 2948 *---------------------------------------------------------------------------- 2949 */ 2950LEAF(get_cmp_d) 2951 srl a3, a0, 12 - 2 # get FS field (even regs only) 2952 and a3, a3, 0xF << 2 # mask FS field 2953 lw a3, cmp_fs_d_tbl(a3) # switch on register number 2954 j a3 2955 2956 .rdata 2957cmp_fs_d_tbl: 2958 .word cmp_fs_d_f0 2959 .word cmp_fs_d_f2 2960 .word cmp_fs_d_f4 2961 .word cmp_fs_d_f6 2962 .word cmp_fs_d_f8 2963 .word cmp_fs_d_f10 2964 .word cmp_fs_d_f12 2965 .word cmp_fs_d_f14 2966 .word cmp_fs_d_f16 2967 .word cmp_fs_d_f18 2968 .word cmp_fs_d_f20 2969 .word cmp_fs_d_f22 2970 .word cmp_fs_d_f24 2971 .word cmp_fs_d_f26 2972 .word cmp_fs_d_f28 2973 .word cmp_fs_d_f30 2974 .text 2975 2976cmp_fs_d_f0: 2977 mfc1 t3, $f0 2978 mfc1 t0, $f1 2979 b cmp_fs_d_done 2980cmp_fs_d_f2: 2981 mfc1 t3, $f2 2982 mfc1 t0, $f3 2983 b cmp_fs_d_done 2984cmp_fs_d_f4: 2985 mfc1 t3, $f4 2986 mfc1 t0, $f5 2987 b cmp_fs_d_done 2988cmp_fs_d_f6: 2989 mfc1 t3, $f6 2990 mfc1 t0, $f7 2991 b cmp_fs_d_done 2992cmp_fs_d_f8: 2993 mfc1 t3, $f8 2994 mfc1 t0, $f9 2995 b cmp_fs_d_done 2996cmp_fs_d_f10: 2997 mfc1 t3, $f10 2998 mfc1 t0, $f11 2999 b cmp_fs_d_done 3000cmp_fs_d_f12: 3001 mfc1 t3, $f12 3002 mfc1 t0, $f13 3003 b cmp_fs_d_done 3004cmp_fs_d_f14: 3005 mfc1 t3, $f14 3006 mfc1 t0, $f15 3007 b cmp_fs_d_done 3008cmp_fs_d_f16: 3009 mfc1 t3, $f16 3010 mfc1 t0, $f17 3011 b cmp_fs_d_done 3012cmp_fs_d_f18: 3013 mfc1 t3, $f18 3014 mfc1 t0, $f19 3015 b cmp_fs_d_done 3016cmp_fs_d_f20: 3017 mfc1 t3, $f20 3018 mfc1 t0, $f21 3019 b cmp_fs_d_done 3020cmp_fs_d_f22: 3021 mfc1 t3, $f22 3022 mfc1 t0, $f23 3023 b cmp_fs_d_done 3024cmp_fs_d_f24: 3025 mfc1 t3, $f24 3026 mfc1 t0, $f25 3027 b cmp_fs_d_done 3028cmp_fs_d_f26: 3029 mfc1 t3, $f26 3030 mfc1 t0, $f27 3031 b cmp_fs_d_done 3032cmp_fs_d_f28: 3033 mfc1 t3, $f28 3034 mfc1 t0, $f29 3035 b cmp_fs_d_done 3036cmp_fs_d_f30: 3037 mfc1 t3, $f30 3038 mfc1 t0, $f31 3039cmp_fs_d_done: 3040 srl t1, t0, 20 # get exponent 3041 and t1, t1, 0x7FF 3042 and t2, t0, 0xFFFFF # get fraction 3043 srl t0, t0, 31 # get sign 3044 3045 srl a3, a0, 17 - 2 # get FT field (even regs only) 3046 and a3, a3, 0xF << 2 # mask FT field 3047 lw a3, cmp_ft_d_tbl(a3) # switch on register number 3048 j a3 3049 3050 .rdata 3051cmp_ft_d_tbl: 3052 .word cmp_ft_d_f0 3053 .word cmp_ft_d_f2 3054 .word cmp_ft_d_f4 3055 .word cmp_ft_d_f6 3056 .word cmp_ft_d_f8 3057 .word cmp_ft_d_f10 3058 .word cmp_ft_d_f12 3059 .word cmp_ft_d_f14 3060 .word cmp_ft_d_f16 3061 .word cmp_ft_d_f18 3062 .word cmp_ft_d_f20 3063 .word cmp_ft_d_f22 3064 .word cmp_ft_d_f24 3065 .word cmp_ft_d_f26 3066 .word cmp_ft_d_f28 3067 .word cmp_ft_d_f30 3068 .text 3069 3070cmp_ft_d_f0: 3071 mfc1 t7, $f0 3072 mfc1 t4, $f1 3073 b cmp_ft_d_done 3074cmp_ft_d_f2: 3075 mfc1 t7, $f2 3076 mfc1 t4, $f3 3077 b cmp_ft_d_done 3078cmp_ft_d_f4: 3079 mfc1 t7, $f4 3080 mfc1 t4, $f5 3081 b cmp_ft_d_done 3082cmp_ft_d_f6: 3083 mfc1 t7, $f6 3084 mfc1 t4, $f7 3085 b cmp_ft_d_done 3086cmp_ft_d_f8: 3087 mfc1 t7, $f8 3088 mfc1 t4, $f9 3089 b cmp_ft_d_done 3090cmp_ft_d_f10: 3091 mfc1 t7, $f10 3092 mfc1 t4, $f11 3093 b cmp_ft_d_done 3094cmp_ft_d_f12: 3095 mfc1 t7, $f12 3096 mfc1 t4, $f13 3097 b cmp_ft_d_done 3098cmp_ft_d_f14: 3099 mfc1 t7, $f14 3100 mfc1 t4, $f15 3101 b cmp_ft_d_done 3102cmp_ft_d_f16: 3103 mfc1 t7, $f16 3104 mfc1 t4, $f17 3105 b cmp_ft_d_done 3106cmp_ft_d_f18: 3107 mfc1 t7, $f18 3108 mfc1 t4, $f19 3109 b cmp_ft_d_done 3110cmp_ft_d_f20: 3111 mfc1 t7, $f20 3112 mfc1 t4, $f21 3113 b cmp_ft_d_done 3114cmp_ft_d_f22: 3115 mfc1 t7, $f22 3116 mfc1 t4, $f23 3117 b cmp_ft_d_done 3118cmp_ft_d_f24: 3119 mfc1 t7, $f24 3120 mfc1 t4, $f25 3121 b cmp_ft_d_done 3122cmp_ft_d_f26: 3123 mfc1 t7, $f26 3124 mfc1 t4, $f27 3125 b cmp_ft_d_done 3126cmp_ft_d_f28: 3127 mfc1 t7, $f28 3128 mfc1 t4, $f29 3129 b cmp_ft_d_done 3130cmp_ft_d_f30: 3131 mfc1 t7, $f30 3132 mfc1 t4, $f31 3133cmp_ft_d_done: 3134 srl t5, t4, 20 # get exponent 3135 and t5, t5, 0x7FF 3136 and t6, t4, 0xFFFFF # get fraction 3137 srl t4, t4, 31 # get sign 3138 j ra 3139END(get_cmp_d) 3140 3141/*---------------------------------------------------------------------------- 3142 * set_fd_s -- 3143 * 3144 * Write (single precision) the FD register (bits 10-6). 3145 * This is an internal routine used by MachEmulateFP only. 3146 * 3147 * Arguments: 3148 * a0 contains the FP instruction 3149 * t0 contains the sign 3150 * t1 contains the (biased) exponent 3151 * t2 contains the fraction 3152 * 3153 * set_fd_word -- 3154 * 3155 * Write (integer) the FD register (bits 10-6). 3156 * This is an internal routine used by MachEmulateFP only. 3157 * 3158 * Arguments: 3159 * a0 contains the FP instruction 3160 * t2 contains the integer 3161 * 3162 *---------------------------------------------------------------------------- 3163 */ 3164LEAF(set_fd_s) 3165 sll t0, t0, 31 # position sign 3166 sll t1, t1, 23 # position exponent 3167 or t2, t2, t0 3168 or t2, t2, t1 3169ALEAF(set_fd_word) 3170 srl a3, a0, 7 - 2 # get FD field (even regs only) 3171 and a3, a3, 0xF << 2 # mask FT field 3172 lw a3, set_fd_s_tbl(a3) # switch on register number 3173 j a3 3174 3175 .rdata 3176set_fd_s_tbl: 3177 .word set_fd_s_f0 3178 .word set_fd_s_f2 3179 .word set_fd_s_f4 3180 .word set_fd_s_f6 3181 .word set_fd_s_f8 3182 .word set_fd_s_f10 3183 .word set_fd_s_f12 3184 .word set_fd_s_f14 3185 .word set_fd_s_f16 3186 .word set_fd_s_f18 3187 .word set_fd_s_f20 3188 .word set_fd_s_f22 3189 .word set_fd_s_f24 3190 .word set_fd_s_f26 3191 .word set_fd_s_f28 3192 .word set_fd_s_f30 3193 .text 3194 3195set_fd_s_f0: 3196 mtc1 t2, $f0 3197 j ra 3198set_fd_s_f2: 3199 mtc1 t2, $f2 3200 j ra 3201set_fd_s_f4: 3202 mtc1 t2, $f4 3203 j ra 3204set_fd_s_f6: 3205 mtc1 t2, $f6 3206 j ra 3207set_fd_s_f8: 3208 mtc1 t2, $f8 3209 j ra 3210set_fd_s_f10: 3211 mtc1 t2, $f10 3212 j ra 3213set_fd_s_f12: 3214 mtc1 t2, $f12 3215 j ra 3216set_fd_s_f14: 3217 mtc1 t2, $f14 3218 j ra 3219set_fd_s_f16: 3220 mtc1 t2, $f16 3221 j ra 3222set_fd_s_f18: 3223 mtc1 t2, $f18 3224 j ra 3225set_fd_s_f20: 3226 mtc1 t2, $f20 3227 j ra 3228set_fd_s_f22: 3229 mtc1 t2, $f22 3230 j ra 3231set_fd_s_f24: 3232 mtc1 t2, $f24 3233 j ra 3234set_fd_s_f26: 3235 mtc1 t2, $f26 3236 j ra 3237set_fd_s_f28: 3238 mtc1 t2, $f28 3239 j ra 3240set_fd_s_f30: 3241 mtc1 t2, $f30 3242 j ra 3243END(set_fd_s) 3244 3245/*---------------------------------------------------------------------------- 3246 * set_fd_d -- 3247 * 3248 * Write (double precision) the FT register (bits 10-6). 3249 * This is an internal routine used by MachEmulateFP only. 3250 * 3251 * Arguments: 3252 * a0 contains the FP instruction 3253 * t0 contains the sign 3254 * t1 contains the (biased) exponent 3255 * t2 contains the fraction 3256 * t3 contains the remaining fraction 3257 * 3258 *---------------------------------------------------------------------------- 3259 */ 3260LEAF(set_fd_d) 3261 sll t0, t0, 31 # set sign 3262 sll t1, t1, 20 # set exponent 3263 or t0, t0, t1 3264 or t0, t0, t2 # set fraction 3265 srl a3, a0, 7 - 2 # get FD field (even regs only) 3266 and a3, a3, 0xF << 2 # mask FD field 3267 lw a3, set_fd_d_tbl(a3) # switch on register number 3268 j a3 3269 3270 .rdata 3271set_fd_d_tbl: 3272 .word set_fd_d_f0 3273 .word set_fd_d_f2 3274 .word set_fd_d_f4 3275 .word set_fd_d_f6 3276 .word set_fd_d_f8 3277 .word set_fd_d_f10 3278 .word set_fd_d_f12 3279 .word set_fd_d_f14 3280 .word set_fd_d_f16 3281 .word set_fd_d_f18 3282 .word set_fd_d_f20 3283 .word set_fd_d_f22 3284 .word set_fd_d_f24 3285 .word set_fd_d_f26 3286 .word set_fd_d_f28 3287 .word set_fd_d_f30 3288 .text 3289 3290set_fd_d_f0: 3291 mtc1 t3, $f0 3292 mtc1 t0, $f1 3293 j ra 3294set_fd_d_f2: 3295 mtc1 t3, $f2 3296 mtc1 t0, $f3 3297 j ra 3298set_fd_d_f4: 3299 mtc1 t3, $f4 3300 mtc1 t0, $f5 3301 j ra 3302set_fd_d_f6: 3303 mtc1 t3, $f6 3304 mtc1 t0, $f7 3305 j ra 3306set_fd_d_f8: 3307 mtc1 t3, $f8 3308 mtc1 t0, $f9 3309 j ra 3310set_fd_d_f10: 3311 mtc1 t3, $f10 3312 mtc1 t0, $f11 3313 j ra 3314set_fd_d_f12: 3315 mtc1 t3, $f12 3316 mtc1 t0, $f13 3317 j ra 3318set_fd_d_f14: 3319 mtc1 t3, $f14 3320 mtc1 t0, $f15 3321 j ra 3322set_fd_d_f16: 3323 mtc1 t3, $f16 3324 mtc1 t0, $f17 3325 j ra 3326set_fd_d_f18: 3327 mtc1 t3, $f18 3328 mtc1 t0, $f19 3329 j ra 3330set_fd_d_f20: 3331 mtc1 t3, $f20 3332 mtc1 t0, $f21 3333 j ra 3334set_fd_d_f22: 3335 mtc1 t3, $f22 3336 mtc1 t0, $f23 3337 j ra 3338set_fd_d_f24: 3339 mtc1 t3, $f24 3340 mtc1 t0, $f25 3341 j ra 3342set_fd_d_f26: 3343 mtc1 t3, $f26 3344 mtc1 t0, $f27 3345 j ra 3346set_fd_d_f28: 3347 mtc1 t3, $f28 3348 mtc1 t0, $f29 3349 j ra 3350set_fd_d_f30: 3351 mtc1 t3, $f30 3352 mtc1 t0, $f31 3353 j ra 3354END(set_fd_d) 3355 3356/*---------------------------------------------------------------------------- 3357 * renorm_fs_s -- 3358 * 3359 * Results: 3360 * t1 unbiased exponent 3361 * t2 normalized fraction 3362 * 3363 *---------------------------------------------------------------------------- 3364 */ 3365LEAF(renorm_fs_s) 3366/* 3367 * Find out how many leading zero bits are in t2 and put in t9. 3368 */ 3369 move v0, t2 3370 move t9, zero 3371 srl v1, v0, 16 3372 bne v1, zero, 1f 3373 addu t9, 16 3374 sll v0, 16 33751: 3376 srl v1, v0, 24 3377 bne v1, zero, 1f 3378 addu t9, 8 3379 sll v0, 8 33801: 3381 srl v1, v0, 28 3382 bne v1, zero, 1f 3383 addu t9, 4 3384 sll v0, 4 33851: 3386 srl v1, v0, 30 3387 bne v1, zero, 1f 3388 addu t9, 2 3389 sll v0, 2 33901: 3391 srl v1, v0, 31 3392 bne v1, zero, 1f 3393 addu t9, 1 3394/* 3395 * Now shift t2 the correct number of bits. 3396 */ 33971: 3398 subu t9, t9, SLEAD_ZEROS # don't count normal leading zeros 3399 li t1, SEXP_MIN 3400 subu t1, t1, t9 # adjust exponent 3401 sll t2, t2, t9 3402 j ra 3403END(renorm_fs_s) 3404 3405/*---------------------------------------------------------------------------- 3406 * renorm_fs_d -- 3407 * 3408 * Results: 3409 * t1 unbiased exponent 3410 * t2,t3 normalized fraction 3411 * 3412 *---------------------------------------------------------------------------- 3413 */ 3414LEAF(renorm_fs_d) 3415/* 3416 * Find out how many leading zero bits are in t2,t3 and put in t9. 3417 */ 3418 move v0, t2 3419 move t9, zero 3420 bne t2, zero, 1f 3421 move v0, t3 3422 addu t9, 32 34231: 3424 srl v1, v0, 16 3425 bne v1, zero, 1f 3426 addu t9, 16 3427 sll v0, 16 34281: 3429 srl v1, v0, 24 3430 bne v1, zero, 1f 3431 addu t9, 8 3432 sll v0, 8 34331: 3434 srl v1, v0, 28 3435 bne v1, zero, 1f 3436 addu t9, 4 3437 sll v0, 4 34381: 3439 srl v1, v0, 30 3440 bne v1, zero, 1f 3441 addu t9, 2 3442 sll v0, 2 34431: 3444 srl v1, v0, 31 3445 bne v1, zero, 1f 3446 addu t9, 1 3447/* 3448 * Now shift t2,t3 the correct number of bits. 3449 */ 34501: 3451 subu t9, t9, DLEAD_ZEROS # don't count normal leading zeros 3452 li t1, DEXP_MIN 3453 subu t1, t1, t9 # adjust exponent 3454 li v0, 32 3455 blt t9, v0, 1f 3456 subu t9, t9, v0 # shift fraction left >= 32 bits 3457 sll t2, t3, t9 3458 move t3, zero 3459 j ra 34601: 3461 subu v0, v0, t9 # shift fraction left < 32 bits 3462 sll t2, t2, t9 3463 srl v1, t3, v0 3464 or t2, t2, v1 3465 sll t3, t3, t9 3466 j ra 3467END(renorm_fs_d) 3468 3469/*---------------------------------------------------------------------------- 3470 * renorm_ft_s -- 3471 * 3472 * Results: 3473 * t5 unbiased exponent 3474 * t6 normalized fraction 3475 * 3476 *---------------------------------------------------------------------------- 3477 */ 3478LEAF(renorm_ft_s) 3479/* 3480 * Find out how many leading zero bits are in t6 and put in t9. 3481 */ 3482 move v0, t6 3483 move t9, zero 3484 srl v1, v0, 16 3485 bne v1, zero, 1f 3486 addu t9, 16 3487 sll v0, 16 34881: 3489 srl v1, v0, 24 3490 bne v1, zero, 1f 3491 addu t9, 8 3492 sll v0, 8 34931: 3494 srl v1, v0, 28 3495 bne v1, zero, 1f 3496 addu t9, 4 3497 sll v0, 4 34981: 3499 srl v1, v0, 30 3500 bne v1, zero, 1f 3501 addu t9, 2 3502 sll v0, 2 35031: 3504 srl v1, v0, 31 3505 bne v1, zero, 1f 3506 addu t9, 1 3507/* 3508 * Now shift t6 the correct number of bits. 3509 */ 35101: 3511 subu t9, t9, SLEAD_ZEROS # don't count normal leading zeros 3512 li t5, SEXP_MIN 3513 subu t5, t5, t9 # adjust exponent 3514 sll t6, t6, t9 3515 j ra 3516END(renorm_ft_s) 3517 3518/*---------------------------------------------------------------------------- 3519 * renorm_ft_d -- 3520 * 3521 * Results: 3522 * t5 unbiased exponent 3523 * t6,t7 normalized fraction 3524 * 3525 *---------------------------------------------------------------------------- 3526 */ 3527LEAF(renorm_ft_d) 3528/* 3529 * Find out how many leading zero bits are in t6,t7 and put in t9. 3530 */ 3531 move v0, t6 3532 move t9, zero 3533 bne t6, zero, 1f 3534 move v0, t7 3535 addu t9, 32 35361: 3537 srl v1, v0, 16 3538 bne v1, zero, 1f 3539 addu t9, 16 3540 sll v0, 16 35411: 3542 srl v1, v0, 24 3543 bne v1, zero, 1f 3544 addu t9, 8 3545 sll v0, 8 35461: 3547 srl v1, v0, 28 3548 bne v1, zero, 1f 3549 addu t9, 4 3550 sll v0, 4 35511: 3552 srl v1, v0, 30 3553 bne v1, zero, 1f 3554 addu t9, 2 3555 sll v0, 2 35561: 3557 srl v1, v0, 31 3558 bne v1, zero, 1f 3559 addu t9, 1 3560/* 3561 * Now shift t6,t7 the correct number of bits. 3562 */ 35631: 3564 subu t9, t9, DLEAD_ZEROS # don't count normal leading zeros 3565 li t5, DEXP_MIN 3566 subu t5, t5, t9 # adjust exponent 3567 li v0, 32 3568 blt t9, v0, 1f 3569 subu t9, t9, v0 # shift fraction left >= 32 bits 3570 sll t6, t7, t9 3571 move t7, zero 3572 j ra 35731: 3574 subu v0, v0, t9 # shift fraction left < 32 bits 3575 sll t6, t6, t9 3576 srl v1, t7, v0 3577 or t6, t6, v1 3578 sll t7, t7, t9 3579 j ra 3580END(renorm_ft_d) 3581