1/* 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. 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 8.1 (Berkeley) 06/10/93 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 FTs 677 move t2, zero # FSs fraction shifted is zero 678 b 4f 6791: 680 move t6, zero # FTs 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 FTs frac 686 move t1, t5 # FT > FS, result exp is FTs 687 sll t8, t2, t9 # save bits shifted out 688 srl t2, t2, v1 # shift FSs fraction 689 b 4f 6903: 691 sll t8, t6, t9 # save bits shifted out 692 srl t6, t6, v1 # shift FTs 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 = FTs 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 FTs 802 move t2, zero # FSs fraction shifted is zero 803 move t3, zero 804 b 4f 8051: 806 move t6, zero # FTs 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 FTs frac 812 move t1, t5 # FT > FS, result exp is FTs 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 # dont lose any one bits 818 or t8, t8, t9 # save sticky bit 819 srl t3, t2, v1 # shift FSs 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 FSs 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 FTs 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 FTs 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 = FTs 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 # dont 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 move t3, zero 1333 bne t1, SEXP_INF, 1f # is FS an infinity? 1334 li t1, DEXP_INF # convert to double 1335 b result_fs_d 13361: 1337 bne t1, zero, 2f # is FS denormalized or zero? 1338 beq t2, zero, result_fs_d # is FS zero? 1339 jal renorm_fs_s 1340 move t8, zero 1341 b norm_d 13422: 1343 addu t1, t1, DEXP_BIAS - SEXP_BIAS # bias exponent correctly 1344 sll t3, t2, 32 - 3 # convert S fraction to D 1345 srl t2, t2, 3 1346 b result_fs_d 1347 1348/* 1349 * Convert integer to double. 1350 */ 1351cvt_d_w: 1352 jal get_fs_int 1353 bne t2, zero, 1f # check for zero 1354 move t1, zero # result=0 1355 move t3, zero 1356 b result_fs_d 1357/* 1358 * Find out how many leading zero bits are in t2 and put in t9. 1359 */ 13601: 1361 move v0, t2 1362 move t9, zero 1363 srl v1, v0, 16 1364 bne v1, zero, 1f 1365 addu t9, 16 1366 sll v0, 16 13671: 1368 srl v1, v0, 24 1369 bne v1, zero, 1f 1370 addu t9, 8 1371 sll v0, 8 13721: 1373 srl v1, v0, 28 1374 bne v1, zero, 1f 1375 addu t9, 4 1376 sll v0, 4 13771: 1378 srl v1, v0, 30 1379 bne v1, zero, 1f 1380 addu t9, 2 1381 sll v0, 2 13821: 1383 srl v1, v0, 31 1384 bne v1, zero, 1f 1385 addu t9, 1 1386/* 1387 * Now shift t2 the correct number of bits. 1388 */ 13891: 1390 subu t9, t9, DLEAD_ZEROS # dont count leading zeros 1391 li t1, DEXP_BIAS + 20 # init exponent 1392 subu t1, t1, t9 # compute exponent 1393 beq t9, zero, 1f 1394 li v0, 32 1395 blt t9, zero, 2f # if shift < 0, shift right 1396 subu v0, v0, t9 1397 sll t2, t2, t9 # shift left 13981: 1399 and t2, t2, ~DIMPL_ONE # clear implied one bit 1400 move t3, zero 1401 b result_fs_d 14022: 1403 negu t9 # shift right by t9 1404 subu v0, v0, t9 1405 sll t3, t2, v0 1406 srl t2, t2, t9 1407 and t2, t2, ~DIMPL_ONE # clear implied one bit 1408 b result_fs_d 1409 1410/* 1411 * Convert single to integer. 1412 */ 1413cvt_w_s: 1414 jal get_fs_s 1415 bne t1, SEXP_INF, 1f # is FS an infinity? 1416 bne t2, zero, invalid_w # invalid conversion 14171: 1418 bne t1, zero, 1f # is FS zero? 1419 beq t2, zero, result_fs_w # result is zero 1420 move t2, zero # result is an inexact zero 1421 b inexact_w 14221: 1423 subu t1, t1, SEXP_BIAS # unbias exponent 1424 or t2, t2, SIMPL_ONE # add implied one bit 1425 sll t3, t2, 32 - 3 # convert S fraction to D 1426 srl t2, t2, 3 1427 b cvt_w 1428 1429/* 1430 * Convert double to integer. 1431 */ 1432cvt_w_d: 1433 jal get_fs_d 1434 bne t1, DEXP_INF, 1f # is FS an infinity? 1435 bne t2, zero, invalid_w # invalid conversion 1436 bne t3, zero, invalid_w # invalid conversion 14371: 1438 bne t1, zero, 2f # is FS zero? 1439 bne t2, zero, 1f 1440 beq t3, zero, result_fs_w # result is zero 14411: 1442 move t2, zero # result is an inexact zero 1443 b inexact_w 14442: 1445 subu t1, t1, DEXP_BIAS # unbias exponent 1446 or t2, t2, DIMPL_ONE # add implied one bit 1447cvt_w: 1448 blt t1, WEXP_MIN, underflow_w # is exponent too small? 1449 li v0, WEXP_MAX+1 1450 bgt t1, v0, overflow_w # is exponent too large? 1451 bne t1, v0, 1f # special check for INT_MIN 1452 beq t0, zero, overflow_w # if positive, overflow 1453 bne t2, DIMPL_ONE, overflow_w 1454 bne t3, zero, overflow_w 1455 li t2, INT_MIN # result is INT_MIN 1456 b result_fs_w 14571: 1458 subu v0, t1, 20 # compute amount to shift 1459 beq v0, zero, 2f # is shift needed? 1460 li v1, 32 1461 blt v0, zero, 1f # if shift < 0, shift right 1462 subu v1, v1, v0 # shift left 1463 sll t2, t2, v0 1464 srl t9, t3, v1 # save bits shifted out of t3 1465 or t2, t2, t9 # and put into t2 1466 sll t3, t3, v0 # shift FSs fraction 1467 b 2f 14681: 1469 negu v0 # shift right by v0 1470 subu v1, v1, v0 1471 sll t8, t3, v1 # save bits shifted out 1472 sltu t8, zero, t8 # dont lose any ones 1473 srl t3, t3, v0 # shift FSs fraction 1474 or t3, t3, t8 1475 sll t9, t2, v1 # save bits shifted out of t2 1476 or t3, t3, t9 # and put into t3 1477 srl t2, t2, v0 1478/* 1479 * round result (t0 is sign, t2 is integer part, t3 is fractional part). 1480 */ 14812: 1482 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1483 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1484 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1485 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1486 beq t0, zero, 5f # if sign is positive, truncate 1487 b 2f 14881: 1489 bne t0, zero, 5f # if sign is negative, truncate 14902: 1491 beq t3, zero, 5f # if no fraction bits, continue 1492 addu t2, t2, 1 # add rounding bit 1493 blt t2, zero, overflow_w # overflow? 1494 b 5f 14953: 1496 li v0, GUARDBIT # load guard bit for rounding 1497 addu v0, v0, t3 # add remainder 1498 sltu v1, v0, t3 # compute carry out 1499 beq v1, zero, 4f # if no carry, continue 1500 addu t2, t2, 1 # add carry to result 1501 blt t2, zero, overflow_w # overflow? 15024: 1503 bne v0, zero, 5f # if rounded remainder is zero 1504 and t2, t2, ~1 # clear LSB (round to nearest) 15055: 1506 beq t0, zero, 1f # result positive? 1507 negu t2 # convert to negative integer 15081: 1509 beq t3, zero, result_fs_w # is result exact? 1510/* 1511 * Handle inexact exception. 1512 */ 1513inexact_w: 1514 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1515 and v0, a1, MACH_FPC_ENABLE_INEXACT 1516 bne v0, zero, fpe_trap 1517 ctc1 a1, MACH_FPC_CSR # save exceptions 1518 b result_fs_w 1519 1520/* 1521 * Conversions to integer which overflow will trap (if enabled), 1522 * or generate an inexact trap (if enabled), 1523 * or generate an invalid exception. 1524 */ 1525overflow_w: 1526 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1527 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1528 bne v0, zero, fpe_trap 1529 and v0, a1, MACH_FPC_ENABLE_INEXACT 1530 bne v0, zero, inexact_w # inexact traps enabled? 1531 b invalid_w 1532 1533/* 1534 * Conversions to integer which underflow will trap (if enabled), 1535 * or generate an inexact trap (if enabled), 1536 * or generate an invalid exception. 1537 */ 1538underflow_w: 1539 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1540 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1541 bne v0, zero, fpe_trap 1542 and v0, a1, MACH_FPC_ENABLE_INEXACT 1543 bne v0, zero, inexact_w # inexact traps enabled? 1544 b invalid_w 1545 1546/* 1547 * Compare single. 1548 */ 1549cmp_s: 1550 jal get_cmp_s 1551 bne t1, SEXP_INF, 1f # is FS an infinity? 1552 bne t2, zero, unordered # FS is a NAN 15531: 1554 bne t5, SEXP_INF, 2f # is FT an infinity? 1555 bne t6, zero, unordered # FT is a NAN 15562: 1557 sll t1, t1, 23 # reassemble exp & frac 1558 or t1, t1, t2 1559 sll t5, t5, 23 # reassemble exp & frac 1560 or t5, t5, t6 1561 beq t0, zero, 1f # is FS positive? 1562 negu t1 15631: 1564 beq t4, zero, 1f # is FT positive? 1565 negu t5 15661: 1567 li v0, COND_LESS 1568 blt t1, t5, test_cond # is FS < FT? 1569 li v0, COND_EQUAL 1570 beq t1, t5, test_cond # is FS == FT? 1571 move v0, zero # FS > FT 1572 b test_cond 1573 1574/* 1575 * Compare double. 1576 */ 1577cmp_d: 1578 jal get_cmp_d 1579 bne t1, DEXP_INF, 1f # is FS an infinity? 1580 bne t2, zero, unordered 1581 bne t3, zero, unordered # FS is a NAN 15821: 1583 bne t5, DEXP_INF, 2f # is FT an infinity? 1584 bne t6, zero, unordered 1585 bne t7, zero, unordered # FT is a NAN 15862: 1587 sll t1, t1, 20 # reassemble exp & frac 1588 or t1, t1, t2 1589 sll t5, t5, 20 # reassemble exp & frac 1590 or t5, t5, t6 1591 beq t0, zero, 1f # is FS positive? 1592 not t3 # negate t1,t3 1593 not t1 1594 addu t3, t3, 1 1595 seq v0, t3, zero # compute carry 1596 addu t1, t1, v0 15971: 1598 beq t4, zero, 1f # is FT positive? 1599 not t7 # negate t5,t7 1600 not t5 1601 addu t7, t7, 1 1602 seq v0, t7, zero # compute carry 1603 addu t5, t5, v0 16041: 1605 li v0, COND_LESS 1606 blt t1, t5, test_cond # is FS(MSW) < FT(MSW)? 1607 move v0, zero 1608 bne t1, t5, test_cond # is FS(MSW) > FT(MSW)? 1609 li v0, COND_LESS 1610 bltu t3, t7, test_cond # is FS(LSW) < FT(LSW)? 1611 li v0, COND_EQUAL 1612 beq t3, t7, test_cond # is FS(LSW) == FT(LSW)? 1613 move v0, zero # FS > FT 1614test_cond: 1615 and v0, v0, a0 # condition match instruction? 1616set_cond: 1617 bne v0, zero, 1f 1618 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1619 b 2f 16201: 1621 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16222: 1623 ctc1 a1, MACH_FPC_CSR # save condition bit 1624 b done 1625 1626unordered: 1627 and v0, a0, COND_UNORDERED # this cmp match unordered? 1628 bne v0, zero, 1f 1629 and a1, a1, ~MACH_FPC_COND_BIT # clear condition bit 1630 b 2f 16311: 1632 or a1, a1, MACH_FPC_COND_BIT # set condition bit 16332: 1634 and v0, a0, COND_SIGNAL 1635 beq v0, zero, 1f # is this a signaling cmp? 1636 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 1637 and v0, a1, MACH_FPC_ENABLE_INVALID 1638 bne v0, zero, fpe_trap 16391: 1640 ctc1 a1, MACH_FPC_CSR # save condition bit 1641 b done 1642 1643/* 1644 * Determine the amount to shift the fraction in order to restore the 1645 * normalized position. After that, round and handle exceptions. 1646 */ 1647norm_s: 1648 move v0, t2 1649 move t9, zero # t9 = num of leading zeros 1650 bne t2, zero, 1f 1651 move v0, t8 1652 addu t9, 32 16531: 1654 srl v1, v0, 16 1655 bne v1, zero, 1f 1656 addu t9, 16 1657 sll v0, 16 16581: 1659 srl v1, v0, 24 1660 bne v1, zero, 1f 1661 addu t9, 8 1662 sll v0, 8 16631: 1664 srl v1, v0, 28 1665 bne v1, zero, 1f 1666 addu t9, 4 1667 sll v0, 4 16681: 1669 srl v1, v0, 30 1670 bne v1, zero, 1f 1671 addu t9, 2 1672 sll v0, 2 16731: 1674 srl v1, v0, 31 1675 bne v1, zero, 1f 1676 addu t9, 1 1677/* 1678 * Now shift t2,t8 the correct number of bits. 1679 */ 16801: 1681 subu t9, t9, SLEAD_ZEROS # dont count leading zeros 1682 subu t1, t1, t9 # adjust the exponent 1683 beq t9, zero, norm_noshift_s 1684 li v1, 32 1685 blt t9, zero, 1f # if shift < 0, shift right 1686 subu v1, v1, t9 1687 sll t2, t2, t9 # shift t2,t8 left 1688 srl v0, t8, v1 # save bits shifted out 1689 or t2, t2, v0 1690 sll t8, t8, t9 1691 b norm_noshift_s 16921: 1693 negu t9 # shift t2,t8 right by t9 1694 subu v1, v1, t9 1695 sll v0, t8, v1 # save bits shifted out 1696 sltu v0, zero, v0 # be sure to save any one bits 1697 srl t8, t8, t9 1698 or t8, t8, v0 1699 sll v0, t2, v1 # save bits shifted out 1700 or t8, t8, v0 1701 srl t2, t2, t9 1702norm_noshift_s: 1703 move t5, t1 # save unrounded exponent 1704 move t6, t2 # save unrounded fraction 1705 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1706 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1707 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1708 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1709 beq t0, zero, 5f # if sign is positive, truncate 1710 b 2f 17111: 1712 bne t0, zero, 5f # if sign is negative, truncate 17132: 1714 beq t8, zero, 5f # if exact, continue 1715 addu t2, t2, 1 # add rounding bit 1716 bne t2, SIMPL_ONE<<1, 5f # need to adjust exponent? 1717 addu t1, t1, 1 # adjust exponent 1718 srl t2, t2, 1 # renormalize fraction 1719 b 5f 17203: 1721 li v0, GUARDBIT # load guard bit for rounding 1722 addu v0, v0, t8 # add remainder 1723 sltu v1, v0, t8 # compute carry out 1724 beq v1, zero, 4f # if no carry, continue 1725 addu t2, t2, 1 # add carry to result 1726 bne t2, SIMPL_ONE<<1, 4f # need to adjust exponent? 1727 addu t1, t1, 1 # adjust exponent 1728 srl t2, t2, 1 # renormalize fraction 17294: 1730 bne v0, zero, 5f # if rounded remainder is zero 1731 and t2, t2, ~1 # clear LSB (round to nearest) 17325: 1733 bgt t1, SEXP_MAX, overflow_s # overflow? 1734 blt t1, SEXP_MIN, underflow_s # underflow? 1735 bne t8, zero, inexact_s # is result inexact? 1736 addu t1, t1, SEXP_BIAS # bias exponent 1737 and t2, t2, ~SIMPL_ONE # clear implied one bit 1738 b result_fs_s 1739 1740/* 1741 * Handle inexact exception. 1742 */ 1743inexact_s: 1744 addu t1, t1, SEXP_BIAS # bias exponent 1745 and t2, t2, ~SIMPL_ONE # clear implied one bit 1746inexact_nobias_s: 1747 jal set_fd_s # save result 1748 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1749 and v0, a1, MACH_FPC_ENABLE_INEXACT 1750 bne v0, zero, fpe_trap 1751 ctc1 a1, MACH_FPC_CSR # save exceptions 1752 b done 1753 1754/* 1755 * Overflow will trap (if enabled), 1756 * or generate an inexact trap (if enabled), 1757 * or generate an infinity. 1758 */ 1759overflow_s: 1760 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 1761 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 1762 beq v0, zero, 1f 1763 subu t1, t1, 192 # bias exponent 1764 and t2, t2, ~SIMPL_ONE # clear implied one bit 1765 jal set_fd_s # save result 1766 b fpe_trap 17671: 1768 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1769 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1770 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 1771 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 1772 bne t0, zero, 3f 17731: 1774 li t1, SEXP_MAX # result is max finite 1775 li t2, 0x007fffff 1776 b inexact_s 17772: 1778 bne t0, zero, 1b 17793: 1780 li t1, SEXP_MAX + 1 # result is infinity 1781 move t2, zero 1782 b inexact_s 1783 1784/* 1785 * In this implementation, "tininess" is detected "after rounding" and 1786 * "loss of accuracy" is detected as "an inexact result". 1787 */ 1788underflow_s: 1789 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 1790 beq v0, zero, 1f 1791/* 1792 * Underflow is enabled so compute the result and trap. 1793 */ 1794 addu t1, t1, 192 # bias exponent 1795 and t2, t2, ~SIMPL_ONE # clear implied one bit 1796 jal set_fd_s # save result 1797 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1798 b fpe_trap 1799/* 1800 * Underflow is not enabled so compute the result, 1801 * signal inexact result (if it is) and trap (if enabled). 1802 */ 18031: 1804 move t1, t5 # get unrounded exponent 1805 move t2, t6 # get unrounded fraction 1806 li t9, SEXP_MIN # compute shift amount 1807 subu t9, t9, t1 # shift t2,t8 right by t9 1808 blt t9, SFRAC_BITS+2, 3f # shift all the bits out? 1809 move t1, zero # result is inexact zero 1810 move t2, zero 1811 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1812/* 1813 * Now round the zero result. 1814 * Only need to worry about rounding to +- infinity when the sign matches. 1815 */ 1816 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1817 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_s # round to nearest 1818 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_s # round to zero 1819 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1820 beq t0, zero, inexact_nobias_s # if sign is positive, truncate 1821 b 2f 18221: 1823 bne t0, zero, inexact_nobias_s # if sign is negative, truncate 18242: 1825 addu t2, t2, 1 # add rounding bit 1826 b inexact_nobias_s 18273: 1828 li v1, 32 1829 subu v1, v1, t9 1830 sltu v0, zero, t8 # be sure to save any one bits 1831 sll t8, t2, v1 # save bits shifted out 1832 or t8, t8, v0 # include sticky bits 1833 srl t2, t2, t9 1834/* 1835 * Now round the denormalized result. 1836 */ 1837 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1838 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1839 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1840 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1841 beq t0, zero, 5f # if sign is positive, truncate 1842 b 2f 18431: 1844 bne t0, zero, 5f # if sign is negative, truncate 18452: 1846 beq t8, zero, 5f # if exact, continue 1847 addu t2, t2, 1 # add rounding bit 1848 b 5f 18493: 1850 li v0, GUARDBIT # load guard bit for rounding 1851 addu v0, v0, t8 # add remainder 1852 sltu v1, v0, t8 # compute carry out 1853 beq v1, zero, 4f # if no carry, continue 1854 addu t2, t2, 1 # add carry to result 18554: 1856 bne v0, zero, 5f # if rounded remainder is zero 1857 and t2, t2, ~1 # clear LSB (round to nearest) 18585: 1859 move t1, zero # denorm or zero exponent 1860 jal set_fd_s # save result 1861 beq t8, zero, done # check for exact result 1862 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 1863 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1864 and v0, a1, MACH_FPC_ENABLE_INEXACT 1865 bne v0, zero, fpe_trap 1866 ctc1 a1, MACH_FPC_CSR # save exceptions 1867 b done 1868 1869/* 1870 * Determine the amount to shift the fraction in order to restore the 1871 * normalized position. After that, round and handle exceptions. 1872 */ 1873norm_d: 1874 move v0, t2 1875 move t9, zero # t9 = num of leading zeros 1876 bne t2, zero, 1f 1877 move v0, t3 1878 addu t9, 32 1879 bne t3, zero, 1f 1880 move v0, t8 1881 addu t9, 32 18821: 1883 srl v1, v0, 16 1884 bne v1, zero, 1f 1885 addu t9, 16 1886 sll v0, 16 18871: 1888 srl v1, v0, 24 1889 bne v1, zero, 1f 1890 addu t9, 8 1891 sll v0, 8 18921: 1893 srl v1, v0, 28 1894 bne v1, zero, 1f 1895 addu t9, 4 1896 sll v0, 4 18971: 1898 srl v1, v0, 30 1899 bne v1, zero, 1f 1900 addu t9, 2 1901 sll v0, 2 19021: 1903 srl v1, v0, 31 1904 bne v1, zero, 1f 1905 addu t9, 1 1906/* 1907 * Now shift t2,t3,t8 the correct number of bits. 1908 */ 19091: 1910 subu t9, t9, DLEAD_ZEROS # dont count leading zeros 1911 subu t1, t1, t9 # adjust the exponent 1912 beq t9, zero, norm_noshift_d 1913 li v1, 32 1914 blt t9, zero, 2f # if shift < 0, shift right 1915 blt t9, v1, 1f # shift by < 32? 1916 subu t9, t9, v1 # shift by >= 32 1917 subu v1, v1, t9 1918 sll t2, t3, t9 # shift left by t9 1919 srl v0, t8, v1 # save bits shifted out 1920 or t2, t2, v0 1921 sll t3, t8, t9 1922 move t8, zero 1923 b norm_noshift_d 19241: 1925 subu v1, v1, t9 1926 sll t2, t2, t9 # shift left by t9 1927 srl v0, t3, v1 # save bits shifted out 1928 or t2, t2, v0 1929 sll t3, t3, t9 1930 srl v0, t8, v1 # save bits shifted out 1931 or t3, t3, v0 1932 sll t8, t8, t9 1933 b norm_noshift_d 19342: 1935 negu t9 # shift right by t9 1936 subu v1, v1, t9 # (known to be < 32 bits) 1937 sll v0, t8, v1 # save bits shifted out 1938 sltu v0, zero, v0 # be sure to save any one bits 1939 srl t8, t8, t9 1940 or t8, t8, v0 1941 sll v0, t3, v1 # save bits shifted out 1942 or t8, t8, v0 1943 srl t3, t3, t9 1944 sll v0, t2, v1 # save bits shifted out 1945 or t3, t3, v0 1946 srl t2, t2, t9 1947norm_noshift_d: 1948 move t5, t1 # save unrounded exponent 1949 move t6, t2 # save unrounded fraction (MS) 1950 move t7, t3 # save unrounded fraction (LS) 1951 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 1952 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 1953 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 1954 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 1955 beq t0, zero, 5f # if sign is positive, truncate 1956 b 2f 19571: 1958 bne t0, zero, 5f # if sign is negative, truncate 19592: 1960 beq t8, zero, 5f # if exact, continue 1961 addu t3, t3, 1 # add rounding bit 1962 bne t3, zero, 5f # branch if no carry 1963 addu t2, t2, 1 # add carry 1964 bne t2, DIMPL_ONE<<1, 5f # need to adjust exponent? 1965 addu t1, t1, 1 # adjust exponent 1966 srl t2, t2, 1 # renormalize fraction 1967 b 5f 19683: 1969 li v0, GUARDBIT # load guard bit for rounding 1970 addu v0, v0, t8 # add remainder 1971 sltu v1, v0, t8 # compute carry out 1972 beq v1, zero, 4f # branch if no carry 1973 addu t3, t3, 1 # add carry 1974 bne t3, zero, 4f # branch if no carry 1975 addu t2, t2, 1 # add carry to result 1976 bne t2, DIMPL_ONE<<1, 4f # need to adjust exponent? 1977 addu t1, t1, 1 # adjust exponent 1978 srl t2, t2, 1 # renormalize fraction 19794: 1980 bne v0, zero, 5f # if rounded remainder is zero 1981 and t3, t3, ~1 # clear LSB (round to nearest) 19825: 1983 bgt t1, DEXP_MAX, overflow_d # overflow? 1984 blt t1, DEXP_MIN, underflow_d # underflow? 1985 bne t8, zero, inexact_d # is result inexact? 1986 addu t1, t1, DEXP_BIAS # bias exponent 1987 and t2, t2, ~DIMPL_ONE # clear implied one bit 1988 b result_fs_d 1989 1990/* 1991 * Handle inexact exception. 1992 */ 1993inexact_d: 1994 addu t1, t1, DEXP_BIAS # bias exponent 1995 and t2, t2, ~DIMPL_ONE # clear implied one bit 1996inexact_nobias_d: 1997 jal set_fd_d # save result 1998 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 1999 and v0, a1, MACH_FPC_ENABLE_INEXACT 2000 bne v0, zero, fpe_trap 2001 ctc1 a1, MACH_FPC_CSR # save exceptions 2002 b done 2003 2004/* 2005 * Overflow will trap (if enabled), 2006 * or generate an inexact trap (if enabled), 2007 * or generate an infinity. 2008 */ 2009overflow_d: 2010 or a1, a1, MACH_FPC_EXCEPTION_OVERFLOW | MACH_FPC_STICKY_OVERFLOW 2011 and v0, a1, MACH_FPC_ENABLE_OVERFLOW 2012 beq v0, zero, 1f 2013 subu t1, t1, 1536 # bias exponent 2014 and t2, t2, ~DIMPL_ONE # clear implied one bit 2015 jal set_fd_d # save result 2016 b fpe_trap 20171: 2018 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2019 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2020 beq v0, MACH_FPC_ROUND_RZ, 1f # round to zero (truncate) 2021 beq v0, MACH_FPC_ROUND_RP, 2f # round to +infinity 2022 bne t0, zero, 3f 20231: 2024 li t1, DEXP_MAX # result is max finite 2025 li t2, 0x000fffff 2026 li t3, 0xffffffff 2027 b inexact_d 20282: 2029 bne t0, zero, 1b 20303: 2031 li t1, DEXP_MAX + 1 # result is infinity 2032 move t2, zero 2033 move t3, zero 2034 b inexact_d 2035 2036/* 2037 * In this implementation, "tininess" is detected "after rounding" and 2038 * "loss of accuracy" is detected as "an inexact result". 2039 */ 2040underflow_d: 2041 and v0, a1, MACH_FPC_ENABLE_UNDERFLOW 2042 beq v0, zero, 1f 2043/* 2044 * Underflow is enabled so compute the result and trap. 2045 */ 2046 addu t1, t1, 1536 # bias exponent 2047 and t2, t2, ~DIMPL_ONE # clear implied one bit 2048 jal set_fd_d # save result 2049 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2050 b fpe_trap 2051/* 2052 * Underflow is not enabled so compute the result, 2053 * signal inexact result (if it is) and trap (if enabled). 2054 */ 20551: 2056 move t1, t5 # get unrounded exponent 2057 move t2, t6 # get unrounded fraction (MS) 2058 move t3, t7 # get unrounded fraction (LS) 2059 li t9, DEXP_MIN # compute shift amount 2060 subu t9, t9, t1 # shift t2,t8 right by t9 2061 blt t9, DFRAC_BITS+2, 3f # shift all the bits out? 2062 move t1, zero # result is inexact zero 2063 move t2, zero 2064 move t3, zero 2065 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2066/* 2067 * Now round the zero result. 2068 * Only need to worry about rounding to +- infinity when the sign matches. 2069 */ 2070 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2071 beq v0, MACH_FPC_ROUND_RN, inexact_nobias_d # round to nearest 2072 beq v0, MACH_FPC_ROUND_RZ, inexact_nobias_d # round to zero 2073 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2074 beq t0, zero, inexact_nobias_d # if sign is positive, truncate 2075 b 2f 20761: 2077 bne t0, zero, inexact_nobias_d # if sign is negative, truncate 20782: 2079 addu t3, t3, 1 # add rounding bit 2080 b inexact_nobias_d 20813: 2082 li v1, 32 2083 blt t9, v1, 1f # shift by < 32? 2084 subu t9, t9, v1 # shift right by >= 32 2085 subu v1, v1, t9 2086 sltu v0, zero, t8 # be sure to save any one bits 2087 sll t8, t2, v1 # save bits shifted out 2088 or t8, t8, v0 # include sticky bits 2089 srl t3, t2, t9 2090 move t2, zero 2091 b 2f 20921: 2093 subu v1, v1, t9 # shift right by t9 2094 sltu v0, zero, t8 # be sure to save any one bits 2095 sll t8, t3, v1 # save bits shifted out 2096 or t8, t8, v0 # include sticky bits 2097 srl t3, t3, t9 2098 sll v0, t2, v1 # save bits shifted out 2099 or t3, t3, v0 2100 srl t2, t2, t9 2101/* 2102 * Now round the denormalized result. 2103 */ 21042: 2105 and v0, a1, MACH_FPC_ROUNDING_BITS # get rounding mode 2106 beq v0, MACH_FPC_ROUND_RN, 3f # round to nearest 2107 beq v0, MACH_FPC_ROUND_RZ, 5f # round to zero (truncate) 2108 beq v0, MACH_FPC_ROUND_RP, 1f # round to +infinity 2109 beq t0, zero, 5f # if sign is positive, truncate 2110 b 2f 21111: 2112 bne t0, zero, 5f # if sign is negative, truncate 21132: 2114 beq t8, zero, 5f # if exact, continue 2115 addu t3, t3, 1 # add rounding bit 2116 bne t3, zero, 5f # if no carry, continue 2117 addu t2, t2, 1 # add carry 2118 b 5f 21193: 2120 li v0, GUARDBIT # load guard bit for rounding 2121 addu v0, v0, t8 # add remainder 2122 sltu v1, v0, t8 # compute carry out 2123 beq v1, zero, 4f # if no carry, continue 2124 addu t3, t3, 1 # add rounding bit 2125 bne t3, zero, 4f # if no carry, continue 2126 addu t2, t2, 1 # add carry 21274: 2128 bne v0, zero, 5f # if rounded remainder is zero 2129 and t3, t3, ~1 # clear LSB (round to nearest) 21305: 2131 move t1, zero # denorm or zero exponent 2132 jal set_fd_d # save result 2133 beq t8, zero, done # check for exact result 2134 or a1, a1, MACH_FPC_EXCEPTION_UNDERFLOW | MACH_FPC_STICKY_UNDERFLOW 2135 or a1, a1, MACH_FPC_EXCEPTION_INEXACT | MACH_FPC_STICKY_INEXACT 2136 and v0, a1, MACH_FPC_ENABLE_INEXACT 2137 bne v0, zero, fpe_trap 2138 ctc1 a1, MACH_FPC_CSR # save exceptions 2139 b done 2140 2141/* 2142 * Signal an invalid operation if the trap is enabled; otherwise, 2143 * the result is a quiet NAN. 2144 */ 2145invalid_s: # trap invalid operation 2146 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2147 and v0, a1, MACH_FPC_ENABLE_INVALID 2148 bne v0, zero, fpe_trap 2149 ctc1 a1, MACH_FPC_CSR # save exceptions 2150 move t0, zero # result is a quiet NAN 2151 li t1, SEXP_INF 2152 li t2, SQUIET_NAN 2153 jal set_fd_s # save result (in t0,t1,t2) 2154 b done 2155 2156/* 2157 * Signal an invalid operation if the trap is enabled; otherwise, 2158 * the result is a quiet NAN. 2159 */ 2160invalid_d: # trap invalid operation 2161 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2162 and v0, a1, MACH_FPC_ENABLE_INVALID 2163 bne v0, zero, fpe_trap 2164 ctc1 a1, MACH_FPC_CSR # save exceptions 2165 move t0, zero # result is a quiet NAN 2166 li t1, DEXP_INF 2167 li t2, DQUIET_NAN0 2168 li t3, DQUIET_NAN1 2169 jal set_fd_d # save result (in t0,t1,t2,t3) 2170 b done 2171 2172/* 2173 * Signal an invalid operation if the trap is enabled; otherwise, 2174 * the result is INT_MAX or INT_MIN. 2175 */ 2176invalid_w: # trap invalid operation 2177 or a1, a1, MACH_FPC_EXCEPTION_INVALID | MACH_FPC_STICKY_INVALID 2178 and v0, a1, MACH_FPC_ENABLE_INVALID 2179 bne v0, zero, fpe_trap 2180 ctc1 a1, MACH_FPC_CSR # save exceptions 2181 bne t0, zero, 1f 2182 li t2, INT_MAX # result is INT_MAX 2183 b result_fs_w 21841: 2185 li t2, INT_MIN # result is INT_MIN 2186 b result_fs_w 2187 2188/* 2189 * Trap if the hardware should have handled this case. 2190 */ 2191fpe_trap: 2192 move a2, a1 # code = FP CSR 2193 ctc1 a1, MACH_FPC_CSR # save exceptions 2194 break 0 2195 2196/* 2197 * Send an illegal instruction signal to the current process. 2198 */ 2199ill: 2200 ctc1 a1, MACH_FPC_CSR # save exceptions 2201 move a2, a0 # code = FP instruction 2202 break 0 2203 2204result_ft_s: 2205 move t0, t4 # result is FT 2206 move t1, t5 2207 move t2, t6 2208result_fs_s: # result is FS 2209 jal set_fd_s # save result (in t0,t1,t2) 2210 b done 2211 2212result_fs_w: 2213 jal set_fd_word # save result (in t2) 2214 b done 2215 2216result_ft_d: 2217 move t0, t4 # result is FT 2218 move t1, t5 2219 move t2, t6 2220 move t3, t7 2221result_fs_d: # result is FS 2222 jal set_fd_d # save result (in t0,t1,t2,t3) 2223 2224done: 2225 lw ra, STAND_RA_OFFSET(sp) 2226 addu sp, sp, STAND_FRAME_SIZE 2227 j ra 2228END(MachEmulateFP) 2229 2230/*---------------------------------------------------------------------------- 2231 * get_fs_int -- 2232 * 2233 * Read (integer) the FS register (bits 15-11). 2234 * This is an internal routine used by MachEmulateFP only. 2235 * 2236 * Results: 2237 * t0 contains the sign 2238 * t2 contains the fraction 2239 * 2240 *---------------------------------------------------------------------------- 2241 */ 2242LEAF(get_fs_int) 2243 srl a3, a0, 12 - 2 # get FS field (even regs only) 2244 and a3, a3, 0xF << 2 # mask FS field 2245 lw a3, get_fs_int_tbl(a3) # switch on register number 2246 j a3 2247 2248 .rdata 2249get_fs_int_tbl: 2250 .word get_fs_int_f0 2251 .word get_fs_int_f2 2252 .word get_fs_int_f4 2253 .word get_fs_int_f6 2254 .word get_fs_int_f8 2255 .word get_fs_int_f10 2256 .word get_fs_int_f12 2257 .word get_fs_int_f14 2258 .word get_fs_int_f16 2259 .word get_fs_int_f18 2260 .word get_fs_int_f20 2261 .word get_fs_int_f22 2262 .word get_fs_int_f24 2263 .word get_fs_int_f26 2264 .word get_fs_int_f28 2265 .word get_fs_int_f30 2266 .text 2267 2268get_fs_int_f0: 2269 mfc1 t2, $f0 2270 b get_fs_int_done 2271get_fs_int_f2: 2272 mfc1 t2, $f2 2273 b get_fs_int_done 2274get_fs_int_f4: 2275 mfc1 t2, $f4 2276 b get_fs_int_done 2277get_fs_int_f6: 2278 mfc1 t2, $f6 2279 b get_fs_int_done 2280get_fs_int_f8: 2281 mfc1 t2, $f8 2282 b get_fs_int_done 2283get_fs_int_f10: 2284 mfc1 t2, $f10 2285 b get_fs_int_done 2286get_fs_int_f12: 2287 mfc1 t2, $f12 2288 b get_fs_int_done 2289get_fs_int_f14: 2290 mfc1 t2, $f14 2291 b get_fs_int_done 2292get_fs_int_f16: 2293 mfc1 t2, $f16 2294 b get_fs_int_done 2295get_fs_int_f18: 2296 mfc1 t2, $f18 2297 b get_fs_int_done 2298get_fs_int_f20: 2299 mfc1 t2, $f20 2300 b get_fs_int_done 2301get_fs_int_f22: 2302 mfc1 t2, $f22 2303 b get_fs_int_done 2304get_fs_int_f24: 2305 mfc1 t2, $f24 2306 b get_fs_int_done 2307get_fs_int_f26: 2308 mfc1 t2, $f26 2309 b get_fs_int_done 2310get_fs_int_f28: 2311 mfc1 t2, $f28 2312 b get_fs_int_done 2313get_fs_int_f30: 2314 mfc1 t2, $f30 2315get_fs_int_done: 2316 srl t0, t2, 31 # init the sign bit 2317 bge t2, zero, 1f 2318 negu t2 23191: 2320 j ra 2321END(get_fs_int) 2322 2323/*---------------------------------------------------------------------------- 2324 * get_ft_fs_s -- 2325 * 2326 * Read (single precision) the FT register (bits 20-16) and 2327 * the FS register (bits 15-11) and break up into fields. 2328 * This is an internal routine used by MachEmulateFP only. 2329 * 2330 * Results: 2331 * t0 contains the FS sign 2332 * t1 contains the FS (biased) exponent 2333 * t2 contains the FS fraction 2334 * t4 contains the FT sign 2335 * t5 contains the FT (biased) exponent 2336 * t6 contains the FT fraction 2337 * 2338 *---------------------------------------------------------------------------- 2339 */ 2340LEAF(get_ft_fs_s) 2341 srl a3, a0, 17 - 2 # get FT field (even regs only) 2342 and a3, a3, 0xF << 2 # mask FT field 2343 lw a3, get_ft_s_tbl(a3) # switch on register number 2344 j a3 2345 2346 .rdata 2347get_ft_s_tbl: 2348 .word get_ft_s_f0 2349 .word get_ft_s_f2 2350 .word get_ft_s_f4 2351 .word get_ft_s_f6 2352 .word get_ft_s_f8 2353 .word get_ft_s_f10 2354 .word get_ft_s_f12 2355 .word get_ft_s_f14 2356 .word get_ft_s_f16 2357 .word get_ft_s_f18 2358 .word get_ft_s_f20 2359 .word get_ft_s_f22 2360 .word get_ft_s_f24 2361 .word get_ft_s_f26 2362 .word get_ft_s_f28 2363 .word get_ft_s_f30 2364 .text 2365 2366get_ft_s_f0: 2367 mfc1 t4, $f0 2368 b get_ft_s_done 2369get_ft_s_f2: 2370 mfc1 t4, $f2 2371 b get_ft_s_done 2372get_ft_s_f4: 2373 mfc1 t4, $f4 2374 b get_ft_s_done 2375get_ft_s_f6: 2376 mfc1 t4, $f6 2377 b get_ft_s_done 2378get_ft_s_f8: 2379 mfc1 t4, $f8 2380 b get_ft_s_done 2381get_ft_s_f10: 2382 mfc1 t4, $f10 2383 b get_ft_s_done 2384get_ft_s_f12: 2385 mfc1 t4, $f12 2386 b get_ft_s_done 2387get_ft_s_f14: 2388 mfc1 t4, $f14 2389 b get_ft_s_done 2390get_ft_s_f16: 2391 mfc1 t4, $f16 2392 b get_ft_s_done 2393get_ft_s_f18: 2394 mfc1 t4, $f18 2395 b get_ft_s_done 2396get_ft_s_f20: 2397 mfc1 t4, $f20 2398 b get_ft_s_done 2399get_ft_s_f22: 2400 mfc1 t4, $f22 2401 b get_ft_s_done 2402get_ft_s_f24: 2403 mfc1 t4, $f24 2404 b get_ft_s_done 2405get_ft_s_f26: 2406 mfc1 t4, $f26 2407 b get_ft_s_done 2408get_ft_s_f28: 2409 mfc1 t4, $f28 2410 b get_ft_s_done 2411get_ft_s_f30: 2412 mfc1 t4, $f30 2413get_ft_s_done: 2414 srl t5, t4, 23 # get exponent 2415 and t5, t5, 0xFF 2416 and t6, t4, 0x7FFFFF # get fraction 2417 srl t4, t4, 31 # get sign 2418 bne t5, SEXP_INF, 1f # is it a signaling NAN? 2419 and v0, t6, SSIGNAL_NAN 2420 bne v0, zero, invalid_s 24211: 2422 /* fall through to get FS */ 2423 2424/*---------------------------------------------------------------------------- 2425 * get_fs_s -- 2426 * 2427 * Read (single precision) the FS register (bits 15-11) and 2428 * break up into fields. 2429 * This is an internal routine used by MachEmulateFP only. 2430 * 2431 * Results: 2432 * t0 contains the sign 2433 * t1 contains the (biased) exponent 2434 * t2 contains the fraction 2435 * 2436 *---------------------------------------------------------------------------- 2437 */ 2438ALEAF(get_fs_s) 2439 srl a3, a0, 12 - 2 # get FS field (even regs only) 2440 and a3, a3, 0xF << 2 # mask FS field 2441 lw a3, get_fs_s_tbl(a3) # switch on register number 2442 j a3 2443 2444 .rdata 2445get_fs_s_tbl: 2446 .word get_fs_s_f0 2447 .word get_fs_s_f2 2448 .word get_fs_s_f4 2449 .word get_fs_s_f6 2450 .word get_fs_s_f8 2451 .word get_fs_s_f10 2452 .word get_fs_s_f12 2453 .word get_fs_s_f14 2454 .word get_fs_s_f16 2455 .word get_fs_s_f18 2456 .word get_fs_s_f20 2457 .word get_fs_s_f22 2458 .word get_fs_s_f24 2459 .word get_fs_s_f26 2460 .word get_fs_s_f28 2461 .word get_fs_s_f30 2462 .text 2463 2464get_fs_s_f0: 2465 mfc1 t0, $f0 2466 b get_fs_s_done 2467get_fs_s_f2: 2468 mfc1 t0, $f2 2469 b get_fs_s_done 2470get_fs_s_f4: 2471 mfc1 t0, $f4 2472 b get_fs_s_done 2473get_fs_s_f6: 2474 mfc1 t0, $f6 2475 b get_fs_s_done 2476get_fs_s_f8: 2477 mfc1 t0, $f8 2478 b get_fs_s_done 2479get_fs_s_f10: 2480 mfc1 t0, $f10 2481 b get_fs_s_done 2482get_fs_s_f12: 2483 mfc1 t0, $f12 2484 b get_fs_s_done 2485get_fs_s_f14: 2486 mfc1 t0, $f14 2487 b get_fs_s_done 2488get_fs_s_f16: 2489 mfc1 t0, $f16 2490 b get_fs_s_done 2491get_fs_s_f18: 2492 mfc1 t0, $f18 2493 b get_fs_s_done 2494get_fs_s_f20: 2495 mfc1 t0, $f20 2496 b get_fs_s_done 2497get_fs_s_f22: 2498 mfc1 t0, $f22 2499 b get_fs_s_done 2500get_fs_s_f24: 2501 mfc1 t0, $f24 2502 b get_fs_s_done 2503get_fs_s_f26: 2504 mfc1 t0, $f26 2505 b get_fs_s_done 2506get_fs_s_f28: 2507 mfc1 t0, $f28 2508 b get_fs_s_done 2509get_fs_s_f30: 2510 mfc1 t0, $f30 2511get_fs_s_done: 2512 srl t1, t0, 23 # get exponent 2513 and t1, t1, 0xFF 2514 and t2, t0, 0x7FFFFF # get fraction 2515 srl t0, t0, 31 # get sign 2516 bne t1, SEXP_INF, 1f # is it a signaling NAN? 2517 and v0, t2, SSIGNAL_NAN 2518 bne v0, zero, invalid_s 25191: 2520 j ra 2521END(get_ft_fs_s) 2522 2523/*---------------------------------------------------------------------------- 2524 * get_ft_fs_d -- 2525 * 2526 * Read (double precision) the FT register (bits 20-16) and 2527 * the FS register (bits 15-11) and break up into fields. 2528 * This is an internal routine used by MachEmulateFP only. 2529 * 2530 * Results: 2531 * t0 contains the FS sign 2532 * t1 contains the FS (biased) exponent 2533 * t2 contains the FS fraction 2534 * t3 contains the FS remaining fraction 2535 * t4 contains the FT sign 2536 * t5 contains the FT (biased) exponent 2537 * t6 contains the FT fraction 2538 * t7 contains the FT remaining fraction 2539 * 2540 *---------------------------------------------------------------------------- 2541 */ 2542LEAF(get_ft_fs_d) 2543 srl a3, a0, 17 - 2 # get FT field (even regs only) 2544 and a3, a3, 0xF << 2 # mask FT field 2545 lw a3, get_ft_d_tbl(a3) # switch on register number 2546 j a3 2547 2548 .rdata 2549get_ft_d_tbl: 2550 .word get_ft_d_f0 2551 .word get_ft_d_f2 2552 .word get_ft_d_f4 2553 .word get_ft_d_f6 2554 .word get_ft_d_f8 2555 .word get_ft_d_f10 2556 .word get_ft_d_f12 2557 .word get_ft_d_f14 2558 .word get_ft_d_f16 2559 .word get_ft_d_f18 2560 .word get_ft_d_f20 2561 .word get_ft_d_f22 2562 .word get_ft_d_f24 2563 .word get_ft_d_f26 2564 .word get_ft_d_f28 2565 .word get_ft_d_f30 2566 .text 2567 2568get_ft_d_f0: 2569 mfc1 t7, $f0 2570 mfc1 t4, $f1 2571 b get_ft_d_done 2572get_ft_d_f2: 2573 mfc1 t7, $f2 2574 mfc1 t4, $f3 2575 b get_ft_d_done 2576get_ft_d_f4: 2577 mfc1 t7, $f4 2578 mfc1 t4, $f5 2579 b get_ft_d_done 2580get_ft_d_f6: 2581 mfc1 t7, $f6 2582 mfc1 t4, $f7 2583 b get_ft_d_done 2584get_ft_d_f8: 2585 mfc1 t7, $f8 2586 mfc1 t4, $f9 2587 b get_ft_d_done 2588get_ft_d_f10: 2589 mfc1 t7, $f10 2590 mfc1 t4, $f11 2591 b get_ft_d_done 2592get_ft_d_f12: 2593 mfc1 t7, $f12 2594 mfc1 t4, $f13 2595 b get_ft_d_done 2596get_ft_d_f14: 2597 mfc1 t7, $f14 2598 mfc1 t4, $f15 2599 b get_ft_d_done 2600get_ft_d_f16: 2601 mfc1 t7, $f16 2602 mfc1 t4, $f17 2603 b get_ft_d_done 2604get_ft_d_f18: 2605 mfc1 t7, $f18 2606 mfc1 t4, $f19 2607 b get_ft_d_done 2608get_ft_d_f20: 2609 mfc1 t7, $f20 2610 mfc1 t4, $f21 2611 b get_ft_d_done 2612get_ft_d_f22: 2613 mfc1 t7, $f22 2614 mfc1 t4, $f23 2615 b get_ft_d_done 2616get_ft_d_f24: 2617 mfc1 t7, $f24 2618 mfc1 t4, $f25 2619 b get_ft_d_done 2620get_ft_d_f26: 2621 mfc1 t7, $f26 2622 mfc1 t4, $f27 2623 b get_ft_d_done 2624get_ft_d_f28: 2625 mfc1 t7, $f28 2626 mfc1 t4, $f29 2627 b get_ft_d_done 2628get_ft_d_f30: 2629 mfc1 t7, $f30 2630 mfc1 t4, $f31 2631get_ft_d_done: 2632 srl t5, t4, 20 # get exponent 2633 and t5, t5, 0x7FF 2634 and t6, t4, 0xFFFFF # get fraction 2635 srl t4, t4, 31 # get sign 2636 bne t5, DEXP_INF, 1f # is it a signaling NAN? 2637 and v0, t6, DSIGNAL_NAN 2638 bne v0, zero, invalid_d 26391: 2640 /* fall through to get FS */ 2641 2642/*---------------------------------------------------------------------------- 2643 * get_fs_d -- 2644 * 2645 * Read (double precision) the FS register (bits 15-11) and 2646 * break up into fields. 2647 * This is an internal routine used by MachEmulateFP only. 2648 * 2649 * Results: 2650 * t0 contains the sign 2651 * t1 contains the (biased) exponent 2652 * t2 contains the fraction 2653 * t3 contains the remaining fraction 2654 * 2655 *---------------------------------------------------------------------------- 2656 */ 2657ALEAF(get_fs_d) 2658 srl a3, a0, 12 - 2 # get FS field (even regs only) 2659 and a3, a3, 0xF << 2 # mask FS field 2660 lw a3, get_fs_d_tbl(a3) # switch on register number 2661 j a3 2662 2663 .rdata 2664get_fs_d_tbl: 2665 .word get_fs_d_f0 2666 .word get_fs_d_f2 2667 .word get_fs_d_f4 2668 .word get_fs_d_f6 2669 .word get_fs_d_f8 2670 .word get_fs_d_f10 2671 .word get_fs_d_f12 2672 .word get_fs_d_f14 2673 .word get_fs_d_f16 2674 .word get_fs_d_f18 2675 .word get_fs_d_f20 2676 .word get_fs_d_f22 2677 .word get_fs_d_f24 2678 .word get_fs_d_f26 2679 .word get_fs_d_f28 2680 .word get_fs_d_f30 2681 .text 2682 2683get_fs_d_f0: 2684 mfc1 t3, $f0 2685 mfc1 t0, $f1 2686 b get_fs_d_done 2687get_fs_d_f2: 2688 mfc1 t3, $f2 2689 mfc1 t0, $f3 2690 b get_fs_d_done 2691get_fs_d_f4: 2692 mfc1 t3, $f4 2693 mfc1 t0, $f5 2694 b get_fs_d_done 2695get_fs_d_f6: 2696 mfc1 t3, $f6 2697 mfc1 t0, $f7 2698 b get_fs_d_done 2699get_fs_d_f8: 2700 mfc1 t3, $f8 2701 mfc1 t0, $f9 2702 b get_fs_d_done 2703get_fs_d_f10: 2704 mfc1 t3, $f10 2705 mfc1 t0, $f11 2706 b get_fs_d_done 2707get_fs_d_f12: 2708 mfc1 t3, $f12 2709 mfc1 t0, $f13 2710 b get_fs_d_done 2711get_fs_d_f14: 2712 mfc1 t3, $f14 2713 mfc1 t0, $f15 2714 b get_fs_d_done 2715get_fs_d_f16: 2716 mfc1 t3, $f16 2717 mfc1 t0, $f17 2718 b get_fs_d_done 2719get_fs_d_f18: 2720 mfc1 t3, $f18 2721 mfc1 t0, $f19 2722 b get_fs_d_done 2723get_fs_d_f20: 2724 mfc1 t3, $f20 2725 mfc1 t0, $f21 2726 b get_fs_d_done 2727get_fs_d_f22: 2728 mfc1 t3, $f22 2729 mfc1 t0, $f23 2730 b get_fs_d_done 2731get_fs_d_f24: 2732 mfc1 t3, $f24 2733 mfc1 t0, $f25 2734 b get_fs_d_done 2735get_fs_d_f26: 2736 mfc1 t3, $f26 2737 mfc1 t0, $f27 2738 b get_fs_d_done 2739get_fs_d_f28: 2740 mfc1 t3, $f28 2741 mfc1 t0, $f29 2742 b get_fs_d_done 2743get_fs_d_f30: 2744 mfc1 t3, $f30 2745 mfc1 t0, $f31 2746get_fs_d_done: 2747 srl t1, t0, 20 # get exponent 2748 and t1, t1, 0x7FF 2749 and t2, t0, 0xFFFFF # get fraction 2750 srl t0, t0, 31 # get sign 2751 bne t1, DEXP_INF, 1f # is it a signaling NAN? 2752 and v0, t2, DSIGNAL_NAN 2753 bne v0, zero, invalid_d 27541: 2755 j ra 2756END(get_ft_fs_d) 2757 2758/*---------------------------------------------------------------------------- 2759 * get_cmp_s -- 2760 * 2761 * Read (single precision) the FS register (bits 15-11) and 2762 * the FT register (bits 20-16) and break up into fields. 2763 * This is an internal routine used by MachEmulateFP only. 2764 * 2765 * Results: 2766 * t0 contains the sign 2767 * t1 contains the (biased) exponent 2768 * t2 contains the fraction 2769 * t4 contains the sign 2770 * t5 contains the (biased) exponent 2771 * t6 contains the fraction 2772 * 2773 *---------------------------------------------------------------------------- 2774 */ 2775LEAF(get_cmp_s) 2776 srl a3, a0, 12 - 2 # get FS field (even regs only) 2777 and a3, a3, 0xF << 2 # mask FS field 2778 lw a3, cmp_fs_s_tbl(a3) # switch on register number 2779 j a3 2780 2781 .rdata 2782cmp_fs_s_tbl: 2783 .word cmp_fs_s_f0 2784 .word cmp_fs_s_f2 2785 .word cmp_fs_s_f4 2786 .word cmp_fs_s_f6 2787 .word cmp_fs_s_f8 2788 .word cmp_fs_s_f10 2789 .word cmp_fs_s_f12 2790 .word cmp_fs_s_f14 2791 .word cmp_fs_s_f16 2792 .word cmp_fs_s_f18 2793 .word cmp_fs_s_f20 2794 .word cmp_fs_s_f22 2795 .word cmp_fs_s_f24 2796 .word cmp_fs_s_f26 2797 .word cmp_fs_s_f28 2798 .word cmp_fs_s_f30 2799 .text 2800 2801cmp_fs_s_f0: 2802 mfc1 t0, $f0 2803 b cmp_fs_s_done 2804cmp_fs_s_f2: 2805 mfc1 t0, $f2 2806 b cmp_fs_s_done 2807cmp_fs_s_f4: 2808 mfc1 t0, $f4 2809 b cmp_fs_s_done 2810cmp_fs_s_f6: 2811 mfc1 t0, $f6 2812 b cmp_fs_s_done 2813cmp_fs_s_f8: 2814 mfc1 t0, $f8 2815 b cmp_fs_s_done 2816cmp_fs_s_f10: 2817 mfc1 t0, $f10 2818 b cmp_fs_s_done 2819cmp_fs_s_f12: 2820 mfc1 t0, $f12 2821 b cmp_fs_s_done 2822cmp_fs_s_f14: 2823 mfc1 t0, $f14 2824 b cmp_fs_s_done 2825cmp_fs_s_f16: 2826 mfc1 t0, $f16 2827 b cmp_fs_s_done 2828cmp_fs_s_f18: 2829 mfc1 t0, $f18 2830 b cmp_fs_s_done 2831cmp_fs_s_f20: 2832 mfc1 t0, $f20 2833 b cmp_fs_s_done 2834cmp_fs_s_f22: 2835 mfc1 t0, $f22 2836 b cmp_fs_s_done 2837cmp_fs_s_f24: 2838 mfc1 t0, $f24 2839 b cmp_fs_s_done 2840cmp_fs_s_f26: 2841 mfc1 t0, $f26 2842 b cmp_fs_s_done 2843cmp_fs_s_f28: 2844 mfc1 t0, $f28 2845 b cmp_fs_s_done 2846cmp_fs_s_f30: 2847 mfc1 t0, $f30 2848cmp_fs_s_done: 2849 srl t1, t0, 23 # get exponent 2850 and t1, t1, 0xFF 2851 and t2, t0, 0x7FFFFF # get fraction 2852 srl t0, t0, 31 # get sign 2853 2854 srl a3, a0, 17 - 2 # get FT field (even regs only) 2855 and a3, a3, 0xF << 2 # mask FT field 2856 lw a3, cmp_ft_s_tbl(a3) # switch on register number 2857 j a3 2858 2859 .rdata 2860cmp_ft_s_tbl: 2861 .word cmp_ft_s_f0 2862 .word cmp_ft_s_f2 2863 .word cmp_ft_s_f4 2864 .word cmp_ft_s_f6 2865 .word cmp_ft_s_f8 2866 .word cmp_ft_s_f10 2867 .word cmp_ft_s_f12 2868 .word cmp_ft_s_f14 2869 .word cmp_ft_s_f16 2870 .word cmp_ft_s_f18 2871 .word cmp_ft_s_f20 2872 .word cmp_ft_s_f22 2873 .word cmp_ft_s_f24 2874 .word cmp_ft_s_f26 2875 .word cmp_ft_s_f28 2876 .word cmp_ft_s_f30 2877 .text 2878 2879cmp_ft_s_f0: 2880 mfc1 t4, $f0 2881 b cmp_ft_s_done 2882cmp_ft_s_f2: 2883 mfc1 t4, $f2 2884 b cmp_ft_s_done 2885cmp_ft_s_f4: 2886 mfc1 t4, $f4 2887 b cmp_ft_s_done 2888cmp_ft_s_f6: 2889 mfc1 t4, $f6 2890 b cmp_ft_s_done 2891cmp_ft_s_f8: 2892 mfc1 t4, $f8 2893 b cmp_ft_s_done 2894cmp_ft_s_f10: 2895 mfc1 t4, $f10 2896 b cmp_ft_s_done 2897cmp_ft_s_f12: 2898 mfc1 t4, $f12 2899 b cmp_ft_s_done 2900cmp_ft_s_f14: 2901 mfc1 t4, $f14 2902 b cmp_ft_s_done 2903cmp_ft_s_f16: 2904 mfc1 t4, $f16 2905 b cmp_ft_s_done 2906cmp_ft_s_f18: 2907 mfc1 t4, $f18 2908 b cmp_ft_s_done 2909cmp_ft_s_f20: 2910 mfc1 t4, $f20 2911 b cmp_ft_s_done 2912cmp_ft_s_f22: 2913 mfc1 t4, $f22 2914 b cmp_ft_s_done 2915cmp_ft_s_f24: 2916 mfc1 t4, $f24 2917 b cmp_ft_s_done 2918cmp_ft_s_f26: 2919 mfc1 t4, $f26 2920 b cmp_ft_s_done 2921cmp_ft_s_f28: 2922 mfc1 t4, $f28 2923 b cmp_ft_s_done 2924cmp_ft_s_f30: 2925 mfc1 t4, $f30 2926cmp_ft_s_done: 2927 srl t5, t4, 23 # get exponent 2928 and t5, t5, 0xFF 2929 and t6, t4, 0x7FFFFF # get fraction 2930 srl t4, t4, 31 # get sign 2931 j ra 2932END(get_cmp_s) 2933 2934/*---------------------------------------------------------------------------- 2935 * get_cmp_d -- 2936 * 2937 * Read (double precision) the FS register (bits 15-11) and 2938 * the FT register (bits 20-16) and break up into fields. 2939 * This is an internal routine used by MachEmulateFP only. 2940 * 2941 * Results: 2942 * t0 contains the sign 2943 * t1 contains the (biased) exponent 2944 * t2 contains the fraction 2945 * t3 contains the remaining fraction 2946 * t4 contains the sign 2947 * t5 contains the (biased) exponent 2948 * t6 contains the fraction 2949 * t7 contains the remaining fraction 2950 * 2951 *---------------------------------------------------------------------------- 2952 */ 2953LEAF(get_cmp_d) 2954 srl a3, a0, 12 - 2 # get FS field (even regs only) 2955 and a3, a3, 0xF << 2 # mask FS field 2956 lw a3, cmp_fs_d_tbl(a3) # switch on register number 2957 j a3 2958 2959 .rdata 2960cmp_fs_d_tbl: 2961 .word cmp_fs_d_f0 2962 .word cmp_fs_d_f2 2963 .word cmp_fs_d_f4 2964 .word cmp_fs_d_f6 2965 .word cmp_fs_d_f8 2966 .word cmp_fs_d_f10 2967 .word cmp_fs_d_f12 2968 .word cmp_fs_d_f14 2969 .word cmp_fs_d_f16 2970 .word cmp_fs_d_f18 2971 .word cmp_fs_d_f20 2972 .word cmp_fs_d_f22 2973 .word cmp_fs_d_f24 2974 .word cmp_fs_d_f26 2975 .word cmp_fs_d_f28 2976 .word cmp_fs_d_f30 2977 .text 2978 2979cmp_fs_d_f0: 2980 mfc1 t3, $f0 2981 mfc1 t0, $f1 2982 b cmp_fs_d_done 2983cmp_fs_d_f2: 2984 mfc1 t3, $f2 2985 mfc1 t0, $f3 2986 b cmp_fs_d_done 2987cmp_fs_d_f4: 2988 mfc1 t3, $f4 2989 mfc1 t0, $f5 2990 b cmp_fs_d_done 2991cmp_fs_d_f6: 2992 mfc1 t3, $f6 2993 mfc1 t0, $f7 2994 b cmp_fs_d_done 2995cmp_fs_d_f8: 2996 mfc1 t3, $f8 2997 mfc1 t0, $f9 2998 b cmp_fs_d_done 2999cmp_fs_d_f10: 3000 mfc1 t3, $f10 3001 mfc1 t0, $f11 3002 b cmp_fs_d_done 3003cmp_fs_d_f12: 3004 mfc1 t3, $f12 3005 mfc1 t0, $f13 3006 b cmp_fs_d_done 3007cmp_fs_d_f14: 3008 mfc1 t3, $f14 3009 mfc1 t0, $f15 3010 b cmp_fs_d_done 3011cmp_fs_d_f16: 3012 mfc1 t3, $f16 3013 mfc1 t0, $f17 3014 b cmp_fs_d_done 3015cmp_fs_d_f18: 3016 mfc1 t3, $f18 3017 mfc1 t0, $f19 3018 b cmp_fs_d_done 3019cmp_fs_d_f20: 3020 mfc1 t3, $f20 3021 mfc1 t0, $f21 3022 b cmp_fs_d_done 3023cmp_fs_d_f22: 3024 mfc1 t3, $f22 3025 mfc1 t0, $f23 3026 b cmp_fs_d_done 3027cmp_fs_d_f24: 3028 mfc1 t3, $f24 3029 mfc1 t0, $f25 3030 b cmp_fs_d_done 3031cmp_fs_d_f26: 3032 mfc1 t3, $f26 3033 mfc1 t0, $f27 3034 b cmp_fs_d_done 3035cmp_fs_d_f28: 3036 mfc1 t3, $f28 3037 mfc1 t0, $f29 3038 b cmp_fs_d_done 3039cmp_fs_d_f30: 3040 mfc1 t3, $f30 3041 mfc1 t0, $f31 3042cmp_fs_d_done: 3043 srl t1, t0, 20 # get exponent 3044 and t1, t1, 0x7FF 3045 and t2, t0, 0xFFFFF # get fraction 3046 srl t0, t0, 31 # get sign 3047 3048 srl a3, a0, 17 - 2 # get FT field (even regs only) 3049 and a3, a3, 0xF << 2 # mask FT field 3050 lw a3, cmp_ft_d_tbl(a3) # switch on register number 3051 j a3 3052 3053 .rdata 3054cmp_ft_d_tbl: 3055 .word cmp_ft_d_f0 3056 .word cmp_ft_d_f2 3057 .word cmp_ft_d_f4 3058 .word cmp_ft_d_f6 3059 .word cmp_ft_d_f8 3060 .word cmp_ft_d_f10 3061 .word cmp_ft_d_f12 3062 .word cmp_ft_d_f14 3063 .word cmp_ft_d_f16 3064 .word cmp_ft_d_f18 3065 .word cmp_ft_d_f20 3066 .word cmp_ft_d_f22 3067 .word cmp_ft_d_f24 3068 .word cmp_ft_d_f26 3069 .word cmp_ft_d_f28 3070 .word cmp_ft_d_f30 3071 .text 3072 3073cmp_ft_d_f0: 3074 mfc1 t7, $f0 3075 mfc1 t4, $f1 3076 b cmp_ft_d_done 3077cmp_ft_d_f2: 3078 mfc1 t7, $f2 3079 mfc1 t4, $f3 3080 b cmp_ft_d_done 3081cmp_ft_d_f4: 3082 mfc1 t7, $f4 3083 mfc1 t4, $f5 3084 b cmp_ft_d_done 3085cmp_ft_d_f6: 3086 mfc1 t7, $f6 3087 mfc1 t4, $f7 3088 b cmp_ft_d_done 3089cmp_ft_d_f8: 3090 mfc1 t7, $f8 3091 mfc1 t4, $f9 3092 b cmp_ft_d_done 3093cmp_ft_d_f10: 3094 mfc1 t7, $f10 3095 mfc1 t4, $f11 3096 b cmp_ft_d_done 3097cmp_ft_d_f12: 3098 mfc1 t7, $f12 3099 mfc1 t4, $f13 3100 b cmp_ft_d_done 3101cmp_ft_d_f14: 3102 mfc1 t7, $f14 3103 mfc1 t4, $f15 3104 b cmp_ft_d_done 3105cmp_ft_d_f16: 3106 mfc1 t7, $f16 3107 mfc1 t4, $f17 3108 b cmp_ft_d_done 3109cmp_ft_d_f18: 3110 mfc1 t7, $f18 3111 mfc1 t4, $f19 3112 b cmp_ft_d_done 3113cmp_ft_d_f20: 3114 mfc1 t7, $f20 3115 mfc1 t4, $f21 3116 b cmp_ft_d_done 3117cmp_ft_d_f22: 3118 mfc1 t7, $f22 3119 mfc1 t4, $f23 3120 b cmp_ft_d_done 3121cmp_ft_d_f24: 3122 mfc1 t7, $f24 3123 mfc1 t4, $f25 3124 b cmp_ft_d_done 3125cmp_ft_d_f26: 3126 mfc1 t7, $f26 3127 mfc1 t4, $f27 3128 b cmp_ft_d_done 3129cmp_ft_d_f28: 3130 mfc1 t7, $f28 3131 mfc1 t4, $f29 3132 b cmp_ft_d_done 3133cmp_ft_d_f30: 3134 mfc1 t7, $f30 3135 mfc1 t4, $f31 3136cmp_ft_d_done: 3137 srl t5, t4, 20 # get exponent 3138 and t5, t5, 0x7FF 3139 and t6, t4, 0xFFFFF # get fraction 3140 srl t4, t4, 31 # get sign 3141 j ra 3142END(get_cmp_d) 3143 3144/*---------------------------------------------------------------------------- 3145 * set_fd_s -- 3146 * 3147 * Write (single precision) the FD register (bits 10-6). 3148 * This is an internal routine used by MachEmulateFP only. 3149 * 3150 * Arguments: 3151 * a0 contains the FP instruction 3152 * t0 contains the sign 3153 * t1 contains the (biased) exponent 3154 * t2 contains the fraction 3155 * 3156 * set_fd_word -- 3157 * 3158 * Write (integer) the FD register (bits 10-6). 3159 * This is an internal routine used by MachEmulateFP only. 3160 * 3161 * Arguments: 3162 * a0 contains the FP instruction 3163 * t2 contains the integer 3164 * 3165 *---------------------------------------------------------------------------- 3166 */ 3167LEAF(set_fd_s) 3168 sll t0, t0, 31 # position sign 3169 sll t1, t1, 23 # position exponent 3170 or t2, t2, t0 3171 or t2, t2, t1 3172ALEAF(set_fd_word) 3173 srl a3, a0, 7 - 2 # get FD field (even regs only) 3174 and a3, a3, 0xF << 2 # mask FT field 3175 lw a3, set_fd_s_tbl(a3) # switch on register number 3176 j a3 3177 3178 .rdata 3179set_fd_s_tbl: 3180 .word set_fd_s_f0 3181 .word set_fd_s_f2 3182 .word set_fd_s_f4 3183 .word set_fd_s_f6 3184 .word set_fd_s_f8 3185 .word set_fd_s_f10 3186 .word set_fd_s_f12 3187 .word set_fd_s_f14 3188 .word set_fd_s_f16 3189 .word set_fd_s_f18 3190 .word set_fd_s_f20 3191 .word set_fd_s_f22 3192 .word set_fd_s_f24 3193 .word set_fd_s_f26 3194 .word set_fd_s_f28 3195 .word set_fd_s_f30 3196 .text 3197 3198set_fd_s_f0: 3199 mtc1 t2, $f0 3200 j ra 3201set_fd_s_f2: 3202 mtc1 t2, $f2 3203 j ra 3204set_fd_s_f4: 3205 mtc1 t2, $f4 3206 j ra 3207set_fd_s_f6: 3208 mtc1 t2, $f6 3209 j ra 3210set_fd_s_f8: 3211 mtc1 t2, $f8 3212 j ra 3213set_fd_s_f10: 3214 mtc1 t2, $f10 3215 j ra 3216set_fd_s_f12: 3217 mtc1 t2, $f12 3218 j ra 3219set_fd_s_f14: 3220 mtc1 t2, $f14 3221 j ra 3222set_fd_s_f16: 3223 mtc1 t2, $f16 3224 j ra 3225set_fd_s_f18: 3226 mtc1 t2, $f18 3227 j ra 3228set_fd_s_f20: 3229 mtc1 t2, $f20 3230 j ra 3231set_fd_s_f22: 3232 mtc1 t2, $f22 3233 j ra 3234set_fd_s_f24: 3235 mtc1 t2, $f24 3236 j ra 3237set_fd_s_f26: 3238 mtc1 t2, $f26 3239 j ra 3240set_fd_s_f28: 3241 mtc1 t2, $f28 3242 j ra 3243set_fd_s_f30: 3244 mtc1 t2, $f30 3245 j ra 3246END(set_fd_s) 3247 3248/*---------------------------------------------------------------------------- 3249 * set_fd_d -- 3250 * 3251 * Write (double precision) the FT register (bits 10-6). 3252 * This is an internal routine used by MachEmulateFP only. 3253 * 3254 * Arguments: 3255 * a0 contains the FP instruction 3256 * t0 contains the sign 3257 * t1 contains the (biased) exponent 3258 * t2 contains the fraction 3259 * t3 contains the remaining fraction 3260 * 3261 *---------------------------------------------------------------------------- 3262 */ 3263LEAF(set_fd_d) 3264 sll t0, t0, 31 # set sign 3265 sll t1, t1, 20 # set exponent 3266 or t0, t0, t1 3267 or t0, t0, t2 # set fraction 3268 srl a3, a0, 7 - 2 # get FD field (even regs only) 3269 and a3, a3, 0xF << 2 # mask FD field 3270 lw a3, set_fd_d_tbl(a3) # switch on register number 3271 j a3 3272 3273 .rdata 3274set_fd_d_tbl: 3275 .word set_fd_d_f0 3276 .word set_fd_d_f2 3277 .word set_fd_d_f4 3278 .word set_fd_d_f6 3279 .word set_fd_d_f8 3280 .word set_fd_d_f10 3281 .word set_fd_d_f12 3282 .word set_fd_d_f14 3283 .word set_fd_d_f16 3284 .word set_fd_d_f18 3285 .word set_fd_d_f20 3286 .word set_fd_d_f22 3287 .word set_fd_d_f24 3288 .word set_fd_d_f26 3289 .word set_fd_d_f28 3290 .word set_fd_d_f30 3291 .text 3292 3293set_fd_d_f0: 3294 mtc1 t3, $f0 3295 mtc1 t0, $f1 3296 j ra 3297set_fd_d_f2: 3298 mtc1 t3, $f2 3299 mtc1 t0, $f3 3300 j ra 3301set_fd_d_f4: 3302 mtc1 t3, $f4 3303 mtc1 t0, $f5 3304 j ra 3305set_fd_d_f6: 3306 mtc1 t3, $f6 3307 mtc1 t0, $f7 3308 j ra 3309set_fd_d_f8: 3310 mtc1 t3, $f8 3311 mtc1 t0, $f9 3312 j ra 3313set_fd_d_f10: 3314 mtc1 t3, $f10 3315 mtc1 t0, $f11 3316 j ra 3317set_fd_d_f12: 3318 mtc1 t3, $f12 3319 mtc1 t0, $f13 3320 j ra 3321set_fd_d_f14: 3322 mtc1 t3, $f14 3323 mtc1 t0, $f15 3324 j ra 3325set_fd_d_f16: 3326 mtc1 t3, $f16 3327 mtc1 t0, $f17 3328 j ra 3329set_fd_d_f18: 3330 mtc1 t3, $f18 3331 mtc1 t0, $f19 3332 j ra 3333set_fd_d_f20: 3334 mtc1 t3, $f20 3335 mtc1 t0, $f21 3336 j ra 3337set_fd_d_f22: 3338 mtc1 t3, $f22 3339 mtc1 t0, $f23 3340 j ra 3341set_fd_d_f24: 3342 mtc1 t3, $f24 3343 mtc1 t0, $f25 3344 j ra 3345set_fd_d_f26: 3346 mtc1 t3, $f26 3347 mtc1 t0, $f27 3348 j ra 3349set_fd_d_f28: 3350 mtc1 t3, $f28 3351 mtc1 t0, $f29 3352 j ra 3353set_fd_d_f30: 3354 mtc1 t3, $f30 3355 mtc1 t0, $f31 3356 j ra 3357END(set_fd_d) 3358 3359/*---------------------------------------------------------------------------- 3360 * renorm_fs_s -- 3361 * 3362 * Results: 3363 * t1 unbiased exponent 3364 * t2 normalized fraction 3365 * 3366 *---------------------------------------------------------------------------- 3367 */ 3368LEAF(renorm_fs_s) 3369/* 3370 * Find out how many leading zero bits are in t2 and put in t9. 3371 */ 3372 move v0, t2 3373 move t9, zero 3374 srl v1, v0, 16 3375 bne v1, zero, 1f 3376 addu t9, 16 3377 sll v0, 16 33781: 3379 srl v1, v0, 24 3380 bne v1, zero, 1f 3381 addu t9, 8 3382 sll v0, 8 33831: 3384 srl v1, v0, 28 3385 bne v1, zero, 1f 3386 addu t9, 4 3387 sll v0, 4 33881: 3389 srl v1, v0, 30 3390 bne v1, zero, 1f 3391 addu t9, 2 3392 sll v0, 2 33931: 3394 srl v1, v0, 31 3395 bne v1, zero, 1f 3396 addu t9, 1 3397/* 3398 * Now shift t2 the correct number of bits. 3399 */ 34001: 3401 subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros 3402 li t1, SEXP_MIN 3403 subu t1, t1, t9 # adjust exponent 3404 sll t2, t2, t9 3405 j ra 3406END(renorm_fs_s) 3407 3408/*---------------------------------------------------------------------------- 3409 * renorm_fs_d -- 3410 * 3411 * Results: 3412 * t1 unbiased exponent 3413 * t2,t3 normalized fraction 3414 * 3415 *---------------------------------------------------------------------------- 3416 */ 3417LEAF(renorm_fs_d) 3418/* 3419 * Find out how many leading zero bits are in t2,t3 and put in t9. 3420 */ 3421 move v0, t2 3422 move t9, zero 3423 bne t2, zero, 1f 3424 move v0, t3 3425 addu t9, 32 34261: 3427 srl v1, v0, 16 3428 bne v1, zero, 1f 3429 addu t9, 16 3430 sll v0, 16 34311: 3432 srl v1, v0, 24 3433 bne v1, zero, 1f 3434 addu t9, 8 3435 sll v0, 8 34361: 3437 srl v1, v0, 28 3438 bne v1, zero, 1f 3439 addu t9, 4 3440 sll v0, 4 34411: 3442 srl v1, v0, 30 3443 bne v1, zero, 1f 3444 addu t9, 2 3445 sll v0, 2 34461: 3447 srl v1, v0, 31 3448 bne v1, zero, 1f 3449 addu t9, 1 3450/* 3451 * Now shift t2,t3 the correct number of bits. 3452 */ 34531: 3454 subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros 3455 li t1, DEXP_MIN 3456 subu t1, t1, t9 # adjust exponent 3457 li v0, 32 3458 blt t9, v0, 1f 3459 subu t9, t9, v0 # shift fraction left >= 32 bits 3460 sll t2, t3, t9 3461 move t3, zero 3462 j ra 34631: 3464 subu v0, v0, t9 # shift fraction left < 32 bits 3465 sll t2, t2, t9 3466 srl v1, t3, v0 3467 or t2, t2, v1 3468 sll t3, t3, t9 3469 j ra 3470END(renorm_fs_d) 3471 3472/*---------------------------------------------------------------------------- 3473 * renorm_ft_s -- 3474 * 3475 * Results: 3476 * t5 unbiased exponent 3477 * t6 normalized fraction 3478 * 3479 *---------------------------------------------------------------------------- 3480 */ 3481LEAF(renorm_ft_s) 3482/* 3483 * Find out how many leading zero bits are in t6 and put in t9. 3484 */ 3485 move v0, t6 3486 move t9, zero 3487 srl v1, v0, 16 3488 bne v1, zero, 1f 3489 addu t9, 16 3490 sll v0, 16 34911: 3492 srl v1, v0, 24 3493 bne v1, zero, 1f 3494 addu t9, 8 3495 sll v0, 8 34961: 3497 srl v1, v0, 28 3498 bne v1, zero, 1f 3499 addu t9, 4 3500 sll v0, 4 35011: 3502 srl v1, v0, 30 3503 bne v1, zero, 1f 3504 addu t9, 2 3505 sll v0, 2 35061: 3507 srl v1, v0, 31 3508 bne v1, zero, 1f 3509 addu t9, 1 3510/* 3511 * Now shift t6 the correct number of bits. 3512 */ 35131: 3514 subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros 3515 li t5, SEXP_MIN 3516 subu t5, t5, t9 # adjust exponent 3517 sll t6, t6, t9 3518 j ra 3519END(renorm_ft_s) 3520 3521/*---------------------------------------------------------------------------- 3522 * renorm_ft_d -- 3523 * 3524 * Results: 3525 * t5 unbiased exponent 3526 * t6,t7 normalized fraction 3527 * 3528 *---------------------------------------------------------------------------- 3529 */ 3530LEAF(renorm_ft_d) 3531/* 3532 * Find out how many leading zero bits are in t6,t7 and put in t9. 3533 */ 3534 move v0, t6 3535 move t9, zero 3536 bne t6, zero, 1f 3537 move v0, t7 3538 addu t9, 32 35391: 3540 srl v1, v0, 16 3541 bne v1, zero, 1f 3542 addu t9, 16 3543 sll v0, 16 35441: 3545 srl v1, v0, 24 3546 bne v1, zero, 1f 3547 addu t9, 8 3548 sll v0, 8 35491: 3550 srl v1, v0, 28 3551 bne v1, zero, 1f 3552 addu t9, 4 3553 sll v0, 4 35541: 3555 srl v1, v0, 30 3556 bne v1, zero, 1f 3557 addu t9, 2 3558 sll v0, 2 35591: 3560 srl v1, v0, 31 3561 bne v1, zero, 1f 3562 addu t9, 1 3563/* 3564 * Now shift t6,t7 the correct number of bits. 3565 */ 35661: 3567 subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros 3568 li t5, DEXP_MIN 3569 subu t5, t5, t9 # adjust exponent 3570 li v0, 32 3571 blt t9, v0, 1f 3572 subu t9, t9, v0 # shift fraction left >= 32 bits 3573 sll t6, t7, t9 3574 move t7, zero 3575 j ra 35761: 3577 subu v0, v0, t9 # shift fraction left < 32 bits 3578 sll t6, t6, t9 3579 srl v1, t7, v0 3580 or t6, t6, v1 3581 sll t7, t7, t9 3582 j ra 3583END(renorm_ft_d) 3584