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.3 (Berkeley) 10/11/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 21#include "assym.h" 22 23#define SEXP_INF 0xff 24#define DEXP_INF 0x7ff 25#define SEXP_BIAS 127 26#define DEXP_BIAS 1023 27#define SEXP_MIN -126 28#define DEXP_MIN -1022 29#define SEXP_MAX 127 30#define DEXP_MAX 1023 31#define WEXP_MAX 30 /* maximum unbiased exponent for int */ 32#define WEXP_MIN -1 /* minimum unbiased exponent for int */ 33#define SFRAC_BITS 23 34#define DFRAC_BITS 52 35#define SIMPL_ONE 0x00800000 36#define DIMPL_ONE 0x00100000 37#define SLEAD_ZEROS 31 - 23 38#define DLEAD_ZEROS 31 - 20 39#define STICKYBIT 1 40#define GUARDBIT 0x80000000 41#define SSIGNAL_NAN 0x00400000 42#define DSIGNAL_NAN 0x00080000 43#define SQUIET_NAN 0x003fffff 44#define DQUIET_NAN0 0x0007ffff 45#define DQUIET_NAN1 0xffffffff 46#define INT_MIN 0x80000000 47#define INT_MAX 0x7fffffff 48 49#define COND_UNORDERED 0x1 50#define COND_EQUAL 0x2 51#define COND_LESS 0x4 52#define COND_SIGNAL 0x8 53 54/*---------------------------------------------------------------------------- 55 * 56 * MachEmulateFP -- 57 * 58 * Emulate unimplemented floating point operations. 59 * This routine should only be called by MachFPInterrupt(). 60 * 61 * MachEmulateFP(instr) 62 * unsigned instr; 63 * 64 * Results: 65 * None. 66 * 67 * Side effects: 68 * Floating point registers are modified according to instruction. 69 * 70 *---------------------------------------------------------------------------- 71 */ 72NON_LEAF(MachEmulateFP, STAND_FRAME_SIZE, ra) 73 subu sp, sp, STAND_FRAME_SIZE 74 sw ra, STAND_RA_OFFSET(sp) 75/* 76 * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0). 77 */ 78 srl v0, a0, 21 - 2 # get FMT field 79 and v0, v0, 0xF << 2 # mask FMT field 80 and v1, a0, 0x3F # mask FUNC field 81 sll v1, v1, 5 # align for table lookup 82 bgt v0, 4 << 2, ill # illegal format 83 84 or v1, v1, v0 85 cfc1 a1, MACH_FPC_CSR # get exception register 86 lw a3, func_fmt_tbl(v1) # switch on FUNC & FMT 87 and a1, a1, ~MACH_FPC_EXCEPTION_UNIMPL # clear exception 88 ctc1 a1, MACH_FPC_CSR 89 j a3 90 91 .rdata 92func_fmt_tbl: 93 .word add_s # 0 94 .word add_d # 0 95 .word ill # 0 96 .word ill # 0 97 .word ill # 0 98 .word ill # 0 99 .word ill # 0 100 .word ill # 0 101 .word sub_s # 1 102 .word sub_d # 1 103 .word ill # 1 104 .word ill # 1 105 .word ill # 1 106 .word ill # 1 107 .word ill # 1 108 .word ill # 1 109 .word mul_s # 2 110 .word mul_d # 2 111 .word ill # 2 112 .word ill # 2 113 .word ill # 2 114 .word ill # 2 115 .word ill # 2 116 .word ill # 2 117 .word div_s # 3 118 .word div_d # 3 119 .word ill # 3 120 .word ill # 3 121 .word ill # 3 122 .word ill # 3 123 .word ill # 3 124 .word ill # 3 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 ill # 4 133 .word abs_s # 5 134 .word abs_d # 5 135 .word ill # 5 136 .word ill # 5 137 .word ill # 5 138 .word ill # 5 139 .word ill # 5 140 .word ill # 5 141 .word mov_s # 6 142 .word mov_d # 6 143 .word ill # 6 144 .word ill # 6 145 .word ill # 6 146 .word ill # 6 147 .word ill # 6 148 .word ill # 6 149 .word neg_s # 7 150 .word neg_d # 7 151 .word ill # 7 152 .word ill # 7 153 .word ill # 7 154 .word ill # 7 155 .word ill # 7 156 .word ill # 7 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 # 8 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 # 9 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 # 10 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 # 11 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 # 12 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 # 13 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 # 14 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 # 15 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 # 16 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 # 17 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 # 18 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 # 19 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 # 20 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 # 21 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 # 22 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 # 23 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 # 24 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 # 25 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 # 26 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 # 27 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 # 28 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 # 29 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 # 30 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 # 31 349 .word ill # 32 350 .word cvt_s_d # 32 351 .word ill # 32 352 .word ill # 32 353 .word cvt_s_w # 32 354 .word ill # 32 355 .word ill # 32 356 .word ill # 32 357 .word cvt_d_s # 33 358 .word ill # 33 359 .word ill # 33 360 .word ill # 33 361 .word cvt_d_w # 33 362 .word ill # 33 363 .word ill # 33 364 .word ill # 33 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 # 34 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 ill # 35 381 .word cvt_w_s # 36 382 .word cvt_w_d # 36 383 .word ill # 36 384 .word ill # 36 385 .word ill # 36 386 .word ill # 36 387 .word ill # 36 388 .word ill # 36 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 # 37 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 # 38 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 # 39 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 # 40 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 # 41 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 # 42 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 # 43 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 # 44 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 # 45 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 # 46 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 ill # 47 477 .word cmp_s # 48 478 .word cmp_d # 48 479 .word ill # 48 480 .word ill # 48 481 .word ill # 48 482 .word ill # 48 483 .word ill # 48 484 .word ill # 48 485 .word cmp_s # 49 486 .word cmp_d # 49 487 .word ill # 49 488 .word ill # 49 489 .word ill # 49 490 .word ill # 49 491 .word ill # 49 492 .word ill # 49 493 .word cmp_s # 50 494 .word cmp_d # 50 495 .word ill # 50 496 .word ill # 50 497 .word ill # 50 498 .word ill # 50 499 .word ill # 50 500 .word ill # 50 501 .word cmp_s # 51 502 .word cmp_d # 51 503 .word ill # 51 504 .word ill # 51 505 .word ill # 51 506 .word ill # 51 507 .word ill # 51 508 .word ill # 51 509 .word cmp_s # 52 510 .word cmp_d # 52 511 .word ill # 52 512 .word ill # 52 513 .word ill # 52 514 .word ill # 52 515 .word ill # 52 516 .word ill # 52 517 .word cmp_s # 53 518 .word cmp_d # 53 519 .word ill # 53 520 .word ill # 53 521 .word ill # 53 522 .word ill # 53 523 .word ill # 53 524 .word ill # 53 525 .word cmp_s # 54 526 .word cmp_d # 54 527 .word ill # 54 528 .word ill # 54 529 .word ill # 54 530 .word ill # 54 531 .word ill # 54 532 .word ill # 54 533 .word cmp_s # 55 534 .word cmp_d # 55 535 .word ill # 55 536 .word ill # 55 537 .word ill # 55 538 .word ill # 55 539 .word ill # 55 540 .word ill # 55 541 .word cmp_s # 56 542 .word cmp_d # 56 543 .word ill # 56 544 .word ill # 56 545 .word ill # 56 546 .word ill # 56 547 .word ill # 56 548 .word ill # 56 549 .word cmp_s # 57 550 .word cmp_d # 57 551 .word ill # 57 552 .word ill # 57 553 .word ill # 57 554 .word ill # 57 555 .word ill # 57 556 .word ill # 57 557 .word cmp_s # 58 558 .word cmp_d # 58 559 .word ill # 58 560 .word ill # 58 561 .word ill # 58 562 .word ill # 58 563 .word ill # 58 564 .word ill # 58 565 .word cmp_s # 59 566 .word cmp_d # 59 567 .word ill # 59 568 .word ill # 59 569 .word ill # 59 570 .word ill # 59 571 .word ill # 59 572 .word ill # 59 573 .word cmp_s # 60 574 .word cmp_d # 60 575 .word ill # 60 576 .word ill # 60 577 .word ill # 60 578 .word ill # 60 579 .word ill # 60 580 .word ill # 60 581 .word cmp_s # 61 582 .word cmp_d # 61 583 .word ill # 61 584 .word ill # 61 585 .word ill # 61 586 .word ill # 61 587 .word ill # 61 588 .word ill # 61 589 .word cmp_s # 62 590 .word cmp_d # 62 591 .word ill # 62 592 .word ill # 62 593 .word ill # 62 594 .word ill # 62 595 .word ill # 62 596 .word ill # 62 597 .word cmp_s # 63 598 .word cmp_d # 63 599 .word ill # 63 600 .word ill # 63 601 .word ill # 63 602 .word ill # 63 603 .word ill # 63 604 .word ill # 63 605 .text 606 607/* 608 * Single precision subtract. 609 */ 610sub_s: 611 jal get_ft_fs_s 612 xor t4, t4, 1 # negate FT sign bit 613 b add_sub_s 614/* 615 * Single precision add. 616 */ 617add_s: 618 jal get_ft_fs_s 619add_sub_s: 620 bne t1, SEXP_INF, 1f # is FS an infinity? 621 bne t5, SEXP_INF, result_fs_s # if FT is not inf, result=FS 622 bne t2, zero, result_fs_s # if FS is NAN, result is FS 623 bne t6, zero, result_ft_s # if FT is NAN, result is FT 624 bne t0, t4, invalid_s # both infinities same sign? 625 b result_fs_s # result is in FS 6261: 627 beq t5, SEXP_INF, result_ft_s # if FT is inf, result=FT 628 bne t1, zero, 4f # is FS a denormalized num? 629 beq t2, zero, 3f # is FS zero? 630 bne t5, zero, 2f # is FT a denormalized num? 631 beq t6, zero, result_fs_s # FT is zero, result=FS 632 jal renorm_fs_s 633 jal renorm_ft_s 634 b 5f 6352: 636 jal renorm_fs_s 637 subu t5, t5, SEXP_BIAS # unbias FT exponent 638 or t6, t6, SIMPL_ONE # set implied one bit 639 b 5f 6403: 641 bne t5, zero, result_ft_s # if FT != 0, result=FT 642 bne t6, zero, result_ft_s 643 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 644 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 645 or t0, t0, t4 # compute result sign 646 b result_fs_s 6471: 648 and t0, t0, t4 # compute result sign 649 b result_fs_s 6504: 651 bne t5, zero, 2f # is FT a denormalized num? 652 beq t6, zero, result_fs_s # FT is zero, result=FS 653 subu t1, t1, SEXP_BIAS # unbias FS exponent 654 or t2, t2, SIMPL_ONE # set implied one bit 655 jal renorm_ft_s 656 b 5f 6572: 658 subu t1, t1, SEXP_BIAS # unbias FS exponent 659 or t2, t2, SIMPL_ONE # set implied one bit 660 subu t5, t5, SEXP_BIAS # unbias FT exponent 661 or t6, t6, SIMPL_ONE # set implied one bit 662/* 663 * Perform the addition. 664 */ 6655: 666 move t8, zero # no shifted bits (sticky reg) 667 beq t1, t5, 4f # no shift needed 668 subu v0, t1, t5 # v0 = difference of exponents 669 move v1, v0 # v1 = abs(difference) 670 bge v0, zero, 1f 671 negu v1 6721: 673 ble v1, SFRAC_BITS+2, 2f # is difference too great? 674 li t8, STICKYBIT # set the sticky bit 675 bge v0, zero, 1f # check which exp is larger 676 move t1, t5 # result exp is FT's 677 move t2, zero # FS's fraction shifted is zero 678 b 4f 6791: 680 move t6, zero # FT's fraction shifted is zero 681 b 4f 6822: 683 li t9, 32 # compute 32 - abs(exp diff) 684 subu t9, t9, v1 685 bgt v0, zero, 3f # if FS > FT, shift FT's frac 686 move t1, t5 # FT > FS, result exp is FT's 687 sll t8, t2, t9 # save bits shifted out 688 srl t2, t2, v1 # shift FS's fraction 689 b 4f 6903: 691 sll t8, t6, t9 # save bits shifted out 692 srl t6, t6, v1 # shift FT's fraction 6934: 694 bne t0, t4, 1f # if signs differ, subtract 695 addu t2, t2, t6 # add fractions 696 b norm_s 6971: 698 blt t2, t6, 3f # subtract larger from smaller 699 bne t2, t6, 2f # if same, result=0 700 move t1, zero # result=0 701 move t2, zero 702 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 703 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 704 or t0, t0, t4 # compute result sign 705 b result_fs_s 7061: 707 and t0, t0, t4 # compute result sign 708 b result_fs_s 7092: 710 sltu t9, zero, t8 # compute t2:zero - t6:t8 711 subu t8, zero, t8 712 subu t2, t2, t6 # subtract fractions 713 subu t2, t2, t9 # subtract barrow 714 b norm_s 7153: 716 move t0, t4 # sign of result = FT's 717 sltu t9, zero, t8 # compute t6:zero - t2:t8 718 subu t8, zero, t8 719 subu t2, t6, t2 # subtract fractions 720 subu t2, t2, t9 # subtract barrow 721 b norm_s 722 723/* 724 * Double precision subtract. 725 */ 726sub_d: 727 jal get_ft_fs_d 728 xor t4, t4, 1 # negate sign bit 729 b add_sub_d 730/* 731 * Double precision add. 732 */ 733add_d: 734 jal get_ft_fs_d 735add_sub_d: 736 bne t1, DEXP_INF, 1f # is FS an infinity? 737 bne t5, DEXP_INF, result_fs_d # if FT is not inf, result=FS 738 bne t2, zero, result_fs_d # if FS is NAN, result is FS 739 bne t3, zero, result_fs_d 740 bne t6, zero, result_ft_d # if FT is NAN, result is FT 741 bne t7, zero, result_ft_d 742 bne t0, t4, invalid_d # both infinities same sign? 743 b result_fs_d # result is in FS 7441: 745 beq t5, DEXP_INF, result_ft_d # if FT is inf, result=FT 746 bne t1, zero, 4f # is FS a denormalized num? 747 bne t2, zero, 1f # is FS zero? 748 beq t3, zero, 3f 7491: 750 bne t5, zero, 2f # is FT a denormalized num? 751 bne t6, zero, 1f 752 beq t7, zero, result_fs_d # FT is zero, result=FS 7531: 754 jal renorm_fs_d 755 jal renorm_ft_d 756 b 5f 7572: 758 jal renorm_fs_d 759 subu t5, t5, DEXP_BIAS # unbias FT exponent 760 or t6, t6, DIMPL_ONE # set implied one bit 761 b 5f 7623: 763 bne t5, zero, result_ft_d # if FT != 0, result=FT 764 bne t6, zero, result_ft_d 765 bne t7, zero, result_ft_d 766 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 767 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 768 or t0, t0, t4 # compute result sign 769 b result_fs_d 7701: 771 and t0, t0, t4 # compute result sign 772 b result_fs_d 7734: 774 bne t5, zero, 2f # is FT a denormalized num? 775 bne t6, zero, 1f 776 beq t7, zero, result_fs_d # FT is zero, result=FS 7771: 778 subu t1, t1, DEXP_BIAS # unbias FS exponent 779 or t2, t2, DIMPL_ONE # set implied one bit 780 jal renorm_ft_d 781 b 5f 7822: 783 subu t1, t1, DEXP_BIAS # unbias FS exponent 784 or t2, t2, DIMPL_ONE # set implied one bit 785 subu t5, t5, DEXP_BIAS # unbias FT exponent 786 or t6, t6, DIMPL_ONE # set implied one bit 787/* 788 * Perform the addition. 789 */ 7905: 791 move t8, zero # no shifted bits (sticky reg) 792 beq t1, t5, 4f # no shift needed 793 subu v0, t1, t5 # v0 = difference of exponents 794 move v1, v0 # v1 = abs(difference) 795 bge v0, zero, 1f 796 negu v1 7971: 798 ble v1, DFRAC_BITS+2, 2f # is difference too great? 799 li t8, STICKYBIT # set the sticky bit 800 bge v0, zero, 1f # check which exp is larger 801 move t1, t5 # result exp is FT's 802 move t2, zero # FS's fraction shifted is zero 803 move t3, zero 804 b 4f 8051: 806 move t6, zero # FT's fraction shifted is zero 807 move t7, zero 808 b 4f 8092: 810 li t9, 32 811 bge v0, zero, 3f # if FS > FT, shift FT's frac 812 move t1, t5 # FT > FS, result exp is FT's 813 blt v1, t9, 1f # shift right by < 32? 814 subu v1, v1, t9 815 subu t9, t9, v1 816 sll t8, t2, t9 # save bits shifted out 817 sltu t9, zero, t3 # don't lose any one bits 818 or t8, t8, t9 # save sticky bit 819 srl t3, t2, v1 # shift FS's fraction 820 move t2, zero 821 b 4f 8221: 823 subu t9, t9, v1 824 sll t8, t3, t9 # save bits shifted out 825 srl t3, t3, v1 # shift FS's fraction 826 sll t9, t2, t9 # save bits shifted out of t2 827 or t3, t3, t9 # and put into t3 828 srl t2, t2, v1 829 b 4f 8303: 831 blt v1, t9, 1f # shift right by < 32? 832 subu v1, v1, t9 833 subu t9, t9, v1 834 sll t8, t6, t9 # save bits shifted out 835 srl t7, t6, v1 # shift FT's fraction 836 move t6, zero 837 b 4f 8381: 839 subu t9, t9, v1 840 sll t8, t7, t9 # save bits shifted out 841 srl t7, t7, v1 # shift FT's fraction 842 sll t9, t6, t9 # save bits shifted out of t2 843 or t7, t7, t9 # and put into t3 844 srl t6, t6, v1 8454: 846 bne t0, t4, 1f # if signs differ, subtract 847 addu t3, t3, t7 # add fractions 848 sltu t9, t3, t7 # compute carry 849 addu t2, t2, t6 # add fractions 850 addu t2, t2, t9 # add carry 851 b norm_d 8521: 853 blt t2, t6, 3f # subtract larger from smaller 854 bne t2, t6, 2f 855 bltu t3, t7, 3f 856 bne t3, t7, 2f # if same, result=0 857 move t1, zero # result=0 858 move t2, zero 859 move t3, zero 860 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 861 bne v0, MACH_FPC_ROUND_RM, 1f # round to -infinity? 862 or t0, t0, t4 # compute result sign 863 b result_fs_d 8641: 865 and t0, t0, t4 # compute result sign 866 b result_fs_d 8672: 868 beq t8, zero, 1f # compute t2:t3:zero - t6:t7:t8 869 subu t8, zero, t8 870 sltu v0, t3, 1 # compute barrow out 871 subu t3, t3, 1 # subtract barrow 872 subu t2, t2, v0 8731: 874 sltu v0, t3, t7 875 subu t3, t3, t7 # subtract fractions 876 subu t2, t2, t6 # subtract fractions 877 subu t2, t2, v0 # subtract barrow 878 b norm_d 8793: 880 move t0, t4 # sign of result = FT's 881 beq t8, zero, 1f # compute t6:t7:zero - t2:t3:t8 882 subu t8, zero, t8 883 sltu v0, t7, 1 # compute barrow out 884 subu t7, t7, 1 # subtract barrow 885 subu t6, t6, v0 8861: 887 sltu v0, t7, t3 888 subu t3, t7, t3 # subtract fractions 889 subu t2, t6, t2 # subtract fractions 890 subu t2, t2, v0 # subtract barrow 891 b norm_d 892 893/* 894 * Single precision multiply. 895 */ 896mul_s: 897 jal get_ft_fs_s 898 xor t0, t0, t4 # compute sign of result 899 move t4, t0 900 bne t1, SEXP_INF, 2f # is FS an infinity? 901 bne t2, zero, result_fs_s # if FS is a NAN, result=FS 902 bne t5, SEXP_INF, 1f # FS is inf, is FT an infinity? 903 bne t6, zero, result_ft_s # if FT is a NAN, result=FT 904 b result_fs_s # result is infinity 9051: 906 bne t5, zero, result_fs_s # inf * zero? if no, result=FS 907 bne t6, zero, result_fs_s 908 b invalid_s # infinity * zero is invalid 9092: 910 bne t5, SEXP_INF, 1f # FS != inf, is FT an infinity? 911 bne t1, zero, result_ft_s # zero * inf? if no, result=FT 912 bne t2, zero, result_ft_s 913 bne t6, zero, result_ft_s # if FT is a NAN, result=FT 914 b invalid_s # zero * infinity is invalid 9151: 916 bne t1, zero, 1f # is FS zero? 917 beq t2, zero, result_fs_s # result is zero 918 jal renorm_fs_s 919 b 2f 9201: 921 subu t1, t1, SEXP_BIAS # unbias FS exponent 922 or t2, t2, SIMPL_ONE # set implied one bit 9232: 924 bne t5, zero, 1f # is FT zero? 925 beq t6, zero, result_ft_s # result is zero 926 jal renorm_ft_s 927 b 2f 9281: 929 subu t5, t5, SEXP_BIAS # unbias FT exponent 930 or t6, t6, SIMPL_ONE # set implied one bit 9312: 932 addu t1, t1, t5 # compute result exponent 933 addu t1, t1, 9 # account for binary point 934 multu t2, t6 # multiply fractions 935 mflo t8 936 mfhi t2 937 b norm_s 938 939/* 940 * Double precision multiply. 941 */ 942mul_d: 943 jal get_ft_fs_d 944 xor t0, t0, t4 # compute sign of result 945 move t4, t0 946 bne t1, DEXP_INF, 2f # is FS an infinity? 947 bne t2, zero, result_fs_d # if FS is a NAN, result=FS 948 bne t3, zero, result_fs_d 949 bne t5, DEXP_INF, 1f # FS is inf, is FT an infinity? 950 bne t6, zero, result_ft_d # if FT is a NAN, result=FT 951 bne t7, zero, result_ft_d 952 b result_fs_d # result is infinity 9531: 954 bne t5, zero, result_fs_d # inf * zero? if no, result=FS 955 bne t6, zero, result_fs_d 956 bne t7, zero, result_fs_d 957 b invalid_d # infinity * zero is invalid 9582: 959 bne t5, DEXP_INF, 1f # FS != inf, is FT an infinity? 960 bne t1, zero, result_ft_d # zero * inf? if no, result=FT 961 bne t2, zero, result_ft_d # if FS is a NAN, result=FS 962 bne t3, zero, result_ft_d 963 bne t6, zero, result_ft_d # if FT is a NAN, result=FT 964 bne t7, zero, result_ft_d 965 b invalid_d # zero * infinity is invalid 9661: 967 bne t1, zero, 2f # is FS zero? 968 bne t2, zero, 1f 969 beq t3, zero, result_fs_d # result is zero 9701: 971 jal renorm_fs_d 972 b 3f 9732: 974 subu t1, t1, DEXP_BIAS # unbias FS exponent 975 or t2, t2, DIMPL_ONE # set implied one bit 9763: 977 bne t5, zero, 2f # is FT zero? 978 bne t6, zero, 1f 979 beq t7, zero, result_ft_d # result is zero 9801: 981 jal renorm_ft_d 982 b 3f 9832: 984 subu t5, t5, DEXP_BIAS # unbias FT exponent 985 or t6, t6, DIMPL_ONE # set implied one bit 9863: 987 addu t1, t1, t5 # compute result exponent 988 addu t1, t1, 12 # ??? 989 multu t3, t7 # multiply fractions (low * low) 990 move t4, t2 # free up t2,t3 for result 991 move t5, t3 992 mflo a3 # save low order bits 993 mfhi t8 994 not v0, t8 995 multu t4, t7 # multiply FS(high) * FT(low) 996 mflo v1 997 mfhi t3 # init low result 998 sltu v0, v0, v1 # compute carry 999 addu t8, v1 1000 multu t5, t6 # multiply FS(low) * FT(high) 1001 addu t3, t3, v0 # add carry 1002 not v0, t8 1003 mflo v1 1004 mfhi t2 1005 sltu v0, v0, v1 1006 addu t8, v1 1007 multu t4, t6 # multiply FS(high) * FT(high) 1008 addu t3, v0 1009 not v1, t3 1010 sltu v1, v1, t2 1011 addu t3, t2 1012 not v0, t3 1013 mfhi t2 1014 addu t2, v1 1015 mflo v1 1016 sltu v0, v0, v1 1017 addu t2, v0 1018 addu t3, v1 1019 sltu a3, zero, a3 # reduce t8,a3 to just t8 1020 or t8, a3 1021 b norm_d 1022 1023/* 1024 * Single precision divide. 1025 */ 1026div_s: 1027 jal get_ft_fs_s 1028 xor t0, t0, t4 # compute sign of result 1029 move t4, t0 1030 bne t1, SEXP_INF, 1f # is FS an infinity? 1031 bne t2, zero, result_fs_s # if FS is NAN, result is FS 1032 bne t5, SEXP_INF, result_fs_s # is FT an infinity? 1033 bne t6, zero, result_ft_s # if FT is NAN, result is FT 1034 b invalid_s # infinity/infinity is invalid 10351: 1036 bne t5, SEXP_INF, 1f # is FT an infinity? 1037 bne t6, zero, result_ft_s # if FT is NAN, result is FT 1038 move t1, zero # x / infinity is zero 1039 move t2, zero 1040 b result_fs_s 10411: 1042 bne t1, zero, 2f # is FS zero? 1043 bne t2, zero, 1f 1044 bne t5, zero, result_fs_s # FS=zero, is FT zero? 1045 beq t6, zero, invalid_s # 0 / 0 1046 b result_fs_s # result = zero 10471: 1048 jal renorm_fs_s 1049 b 3f 10502: 1051 subu t1, t1, SEXP_BIAS # unbias FS exponent 1052 or t2, t2, SIMPL_ONE # set implied one bit 10533: 1054 bne t5, zero, 2f # is FT zero? 1055 bne t6, zero, 1f 1056 or a1, a1, MACH_FPC_EXCEPTION_DIV0 | MACH_FPC_STICKY_DIV0 1057 and v0, a1, MACH_FPC_ENABLE_DIV0 # trap enabled? 1058 bne v0, zero, fpe_trap 1059 ctc1 a1, MACH_FPC_CSR # save exceptions 1060 li t1, SEXP_INF # result is infinity 1061 move t2, zero 1062 b result_fs_s 10631: 1064 jal renorm_ft_s 1065 b 3f 10662: 1067 subu t5, t5, SEXP_BIAS # unbias FT exponent 1068 or t6, t6, SIMPL_ONE # set implied one bit 10693: 1070 subu t1, t1, t5 # compute exponent 1071 subu t1, t1, 3 # compensate for result position 1072 li v0, SFRAC_BITS+3 # number of bits to divide 1073 move t8, t2 # init dividend 1074 move t2, zero # init result 10751: 1076 bltu t8, t6, 3f # is dividend >= divisor? 10772: 1078 subu t8, t8, t6 # subtract divisor from dividend 1079 or t2, t2, 1 # remember that we did 1080 bne t8, zero, 3f # if not done, continue 1081 sll t2, t2, v0 # shift result to final position 1082 b norm_s 10833: 1084 sll t8, t8, 1 # shift dividend 1085 sll t2, t2, 1 # shift result 1086 subu v0, v0, 1 # are we done? 1087 bne v0, zero, 1b # no, continue 1088 b norm_s 1089 1090/* 1091 * Double precision divide. 1092 */ 1093div_d: 1094 jal get_ft_fs_d 1095 xor t0, t0, t4 # compute sign of result 1096 move t4, t0 1097 bne t1, DEXP_INF, 1f # is FS an infinity? 1098 bne t2, zero, result_fs_d # if FS is NAN, result is FS 1099 bne t3, zero, result_fs_d 1100 bne t5, DEXP_INF, result_fs_d # is FT an infinity? 1101 bne t6, zero, result_ft_d # if FT is NAN, result is FT 1102 bne t7, zero, result_ft_d 1103 b invalid_d # infinity/infinity is invalid 11041: 1105 bne t5, DEXP_INF, 1f # is FT an infinity? 1106 bne t6, zero, result_ft_d # if FT is NAN, result is FT 1107 bne t7, zero, result_ft_d 1108 move t1, zero # x / infinity is zero 1109 move t2, zero 1110 move t3, zero 1111 b result_fs_d 11121: 1113 bne t1, zero, 2f # is FS zero? 1114 bne t2, zero, 1f 1115 bne t3, zero, 1f 1116 bne t5, zero, result_fs_d # FS=zero, is FT zero? 1117 bne t6, zero, result_fs_d 1118 beq t7, zero, invalid_d # 0 / 0 1119 b result_fs_d # result = zero 11201: 1121 jal renorm_fs_d 1122 b 3f 11232: 1124 subu t1, t1, DEXP_BIAS # unbias FS exponent 1125 or t2, t2, DIMPL_ONE # set implied one bit 11263: 1127 bne t5, zero, 2f # is FT zero? 1128 bne t6, zero, 1f 1129 bne t7, zero, 1f 1130 or a1, a1, MACH_FPC_EXCEPTION_DIV0 | MACH_FPC_STICKY_DIV0 1131 and v0, a1, MACH_FPC_ENABLE_DIV0 # trap enabled? 1132 bne v0, zero, fpe_trap 1133 ctc1 a1, MACH_FPC_CSR # Save exceptions 1134 li t1, DEXP_INF # result is infinity 1135 move t2, zero 1136 move t3, zero 1137 b result_fs_d 11381: 1139 jal renorm_ft_d 1140 b 3f 11412: 1142 subu t5, t5, DEXP_BIAS # unbias FT exponent 1143 or t6, t6, DIMPL_ONE # set implied one bit 11443: 1145 subu t1, t1, t5 # compute exponent 1146 subu t1, t1, 3 # compensate for result position 1147 li v0, DFRAC_BITS+3 # number of bits to divide 1148 move t8, t2 # init dividend 1149 move t9, t3 1150 move t2, zero # init result 1151 move t3, zero 11521: 1153 bltu t8, t6, 3f # is dividend >= divisor? 1154 bne t8, t6, 2f 1155 bltu t9, t7, 3f 11562: 1157 sltu v1, t9, t7 # subtract divisor from dividend 1158 subu t9, t9, t7 1159 subu t8, t8, t6 1160 subu t8, t8, v1 1161 or t3, t3, 1 # remember that we did 1162 bne t8, zero, 3f # if not done, continue 1163 bne t9, zero, 3f 1164 li v1, 32 # shift result to final position 1165 blt v0, v1, 2f # shift < 32 bits? 1166 subu v0, v0, v1 # shift by > 32 bits 1167 sll t2, t3, v0 # shift upper part 1168 move t3, zero 1169 b norm_d 11702: 1171 subu v1, v1, v0 # shift by < 32 bits 1172 sll t2, t2, v0 # shift upper part 1173 srl t9, t3, v1 # save bits shifted out 1174 or t2, t2, t9 # and put into upper part 1175 sll t3, t3, v0 1176 b norm_d 11773: 1178 sll t8, t8, 1 # shift dividend 1179 srl v1, t9, 31 # save bit shifted out 1180 or t8, t8, v1 # and put into upper part 1181 sll t9, t9, 1 1182 sll t2, t2, 1 # shift result 1183 srl v1, t3, 31 # save bit shifted out 1184 or t2, t2, v1 # and put into upper part 1185 sll t3, t3, 1 1186 subu v0, v0, 1 # are we done? 1187 bne v0, zero, 1b # no, continue 1188 sltu v0, zero, t9 # be sure to save any one bits 1189 or t8, t8, v0 # from the lower remainder 1190 b norm_d 1191 1192/* 1193 * Single precision absolute value. 1194 */ 1195abs_s: 1196 jal get_fs_s 1197 move t0, zero # set sign positive 1198 b result_fs_s 1199 1200/* 1201 * Double precision absolute value. 1202 */ 1203abs_d: 1204 jal get_fs_d 1205 move t0, zero # set sign positive 1206 b result_fs_d 1207 1208/* 1209 * Single precision move. 1210 */ 1211mov_s: 1212 jal get_fs_s 1213 b result_fs_s 1214 1215/* 1216 * Double precision move. 1217 */ 1218mov_d: 1219 jal get_fs_d 1220 b result_fs_d 1221 1222/* 1223 * Single precision negate. 1224 */ 1225neg_s: 1226 jal get_fs_s 1227 xor t0, t0, 1 # reverse sign 1228 b result_fs_s 1229 1230/* 1231 * Double precision negate. 1232 */ 1233neg_d: 1234 jal get_fs_d 1235 xor t0, t0, 1 # reverse sign 1236 b result_fs_d 1237 1238/* 1239 * Convert double to single. 1240 */ 1241cvt_s_d: 1242 jal get_fs_d 1243 bne t1, DEXP_INF, 1f # is FS an infinity? 1244 li t1, SEXP_INF # convert to single 1245 sll t2, t2, 3 # convert D fraction to S 1246 srl t8, t3, 32 - 3 1247 or t2, t2, t8 1248 b result_fs_s 12491: 1250 bne t1, zero, 2f # is FS zero? 1251 bne t2, zero, 1f 1252 beq t3, zero, result_fs_s # result=0 12531: 1254 jal renorm_fs_d 1255 subu t1, t1, 3 # correct exp for shift below 1256 b 3f 12572: 1258 subu t1, t1, DEXP_BIAS # unbias exponent 1259 or t2, t2, DIMPL_ONE # add implied one bit 12603: 1261 sll t2, t2, 3 # convert D fraction to S 1262 srl t8, t3, 32 - 3 1263 or t2, t2, t8 1264 sll t8, t3, 3 1265 b norm_noshift_s 1266 1267/* 1268 * Convert integer to single. 1269 */ 1270cvt_s_w: 1271 jal get_fs_int 1272 bne t2, zero, 1f # check for zero 1273 move t1, zero 1274 b result_fs_s 1275/* 1276 * Find out how many leading zero bits are in t2 and put in t9. 1277 */ 12781: 1279 move v0, t2 1280 move t9, zero 1281 srl v1, v0, 16 1282 bne v1, zero, 1f 1283 addu t9, 16 1284 sll v0, 16 12851: 1286 srl v1, v0, 24 1287 bne v1, zero, 1f 1288 addu t9, 8 1289 sll v0, 8 12901: 1291 srl v1, v0, 28 1292 bne v1, zero, 1f 1293 addu t9, 4 1294 sll v0, 4 12951: 1296 srl v1, v0, 30 1297 bne v1, zero, 1f 1298 addu t9, 2 1299 sll v0, 2 13001: 1301 srl v1, v0, 31 1302 bne v1, zero, 1f 1303 addu t9, 1 1304/* 1305 * Now shift t2 the correct number of bits. 1306 */ 13071: 1308 subu t9, t9, SLEAD_ZEROS # don't count leading zeros 1309 li t1, 23 # init exponent 1310 subu t1, t1, t9 # compute exponent 1311 beq t9, zero, 1f 1312 li v0, 32 1313 blt t9, zero, 2f # if shift < 0, shift right 1314 subu v0, v0, t9 1315 sll t2, t2, t9 # shift left 13161: 1317 add t1, t1, SEXP_BIAS # bias exponent 1318 and t2, t2, ~SIMPL_ONE # clear implied one bit 1319 b result_fs_s 13202: 1321 negu t9 # shift right by t9 1322 subu v0, v0, t9 1323 sll t8, t2, v0 # save bits shifted out 1324 srl t2, t2, t9 1325 b norm_noshift_s 1326 1327/* 1328 * Convert single to double. 1329 */ 1330cvt_d_s: 1331 jal get_fs_s 1332 bne t1, SEXP_INF, 1f # is FS an infinity? 1333 li t1, DEXP_INF # convert to double 1334 b 2f 13351: 1336 bne t1, zero, 2f # is FS denormalized or zero? 1337 beq t2, zero, result_fs_d # is FS zero? 1338 jal renorm_fs_s 1339 move t8, zero 1340 b norm_d 13412: 1342 addu t1, t1, DEXP_BIAS - SEXP_BIAS # bias exponent correctly 1343 sll t3, t2, 32 - 3 # convert S fraction to D 1344 srl t2, t2, 3 1345 b result_fs_d 1346 1347/* 1348 * Convert integer to double. 1349 */ 1350cvt_d_w: 1351 jal get_fs_int 1352 bne t2, zero, 1f # check for zero 1353 move t1, zero # result=0 1354 move t3, zero 1355 b result_fs_d 1356/* 1357 * Find out how many leading zero bits are in t2 and put in t9. 1358 */ 13591: 1360 move v0, t2 1361 move t9, zero 1362 srl v1, v0, 16 1363 bne v1, zero, 1f 1364 addu t9, 16 1365 sll v0, 16 13661: 1367 srl v1, v0, 24 1368 bne v1, zero, 1f 1369 addu t9, 8 1370 sll v0, 8 13711: 1372 srl v1, v0, 28 1373 bne v1, zero, 1f 1374 addu t9, 4 1375 sll v0, 4 13761: 1377 srl v1, v0, 30 1378 bne v1, zero, 1f 1379 addu t9, 2 1380 sll v0, 2 13811: 1382 srl v1, v0, 31 1383 bne v1, zero, 1f 1384 addu t9, 1 1385/* 1386 * Now shift t2 the correct number of bits. 1387 */ 13881: 1389 subu t9, t9, DLEAD_ZEROS # don't count leading zeros 1390 li t1, DEXP_BIAS + 23 # init exponent 1391 subu t1, t1, t9 # compute exponent 1392 beq t9, zero, 1f 1393 li v0, 32 1394 blt t9, zero, 2f # if shift < 0, shift right 1395 subu v0, v0, t9 1396 sll t2, t2, t9 # shift left 13971: 1398 and t2, t2, ~DIMPL_ONE # clear implied one bit 1399 b result_fs_d 14002: 1401 negu t9 # shift right by t9 1402 subu v0, v0, t9 1403 sll t3, t2, v0 1404 srl t2, t2, t9 1405 and t2, t2, ~DIMPL_ONE # clear implied one bit 1406 b result_fs_d 1407 1408/* 1409 * Convert single to integer. 1410 */ 1411cvt_w_s: 1412 jal get_fs_s 1413 bne t1, SEXP_INF, 1f # is FS an infinity? 1414 bne t2, zero, invalid_w # invalid conversion 14151: 1416 bne t1, zero, 1f # is FS zero? 1417 beq t2, zero, result_fs_w # result is zero 1418 move t2, zero # result is an inexact zero 1419 b inexact_w 14201: 1421 subu t1, t1, SEXP_BIAS # unbias exponent 1422 or t2, t2, SIMPL_ONE # add implied one bit 1423 sll t3, t2, 32 - 3 # convert S fraction to D 1424 srl t2, t2, 3 1425 b cvt_w 1426 1427/* 1428 * Convert double to integer. 1429 */ 1430cvt_w_d: 1431 jal get_fs_d 1432 bne t1, DEXP_INF, 1f # is FS an infinity? 1433 bne t2, zero, invalid_w # invalid conversion 1434 bne t3, zero, invalid_w # invalid conversion 14351: 1436 bne t1, zero, 2f # is FS zero? 1437 bne t2, zero, 1f 1438 beq t3, zero, result_fs_w # result is zero 14391: 1440 move t2, zero # result is an inexact zero 1441 b inexact_w 14422: 1443 subu t1, t1, DEXP_BIAS # unbias exponent 1444 or t2, t2, DIMPL_ONE # add implied one bit 1445cvt_w: 1446 blt t1, WEXP_MIN, underflow_w # is exponent too small? 1447 li v0, WEXP_MAX+1 1448 bgt t1, v0, overflow_w # is exponent too large? 1449 bne t1, v0, 1f # special check for INT_MIN 1450 beq t0, zero, overflow_w # if positive, overflow 1451 bne t2, DIMPL_ONE, overflow_w 1452 bne t3, zero, overflow_w 1453 li t2, INT_MIN # result is INT_MIN 1454 b result_fs_w 14551: 1456 subu v0, t1, 20 # compute amount to shift 1457 beq v0, zero, 2f # is shift needed? 1458 li v1, 32 1459 blt v0, zero, 1f # if shift < 0, shift right 1460 subu v1, v1, v0 # shift left 1461 sll t2, t2, v0 1462 srl t9, t3, v1 # save bits shifted out of t3 1463 or t2, t2, t9 # and put into t2 1464 sll t3, t3, v0 # shift FS's fraction 1465 b 2f 14661: 1467 negu v0 # shift right by v0 1468 subu v1, v1, v0 1469 sll t8, t3, v1 # save bits shifted out 1470 sltu t8, zero, t8 # don't lose any one's 1471 srl t3, t3, v0 # shift FS's fraction 1472 or t3, t3, t8 1473 sll t9, t2, v1 # save bits shifted out of t2 1474 or t3, t3, t9 # and put into t3 1475 srl t2, t2, v0 1476/* 1477 * round result (t0 is sign, t2 is integer part, t3 is fractional part). 1478 */ 14792: 1480 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1481 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1482 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1483 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1484 beq t0, zero, 5f # if sign is positive, truncate 1485 b 2f 14861: 1487 bne t0, zero, 5f # if sign is negative, truncate 14882: 1489 beq t3, zero, 5f # if no fraction bits, continue 1490 addu t2, t2, 1 # add rounding bit 1491 blt t2, zero, overflow_w # overflow? 1492 b 5f 14933: 1494 li v0, GUARDBIT # load guard bit for rounding 1495 addu v0, v0, t3 # add remainder 1496 sltu v1, v0, t3 # compute carry out 1497 beq v1, zero, 4f # if no carry, continue 1498 addu t2, t2, 1 # add carry to result 1499 blt t2, zero, overflow_w # overflow? 15004: 1501 bne v0, zero, 5f # if rounded remainder is zero 1502 and t2, t2, ~1 # clear LSB (round to nearest) 15035: 1504 beq t0, zero, 1f # result positive? 1505 negu t2 # convert to negative integer 15061: 1507 beq t3, zero, result_fs_w # is result exact? 1508/* 1509 * Handle inexact exception. 1510 */ 1511inexact_w: 1512 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1513 and v0, a1, MACH_FPC_ENABLE_INEXACT 1514 bne v0, zero, fpe_trap 1515 ctc1 a1, MACH_FPC_CSR # save exceptions 1516 b result_fs_w 1517 1518/* 1519 * Conversions to integer which overflow will trap (if enabled), 1520 * or generate an inexact trap (if enabled), 1521 * or generate an invalid exception. 1522 */ 1523overflow_w: 1524 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1525 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1526 bne v0, zero, fpe_trap 1527 and v0, a1, MACH_FPC_ENABLE_INEXACT 1528 bne v0, zero, inexact_w # inexact traps enabled? 1529 b invalid_w 1530 1531/* 1532 * Conversions to integer which underflow will trap (if enabled), 1533 * or generate an inexact trap (if enabled), 1534 * or generate an invalid exception. 1535 */ 1536underflow_w: 1537 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1538 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1539 bne v0, zero, fpe_trap 1540 and v0, a1, MACH_FPC_ENABLE_INEXACT 1541 bne v0, zero, inexact_w # inexact traps enabled? 1542 b invalid_w 1543 1544/* 1545 * Compare single. 1546 */ 1547cmp_s: 1548 jal get_cmp_s 1549 bne t1, SEXP_INF, 1f # is FS an infinity? 1550 bne t2, zero, unordered # FS is a NAN 15511: 1552 bne t5, SEXP_INF, 2f # is FT an infinity? 1553 bne t6, zero, unordered # FT is a NAN 15542: 1555 sll t1, t1, 23 # reassemble exp & frac 1556 or t1, t1, t2 1557 sll t5, t5, 23 # reassemble exp & frac 1558 or t5, t5, t6 1559 beq t0, zero, 1f # is FS positive? 1560 negu t1 15611: 1562 beq t4, zero, 1f # is FT positive? 1563 negu t5 15641: 1565 li v0, COND_LESS 1566 blt t1, t5, test_cond # is FS < FT? 1567 li v0, COND_EQUAL 1568 beq t1, t5, test_cond # is FS == FT? 1569 move v0, zero # FS > FT 1570 b test_cond 1571 1572/* 1573 * Compare double. 1574 */ 1575cmp_d: 1576 jal get_cmp_d 1577 bne t1, DEXP_INF, 1f # is FS an infinity? 1578 bne t2, zero, unordered 1579 bne t3, zero, unordered # FS is a NAN 15801: 1581 bne t5, DEXP_INF, 2f # is FT an infinity? 1582 bne t6, zero, unordered 1583 bne t7, zero, unordered # FT is a NAN 15842: 1585 sll t1, t1, 20 # reassemble exp & frac 1586 or t1, t1, t2 1587 sll t5, t5, 20 # reassemble exp & frac 1588 or t5, t5, t6 1589 beq t0, zero, 1f # is FS positive? 1590 not t3 # negate t1,t3 1591 not t1 1592 addu t3, t3, 1 1593 seq v0, t3, zero # compute carry 1594 addu t1, t1, v0 15951: 1596 beq t4, zero, 1f # is FT positive? 1597 not t7 # negate t5,t7 1598 not t5 1599 addu t7, t7, 1 1600 seq v0, t7, zero # compute carry 1601 addu t5, t5, v0 16021: 1603 li v0, COND_LESS 1604 blt t1, t5, test_cond # is FS(MSW) < FT(MSW)? 1605 move v0, zero 1606 bne t1, t5, test_cond # is FS(MSW) > FT(MSW)? 1607 li v0, COND_LESS 1608 bltu t3, t7, test_cond # is FS(LSW) < FT(LSW)? 1609 li v0, COND_EQUAL 1610 beq t3, t7, test_cond # is FS(LSW) == FT(LSW)? 1611 move v0, zero # FS > FT 1612test_cond: 1613 and v0, v0, a0 # condition match instruction? 1614set_cond: 1615 bne v0, zero, 1f 1616 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1617 b 2f 16181: 1619 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16202: 1621 ctc1 a1, MACH_FPC_CSR # save condition bit 1622 b done 1623 1624unordered: 1625 and v0, a0, COND_UNORDERED # this cmp match unordered? 1626 bne v0, zero, 1f 1627 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1628 b 2f 16291: 1630 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16312: 1632 and v0, a0, COND_SIGNAL 1633 beq v0, zero, 1f # is this a signaling cmp? 1634 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 1635 and v0, a1, MACH_FPC_ENABLE_INVALID 1636 bne v0, zero, fpe_trap 16371: 1638 ctc1 a1, MACH_FPC_CSR # save condition bit 1639 b done 1640 1641/* 1642 * Determine the amount to shift the fraction in order to restore the 1643 * normalized position. After that, round and handle exceptions. 1644 */ 1645norm_s: 1646 move v0, t2 1647 move t9, zero # t9 = num of leading zeros 1648 bne t2, zero, 1f 1649 move v0, t8 1650 addu t9, 32 16511: 1652 srl v1, v0, 16 1653 bne v1, zero, 1f 1654 addu t9, 16 1655 sll v0, 16 16561: 1657 srl v1, v0, 24 1658 bne v1, zero, 1f 1659 addu t9, 8 1660 sll v0, 8 16611: 1662 srl v1, v0, 28 1663 bne v1, zero, 1f 1664 addu t9, 4 1665 sll v0, 4 16661: 1667 srl v1, v0, 30 1668 bne v1, zero, 1f 1669 addu t9, 2 1670 sll v0, 2 16711: 1672 srl v1, v0, 31 1673 bne v1, zero, 1f 1674 addu t9, 1 1675/* 1676 * Now shift t2,t8 the correct number of bits. 1677 */ 16781: 1679 subu t9, t9, SLEAD_ZEROS # don't count leading zeros 1680 subu t1, t1, t9 # adjust the exponent 1681 beq t9, zero, norm_noshift_s 1682 li v1, 32 1683 blt t9, zero, 1f # if shift < 0, shift right 1684 subu v1, v1, t9 1685 sll t2, t2, t9 # shift t2,t8 left 1686 srl v0, t8, v1 # save bits shifted out 1687 or t2, t2, v0 1688 sll t8, t8, t9 1689 b norm_noshift_s 16901: 1691 negu t9 # shift t2,t8 right by t9 1692 subu v1, v1, t9 1693 sll v0, t8, v1 # save bits shifted out 1694 sltu v0, zero, v0 # be sure to save any one bits 1695 srl t8, t8, t9 1696 or t8, t8, v0 1697 sll v0, t2, v1 # save bits shifted out 1698 or t8, t8, v0 1699 srl t2, t2, t9 1700norm_noshift_s: 1701 move t5, t1 # save unrounded exponent 1702 move t6, t2 # save unrounded fraction 1703 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1704 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1705 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1706 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1707 beq t0, zero, 5f # if sign is positive, truncate 1708 b 2f 17091: 1710 bne t0, zero, 5f # if sign is negative, truncate 17112: 1712 beq t8, zero, 5f # if exact, continue 1713 addu t2, t2, 1 # add rounding bit 1714 bne t2, SIMPL_ONE<<1, 5f # need to adjust exponent? 1715 addu t1, t1, 1 # adjust exponent 1716 srl t2, t2, 1 # renormalize fraction 1717 b 5f 17183: 1719 li v0, GUARDBIT # load guard bit for rounding 1720 addu v0, v0, t8 # add remainder 1721 sltu v1, v0, t8 # compute carry out 1722 beq v1, zero, 4f # if no carry, continue 1723 addu t2, t2, 1 # add carry to result 1724 bne t2, SIMPL_ONE<<1, 4f # need to adjust exponent? 1725 addu t1, t1, 1 # adjust exponent 1726 srl t2, t2, 1 # renormalize fraction 17274: 1728 bne v0, zero, 5f # if rounded remainder is zero 1729 and t2, t2, ~1 # clear LSB (round to nearest) 17305: 1731 bgt t1, SEXP_MAX, overflow_s # overflow? 1732 blt t1, SEXP_MIN, underflow_s # underflow? 1733 bne t8, zero, inexact_s # is result inexact? 1734 addu t1, t1, SEXP_BIAS # bias exponent 1735 and t2, t2, ~SIMPL_ONE # clear implied one bit 1736 b result_fs_s 1737 1738/* 1739 * Handle inexact exception. 1740 */ 1741inexact_s: 1742 addu t1, t1, SEXP_BIAS # bias exponent 1743 and t2, t2, ~SIMPL_ONE # clear implied one bit 1744inexact_nobias_s: 1745 jal set_fd_s # save result 1746 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1747 and v0, a1, MACH_FPC_ENABLE_INEXACT 1748 bne v0, zero, fpe_trap 1749 ctc1 a1, MACH_FPC_CSR # save exceptions 1750 b done 1751 1752/* 1753 * Overflow will trap (if enabled), 1754 * or generate an inexact trap (if enabled), 1755 * or generate an infinity. 1756 */ 1757overflow_s: 1758 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1759 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1760 beq v0, zero, 1f 1761 subu t1, t1, 192 # bias exponent 1762 and t2, t2, ~SIMPL_ONE # clear implied one bit 1763 jal set_fd_s # save result 1764 b fpe_trap 17651: 1766 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1767 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1768 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 1769 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 1770 bne t0, zero, 3f 17711: 1772 li t1, SEXP_MAX # result is max finite 1773 li t2, 0x007fffff 1774 b inexact_s 17752: 1776 bne t0, zero, 1b 17773: 1778 li t1, SEXP_MAX + 1 # result is infinity 1779 move t2, zero 1780 b inexact_s 1781 1782/* 1783 * In this implementation, "tininess" is detected "after rounding" and 1784 * "loss of accuracy" is detected as "an inexact result". 1785 */ 1786underflow_s: 1787 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1788 beq v0, zero, 1f 1789/* 1790 * Underflow is enabled so compute the result and trap. 1791 */ 1792 addu t1, t1, 192 # bias exponent 1793 and t2, t2, ~SIMPL_ONE # clear implied one bit 1794 jal set_fd_s # save result 1795 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1796 b fpe_trap 1797/* 1798 * Underflow is not enabled so compute the result, 1799 * signal inexact result (if it is) and trap (if enabled). 1800 */ 18011: 1802 move t1, t5 # get unrounded exponent 1803 move t2, t6 # get unrounded fraction 1804 li t9, SEXP_MIN # compute shift amount 1805 subu t9, t9, t1 # shift t2,t8 right by t9 1806 blt t9, SFRAC_BITS+2, 3f # shift all the bits out? 1807 move t1, zero # result is inexact zero 1808 move t2, zero 1809 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1810/* 1811 * Now round the zero result. 1812 * Only need to worry about rounding to +- infinity when the sign matches. 1813 */ 1814 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1815 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_s # round to nearest 1816 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_s # round to zero 1817 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1818 beq t0, zero, inexact_nobias_s # if sign is positive, truncate 1819 b 2f 18201: 1821 bne t0, zero, inexact_nobias_s # if sign is negative, truncate 18222: 1823 addu t2, t2, 1 # add rounding bit 1824 b inexact_nobias_s 18253: 1826 li v1, 32 1827 subu v1, v1, t9 1828 sltu v0, zero, t8 # be sure to save any one bits 1829 sll t8, t2, v1 # save bits shifted out 1830 or t8, t8, v0 # include sticky bits 1831 srl t2, t2, t9 1832/* 1833 * Now round the denormalized result. 1834 */ 1835 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1836 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1837 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1838 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1839 beq t0, zero, 5f # if sign is positive, truncate 1840 b 2f 18411: 1842 bne t0, zero, 5f # if sign is negative, truncate 18432: 1844 beq t8, zero, 5f # if exact, continue 1845 addu t2, t2, 1 # add rounding bit 1846 b 5f 18473: 1848 li v0, GUARDBIT # load guard bit for rounding 1849 addu v0, v0, t8 # add remainder 1850 sltu v1, v0, t8 # compute carry out 1851 beq v1, zero, 4f # if no carry, continue 1852 addu t2, t2, 1 # add carry to result 18534: 1854 bne v0, zero, 5f # if rounded remainder is zero 1855 and t2, t2, ~1 # clear LSB (round to nearest) 18565: 1857 move t1, zero # denorm or zero exponent 1858 jal set_fd_s # save result 1859 beq t8, zero, done # check for exact result 1860 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1861 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1862 and v0, a1, MACH_FPC_ENABLE_INEXACT 1863 bne v0, zero, fpe_trap 1864 ctc1 a1, MACH_FPC_CSR # save exceptions 1865 b done 1866 1867/* 1868 * Determine the amount to shift the fraction in order to restore the 1869 * normalized position. After that, round and handle exceptions. 1870 */ 1871norm_d: 1872 move v0, t2 1873 move t9, zero # t9 = num of leading zeros 1874 bne t2, zero, 1f 1875 move v0, t3 1876 addu t9, 32 1877 bne t3, zero, 1f 1878 move v0, t8 1879 addu t9, 32 18801: 1881 srl v1, v0, 16 1882 bne v1, zero, 1f 1883 addu t9, 16 1884 sll v0, 16 18851: 1886 srl v1, v0, 24 1887 bne v1, zero, 1f 1888 addu t9, 8 1889 sll v0, 8 18901: 1891 srl v1, v0, 28 1892 bne v1, zero, 1f 1893 addu t9, 4 1894 sll v0, 4 18951: 1896 srl v1, v0, 30 1897 bne v1, zero, 1f 1898 addu t9, 2 1899 sll v0, 2 19001: 1901 srl v1, v0, 31 1902 bne v1, zero, 1f 1903 addu t9, 1 1904/* 1905 * Now shift t2,t3,t8 the correct number of bits. 1906 */ 19071: 1908 subu t9, t9, DLEAD_ZEROS # don't count leading zeros 1909 subu t1, t1, t9 # adjust the exponent 1910 beq t9, zero, norm_noshift_d 1911 li v1, 32 1912 blt t9, zero, 2f # if shift < 0, shift right 1913 blt t9, v1, 1f # shift by < 32? 1914 subu t9, t9, v1 # shift by >= 32 1915 subu v1, v1, t9 1916 sll t2, t3, t9 # shift left by t9 1917 srl v0, t8, v1 # save bits shifted out 1918 or t2, t2, v0 1919 sll t3, t8, t9 1920 move t8, zero 1921 b norm_noshift_d 19221: 1923 subu v1, v1, t9 1924 sll t2, t2, t9 # shift left by t9 1925 srl v0, t3, v1 # save bits shifted out 1926 or t2, t2, v0 1927 sll t3, t3, t9 1928 srl v0, t8, v1 # save bits shifted out 1929 or t3, t3, v0 1930 sll t8, t8, t9 1931 b norm_noshift_d 19322: 1933 negu t9 # shift right by t9 1934 subu v1, v1, t9 # (known to be < 32 bits) 1935 sll v0, t8, v1 # save bits shifted out 1936 sltu v0, zero, v0 # be sure to save any one bits 1937 srl t8, t8, t9 1938 or t8, t8, v0 1939 sll v0, t3, v1 # save bits shifted out 1940 or t8, t8, v0 1941 srl t3, t3, t9 1942 sll v0, t2, v1 # save bits shifted out 1943 or t3, t3, v0 1944 srl t2, t2, t9 1945norm_noshift_d: 1946 move t5, t1 # save unrounded exponent 1947 move t6, t2 # save unrounded fraction (MS) 1948 move t7, t3 # save unrounded fraction (LS) 1949 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1950 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1951 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1952 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1953 beq t0, zero, 5f # if sign is positive, truncate 1954 b 2f 19551: 1956 bne t0, zero, 5f # if sign is negative, truncate 19572: 1958 beq t8, zero, 5f # if exact, continue 1959 addu t3, t3, 1 # add rounding bit 1960 bne t3, zero, 5f # branch if no carry 1961 addu t2, t2, 1 # add carry 1962 bne t2, DIMPL_ONE<<1, 5f # need to adjust exponent? 1963 addu t1, t1, 1 # adjust exponent 1964 srl t2, t2, 1 # renormalize fraction 1965 b 5f 19663: 1967 li v0, GUARDBIT # load guard bit for rounding 1968 addu v0, v0, t8 # add remainder 1969 sltu v1, v0, t8 # compute carry out 1970 beq v1, zero, 4f # branch if no carry 1971 addu t3, t3, 1 # add carry 1972 bne t3, zero, 4f # branch if no carry 1973 addu t2, t2, 1 # add carry to result 1974 bne t2, DIMPL_ONE<<1, 4f # need to adjust exponent? 1975 addu t1, t1, 1 # adjust exponent 1976 srl t2, t2, 1 # renormalize fraction 19774: 1978 bne v0, zero, 5f # if rounded remainder is zero 1979 and t3, t3, ~1 # clear LSB (round to nearest) 19805: 1981 bgt t1, DEXP_MAX, overflow_d # overflow? 1982 blt t1, DEXP_MIN, underflow_d # underflow? 1983 bne t8, zero, inexact_d # is result inexact? 1984 addu t1, t1, DEXP_BIAS # bias exponent 1985 and t2, t2, ~DIMPL_ONE # clear implied one bit 1986 b result_fs_d 1987 1988/* 1989 * Handle inexact exception. 1990 */ 1991inexact_d: 1992 addu t1, t1, DEXP_BIAS # bias exponent 1993 and t2, t2, ~DIMPL_ONE # clear implied one bit 1994inexact_nobias_d: 1995 jal set_fd_d # save result 1996 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1997 and v0, a1, MACH_FPC_ENABLE_INEXACT 1998 bne v0, zero, fpe_trap 1999 ctc1 a1, MACH_FPC_CSR # save exceptions 2000 b done 2001 2002/* 2003 * Overflow will trap (if enabled), 2004 * or generate an inexact trap (if enabled), 2005 * or generate an infinity. 2006 */ 2007overflow_d: 2008 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 2009 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 2010 beq v0, zero, 1f 2011 subu t1, t1, 1536 # bias exponent 2012 and t2, t2, ~DIMPL_ONE # clear implied one bit 2013 jal set_fd_d # save result 2014 b fpe_trap 20151: 2016 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2017 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2018 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 2019 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 2020 bne t0, zero, 3f 20211: 2022 li t1, DEXP_MAX # result is max finite 2023 li t2, 0x000fffff 2024 li t3, 0xffffffff 2025 b inexact_d 20262: 2027 bne t0, zero, 1b 20283: 2029 li t1, DEXP_MAX + 1 # result is infinity 2030 move t2, zero 2031 move t3, zero 2032 b inexact_d 2033 2034/* 2035 * In this implementation, "tininess" is detected "after rounding" and 2036 * "loss of accuracy" is detected as "an inexact result". 2037 */ 2038underflow_d: 2039 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 2040 beq v0, zero, 1f 2041/* 2042 * Underflow is enabled so compute the result and trap. 2043 */ 2044 addu t1, t1, 1536 # bias exponent 2045 and t2, t2, ~DIMPL_ONE # clear implied one bit 2046 jal set_fd_d # save result 2047 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2048 b fpe_trap 2049/* 2050 * Underflow is not enabled so compute the result, 2051 * signal inexact result (if it is) and trap (if enabled). 2052 */ 20531: 2054 move t1, t5 # get unrounded exponent 2055 move t2, t6 # get unrounded fraction (MS) 2056 move t3, t7 # get unrounded fraction (LS) 2057 li t9, DEXP_MIN # compute shift amount 2058 subu t9, t9, t1 # shift t2,t8 right by t9 2059 blt t9, DFRAC_BITS+2, 3f # shift all the bits out? 2060 move t1, zero # result is inexact zero 2061 move t2, zero 2062 move t3, zero 2063 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2064/* 2065 * Now round the zero result. 2066 * Only need to worry about rounding to +- infinity when the sign matches. 2067 */ 2068 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2069 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_d # round to nearest 2070 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_d # round to zero 2071 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2072 beq t0, zero, inexact_nobias_d # if sign is positive, truncate 2073 b 2f 20741: 2075 bne t0, zero, inexact_nobias_d # if sign is negative, truncate 20762: 2077 addu t3, t3, 1 # add rounding bit 2078 b inexact_nobias_d 20793: 2080 li v1, 32 2081 blt t9, v1, 1f # shift by < 32? 2082 subu t9, t9, v1 # shift right by >= 32 2083 subu v1, v1, t9 2084 sltu v0, zero, t8 # be sure to save any one bits 2085 sll t8, t2, v1 # save bits shifted out 2086 or t8, t8, v0 # include sticky bits 2087 srl t3, t2, t9 2088 move t2, zero 2089 b 2f 20901: 2091 subu v1, v1, t9 # shift right by t9 2092 sltu v0, zero, t8 # be sure to save any one bits 2093 sll t8, t3, v1 # save bits shifted out 2094 or t8, t8, v0 # include sticky bits 2095 srl t3, t3, t9 2096 sll v0, t2, v1 # save bits shifted out 2097 or t3, t3, v0 2098 srl t2, t2, t9 2099/* 2100 * Now round the denormalized result. 2101 */ 21022: 2103 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2104 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2105 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 2106 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2107 beq t0, zero, 5f # if sign is positive, truncate 2108 b 2f 21091: 2110 bne t0, zero, 5f # if sign is negative, truncate 21112: 2112 beq t8, zero, 5f # if exact, continue 2113 addu t3, t3, 1 # add rounding bit 2114 bne t3, zero, 5f # if no carry, continue 2115 addu t2, t2, 1 # add carry 2116 b 5f 21173: 2118 li v0, GUARDBIT # load guard bit for rounding 2119 addu v0, v0, t8 # add remainder 2120 sltu v1, v0, t8 # compute carry out 2121 beq v1, zero, 4f # if no carry, continue 2122 addu t3, t3, 1 # add rounding bit 2123 bne t3, zero, 4f # if no carry, continue 2124 addu t2, t2, 1 # add carry 21254: 2126 bne v0, zero, 5f # if rounded remainder is zero 2127 and t3, t3, ~1 # clear LSB (round to nearest) 21285: 2129 move t1, zero # denorm or zero exponent 2130 jal set_fd_d # save result 2131 beq t8, zero, done # check for exact result 2132 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2133 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 2134 and v0, a1, MACH_FPC_ENABLE_INEXACT 2135 bne v0, zero, fpe_trap 2136 ctc1 a1, MACH_FPC_CSR # save exceptions 2137 b done 2138 2139/* 2140 * Signal an invalid operation if the trap is enabled; otherwise, 2141 * the result is a quiet NAN. 2142 */ 2143invalid_s: # trap invalid operation 2144 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2145 and v0, a1, MACH_FPC_ENABLE_INVALID 2146 bne v0, zero, fpe_trap 2147 ctc1 a1, MACH_FPC_CSR # save exceptions 2148 move t0, zero # result is a quiet NAN 2149 li t1, SEXP_INF 2150 li t2, SQUIET_NAN 2151 jal set_fd_s # save result (in t0,t1,t2) 2152 b done 2153 2154/* 2155 * Signal an invalid operation if the trap is enabled; otherwise, 2156 * the result is a quiet NAN. 2157 */ 2158invalid_d: # trap invalid operation 2159 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2160 and v0, a1, MACH_FPC_ENABLE_INVALID 2161 bne v0, zero, fpe_trap 2162 ctc1 a1, MACH_FPC_CSR # save exceptions 2163 move t0, zero # result is a quiet NAN 2164 li t1, DEXP_INF 2165 li t2, DQUIET_NAN0 2166 li t3, DQUIET_NAN1 2167 jal set_fd_d # save result (in t0,t1,t2,t3) 2168 b done 2169 2170/* 2171 * Signal an invalid operation if the trap is enabled; otherwise, 2172 * the result is INT_MAX or INT_MIN. 2173 */ 2174invalid_w: # trap invalid operation 2175 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2176 and v0, a1, MACH_FPC_ENABLE_INVALID 2177 bne v0, zero, fpe_trap 2178 ctc1 a1, MACH_FPC_CSR # save exceptions 2179 bne t0, zero, 1f 2180 li t2, INT_MAX # result is INT_MAX 2181 b result_fs_w 21821: 2183 li t2, INT_MIN # result is INT_MIN 2184 b result_fs_w 2185 2186/* 2187 * Trap if the hardware should have handled this case. 2188 */ 2189fpe_trap: 2190 move a2, a1 # code = FP CSR 2191 ctc1 a1, MACH_FPC_CSR # save exceptions 2192 break 0 2193 2194/* 2195 * Send an illegal instruction signal to the current process. 2196 */ 2197ill: 2198 ctc1 a1, MACH_FPC_CSR # save exceptions 2199 move a2, a0 # code = FP instruction 2200 break 0 2201 2202result_ft_s: 2203 move t0, t4 # result is FT 2204 move t1, t5 2205 move t2, t6 2206result_fs_s: # result is FS 2207 jal set_fd_s # save result (in t0,t1,t2) 2208 b done 2209 2210result_fs_w: 2211 jal set_fd_word # save result (in t2) 2212 b done 2213 2214result_ft_d: 2215 move t0, t4 # result is FT 2216 move t1, t5 2217 move t2, t6 2218 move t3, t7 2219result_fs_d: # result is FS 2220 jal set_fd_d # save result (in t0,t1,t2,t3) 2221 2222done: 2223 lw ra, STAND_RA_OFFSET(sp) 2224 addu sp, sp, STAND_FRAME_SIZE 2225 j ra 2226END(MachEmulateFP) 2227 2228/*---------------------------------------------------------------------------- 2229 * get_fs_int -- 2230 * 2231 * Read (integer) the FS register (bits 15-11). 2232 * This is an internal routine used by MachEmulateFP only. 2233 * 2234 * Results: 2235 * t0 contains the sign 2236 * t2 contains the fraction 2237 * 2238 *---------------------------------------------------------------------------- 2239 */ 2240LEAF(get_fs_int) 2241 srl a3, a0, 12 - 2 # get FS field (even regs only) 2242 and a3, a3, 0xF << 2 # mask FS field 2243 lw a3, get_fs_int_tbl(a3) # switch on register number 2244 j a3 2245 2246 .rdata 2247get_fs_int_tbl: 2248 .word get_fs_int_f0 2249 .word get_fs_int_f2 2250 .word get_fs_int_f4 2251 .word get_fs_int_f6 2252 .word get_fs_int_f8 2253 .word get_fs_int_f10 2254 .word get_fs_int_f12 2255 .word get_fs_int_f14 2256 .word get_fs_int_f16 2257 .word get_fs_int_f18 2258 .word get_fs_int_f20 2259 .word get_fs_int_f22 2260 .word get_fs_int_f24 2261 .word get_fs_int_f26 2262 .word get_fs_int_f28 2263 .word get_fs_int_f30 2264 .text 2265 2266get_fs_int_f0: 2267 mfc1 t2, $f0 2268 b get_fs_int_done 2269get_fs_int_f2: 2270 mfc1 t2, $f2 2271 b get_fs_int_done 2272get_fs_int_f4: 2273 mfc1 t2, $f4 2274 b get_fs_int_done 2275get_fs_int_f6: 2276 mfc1 t2, $f6 2277 b get_fs_int_done 2278get_fs_int_f8: 2279 mfc1 t2, $f8 2280 b get_fs_int_done 2281get_fs_int_f10: 2282 mfc1 t2, $f10 2283 b get_fs_int_done 2284get_fs_int_f12: 2285 mfc1 t2, $f12 2286 b get_fs_int_done 2287get_fs_int_f14: 2288 mfc1 t2, $f14 2289 b get_fs_int_done 2290get_fs_int_f16: 2291 mfc1 t2, $f16 2292 b get_fs_int_done 2293get_fs_int_f18: 2294 mfc1 t2, $f18 2295 b get_fs_int_done 2296get_fs_int_f20: 2297 mfc1 t2, $f20 2298 b get_fs_int_done 2299get_fs_int_f22: 2300 mfc1 t2, $f22 2301 b get_fs_int_done 2302get_fs_int_f24: 2303 mfc1 t2, $f24 2304 b get_fs_int_done 2305get_fs_int_f26: 2306 mfc1 t2, $f26 2307 b get_fs_int_done 2308get_fs_int_f28: 2309 mfc1 t2, $f28 2310 b get_fs_int_done 2311get_fs_int_f30: 2312 mfc1 t2, $f30 2313get_fs_int_done: 2314 srl t0, t2, 31 # init the sign bit 2315 bge t2, zero, 1f 2316 negu t2 23171: 2318 j ra 2319END(get_fs_int) 2320 2321/*---------------------------------------------------------------------------- 2322 * get_ft_fs_s -- 2323 * 2324 * Read (single precision) the FT register (bits 20-16) and 2325 * the FS register (bits 15-11) and break up into fields. 2326 * This is an internal routine used by MachEmulateFP only. 2327 * 2328 * Results: 2329 * t0 contains the FS sign 2330 * t1 contains the FS (biased) exponent 2331 * t2 contains the FS fraction 2332 * t4 contains the FT sign 2333 * t5 contains the FT (biased) exponent 2334 * t6 contains the FT fraction 2335 * 2336 *---------------------------------------------------------------------------- 2337 */ 2338LEAF(get_ft_fs_s) 2339 srl a3, a0, 17 - 2 # get FT field (even regs only) 2340 and a3, a3, 0xF << 2 # mask FT field 2341 lw a3, get_ft_s_tbl(a3) # switch on register number 2342 j a3 2343 2344 .rdata 2345get_ft_s_tbl: 2346 .word get_ft_s_f0 2347 .word get_ft_s_f2 2348 .word get_ft_s_f4 2349 .word get_ft_s_f6 2350 .word get_ft_s_f8 2351 .word get_ft_s_f10 2352 .word get_ft_s_f12 2353 .word get_ft_s_f14 2354 .word get_ft_s_f16 2355 .word get_ft_s_f18 2356 .word get_ft_s_f20 2357 .word get_ft_s_f22 2358 .word get_ft_s_f24 2359 .word get_ft_s_f26 2360 .word get_ft_s_f28 2361 .word get_ft_s_f30 2362 .text 2363 2364get_ft_s_f0: 2365 mfc1 t4, $f0 2366 b get_ft_s_done 2367get_ft_s_f2: 2368 mfc1 t4, $f2 2369 b get_ft_s_done 2370get_ft_s_f4: 2371 mfc1 t4, $f4 2372 b get_ft_s_done 2373get_ft_s_f6: 2374 mfc1 t4, $f6 2375 b get_ft_s_done 2376get_ft_s_f8: 2377 mfc1 t4, $f8 2378 b get_ft_s_done 2379get_ft_s_f10: 2380 mfc1 t4, $f10 2381 b get_ft_s_done 2382get_ft_s_f12: 2383 mfc1 t4, $f12 2384 b get_ft_s_done 2385get_ft_s_f14: 2386 mfc1 t4, $f14 2387 b get_ft_s_done 2388get_ft_s_f16: 2389 mfc1 t4, $f16 2390 b get_ft_s_done 2391get_ft_s_f18: 2392 mfc1 t4, $f18 2393 b get_ft_s_done 2394get_ft_s_f20: 2395 mfc1 t4, $f20 2396 b get_ft_s_done 2397get_ft_s_f22: 2398 mfc1 t4, $f22 2399 b get_ft_s_done 2400get_ft_s_f24: 2401 mfc1 t4, $f24 2402 b get_ft_s_done 2403get_ft_s_f26: 2404 mfc1 t4, $f26 2405 b get_ft_s_done 2406get_ft_s_f28: 2407 mfc1 t4, $f28 2408 b get_ft_s_done 2409get_ft_s_f30: 2410 mfc1 t4, $f30 2411get_ft_s_done: 2412 srl t5, t4, 23 # get exponent 2413 and t5, t5, 0xFF 2414 and t6, t4, 0x7FFFFF # get fraction 2415 srl t4, t4, 31 # get sign 2416 bne t5, SEXP_INF, 1f # is it a signaling NAN? 2417 and v0, t6, SSIGNAL_NAN 2418 bne v0, zero, invalid_s 24191: 2420 /* fall through to get FS */ 2421 2422/*---------------------------------------------------------------------------- 2423 * get_fs_s -- 2424 * 2425 * Read (single precision) the FS register (bits 15-11) and 2426 * break up into fields. 2427 * This is an internal routine used by MachEmulateFP only. 2428 * 2429 * Results: 2430 * t0 contains the sign 2431 * t1 contains the (biased) exponent 2432 * t2 contains the fraction 2433 * 2434 *---------------------------------------------------------------------------- 2435 */ 2436ALEAF(get_fs_s) 2437 srl a3, a0, 12 - 2 # get FS field (even regs only) 2438 and a3, a3, 0xF << 2 # mask FS field 2439 lw a3, get_fs_s_tbl(a3) # switch on register number 2440 j a3 2441 2442 .rdata 2443get_fs_s_tbl: 2444 .word get_fs_s_f0 2445 .word get_fs_s_f2 2446 .word get_fs_s_f4 2447 .word get_fs_s_f6 2448 .word get_fs_s_f8 2449 .word get_fs_s_f10 2450 .word get_fs_s_f12 2451 .word get_fs_s_f14 2452 .word get_fs_s_f16 2453 .word get_fs_s_f18 2454 .word get_fs_s_f20 2455 .word get_fs_s_f22 2456 .word get_fs_s_f24 2457 .word get_fs_s_f26 2458 .word get_fs_s_f28 2459 .word get_fs_s_f30 2460 .text 2461 2462get_fs_s_f0: 2463 mfc1 t0, $f0 2464 b get_fs_s_done 2465get_fs_s_f2: 2466 mfc1 t0, $f2 2467 b get_fs_s_done 2468get_fs_s_f4: 2469 mfc1 t0, $f4 2470 b get_fs_s_done 2471get_fs_s_f6: 2472 mfc1 t0, $f6 2473 b get_fs_s_done 2474get_fs_s_f8: 2475 mfc1 t0, $f8 2476 b get_fs_s_done 2477get_fs_s_f10: 2478 mfc1 t0, $f10 2479 b get_fs_s_done 2480get_fs_s_f12: 2481 mfc1 t0, $f12 2482 b get_fs_s_done 2483get_fs_s_f14: 2484 mfc1 t0, $f14 2485 b get_fs_s_done 2486get_fs_s_f16: 2487 mfc1 t0, $f16 2488 b get_fs_s_done 2489get_fs_s_f18: 2490 mfc1 t0, $f18 2491 b get_fs_s_done 2492get_fs_s_f20: 2493 mfc1 t0, $f20 2494 b get_fs_s_done 2495get_fs_s_f22: 2496 mfc1 t0, $f22 2497 b get_fs_s_done 2498get_fs_s_f24: 2499 mfc1 t0, $f24 2500 b get_fs_s_done 2501get_fs_s_f26: 2502 mfc1 t0, $f26 2503 b get_fs_s_done 2504get_fs_s_f28: 2505 mfc1 t0, $f28 2506 b get_fs_s_done 2507get_fs_s_f30: 2508 mfc1 t0, $f30 2509get_fs_s_done: 2510 srl t1, t0, 23 # get exponent 2511 and t1, t1, 0xFF 2512 and t2, t0, 0x7FFFFF # get fraction 2513 srl t0, t0, 31 # get sign 2514 bne t1, SEXP_INF, 1f # is it a signaling NAN? 2515 and v0, t2, SSIGNAL_NAN 2516 bne v0, zero, invalid_s 25171: 2518 j ra 2519END(get_ft_fs_s) 2520 2521/*---------------------------------------------------------------------------- 2522 * get_ft_fs_d -- 2523 * 2524 * Read (double precision) the FT register (bits 20-16) and 2525 * the FS register (bits 15-11) and break up into fields. 2526 * This is an internal routine used by MachEmulateFP only. 2527 * 2528 * Results: 2529 * t0 contains the FS sign 2530 * t1 contains the FS (biased) exponent 2531 * t2 contains the FS fraction 2532 * t3 contains the FS remaining fraction 2533 * t4 contains the FT sign 2534 * t5 contains the FT (biased) exponent 2535 * t6 contains the FT fraction 2536 * t7 contains the FT remaining fraction 2537 * 2538 *---------------------------------------------------------------------------- 2539 */ 2540LEAF(get_ft_fs_d) 2541 srl a3, a0, 17 - 2 # get FT field (even regs only) 2542 and a3, a3, 0xF << 2 # mask FT field 2543 lw a3, get_ft_d_tbl(a3) # switch on register number 2544 j a3 2545 2546 .rdata 2547get_ft_d_tbl: 2548 .word get_ft_d_f0 2549 .word get_ft_d_f2 2550 .word get_ft_d_f4 2551 .word get_ft_d_f6 2552 .word get_ft_d_f8 2553 .word get_ft_d_f10 2554 .word get_ft_d_f12 2555 .word get_ft_d_f14 2556 .word get_ft_d_f16 2557 .word get_ft_d_f18 2558 .word get_ft_d_f20 2559 .word get_ft_d_f22 2560 .word get_ft_d_f24 2561 .word get_ft_d_f26 2562 .word get_ft_d_f28 2563 .word get_ft_d_f30 2564 .text 2565 2566get_ft_d_f0: 2567 mfc1 t7, $f0 2568 mfc1 t4, $f1 2569 b get_ft_d_done 2570get_ft_d_f2: 2571 mfc1 t7, $f2 2572 mfc1 t4, $f3 2573 b get_ft_d_done 2574get_ft_d_f4: 2575 mfc1 t7, $f4 2576 mfc1 t4, $f5 2577 b get_ft_d_done 2578get_ft_d_f6: 2579 mfc1 t7, $f6 2580 mfc1 t4, $f7 2581 b get_ft_d_done 2582get_ft_d_f8: 2583 mfc1 t7, $f8 2584 mfc1 t4, $f9 2585 b get_ft_d_done 2586get_ft_d_f10: 2587 mfc1 t7, $f10 2588 mfc1 t4, $f11 2589 b get_ft_d_done 2590get_ft_d_f12: 2591 mfc1 t7, $f12 2592 mfc1 t4, $f13 2593 b get_ft_d_done 2594get_ft_d_f14: 2595 mfc1 t7, $f14 2596 mfc1 t4, $f15 2597 b get_ft_d_done 2598get_ft_d_f16: 2599 mfc1 t7, $f16 2600 mfc1 t4, $f17 2601 b get_ft_d_done 2602get_ft_d_f18: 2603 mfc1 t7, $f18 2604 mfc1 t4, $f19 2605 b get_ft_d_done 2606get_ft_d_f20: 2607 mfc1 t7, $f20 2608 mfc1 t4, $f21 2609 b get_ft_d_done 2610get_ft_d_f22: 2611 mfc1 t7, $f22 2612 mfc1 t4, $f23 2613 b get_ft_d_done 2614get_ft_d_f24: 2615 mfc1 t7, $f24 2616 mfc1 t4, $f25 2617 b get_ft_d_done 2618get_ft_d_f26: 2619 mfc1 t7, $f26 2620 mfc1 t4, $f27 2621 b get_ft_d_done 2622get_ft_d_f28: 2623 mfc1 t7, $f28 2624 mfc1 t4, $f29 2625 b get_ft_d_done 2626get_ft_d_f30: 2627 mfc1 t7, $f30 2628 mfc1 t4, $f31 2629get_ft_d_done: 2630 srl t5, t4, 20 # get exponent 2631 and t5, t5, 0x7FF 2632 and t6, t4, 0xFFFFF # get fraction 2633 srl t4, t4, 31 # get sign 2634 bne t5, DEXP_INF, 1f # is it a signaling NAN? 2635 and v0, t6, DSIGNAL_NAN 2636 bne v0, zero, invalid_d 26371: 2638 /* fall through to get FS */ 2639 2640/*---------------------------------------------------------------------------- 2641 * get_fs_d -- 2642 * 2643 * Read (double precision) the FS register (bits 15-11) and 2644 * break up into fields. 2645 * This is an internal routine used by MachEmulateFP only. 2646 * 2647 * Results: 2648 * t0 contains the sign 2649 * t1 contains the (biased) exponent 2650 * t2 contains the fraction 2651 * t3 contains the remaining fraction 2652 * 2653 *---------------------------------------------------------------------------- 2654 */ 2655ALEAF(get_fs_d) 2656 srl a3, a0, 12 - 2 # get FS field (even regs only) 2657 and a3, a3, 0xF << 2 # mask FS field 2658 lw a3, get_fs_d_tbl(a3) # switch on register number 2659 j a3 2660 2661 .rdata 2662get_fs_d_tbl: 2663 .word get_fs_d_f0 2664 .word get_fs_d_f2 2665 .word get_fs_d_f4 2666 .word get_fs_d_f6 2667 .word get_fs_d_f8 2668 .word get_fs_d_f10 2669 .word get_fs_d_f12 2670 .word get_fs_d_f14 2671 .word get_fs_d_f16 2672 .word get_fs_d_f18 2673 .word get_fs_d_f20 2674 .word get_fs_d_f22 2675 .word get_fs_d_f24 2676 .word get_fs_d_f26 2677 .word get_fs_d_f28 2678 .word get_fs_d_f30 2679 .text 2680 2681get_fs_d_f0: 2682 mfc1 t3, $f0 2683 mfc1 t0, $f1 2684 b get_fs_d_done 2685get_fs_d_f2: 2686 mfc1 t3, $f2 2687 mfc1 t0, $f3 2688 b get_fs_d_done 2689get_fs_d_f4: 2690 mfc1 t3, $f4 2691 mfc1 t0, $f5 2692 b get_fs_d_done 2693get_fs_d_f6: 2694 mfc1 t3, $f6 2695 mfc1 t0, $f7 2696 b get_fs_d_done 2697get_fs_d_f8: 2698 mfc1 t3, $f8 2699 mfc1 t0, $f9 2700 b get_fs_d_done 2701get_fs_d_f10: 2702 mfc1 t3, $f10 2703 mfc1 t0, $f11 2704 b get_fs_d_done 2705get_fs_d_f12: 2706 mfc1 t3, $f12 2707 mfc1 t0, $f13 2708 b get_fs_d_done 2709get_fs_d_f14: 2710 mfc1 t3, $f14 2711 mfc1 t0, $f15 2712 b get_fs_d_done 2713get_fs_d_f16: 2714 mfc1 t3, $f16 2715 mfc1 t0, $f17 2716 b get_fs_d_done 2717get_fs_d_f18: 2718 mfc1 t3, $f18 2719 mfc1 t0, $f19 2720 b get_fs_d_done 2721get_fs_d_f20: 2722 mfc1 t3, $f20 2723 mfc1 t0, $f21 2724 b get_fs_d_done 2725get_fs_d_f22: 2726 mfc1 t3, $f22 2727 mfc1 t0, $f23 2728 b get_fs_d_done 2729get_fs_d_f24: 2730 mfc1 t3, $f24 2731 mfc1 t0, $f25 2732 b get_fs_d_done 2733get_fs_d_f26: 2734 mfc1 t3, $f26 2735 mfc1 t0, $f27 2736 b get_fs_d_done 2737get_fs_d_f28: 2738 mfc1 t3, $f28 2739 mfc1 t0, $f29 2740 b get_fs_d_done 2741get_fs_d_f30: 2742 mfc1 t3, $f30 2743 mfc1 t0, $f31 2744get_fs_d_done: 2745 srl t1, t0, 20 # get exponent 2746 and t1, t1, 0x7FF 2747 and t2, t0, 0xFFFFF # get fraction 2748 srl t0, t0, 31 # get sign 2749 bne t1, DEXP_INF, 1f # is it a signaling NAN? 2750 and v0, t2, DSIGNAL_NAN 2751 bne v0, zero, invalid_d 27521: 2753 j ra 2754END(get_ft_fs_d) 2755 2756/*---------------------------------------------------------------------------- 2757 * get_cmp_s -- 2758 * 2759 * Read (single precision) the FS register (bits 15-11) and 2760 * the FT register (bits 20-16) and break up into fields. 2761 * This is an internal routine used by MachEmulateFP only. 2762 * 2763 * Results: 2764 * t0 contains the sign 2765 * t1 contains the (biased) exponent 2766 * t2 contains the fraction 2767 * t4 contains the sign 2768 * t5 contains the (biased) exponent 2769 * t6 contains the fraction 2770 * 2771 *---------------------------------------------------------------------------- 2772 */ 2773LEAF(get_cmp_s) 2774 srl a3, a0, 12 - 2 # get FS field (even regs only) 2775 and a3, a3, 0xF << 2 # mask FS field 2776 lw a3, cmp_fs_s_tbl(a3) # switch on register number 2777 j a3 2778 2779 .rdata 2780cmp_fs_s_tbl: 2781 .word cmp_fs_s_f0 2782 .word cmp_fs_s_f2 2783 .word cmp_fs_s_f4 2784 .word cmp_fs_s_f6 2785 .word cmp_fs_s_f8 2786 .word cmp_fs_s_f10 2787 .word cmp_fs_s_f12 2788 .word cmp_fs_s_f14 2789 .word cmp_fs_s_f16 2790 .word cmp_fs_s_f18 2791 .word cmp_fs_s_f20 2792 .word cmp_fs_s_f22 2793 .word cmp_fs_s_f24 2794 .word cmp_fs_s_f26 2795 .word cmp_fs_s_f28 2796 .word cmp_fs_s_f30 2797 .text 2798 2799cmp_fs_s_f0: 2800 mfc1 t0, $f0 2801 b cmp_fs_s_done 2802cmp_fs_s_f2: 2803 mfc1 t0, $f2 2804 b cmp_fs_s_done 2805cmp_fs_s_f4: 2806 mfc1 t0, $f4 2807 b cmp_fs_s_done 2808cmp_fs_s_f6: 2809 mfc1 t0, $f6 2810 b cmp_fs_s_done 2811cmp_fs_s_f8: 2812 mfc1 t0, $f8 2813 b cmp_fs_s_done 2814cmp_fs_s_f10: 2815 mfc1 t0, $f10 2816 b cmp_fs_s_done 2817cmp_fs_s_f12: 2818 mfc1 t0, $f12 2819 b cmp_fs_s_done 2820cmp_fs_s_f14: 2821 mfc1 t0, $f14 2822 b cmp_fs_s_done 2823cmp_fs_s_f16: 2824 mfc1 t0, $f16 2825 b cmp_fs_s_done 2826cmp_fs_s_f18: 2827 mfc1 t0, $f18 2828 b cmp_fs_s_done 2829cmp_fs_s_f20: 2830 mfc1 t0, $f20 2831 b cmp_fs_s_done 2832cmp_fs_s_f22: 2833 mfc1 t0, $f22 2834 b cmp_fs_s_done 2835cmp_fs_s_f24: 2836 mfc1 t0, $f24 2837 b cmp_fs_s_done 2838cmp_fs_s_f26: 2839 mfc1 t0, $f26 2840 b cmp_fs_s_done 2841cmp_fs_s_f28: 2842 mfc1 t0, $f28 2843 b cmp_fs_s_done 2844cmp_fs_s_f30: 2845 mfc1 t0, $f30 2846cmp_fs_s_done: 2847 srl t1, t0, 23 # get exponent 2848 and t1, t1, 0xFF 2849 and t2, t0, 0x7FFFFF # get fraction 2850 srl t0, t0, 31 # get sign 2851 2852 srl a3, a0, 17 - 2 # get FT field (even regs only) 2853 and a3, a3, 0xF << 2 # mask FT field 2854 lw a3, cmp_ft_s_tbl(a3) # switch on register number 2855 j a3 2856 2857 .rdata 2858cmp_ft_s_tbl: 2859 .word cmp_ft_s_f0 2860 .word cmp_ft_s_f2 2861 .word cmp_ft_s_f4 2862 .word cmp_ft_s_f6 2863 .word cmp_ft_s_f8 2864 .word cmp_ft_s_f10 2865 .word cmp_ft_s_f12 2866 .word cmp_ft_s_f14 2867 .word cmp_ft_s_f16 2868 .word cmp_ft_s_f18 2869 .word cmp_ft_s_f20 2870 .word cmp_ft_s_f22 2871 .word cmp_ft_s_f24 2872 .word cmp_ft_s_f26 2873 .word cmp_ft_s_f28 2874 .word cmp_ft_s_f30 2875 .text 2876 2877cmp_ft_s_f0: 2878 mfc1 t4, $f0 2879 b cmp_ft_s_done 2880cmp_ft_s_f2: 2881 mfc1 t4, $f2 2882 b cmp_ft_s_done 2883cmp_ft_s_f4: 2884 mfc1 t4, $f4 2885 b cmp_ft_s_done 2886cmp_ft_s_f6: 2887 mfc1 t4, $f6 2888 b cmp_ft_s_done 2889cmp_ft_s_f8: 2890 mfc1 t4, $f8 2891 b cmp_ft_s_done 2892cmp_ft_s_f10: 2893 mfc1 t4, $f10 2894 b cmp_ft_s_done 2895cmp_ft_s_f12: 2896 mfc1 t4, $f12 2897 b cmp_ft_s_done 2898cmp_ft_s_f14: 2899 mfc1 t4, $f14 2900 b cmp_ft_s_done 2901cmp_ft_s_f16: 2902 mfc1 t4, $f16 2903 b cmp_ft_s_done 2904cmp_ft_s_f18: 2905 mfc1 t4, $f18 2906 b cmp_ft_s_done 2907cmp_ft_s_f20: 2908 mfc1 t4, $f20 2909 b cmp_ft_s_done 2910cmp_ft_s_f22: 2911 mfc1 t4, $f22 2912 b cmp_ft_s_done 2913cmp_ft_s_f24: 2914 mfc1 t4, $f24 2915 b cmp_ft_s_done 2916cmp_ft_s_f26: 2917 mfc1 t4, $f26 2918 b cmp_ft_s_done 2919cmp_ft_s_f28: 2920 mfc1 t4, $f28 2921 b cmp_ft_s_done 2922cmp_ft_s_f30: 2923 mfc1 t4, $f30 2924cmp_ft_s_done: 2925 srl t5, t4, 23 # get exponent 2926 and t5, t5, 0xFF 2927 and t6, t4, 0x7FFFFF # get fraction 2928 srl t4, t4, 31 # get sign 2929 j ra 2930END(get_cmp_s) 2931 2932/*---------------------------------------------------------------------------- 2933 * get_cmp_d -- 2934 * 2935 * Read (double precision) the FS register (bits 15-11) and 2936 * the FT register (bits 20-16) and break up into fields. 2937 * This is an internal routine used by MachEmulateFP only. 2938 * 2939 * Results: 2940 * t0 contains the sign 2941 * t1 contains the (biased) exponent 2942 * t2 contains the fraction 2943 * t3 contains the remaining fraction 2944 * t4 contains the sign 2945 * t5 contains the (biased) exponent 2946 * t6 contains the fraction 2947 * t7 contains the remaining fraction 2948 * 2949 *---------------------------------------------------------------------------- 2950 */ 2951LEAF(get_cmp_d) 2952 srl a3, a0, 12 - 2 # get FS field (even regs only) 2953 and a3, a3, 0xF << 2 # mask FS field 2954 lw a3, cmp_fs_d_tbl(a3) # switch on register number 2955 j a3 2956 2957 .rdata 2958cmp_fs_d_tbl: 2959 .word cmp_fs_d_f0 2960 .word cmp_fs_d_f2 2961 .word cmp_fs_d_f4 2962 .word cmp_fs_d_f6 2963 .word cmp_fs_d_f8 2964 .word cmp_fs_d_f10 2965 .word cmp_fs_d_f12 2966 .word cmp_fs_d_f14 2967 .word cmp_fs_d_f16 2968 .word cmp_fs_d_f18 2969 .word cmp_fs_d_f20 2970 .word cmp_fs_d_f22 2971 .word cmp_fs_d_f24 2972 .word cmp_fs_d_f26 2973 .word cmp_fs_d_f28 2974 .word cmp_fs_d_f30 2975 .text 2976 2977cmp_fs_d_f0: 2978 mfc1 t3, $f0 2979 mfc1 t0, $f1 2980 b cmp_fs_d_done 2981cmp_fs_d_f2: 2982 mfc1 t3, $f2 2983 mfc1 t0, $f3 2984 b cmp_fs_d_done 2985cmp_fs_d_f4: 2986 mfc1 t3, $f4 2987 mfc1 t0, $f5 2988 b cmp_fs_d_done 2989cmp_fs_d_f6: 2990 mfc1 t3, $f6 2991 mfc1 t0, $f7 2992 b cmp_fs_d_done 2993cmp_fs_d_f8: 2994 mfc1 t3, $f8 2995 mfc1 t0, $f9 2996 b cmp_fs_d_done 2997cmp_fs_d_f10: 2998 mfc1 t3, $f10 2999 mfc1 t0, $f11 3000 b cmp_fs_d_done 3001cmp_fs_d_f12: 3002 mfc1 t3, $f12 3003 mfc1 t0, $f13 3004 b cmp_fs_d_done 3005cmp_fs_d_f14: 3006 mfc1 t3, $f14 3007 mfc1 t0, $f15 3008 b cmp_fs_d_done 3009cmp_fs_d_f16: 3010 mfc1 t3, $f16 3011 mfc1 t0, $f17 3012 b cmp_fs_d_done 3013cmp_fs_d_f18: 3014 mfc1 t3, $f18 3015 mfc1 t0, $f19 3016 b cmp_fs_d_done 3017cmp_fs_d_f20: 3018 mfc1 t3, $f20 3019 mfc1 t0, $f21 3020 b cmp_fs_d_done 3021cmp_fs_d_f22: 3022 mfc1 t3, $f22 3023 mfc1 t0, $f23 3024 b cmp_fs_d_done 3025cmp_fs_d_f24: 3026 mfc1 t3, $f24 3027 mfc1 t0, $f25 3028 b cmp_fs_d_done 3029cmp_fs_d_f26: 3030 mfc1 t3, $f26 3031 mfc1 t0, $f27 3032 b cmp_fs_d_done 3033cmp_fs_d_f28: 3034 mfc1 t3, $f28 3035 mfc1 t0, $f29 3036 b cmp_fs_d_done 3037cmp_fs_d_f30: 3038 mfc1 t3, $f30 3039 mfc1 t0, $f31 3040cmp_fs_d_done: 3041 srl t1, t0, 20 # get exponent 3042 and t1, t1, 0x7FF 3043 and t2, t0, 0xFFFFF # get fraction 3044 srl t0, t0, 31 # get sign 3045 3046 srl a3, a0, 17 - 2 # get FT field (even regs only) 3047 and a3, a3, 0xF << 2 # mask FT field 3048 lw a3, cmp_ft_d_tbl(a3) # switch on register number 3049 j a3 3050 3051 .rdata 3052cmp_ft_d_tbl: 3053 .word cmp_ft_d_f0 3054 .word cmp_ft_d_f2 3055 .word cmp_ft_d_f4 3056 .word cmp_ft_d_f6 3057 .word cmp_ft_d_f8 3058 .word cmp_ft_d_f10 3059 .word cmp_ft_d_f12 3060 .word cmp_ft_d_f14 3061 .word cmp_ft_d_f16 3062 .word cmp_ft_d_f18 3063 .word cmp_ft_d_f20 3064 .word cmp_ft_d_f22 3065 .word cmp_ft_d_f24 3066 .word cmp_ft_d_f26 3067 .word cmp_ft_d_f28 3068 .word cmp_ft_d_f30 3069 .text 3070 3071cmp_ft_d_f0: 3072 mfc1 t7, $f0 3073 mfc1 t4, $f1 3074 b cmp_ft_d_done 3075cmp_ft_d_f2: 3076 mfc1 t7, $f2 3077 mfc1 t4, $f3 3078 b cmp_ft_d_done 3079cmp_ft_d_f4: 3080 mfc1 t7, $f4 3081 mfc1 t4, $f5 3082 b cmp_ft_d_done 3083cmp_ft_d_f6: 3084 mfc1 t7, $f6 3085 mfc1 t4, $f7 3086 b cmp_ft_d_done 3087cmp_ft_d_f8: 3088 mfc1 t7, $f8 3089 mfc1 t4, $f9 3090 b cmp_ft_d_done 3091cmp_ft_d_f10: 3092 mfc1 t7, $f10 3093 mfc1 t4, $f11 3094 b cmp_ft_d_done 3095cmp_ft_d_f12: 3096 mfc1 t7, $f12 3097 mfc1 t4, $f13 3098 b cmp_ft_d_done 3099cmp_ft_d_f14: 3100 mfc1 t7, $f14 3101 mfc1 t4, $f15 3102 b cmp_ft_d_done 3103cmp_ft_d_f16: 3104 mfc1 t7, $f16 3105 mfc1 t4, $f17 3106 b cmp_ft_d_done 3107cmp_ft_d_f18: 3108 mfc1 t7, $f18 3109 mfc1 t4, $f19 3110 b cmp_ft_d_done 3111cmp_ft_d_f20: 3112 mfc1 t7, $f20 3113 mfc1 t4, $f21 3114 b cmp_ft_d_done 3115cmp_ft_d_f22: 3116 mfc1 t7, $f22 3117 mfc1 t4, $f23 3118 b cmp_ft_d_done 3119cmp_ft_d_f24: 3120 mfc1 t7, $f24 3121 mfc1 t4, $f25 3122 b cmp_ft_d_done 3123cmp_ft_d_f26: 3124 mfc1 t7, $f26 3125 mfc1 t4, $f27 3126 b cmp_ft_d_done 3127cmp_ft_d_f28: 3128 mfc1 t7, $f28 3129 mfc1 t4, $f29 3130 b cmp_ft_d_done 3131cmp_ft_d_f30: 3132 mfc1 t7, $f30 3133 mfc1 t4, $f31 3134cmp_ft_d_done: 3135 srl t5, t4, 20 # get exponent 3136 and t5, t5, 0x7FF 3137 and t6, t4, 0xFFFFF # get fraction 3138 srl t4, t4, 31 # get sign 3139 j ra 3140END(get_cmp_d) 3141 3142/*---------------------------------------------------------------------------- 3143 * set_fd_s -- 3144 * 3145 * Write (single precision) the FD register (bits 10-6). 3146 * This is an internal routine used by MachEmulateFP only. 3147 * 3148 * Arguments: 3149 * a0 contains the FP instruction 3150 * t0 contains the sign 3151 * t1 contains the (biased) exponent 3152 * t2 contains the fraction 3153 * 3154 * set_fd_word -- 3155 * 3156 * Write (integer) the FD register (bits 10-6). 3157 * This is an internal routine used by MachEmulateFP only. 3158 * 3159 * Arguments: 3160 * a0 contains the FP instruction 3161 * t2 contains the integer 3162 * 3163 *---------------------------------------------------------------------------- 3164 */ 3165LEAF(set_fd_s) 3166 sll t0, t0, 31 # position sign 3167 sll t1, t1, 23 # position exponent 3168 or t2, t2, t0 3169 or t2, t2, t1 3170ALEAF(set_fd_word) 3171 srl a3, a0, 7 - 2 # get FD field (even regs only) 3172 and a3, a3, 0xF << 2 # mask FT field 3173 lw a3, set_fd_s_tbl(a3) # switch on register number 3174 j a3 3175 3176 .rdata 3177set_fd_s_tbl: 3178 .word set_fd_s_f0 3179 .word set_fd_s_f2 3180 .word set_fd_s_f4 3181 .word set_fd_s_f6 3182 .word set_fd_s_f8 3183 .word set_fd_s_f10 3184 .word set_fd_s_f12 3185 .word set_fd_s_f14 3186 .word set_fd_s_f16 3187 .word set_fd_s_f18 3188 .word set_fd_s_f20 3189 .word set_fd_s_f22 3190 .word set_fd_s_f24 3191 .word set_fd_s_f26 3192 .word set_fd_s_f28 3193 .word set_fd_s_f30 3194 .text 3195 3196set_fd_s_f0: 3197 mtc1 t2, $f0 3198 j ra 3199set_fd_s_f2: 3200 mtc1 t2, $f2 3201 j ra 3202set_fd_s_f4: 3203 mtc1 t2, $f4 3204 j ra 3205set_fd_s_f6: 3206 mtc1 t2, $f6 3207 j ra 3208set_fd_s_f8: 3209 mtc1 t2, $f8 3210 j ra 3211set_fd_s_f10: 3212 mtc1 t2, $f10 3213 j ra 3214set_fd_s_f12: 3215 mtc1 t2, $f12 3216 j ra 3217set_fd_s_f14: 3218 mtc1 t2, $f14 3219 j ra 3220set_fd_s_f16: 3221 mtc1 t2, $f16 3222 j ra 3223set_fd_s_f18: 3224 mtc1 t2, $f18 3225 j ra 3226set_fd_s_f20: 3227 mtc1 t2, $f20 3228 j ra 3229set_fd_s_f22: 3230 mtc1 t2, $f22 3231 j ra 3232set_fd_s_f24: 3233 mtc1 t2, $f24 3234 j ra 3235set_fd_s_f26: 3236 mtc1 t2, $f26 3237 j ra 3238set_fd_s_f28: 3239 mtc1 t2, $f28 3240 j ra 3241set_fd_s_f30: 3242 mtc1 t2, $f30 3243 j ra 3244END(set_fd_s) 3245 3246/*---------------------------------------------------------------------------- 3247 * set_fd_d -- 3248 * 3249 * Write (double precision) the FT register (bits 10-6). 3250 * This is an internal routine used by MachEmulateFP only. 3251 * 3252 * Arguments: 3253 * a0 contains the FP instruction 3254 * t0 contains the sign 3255 * t1 contains the (biased) exponent 3256 * t2 contains the fraction 3257 * t3 contains the remaining fraction 3258 * 3259 *---------------------------------------------------------------------------- 3260 */ 3261LEAF(set_fd_d) 3262 sll t0, t0, 31 # set sign 3263 sll t1, t1, 20 # set exponent 3264 or t0, t0, t1 3265 or t0, t0, t2 # set fraction 3266 srl a3, a0, 7 - 2 # get FD field (even regs only) 3267 and a3, a3, 0xF << 2 # mask FD field 3268 lw a3, set_fd_d_tbl(a3) # switch on register number 3269 j a3 3270 3271 .rdata 3272set_fd_d_tbl: 3273 .word set_fd_d_f0 3274 .word set_fd_d_f2 3275 .word set_fd_d_f4 3276 .word set_fd_d_f6 3277 .word set_fd_d_f8 3278 .word set_fd_d_f10 3279 .word set_fd_d_f12 3280 .word set_fd_d_f14 3281 .word set_fd_d_f16 3282 .word set_fd_d_f18 3283 .word set_fd_d_f20 3284 .word set_fd_d_f22 3285 .word set_fd_d_f24 3286 .word set_fd_d_f26 3287 .word set_fd_d_f28 3288 .word set_fd_d_f30 3289 .text 3290 3291set_fd_d_f0: 3292 mtc1 t3, $f0 3293 mtc1 t0, $f1 3294 j ra 3295set_fd_d_f2: 3296 mtc1 t3, $f2 3297 mtc1 t0, $f3 3298 j ra 3299set_fd_d_f4: 3300 mtc1 t3, $f4 3301 mtc1 t0, $f5 3302 j ra 3303set_fd_d_f6: 3304 mtc1 t3, $f6 3305 mtc1 t0, $f7 3306 j ra 3307set_fd_d_f8: 3308 mtc1 t3, $f8 3309 mtc1 t0, $f9 3310 j ra 3311set_fd_d_f10: 3312 mtc1 t3, $f10 3313 mtc1 t0, $f11 3314 j ra 3315set_fd_d_f12: 3316 mtc1 t3, $f12 3317 mtc1 t0, $f13 3318 j ra 3319set_fd_d_f14: 3320 mtc1 t3, $f14 3321 mtc1 t0, $f15 3322 j ra 3323set_fd_d_f16: 3324 mtc1 t3, $f16 3325 mtc1 t0, $f17 3326 j ra 3327set_fd_d_f18: 3328 mtc1 t3, $f18 3329 mtc1 t0, $f19 3330 j ra 3331set_fd_d_f20: 3332 mtc1 t3, $f20 3333 mtc1 t0, $f21 3334 j ra 3335set_fd_d_f22: 3336 mtc1 t3, $f22 3337 mtc1 t0, $f23 3338 j ra 3339set_fd_d_f24: 3340 mtc1 t3, $f24 3341 mtc1 t0, $f25 3342 j ra 3343set_fd_d_f26: 3344 mtc1 t3, $f26 3345 mtc1 t0, $f27 3346 j ra 3347set_fd_d_f28: 3348 mtc1 t3, $f28 3349 mtc1 t0, $f29 3350 j ra 3351set_fd_d_f30: 3352 mtc1 t3, $f30 3353 mtc1 t0, $f31 3354 j ra 3355END(set_fd_d) 3356 3357/*---------------------------------------------------------------------------- 3358 * renorm_fs_s -- 3359 * 3360 * Results: 3361 * t1 unbiased exponent 3362 * t2 normalized fraction 3363 * 3364 *---------------------------------------------------------------------------- 3365 */ 3366LEAF(renorm_fs_s) 3367/* 3368 * Find out how many leading zero bits are in t2 and put in t9. 3369 */ 3370 move v0, t2 3371 move t9, zero 3372 srl v1, v0, 16 3373 bne v1, zero, 1f 3374 addu t9, 16 3375 sll v0, 16 33761: 3377 srl v1, v0, 24 3378 bne v1, zero, 1f 3379 addu t9, 8 3380 sll v0, 8 33811: 3382 srl v1, v0, 28 3383 bne v1, zero, 1f 3384 addu t9, 4 3385 sll v0, 4 33861: 3387 srl v1, v0, 30 3388 bne v1, zero, 1f 3389 addu t9, 2 3390 sll v0, 2 33911: 3392 srl v1, v0, 31 3393 bne v1, zero, 1f 3394 addu t9, 1 3395/* 3396 * Now shift t2 the correct number of bits. 3397 */ 33981: 3399 subu t9, t9, SLEAD_ZEROS # don't count normal leading zeros 3400 li t1, SEXP_MIN 3401 subu t1, t1, t9 # adjust exponent 3402 sll t2, t2, t9 3403 j ra 3404END(renorm_fs_s) 3405 3406/*---------------------------------------------------------------------------- 3407 * renorm_fs_d -- 3408 * 3409 * Results: 3410 * t1 unbiased exponent 3411 * t2,t3 normalized fraction 3412 * 3413 *---------------------------------------------------------------------------- 3414 */ 3415LEAF(renorm_fs_d) 3416/* 3417 * Find out how many leading zero bits are in t2,t3 and put in t9. 3418 */ 3419 move v0, t2 3420 move t9, zero 3421 bne t2, zero, 1f 3422 move v0, t3 3423 addu t9, 32 34241: 3425 srl v1, v0, 16 3426 bne v1, zero, 1f 3427 addu t9, 16 3428 sll v0, 16 34291: 3430 srl v1, v0, 24 3431 bne v1, zero, 1f 3432 addu t9, 8 3433 sll v0, 8 34341: 3435 srl v1, v0, 28 3436 bne v1, zero, 1f 3437 addu t9, 4 3438 sll v0, 4 34391: 3440 srl v1, v0, 30 3441 bne v1, zero, 1f 3442 addu t9, 2 3443 sll v0, 2 34441: 3445 srl v1, v0, 31 3446 bne v1, zero, 1f 3447 addu t9, 1 3448/* 3449 * Now shift t2,t3 the correct number of bits. 3450 */ 34511: 3452 subu t9, t9, DLEAD_ZEROS # don't count normal leading zeros 3453 li t1, DEXP_MIN 3454 subu t1, t1, t9 # adjust exponent 3455 li v0, 32 3456 blt t9, v0, 1f 3457 subu t9, t9, v0 # shift fraction left >= 32 bits 3458 sll t2, t3, t9 3459 move t3, zero 3460 j ra 34611: 3462 subu v0, v0, t9 # shift fraction left < 32 bits 3463 sll t2, t2, t9 3464 srl v1, t3, v0 3465 or t2, t2, v1 3466 sll t3, t3, t9 3467 j ra 3468END(renorm_fs_d) 3469 3470/*---------------------------------------------------------------------------- 3471 * renorm_ft_s -- 3472 * 3473 * Results: 3474 * t5 unbiased exponent 3475 * t6 normalized fraction 3476 * 3477 *---------------------------------------------------------------------------- 3478 */ 3479LEAF(renorm_ft_s) 3480/* 3481 * Find out how many leading zero bits are in t6 and put in t9. 3482 */ 3483 move v0, t6 3484 move t9, zero 3485 srl v1, v0, 16 3486 bne v1, zero, 1f 3487 addu t9, 16 3488 sll v0, 16 34891: 3490 srl v1, v0, 24 3491 bne v1, zero, 1f 3492 addu t9, 8 3493 sll v0, 8 34941: 3495 srl v1, v0, 28 3496 bne v1, zero, 1f 3497 addu t9, 4 3498 sll v0, 4 34991: 3500 srl v1, v0, 30 3501 bne v1, zero, 1f 3502 addu t9, 2 3503 sll v0, 2 35041: 3505 srl v1, v0, 31 3506 bne v1, zero, 1f 3507 addu t9, 1 3508/* 3509 * Now shift t6 the correct number of bits. 3510 */ 35111: 3512 subu t9, t9, SLEAD_ZEROS # don't count normal leading zeros 3513 li t5, SEXP_MIN 3514 subu t5, t5, t9 # adjust exponent 3515 sll t6, t6, t9 3516 j ra 3517END(renorm_ft_s) 3518 3519/*---------------------------------------------------------------------------- 3520 * renorm_ft_d -- 3521 * 3522 * Results: 3523 * t5 unbiased exponent 3524 * t6,t7 normalized fraction 3525 * 3526 *---------------------------------------------------------------------------- 3527 */ 3528LEAF(renorm_ft_d) 3529/* 3530 * Find out how many leading zero bits are in t6,t7 and put in t9. 3531 */ 3532 move v0, t6 3533 move t9, zero 3534 bne t6, zero, 1f 3535 move v0, t7 3536 addu t9, 32 35371: 3538 srl v1, v0, 16 3539 bne v1, zero, 1f 3540 addu t9, 16 3541 sll v0, 16 35421: 3543 srl v1, v0, 24 3544 bne v1, zero, 1f 3545 addu t9, 8 3546 sll v0, 8 35471: 3548 srl v1, v0, 28 3549 bne v1, zero, 1f 3550 addu t9, 4 3551 sll v0, 4 35521: 3553 srl v1, v0, 30 3554 bne v1, zero, 1f 3555 addu t9, 2 3556 sll v0, 2 35571: 3558 srl v1, v0, 31 3559 bne v1, zero, 1f 3560 addu t9, 1 3561/* 3562 * Now shift t6,t7 the correct number of bits. 3563 */ 35641: 3565 subu t9, t9, DLEAD_ZEROS # don't count normal leading zeros 3566 li t5, DEXP_MIN 3567 subu t5, t5, t9 # adjust exponent 3568 li v0, 32 3569 blt t9, v0, 1f 3570 subu t9, t9, v0 # shift fraction left >= 32 bits 3571 sll t6, t7, t9 3572 move t7, zero 3573 j ra 35741: 3575 subu v0, v0, t9 # shift fraction left < 32 bits 3576 sll t6, t6, t9 3577 srl v1, t7, v0 3578 or t6, t6, v1 3579 sll t7, t7, t9 3580 j ra 3581END(renorm_ft_d) 3582