1/* $OpenBSD: fp.S,v 1.2 1998/03/16 09:03:31 pefo Exp $ */ 2/*- 3 * Copyright (c) 1992, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Ralph Campbell. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * from: @(#)fp.s 8.1 (Berkeley) 6/10/93 34 * JNPR: fp.S,v 1.1 2006/08/07 05:38:57 katta 35 * $FreeBSD$ 36 */ 37 38/* 39 * Standard header stuff. 40 */ 41 42#include <machine/asm.h> 43#include <machine/regnum.h> 44#include <machine/cpuregs.h> 45 46#include "assym.inc" 47 48#define SEXP_INF 0xff 49#define DEXP_INF 0x7ff 50#define SEXP_BIAS 127 51#define DEXP_BIAS 1023 52#define SEXP_MIN -126 53#define DEXP_MIN -1022 54#define SEXP_MAX 127 55#define DEXP_MAX 1023 56#define WEXP_MAX 30 /* maximum unbiased exponent for int */ 57#define WEXP_MIN -1 /* minimum unbiased exponent for int */ 58#define SFRAC_BITS 23 59#define DFRAC_BITS 52 60#define SIMPL_ONE 0x00800000 61#define DIMPL_ONE 0x00100000 62#define SLEAD_ZEROS 31 - 23 63#define DLEAD_ZEROS 31 - 20 64#define STICKYBIT 1 65#define GUARDBIT 0x80000000 66#define SSIGNAL_NAN 0x00400000 67#define DSIGNAL_NAN 0x00080000 68#define SQUIET_NAN 0x003fffff 69#define DQUIET_NAN0 0x0007ffff 70#define DQUIET_NAN1 0xffffffff 71#define INT_MIN 0x80000000 72#define INT_MAX 0x7fffffff 73 74#define COND_UNORDERED 0x1 75#define COND_EQUAL 0x2 76#define COND_LESS 0x4 77#define COND_SIGNAL 0x8 78 79.set hardfloat 80 81/*---------------------------------------------------------------------------- 82 * 83 * MipsEmulateFP -- 84 * 85 * Emulate unimplemented floating point operations. 86 * This routine should only be called by MipsFPInterrupt(). 87 * 88 * MipsEmulateFP(instr) 89 * unsigned instr; 90 * 91 * Results: 92 * None. 93 * 94 * Side effects: 95 * Floating point registers are modified according to instruction. 96 * 97 *---------------------------------------------------------------------------- 98 */ 99NESTED(MipsEmulateFP, CALLFRAME_SIZ, ra) 100 subu sp, sp, CALLFRAME_SIZ 101 sw ra, CALLFRAME_RA(sp) 102/* 103 * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0). 104 */ 105 srl v0, a0, 21 - 2 # get FMT field 106 and v0, v0, 0xF << 2 # mask FMT field 107 and v1, a0, 0x3F # mask FUNC field 108 sll v1, v1, 5 # align for table lookup 109 bgt v0, 4 << 2, ill # illegal format 110 111 or v1, v1, v0 112 cfc1 a1, MIPS_FPU_CSR # get exception register 113 lw a3, func_fmt_tbl(v1) # switch on FUNC & FMT 114 and a1, a1, ~MIPS_FPU_EXCEPTION_UNIMPL # clear exception 115 ctc1 a1, MIPS_FPU_CSR 116 j a3 117 118 .rdata 119func_fmt_tbl: 120 .word add_s # 0 121 .word add_d # 0 122 .word ill # 0 123 .word ill # 0 124 .word ill # 0 125 .word ill # 0 126 .word ill # 0 127 .word ill # 0 128 .word sub_s # 1 129 .word sub_d # 1 130 .word ill # 1 131 .word ill # 1 132 .word ill # 1 133 .word ill # 1 134 .word ill # 1 135 .word ill # 1 136 .word mul_s # 2 137 .word mul_d # 2 138 .word ill # 2 139 .word ill # 2 140 .word ill # 2 141 .word ill # 2 142 .word ill # 2 143 .word ill # 2 144 .word div_s # 3 145 .word div_d # 3 146 .word ill # 3 147 .word ill # 3 148 .word ill # 3 149 .word ill # 3 150 .word ill # 3 151 .word ill # 3 152 .word ill # 4 153 .word ill # 4 154 .word ill # 4 155 .word ill # 4 156 .word ill # 4 157 .word ill # 4 158 .word ill # 4 159 .word ill # 4 160 .word abs_s # 5 161 .word abs_d # 5 162 .word ill # 5 163 .word ill # 5 164 .word ill # 5 165 .word ill # 5 166 .word ill # 5 167 .word ill # 5 168 .word mov_s # 6 169 .word mov_d # 6 170 .word ill # 6 171 .word ill # 6 172 .word ill # 6 173 .word ill # 6 174 .word ill # 6 175 .word ill # 6 176 .word neg_s # 7 177 .word neg_d # 7 178 .word ill # 7 179 .word ill # 7 180 .word ill # 7 181 .word ill # 7 182 .word ill # 7 183 .word ill # 7 184 .word ill # 8 185 .word ill # 8 186 .word ill # 8 187 .word ill # 8 188 .word ill # 8 189 .word ill # 8 190 .word ill # 8 191 .word ill # 8 192 .word ill # 9 193 .word ill # 9 194 .word ill # 9 195 .word ill # 9 196 .word ill # 9 197 .word ill # 9 198 .word ill # 9 199 .word ill # 9 200 .word ill # 10 201 .word ill # 10 202 .word ill # 10 203 .word ill # 10 204 .word ill # 10 205 .word ill # 10 206 .word ill # 10 207 .word ill # 10 208 .word ill # 11 209 .word ill # 11 210 .word ill # 11 211 .word ill # 11 212 .word ill # 11 213 .word ill # 11 214 .word ill # 11 215 .word ill # 11 216 .word ill # 12 217 .word ill # 12 218 .word ill # 12 219 .word ill # 12 220 .word ill # 12 221 .word ill # 12 222 .word ill # 12 223 .word ill # 12 224 .word ill # 13 225 .word ill # 13 226 .word ill # 13 227 .word ill # 13 228 .word ill # 13 229 .word ill # 13 230 .word ill # 13 231 .word ill # 13 232 .word ill # 14 233 .word ill # 14 234 .word ill # 14 235 .word ill # 14 236 .word ill # 14 237 .word ill # 14 238 .word ill # 14 239 .word ill # 14 240 .word ill # 15 241 .word ill # 15 242 .word ill # 15 243 .word ill # 15 244 .word ill # 15 245 .word ill # 15 246 .word ill # 15 247 .word ill # 15 248 .word ill # 16 249 .word ill # 16 250 .word ill # 16 251 .word ill # 16 252 .word ill # 16 253 .word ill # 16 254 .word ill # 16 255 .word ill # 16 256 .word ill # 17 257 .word ill # 17 258 .word ill # 17 259 .word ill # 17 260 .word ill # 17 261 .word ill # 17 262 .word ill # 17 263 .word ill # 17 264 .word ill # 18 265 .word ill # 18 266 .word ill # 18 267 .word ill # 18 268 .word ill # 18 269 .word ill # 18 270 .word ill # 18 271 .word ill # 18 272 .word ill # 19 273 .word ill # 19 274 .word ill # 19 275 .word ill # 19 276 .word ill # 19 277 .word ill # 19 278 .word ill # 19 279 .word ill # 19 280 .word ill # 20 281 .word ill # 20 282 .word ill # 20 283 .word ill # 20 284 .word ill # 20 285 .word ill # 20 286 .word ill # 20 287 .word ill # 20 288 .word ill # 21 289 .word ill # 21 290 .word ill # 21 291 .word ill # 21 292 .word ill # 21 293 .word ill # 21 294 .word ill # 21 295 .word ill # 21 296 .word ill # 22 297 .word ill # 22 298 .word ill # 22 299 .word ill # 22 300 .word ill # 22 301 .word ill # 22 302 .word ill # 22 303 .word ill # 22 304 .word ill # 23 305 .word ill # 23 306 .word ill # 23 307 .word ill # 23 308 .word ill # 23 309 .word ill # 23 310 .word ill # 23 311 .word ill # 23 312 .word ill # 24 313 .word ill # 24 314 .word ill # 24 315 .word ill # 24 316 .word ill # 24 317 .word ill # 24 318 .word ill # 24 319 .word ill # 24 320 .word ill # 25 321 .word ill # 25 322 .word ill # 25 323 .word ill # 25 324 .word ill # 25 325 .word ill # 25 326 .word ill # 25 327 .word ill # 25 328 .word ill # 26 329 .word ill # 26 330 .word ill # 26 331 .word ill # 26 332 .word ill # 26 333 .word ill # 26 334 .word ill # 26 335 .word ill # 26 336 .word ill # 27 337 .word ill # 27 338 .word ill # 27 339 .word ill # 27 340 .word ill # 27 341 .word ill # 27 342 .word ill # 27 343 .word ill # 27 344 .word ill # 28 345 .word ill # 28 346 .word ill # 28 347 .word ill # 28 348 .word ill # 28 349 .word ill # 28 350 .word ill # 28 351 .word ill # 28 352 .word ill # 29 353 .word ill # 29 354 .word ill # 29 355 .word ill # 29 356 .word ill # 29 357 .word ill # 29 358 .word ill # 29 359 .word ill # 29 360 .word ill # 30 361 .word ill # 30 362 .word ill # 30 363 .word ill # 30 364 .word ill # 30 365 .word ill # 30 366 .word ill # 30 367 .word ill # 30 368 .word ill # 31 369 .word ill # 31 370 .word ill # 31 371 .word ill # 31 372 .word ill # 31 373 .word ill # 31 374 .word ill # 31 375 .word ill # 31 376 .word ill # 32 377 .word cvt_s_d # 32 378 .word ill # 32 379 .word ill # 32 380 .word cvt_s_w # 32 381 .word ill # 32 382 .word ill # 32 383 .word ill # 32 384 .word cvt_d_s # 33 385 .word ill # 33 386 .word ill # 33 387 .word ill # 33 388 .word cvt_d_w # 33 389 .word ill # 33 390 .word ill # 33 391 .word ill # 33 392 .word ill # 34 393 .word ill # 34 394 .word ill # 34 395 .word ill # 34 396 .word ill # 34 397 .word ill # 34 398 .word ill # 34 399 .word ill # 34 400 .word ill # 35 401 .word ill # 35 402 .word ill # 35 403 .word ill # 35 404 .word ill # 35 405 .word ill # 35 406 .word ill # 35 407 .word ill # 35 408 .word cvt_w_s # 36 409 .word cvt_w_d # 36 410 .word ill # 36 411 .word ill # 36 412 .word ill # 36 413 .word ill # 36 414 .word ill # 36 415 .word ill # 36 416 .word ill # 37 417 .word ill # 37 418 .word ill # 37 419 .word ill # 37 420 .word ill # 37 421 .word ill # 37 422 .word ill # 37 423 .word ill # 37 424 .word ill # 38 425 .word ill # 38 426 .word ill # 38 427 .word ill # 38 428 .word ill # 38 429 .word ill # 38 430 .word ill # 38 431 .word ill # 38 432 .word ill # 39 433 .word ill # 39 434 .word ill # 39 435 .word ill # 39 436 .word ill # 39 437 .word ill # 39 438 .word ill # 39 439 .word ill # 39 440 .word ill # 40 441 .word ill # 40 442 .word ill # 40 443 .word ill # 40 444 .word ill # 40 445 .word ill # 40 446 .word ill # 40 447 .word ill # 40 448 .word ill # 41 449 .word ill # 41 450 .word ill # 41 451 .word ill # 41 452 .word ill # 41 453 .word ill # 41 454 .word ill # 41 455 .word ill # 41 456 .word ill # 42 457 .word ill # 42 458 .word ill # 42 459 .word ill # 42 460 .word ill # 42 461 .word ill # 42 462 .word ill # 42 463 .word ill # 42 464 .word ill # 43 465 .word ill # 43 466 .word ill # 43 467 .word ill # 43 468 .word ill # 43 469 .word ill # 43 470 .word ill # 43 471 .word ill # 43 472 .word ill # 44 473 .word ill # 44 474 .word ill # 44 475 .word ill # 44 476 .word ill # 44 477 .word ill # 44 478 .word ill # 44 479 .word ill # 44 480 .word ill # 45 481 .word ill # 45 482 .word ill # 45 483 .word ill # 45 484 .word ill # 45 485 .word ill # 45 486 .word ill # 45 487 .word ill # 45 488 .word ill # 46 489 .word ill # 46 490 .word ill # 46 491 .word ill # 46 492 .word ill # 46 493 .word ill # 46 494 .word ill # 46 495 .word ill # 46 496 .word ill # 47 497 .word ill # 47 498 .word ill # 47 499 .word ill # 47 500 .word ill # 47 501 .word ill # 47 502 .word ill # 47 503 .word ill # 47 504 .word cmp_s # 48 505 .word cmp_d # 48 506 .word ill # 48 507 .word ill # 48 508 .word ill # 48 509 .word ill # 48 510 .word ill # 48 511 .word ill # 48 512 .word cmp_s # 49 513 .word cmp_d # 49 514 .word ill # 49 515 .word ill # 49 516 .word ill # 49 517 .word ill # 49 518 .word ill # 49 519 .word ill # 49 520 .word cmp_s # 50 521 .word cmp_d # 50 522 .word ill # 50 523 .word ill # 50 524 .word ill # 50 525 .word ill # 50 526 .word ill # 50 527 .word ill # 50 528 .word cmp_s # 51 529 .word cmp_d # 51 530 .word ill # 51 531 .word ill # 51 532 .word ill # 51 533 .word ill # 51 534 .word ill # 51 535 .word ill # 51 536 .word cmp_s # 52 537 .word cmp_d # 52 538 .word ill # 52 539 .word ill # 52 540 .word ill # 52 541 .word ill # 52 542 .word ill # 52 543 .word ill # 52 544 .word cmp_s # 53 545 .word cmp_d # 53 546 .word ill # 53 547 .word ill # 53 548 .word ill # 53 549 .word ill # 53 550 .word ill # 53 551 .word ill # 53 552 .word cmp_s # 54 553 .word cmp_d # 54 554 .word ill # 54 555 .word ill # 54 556 .word ill # 54 557 .word ill # 54 558 .word ill # 54 559 .word ill # 54 560 .word cmp_s # 55 561 .word cmp_d # 55 562 .word ill # 55 563 .word ill # 55 564 .word ill # 55 565 .word ill # 55 566 .word ill # 55 567 .word ill # 55 568 .word cmp_s # 56 569 .word cmp_d # 56 570 .word ill # 56 571 .word ill # 56 572 .word ill # 56 573 .word ill # 56 574 .word ill # 56 575 .word ill # 56 576 .word cmp_s # 57 577 .word cmp_d # 57 578 .word ill # 57 579 .word ill # 57 580 .word ill # 57 581 .word ill # 57 582 .word ill # 57 583 .word ill # 57 584 .word cmp_s # 58 585 .word cmp_d # 58 586 .word ill # 58 587 .word ill # 58 588 .word ill # 58 589 .word ill # 58 590 .word ill # 58 591 .word ill # 58 592 .word cmp_s # 59 593 .word cmp_d # 59 594 .word ill # 59 595 .word ill # 59 596 .word ill # 59 597 .word ill # 59 598 .word ill # 59 599 .word ill # 59 600 .word cmp_s # 60 601 .word cmp_d # 60 602 .word ill # 60 603 .word ill # 60 604 .word ill # 60 605 .word ill # 60 606 .word ill # 60 607 .word ill # 60 608 .word cmp_s # 61 609 .word cmp_d # 61 610 .word ill # 61 611 .word ill # 61 612 .word ill # 61 613 .word ill # 61 614 .word ill # 61 615 .word ill # 61 616 .word cmp_s # 62 617 .word cmp_d # 62 618 .word ill # 62 619 .word ill # 62 620 .word ill # 62 621 .word ill # 62 622 .word ill # 62 623 .word ill # 62 624 .word cmp_s # 63 625 .word cmp_d # 63 626 .word ill # 63 627 .word ill # 63 628 .word ill # 63 629 .word ill # 63 630 .word ill # 63 631 .word ill # 63 632 .text 633 634/* 635 * Single precision subtract. 636 */ 637sub_s: 638 jal get_ft_fs_s 639 xor ta0, ta0, 1 # negate FT sign bit 640 b add_sub_s 641/* 642 * Single precision add. 643 */ 644add_s: 645 jal get_ft_fs_s 646add_sub_s: 647 bne t1, SEXP_INF, 1f # is FS an infinity? 648 bne ta1, SEXP_INF, result_fs_s # if FT is not inf, result=FS 649 bne t2, zero, result_fs_s # if FS is NAN, result is FS 650 bne ta2, zero, result_ft_s # if FT is NAN, result is FT 651 bne t0, ta0, invalid_s # both infinities same sign? 652 b result_fs_s # result is in FS 6531: 654 beq ta1, SEXP_INF, result_ft_s # if FT is inf, result=FT 655 bne t1, zero, 4f # is FS a denormalized num? 656 beq t2, zero, 3f # is FS zero? 657 bne ta1, zero, 2f # is FT a denormalized num? 658 beq ta2, zero, result_fs_s # FT is zero, result=FS 659 jal renorm_fs_s 660 jal renorm_ft_s 661 b 5f 6622: 663 jal renorm_fs_s 664 subu ta1, ta1, SEXP_BIAS # unbias FT exponent 665 or ta2, ta2, SIMPL_ONE # set implied one bit 666 b 5f 6673: 668 bne ta1, zero, result_ft_s # if FT != 0, result=FT 669 bne ta2, zero, result_ft_s 670 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 671 bne v0, MIPS_FPU_ROUND_RM, 1f # round to -infinity? 672 or t0, t0, ta0 # compute result sign 673 b result_fs_s 6741: 675 and t0, t0, ta0 # compute result sign 676 b result_fs_s 6774: 678 bne ta1, zero, 2f # is FT a denormalized num? 679 beq ta2, zero, result_fs_s # FT is zero, result=FS 680 subu t1, t1, SEXP_BIAS # unbias FS exponent 681 or t2, t2, SIMPL_ONE # set implied one bit 682 jal renorm_ft_s 683 b 5f 6842: 685 subu t1, t1, SEXP_BIAS # unbias FS exponent 686 or t2, t2, SIMPL_ONE # set implied one bit 687 subu ta1, ta1, SEXP_BIAS # unbias FT exponent 688 or ta2, ta2, SIMPL_ONE # set implied one bit 689/* 690 * Perform the addition. 691 */ 6925: 693 move t8, zero # no shifted bits (sticky reg) 694 beq t1, ta1, 4f # no shift needed 695 subu v0, t1, ta1 # v0 = difference of exponents 696 move v1, v0 # v1 = abs(difference) 697 bge v0, zero, 1f 698 negu v1 6991: 700 ble v1, SFRAC_BITS+2, 2f # is difference too great? 701 li t8, STICKYBIT # set the sticky bit 702 bge v0, zero, 1f # check which exp is larger 703 move t1, ta1 # result exp is FTs 704 move t2, zero # FSs fraction shifted is zero 705 b 4f 7061: 707 move ta2, zero # FTs fraction shifted is zero 708 b 4f 7092: 710 li t9, 32 # compute 32 - abs(exp diff) 711 subu t9, t9, v1 712 bgt v0, zero, 3f # if FS > FT, shift FTs frac 713 move t1, ta1 # FT > FS, result exp is FTs 714 sll t8, t2, t9 # save bits shifted out 715 srl t2, t2, v1 # shift FSs fraction 716 b 4f 7173: 718 sll t8, ta2, t9 # save bits shifted out 719 srl ta2, ta2, v1 # shift FTs fraction 7204: 721 bne t0, ta0, 1f # if signs differ, subtract 722 addu t2, t2, ta2 # add fractions 723 b norm_s 7241: 725 blt t2, ta2, 3f # subtract larger from smaller 726 bne t2, ta2, 2f # if same, result=0 727 move t1, zero # result=0 728 move t2, zero 729 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 730 bne v0, MIPS_FPU_ROUND_RM, 1f # round to -infinity? 731 or t0, t0, ta0 # compute result sign 732 b result_fs_s 7331: 734 and t0, t0, ta0 # compute result sign 735 b result_fs_s 7362: 737 sltu t9, zero, t8 # compute t2:zero - ta2:t8 738 subu t8, zero, t8 739 subu t2, t2, ta2 # subtract fractions 740 subu t2, t2, t9 # subtract barrow 741 b norm_s 7423: 743 move t0, ta0 # sign of result = FTs 744 sltu t9, zero, t8 # compute ta2:zero - t2:t8 745 subu t8, zero, t8 746 subu t2, ta2, t2 # subtract fractions 747 subu t2, t2, t9 # subtract barrow 748 b norm_s 749 750/* 751 * Double precision subtract. 752 */ 753sub_d: 754 jal get_ft_fs_d 755 xor ta0, ta0, 1 # negate sign bit 756 b add_sub_d 757/* 758 * Double precision add. 759 */ 760add_d: 761 jal get_ft_fs_d 762add_sub_d: 763 bne t1, DEXP_INF, 1f # is FS an infinity? 764 bne ta1, DEXP_INF, result_fs_d # if FT is not inf, result=FS 765 bne t2, zero, result_fs_d # if FS is NAN, result is FS 766 bne t3, zero, result_fs_d 767 bne ta2, zero, result_ft_d # if FT is NAN, result is FT 768 bne ta3, zero, result_ft_d 769 bne t0, ta0, invalid_d # both infinities same sign? 770 b result_fs_d # result is in FS 7711: 772 beq ta1, DEXP_INF, result_ft_d # if FT is inf, result=FT 773 bne t1, zero, 4f # is FS a denormalized num? 774 bne t2, zero, 1f # is FS zero? 775 beq t3, zero, 3f 7761: 777 bne ta1, zero, 2f # is FT a denormalized num? 778 bne ta2, zero, 1f 779 beq ta3, zero, result_fs_d # FT is zero, result=FS 7801: 781 jal renorm_fs_d 782 jal renorm_ft_d 783 b 5f 7842: 785 jal renorm_fs_d 786 subu ta1, ta1, DEXP_BIAS # unbias FT exponent 787 or ta2, ta2, DIMPL_ONE # set implied one bit 788 b 5f 7893: 790 bne ta1, zero, result_ft_d # if FT != 0, result=FT 791 bne ta2, zero, result_ft_d 792 bne ta3, zero, result_ft_d 793 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 794 bne v0, MIPS_FPU_ROUND_RM, 1f # round to -infinity? 795 or t0, t0, ta0 # compute result sign 796 b result_fs_d 7971: 798 and t0, t0, ta0 # compute result sign 799 b result_fs_d 8004: 801 bne ta1, zero, 2f # is FT a denormalized num? 802 bne ta2, zero, 1f 803 beq ta3, zero, result_fs_d # FT is zero, result=FS 8041: 805 subu t1, t1, DEXP_BIAS # unbias FS exponent 806 or t2, t2, DIMPL_ONE # set implied one bit 807 jal renorm_ft_d 808 b 5f 8092: 810 subu t1, t1, DEXP_BIAS # unbias FS exponent 811 or t2, t2, DIMPL_ONE # set implied one bit 812 subu ta1, ta1, DEXP_BIAS # unbias FT exponent 813 or ta2, ta2, DIMPL_ONE # set implied one bit 814/* 815 * Perform the addition. 816 */ 8175: 818 move t8, zero # no shifted bits (sticky reg) 819 beq t1, ta1, 4f # no shift needed 820 subu v0, t1, ta1 # v0 = difference of exponents 821 move v1, v0 # v1 = abs(difference) 822 bge v0, zero, 1f 823 negu v1 8241: 825 ble v1, DFRAC_BITS+2, 2f # is difference too great? 826 li t8, STICKYBIT # set the sticky bit 827 bge v0, zero, 1f # check which exp is larger 828 move t1, ta1 # result exp is FTs 829 move t2, zero # FSs fraction shifted is zero 830 move t3, zero 831 b 4f 8321: 833 move ta2, zero # FTs fraction shifted is zero 834 move ta3, zero 835 b 4f 8362: 837 li t9, 32 838 bge v0, zero, 3f # if FS > FT, shift FTs frac 839 move t1, ta1 # FT > FS, result exp is FTs 840 blt v1, t9, 1f # shift right by < 32? 841 subu v1, v1, t9 842 subu t9, t9, v1 843 sll t8, t2, t9 # save bits shifted out 844 sltu t9, zero, t3 # dont lose any one bits 845 or t8, t8, t9 # save sticky bit 846 srl t3, t2, v1 # shift FSs fraction 847 move t2, zero 848 b 4f 8491: 850 subu t9, t9, v1 851 sll t8, t3, t9 # save bits shifted out 852 srl t3, t3, v1 # shift FSs fraction 853 sll t9, t2, t9 # save bits shifted out of t2 854 or t3, t3, t9 # and put into t3 855 srl t2, t2, v1 856 b 4f 8573: 858 blt v1, t9, 1f # shift right by < 32? 859 subu v1, v1, t9 860 subu t9, t9, v1 861 sll t8, ta2, t9 # save bits shifted out 862 srl ta3, ta2, v1 # shift FTs fraction 863 move ta2, zero 864 b 4f 8651: 866 subu t9, t9, v1 867 sll t8, ta3, t9 # save bits shifted out 868 srl ta3, ta3, v1 # shift FTs fraction 869 sll t9, ta2, t9 # save bits shifted out of t2 870 or ta3, ta3, t9 # and put into t3 871 srl ta2, ta2, v1 8724: 873 bne t0, ta0, 1f # if signs differ, subtract 874 addu t3, t3, ta3 # add fractions 875 sltu t9, t3, ta3 # compute carry 876 addu t2, t2, ta2 # add fractions 877 addu t2, t2, t9 # add carry 878 b norm_d 8791: 880 blt t2, ta2, 3f # subtract larger from smaller 881 bne t2, ta2, 2f 882 bltu t3, ta3, 3f 883 bne t3, ta3, 2f # if same, result=0 884 move t1, zero # result=0 885 move t2, zero 886 move t3, zero 887 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 888 bne v0, MIPS_FPU_ROUND_RM, 1f # round to -infinity? 889 or t0, t0, ta0 # compute result sign 890 b result_fs_d 8911: 892 and t0, t0, ta0 # compute result sign 893 b result_fs_d 8942: 895 beq t8, zero, 1f # compute t2:t3:zero - ta2:ta3:t8 896 subu t8, zero, t8 897 sltu v0, t3, 1 # compute barrow out 898 subu t3, t3, 1 # subtract barrow 899 subu t2, t2, v0 9001: 901 sltu v0, t3, ta3 902 subu t3, t3, ta3 # subtract fractions 903 subu t2, t2, ta2 # subtract fractions 904 subu t2, t2, v0 # subtract barrow 905 b norm_d 9063: 907 move t0, ta0 # sign of result = FTs 908 beq t8, zero, 1f # compute ta2:ta3:zero - t2:t3:t8 909 subu t8, zero, t8 910 sltu v0, ta3, 1 # compute barrow out 911 subu ta3, ta3, 1 # subtract barrow 912 subu ta2, ta2, v0 9131: 914 sltu v0, ta3, t3 915 subu t3, ta3, t3 # subtract fractions 916 subu t2, ta2, t2 # subtract fractions 917 subu t2, t2, v0 # subtract barrow 918 b norm_d 919 920/* 921 * Single precision multiply. 922 */ 923mul_s: 924 jal get_ft_fs_s 925 xor t0, t0, ta0 # compute sign of result 926 move ta0, t0 927 bne t1, SEXP_INF, 2f # is FS an infinity? 928 bne t2, zero, result_fs_s # if FS is a NAN, result=FS 929 bne ta1, SEXP_INF, 1f # FS is inf, is FT an infinity? 930 bne ta2, zero, result_ft_s # if FT is a NAN, result=FT 931 b result_fs_s # result is infinity 9321: 933 bne ta1, zero, result_fs_s # inf * zero? if no, result=FS 934 bne ta2, zero, result_fs_s 935 b invalid_s # infinity * zero is invalid 9362: 937 bne ta1, SEXP_INF, 1f # FS != inf, is FT an infinity? 938 bne t1, zero, result_ft_s # zero * inf? if no, result=FT 939 bne t2, zero, result_ft_s 940 bne ta2, zero, result_ft_s # if FT is a NAN, result=FT 941 b invalid_s # zero * infinity is invalid 9421: 943 bne t1, zero, 1f # is FS zero? 944 beq t2, zero, result_fs_s # result is zero 945 jal renorm_fs_s 946 b 2f 9471: 948 subu t1, t1, SEXP_BIAS # unbias FS exponent 949 or t2, t2, SIMPL_ONE # set implied one bit 9502: 951 bne ta1, zero, 1f # is FT zero? 952 beq ta2, zero, result_ft_s # result is zero 953 jal renorm_ft_s 954 b 2f 9551: 956 subu ta1, ta1, SEXP_BIAS # unbias FT exponent 957 or ta2, ta2, SIMPL_ONE # set implied one bit 9582: 959 addu t1, t1, ta1 # compute result exponent 960 addu t1, t1, 9 # account for binary point 961 multu t2, ta2 # multiply fractions 962 mflo t8 963 mfhi t2 964 b norm_s 965 966/* 967 * Double precision multiply. 968 */ 969mul_d: 970 jal get_ft_fs_d 971 xor t0, t0, ta0 # compute sign of result 972 move ta0, t0 973 bne t1, DEXP_INF, 2f # is FS an infinity? 974 bne t2, zero, result_fs_d # if FS is a NAN, result=FS 975 bne t3, zero, result_fs_d 976 bne ta1, DEXP_INF, 1f # FS is inf, is FT an infinity? 977 bne ta2, zero, result_ft_d # if FT is a NAN, result=FT 978 bne ta3, zero, result_ft_d 979 b result_fs_d # result is infinity 9801: 981 bne ta1, zero, result_fs_d # inf * zero? if no, result=FS 982 bne ta2, zero, result_fs_d 983 bne ta3, zero, result_fs_d 984 b invalid_d # infinity * zero is invalid 9852: 986 bne ta1, DEXP_INF, 1f # FS != inf, is FT an infinity? 987 bne t1, zero, result_ft_d # zero * inf? if no, result=FT 988 bne t2, zero, result_ft_d # if FS is a NAN, result=FS 989 bne t3, zero, result_ft_d 990 bne ta2, zero, result_ft_d # if FT is a NAN, result=FT 991 bne ta3, zero, result_ft_d 992 b invalid_d # zero * infinity is invalid 9931: 994 bne t1, zero, 2f # is FS zero? 995 bne t2, zero, 1f 996 beq t3, zero, result_fs_d # result is zero 9971: 998 jal renorm_fs_d 999 b 3f 10002: 1001 subu t1, t1, DEXP_BIAS # unbias FS exponent 1002 or t2, t2, DIMPL_ONE # set implied one bit 10033: 1004 bne ta1, zero, 2f # is FT zero? 1005 bne ta2, zero, 1f 1006 beq ta3, zero, result_ft_d # result is zero 10071: 1008 jal renorm_ft_d 1009 b 3f 10102: 1011 subu ta1, ta1, DEXP_BIAS # unbias FT exponent 1012 or ta2, ta2, DIMPL_ONE # set implied one bit 10133: 1014 addu t1, t1, ta1 # compute result exponent 1015 addu t1, t1, 12 # ??? 1016 multu t3, ta3 # multiply fractions (low * low) 1017 move ta0, t2 # free up t2,t3 for result 1018 move ta1, t3 1019 mflo a3 # save low order bits 1020 mfhi t8 1021 not v0, t8 1022 multu ta0, ta3 # multiply FS(high) * FT(low) 1023 mflo v1 1024 mfhi t3 # init low result 1025 sltu v0, v0, v1 # compute carry 1026 addu t8, v1 1027 multu ta1, ta2 # multiply FS(low) * FT(high) 1028 addu t3, t3, v0 # add carry 1029 not v0, t8 1030 mflo v1 1031 mfhi t2 1032 sltu v0, v0, v1 1033 addu t8, v1 1034 multu ta0, ta2 # multiply FS(high) * FT(high) 1035 addu t3, v0 1036 not v1, t3 1037 sltu v1, v1, t2 1038 addu t3, t2 1039 not v0, t3 1040 mfhi t2 1041 addu t2, v1 1042 mflo v1 1043 sltu v0, v0, v1 1044 addu t2, v0 1045 addu t3, v1 1046 sltu a3, zero, a3 # reduce t8,a3 to just t8 1047 or t8, a3 1048 b norm_d 1049 1050/* 1051 * Single precision divide. 1052 */ 1053div_s: 1054 jal get_ft_fs_s 1055 xor t0, t0, ta0 # compute sign of result 1056 move ta0, t0 1057 bne t1, SEXP_INF, 1f # is FS an infinity? 1058 bne t2, zero, result_fs_s # if FS is NAN, result is FS 1059 bne ta1, SEXP_INF, result_fs_s # is FT an infinity? 1060 bne ta2, zero, result_ft_s # if FT is NAN, result is FT 1061 b invalid_s # infinity/infinity is invalid 10621: 1063 bne ta1, SEXP_INF, 1f # is FT an infinity? 1064 bne ta2, zero, result_ft_s # if FT is NAN, result is FT 1065 move t1, zero # x / infinity is zero 1066 move t2, zero 1067 b result_fs_s 10681: 1069 bne t1, zero, 2f # is FS zero? 1070 bne t2, zero, 1f 1071 bne ta1, zero, result_fs_s # FS=zero, is FT zero? 1072 beq ta2, zero, invalid_s # 0 / 0 1073 b result_fs_s # result = zero 10741: 1075 jal renorm_fs_s 1076 b 3f 10772: 1078 subu t1, t1, SEXP_BIAS # unbias FS exponent 1079 or t2, t2, SIMPL_ONE # set implied one bit 10803: 1081 bne ta1, zero, 2f # is FT zero? 1082 bne ta2, zero, 1f 1083 or a1, a1, MIPS_FPU_EXCEPTION_DIV0 | MIPS_FPU_STICKY_DIV0 1084 and v0, a1, MIPS_FPU_ENABLE_DIV0 # trap enabled? 1085 bne v0, zero, fpe_trap 1086 ctc1 a1, MIPS_FPU_CSR # save exceptions 1087 li t1, SEXP_INF # result is infinity 1088 move t2, zero 1089 b result_fs_s 10901: 1091 jal renorm_ft_s 1092 b 3f 10932: 1094 subu ta1, ta1, SEXP_BIAS # unbias FT exponent 1095 or ta2, ta2, SIMPL_ONE # set implied one bit 10963: 1097 subu t1, t1, ta1 # compute exponent 1098 subu t1, t1, 3 # compensate for result position 1099 li v0, SFRAC_BITS+3 # number of bits to divide 1100 move t8, t2 # init dividend 1101 move t2, zero # init result 11021: 1103 bltu t8, ta2, 3f # is dividend >= divisor? 11042: 1105 subu t8, t8, ta2 # subtract divisor from dividend 1106 or t2, t2, 1 # remember that we did 1107 bne t8, zero, 3f # if not done, continue 1108 sll t2, t2, v0 # shift result to final position 1109 b norm_s 11103: 1111 sll t8, t8, 1 # shift dividend 1112 sll t2, t2, 1 # shift result 1113 subu v0, v0, 1 # are we done? 1114 bne v0, zero, 1b # no, continue 1115 b norm_s 1116 1117/* 1118 * Double precision divide. 1119 */ 1120div_d: 1121 jal get_ft_fs_d 1122 xor t0, t0, ta0 # compute sign of result 1123 move ta0, t0 1124 bne t1, DEXP_INF, 1f # is FS an infinity? 1125 bne t2, zero, result_fs_d # if FS is NAN, result is FS 1126 bne t3, zero, result_fs_d 1127 bne ta1, DEXP_INF, result_fs_d # is FT an infinity? 1128 bne ta2, zero, result_ft_d # if FT is NAN, result is FT 1129 bne ta3, zero, result_ft_d 1130 b invalid_d # infinity/infinity is invalid 11311: 1132 bne ta1, DEXP_INF, 1f # is FT an infinity? 1133 bne ta2, zero, result_ft_d # if FT is NAN, result is FT 1134 bne ta3, zero, result_ft_d 1135 move t1, zero # x / infinity is zero 1136 move t2, zero 1137 move t3, zero 1138 b result_fs_d 11391: 1140 bne t1, zero, 2f # is FS zero? 1141 bne t2, zero, 1f 1142 bne t3, zero, 1f 1143 bne ta1, zero, result_fs_d # FS=zero, is FT zero? 1144 bne ta2, zero, result_fs_d 1145 beq ta3, zero, invalid_d # 0 / 0 1146 b result_fs_d # result = zero 11471: 1148 jal renorm_fs_d 1149 b 3f 11502: 1151 subu t1, t1, DEXP_BIAS # unbias FS exponent 1152 or t2, t2, DIMPL_ONE # set implied one bit 11533: 1154 bne ta1, zero, 2f # is FT zero? 1155 bne ta2, zero, 1f 1156 bne ta3, zero, 1f 1157 or a1, a1, MIPS_FPU_EXCEPTION_DIV0 | MIPS_FPU_STICKY_DIV0 1158 and v0, a1, MIPS_FPU_ENABLE_DIV0 # trap enabled? 1159 bne v0, zero, fpe_trap 1160 ctc1 a1, MIPS_FPU_CSR # Save exceptions 1161 li t1, DEXP_INF # result is infinity 1162 move t2, zero 1163 move t3, zero 1164 b result_fs_d 11651: 1166 jal renorm_ft_d 1167 b 3f 11682: 1169 subu ta1, ta1, DEXP_BIAS # unbias FT exponent 1170 or ta2, ta2, DIMPL_ONE # set implied one bit 11713: 1172 subu t1, t1, ta1 # compute exponent 1173 subu t1, t1, 3 # compensate for result position 1174 li v0, DFRAC_BITS+3 # number of bits to divide 1175 move t8, t2 # init dividend 1176 move t9, t3 1177 move t2, zero # init result 1178 move t3, zero 11791: 1180 bltu t8, ta2, 3f # is dividend >= divisor? 1181 bne t8, ta2, 2f 1182 bltu t9, ta3, 3f 11832: 1184 sltu v1, t9, ta3 # subtract divisor from dividend 1185 subu t9, t9, ta3 1186 subu t8, t8, ta2 1187 subu t8, t8, v1 1188 or t3, t3, 1 # remember that we did 1189 bne t8, zero, 3f # if not done, continue 1190 bne t9, zero, 3f 1191 li v1, 32 # shift result to final position 1192 blt v0, v1, 2f # shift < 32 bits? 1193 subu v0, v0, v1 # shift by > 32 bits 1194 sll t2, t3, v0 # shift upper part 1195 move t3, zero 1196 b norm_d 11972: 1198 subu v1, v1, v0 # shift by < 32 bits 1199 sll t2, t2, v0 # shift upper part 1200 srl t9, t3, v1 # save bits shifted out 1201 or t2, t2, t9 # and put into upper part 1202 sll t3, t3, v0 1203 b norm_d 12043: 1205 sll t8, t8, 1 # shift dividend 1206 srl v1, t9, 31 # save bit shifted out 1207 or t8, t8, v1 # and put into upper part 1208 sll t9, t9, 1 1209 sll t2, t2, 1 # shift result 1210 srl v1, t3, 31 # save bit shifted out 1211 or t2, t2, v1 # and put into upper part 1212 sll t3, t3, 1 1213 subu v0, v0, 1 # are we done? 1214 bne v0, zero, 1b # no, continue 1215 sltu v0, zero, t9 # be sure to save any one bits 1216 or t8, t8, v0 # from the lower remainder 1217 b norm_d 1218 1219/* 1220 * Single precision absolute value. 1221 */ 1222abs_s: 1223 jal get_fs_s 1224 move t0, zero # set sign positive 1225 b result_fs_s 1226 1227/* 1228 * Double precision absolute value. 1229 */ 1230abs_d: 1231 jal get_fs_d 1232 move t0, zero # set sign positive 1233 b result_fs_d 1234 1235/* 1236 * Single precision move. 1237 */ 1238mov_s: 1239 jal get_fs_s 1240 b result_fs_s 1241 1242/* 1243 * Double precision move. 1244 */ 1245mov_d: 1246 jal get_fs_d 1247 b result_fs_d 1248 1249/* 1250 * Single precision negate. 1251 */ 1252neg_s: 1253 jal get_fs_s 1254 xor t0, t0, 1 # reverse sign 1255 b result_fs_s 1256 1257/* 1258 * Double precision negate. 1259 */ 1260neg_d: 1261 jal get_fs_d 1262 xor t0, t0, 1 # reverse sign 1263 b result_fs_d 1264 1265/* 1266 * Convert double to single. 1267 */ 1268cvt_s_d: 1269 jal get_fs_d 1270 bne t1, DEXP_INF, 1f # is FS an infinity? 1271 li t1, SEXP_INF # convert to single 1272 sll t2, t2, 3 # convert D fraction to S 1273 srl t8, t3, 32 - 3 1274 or t2, t2, t8 1275 b result_fs_s 12761: 1277 bne t1, zero, 2f # is FS zero? 1278 bne t2, zero, 1f 1279 beq t3, zero, result_fs_s # result=0 12801: 1281 jal renorm_fs_d 1282 subu t1, t1, 3 # correct exp for shift below 1283 b 3f 12842: 1285 subu t1, t1, DEXP_BIAS # unbias exponent 1286 or t2, t2, DIMPL_ONE # add implied one bit 12873: 1288 sll t2, t2, 3 # convert D fraction to S 1289 srl t8, t3, 32 - 3 1290 or t2, t2, t8 1291 sll t8, t3, 3 1292 b norm_noshift_s 1293 1294/* 1295 * Convert integer to single. 1296 */ 1297cvt_s_w: 1298 jal get_fs_int 1299 bne t2, zero, 1f # check for zero 1300 move t1, zero 1301 b result_fs_s 1302/* 1303 * Find out how many leading zero bits are in t2 and put in t9. 1304 */ 13051: 1306 move v0, t2 1307 move t9, zero 1308 srl v1, v0, 16 1309 bne v1, zero, 1f 1310 addu t9, 16 1311 sll v0, 16 13121: 1313 srl v1, v0, 24 1314 bne v1, zero, 1f 1315 addu t9, 8 1316 sll v0, 8 13171: 1318 srl v1, v0, 28 1319 bne v1, zero, 1f 1320 addu t9, 4 1321 sll v0, 4 13221: 1323 srl v1, v0, 30 1324 bne v1, zero, 1f 1325 addu t9, 2 1326 sll v0, 2 13271: 1328 srl v1, v0, 31 1329 bne v1, zero, 1f 1330 addu t9, 1 1331/* 1332 * Now shift t2 the correct number of bits. 1333 */ 13341: 1335 subu t9, t9, SLEAD_ZEROS # dont count leading zeros 1336 li t1, 23 # init exponent 1337 subu t1, t1, t9 # compute exponent 1338 beq t9, zero, 1f 1339 li v0, 32 1340 blt t9, zero, 2f # if shift < 0, shift right 1341 subu v0, v0, t9 1342 sll t2, t2, t9 # shift left 13431: 1344 add t1, t1, SEXP_BIAS # bias exponent 1345 and t2, t2, ~SIMPL_ONE # clear implied one bit 1346 b result_fs_s 13472: 1348 negu t9 # shift right by t9 1349 subu v0, v0, t9 1350 sll t8, t2, v0 # save bits shifted out 1351 srl t2, t2, t9 1352 b norm_noshift_s 1353 1354/* 1355 * Convert single to double. 1356 */ 1357cvt_d_s: 1358 jal get_fs_s 1359 move t3, zero 1360 bne t1, SEXP_INF, 1f # is FS an infinity? 1361 li t1, DEXP_INF # convert to double 1362 b result_fs_d 13631: 1364 bne t1, zero, 2f # is FS denormalized or zero? 1365 beq t2, zero, result_fs_d # is FS zero? 1366 jal renorm_fs_s 1367 move t8, zero 1368 b norm_d 13692: 1370 addu t1, t1, DEXP_BIAS - SEXP_BIAS # bias exponent correctly 1371 sll t3, t2, 32 - 3 # convert S fraction to D 1372 srl t2, t2, 3 1373 b result_fs_d 1374 1375/* 1376 * Convert integer to double. 1377 */ 1378cvt_d_w: 1379 jal get_fs_int 1380 bne t2, zero, 1f # check for zero 1381 move t1, zero # result=0 1382 move t3, zero 1383 b result_fs_d 1384/* 1385 * Find out how many leading zero bits are in t2 and put in t9. 1386 */ 13871: 1388 move v0, t2 1389 move t9, zero 1390 srl v1, v0, 16 1391 bne v1, zero, 1f 1392 addu t9, 16 1393 sll v0, 16 13941: 1395 srl v1, v0, 24 1396 bne v1, zero, 1f 1397 addu t9, 8 1398 sll v0, 8 13991: 1400 srl v1, v0, 28 1401 bne v1, zero, 1f 1402 addu t9, 4 1403 sll v0, 4 14041: 1405 srl v1, v0, 30 1406 bne v1, zero, 1f 1407 addu t9, 2 1408 sll v0, 2 14091: 1410 srl v1, v0, 31 1411 bne v1, zero, 1f 1412 addu t9, 1 1413/* 1414 * Now shift t2 the correct number of bits. 1415 */ 14161: 1417 subu t9, t9, DLEAD_ZEROS # dont count leading zeros 1418 li t1, DEXP_BIAS + 20 # init exponent 1419 subu t1, t1, t9 # compute exponent 1420 beq t9, zero, 1f 1421 li v0, 32 1422 blt t9, zero, 2f # if shift < 0, shift right 1423 subu v0, v0, t9 1424 sll t2, t2, t9 # shift left 14251: 1426 and t2, t2, ~DIMPL_ONE # clear implied one bit 1427 move t3, zero 1428 b result_fs_d 14292: 1430 negu t9 # shift right by t9 1431 subu v0, v0, t9 1432 sll t3, t2, v0 1433 srl t2, t2, t9 1434 and t2, t2, ~DIMPL_ONE # clear implied one bit 1435 b result_fs_d 1436 1437/* 1438 * Convert single to integer. 1439 */ 1440cvt_w_s: 1441 jal get_fs_s 1442 bne t1, SEXP_INF, 1f # is FS an infinity? 1443 bne t2, zero, invalid_w # invalid conversion 14441: 1445 bne t1, zero, 1f # is FS zero? 1446 beq t2, zero, result_fs_w # result is zero 1447 move t2, zero # result is an inexact zero 1448 b inexact_w 14491: 1450 subu t1, t1, SEXP_BIAS # unbias exponent 1451 or t2, t2, SIMPL_ONE # add implied one bit 1452 sll t3, t2, 32 - 3 # convert S fraction to D 1453 srl t2, t2, 3 1454 b cvt_w 1455 1456/* 1457 * Convert double to integer. 1458 */ 1459cvt_w_d: 1460 jal get_fs_d 1461 bne t1, DEXP_INF, 1f # is FS an infinity? 1462 bne t2, zero, invalid_w # invalid conversion 1463 bne t3, zero, invalid_w # invalid conversion 14641: 1465 bne t1, zero, 2f # is FS zero? 1466 bne t2, zero, 1f 1467 beq t3, zero, result_fs_w # result is zero 14681: 1469 move t2, zero # result is an inexact zero 1470 b inexact_w 14712: 1472 subu t1, t1, DEXP_BIAS # unbias exponent 1473 or t2, t2, DIMPL_ONE # add implied one bit 1474cvt_w: 1475 blt t1, WEXP_MIN, underflow_w # is exponent too small? 1476 li v0, WEXP_MAX+1 1477 bgt t1, v0, overflow_w # is exponent too large? 1478 bne t1, v0, 1f # special check for INT_MIN 1479 beq t0, zero, overflow_w # if positive, overflow 1480 bne t2, DIMPL_ONE, overflow_w 1481 bne t3, zero, overflow_w 1482 li t2, INT_MIN # result is INT_MIN 1483 b result_fs_w 14841: 1485 subu v0, t1, 20 # compute amount to shift 1486 beq v0, zero, 2f # is shift needed? 1487 li v1, 32 1488 blt v0, zero, 1f # if shift < 0, shift right 1489 subu v1, v1, v0 # shift left 1490 sll t2, t2, v0 1491 srl t9, t3, v1 # save bits shifted out of t3 1492 or t2, t2, t9 # and put into t2 1493 sll t3, t3, v0 # shift FSs fraction 1494 b 2f 14951: 1496 negu v0 # shift right by v0 1497 subu v1, v1, v0 1498 sll t8, t3, v1 # save bits shifted out 1499 sltu t8, zero, t8 # dont lose any ones 1500 srl t3, t3, v0 # shift FSs fraction 1501 or t3, t3, t8 1502 sll t9, t2, v1 # save bits shifted out of t2 1503 or t3, t3, t9 # and put into t3 1504 srl t2, t2, v0 1505/* 1506 * round result (t0 is sign, t2 is integer part, t3 is fractional part). 1507 */ 15082: 1509 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1510 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 1511 beq v0, MIPS_FPU_ROUND_RZ, 5f # round to zero (truncate) 1512 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 1513 beq t0, zero, 5f # if sign is positive, truncate 1514 b 2f 15151: 1516 bne t0, zero, 5f # if sign is negative, truncate 15172: 1518 beq t3, zero, 5f # if no fraction bits, continue 1519 addu t2, t2, 1 # add rounding bit 1520 blt t2, zero, overflow_w # overflow? 1521 b 5f 15223: 1523 li v0, GUARDBIT # load guard bit for rounding 1524 addu v0, v0, t3 # add remainder 1525 sltu v1, v0, t3 # compute carry out 1526 beq v1, zero, 4f # if no carry, continue 1527 addu t2, t2, 1 # add carry to result 1528 blt t2, zero, overflow_w # overflow? 15294: 1530 bne v0, zero, 5f # if rounded remainder is zero 1531 and t2, t2, ~1 # clear LSB (round to nearest) 15325: 1533 beq t0, zero, 1f # result positive? 1534 negu t2 # convert to negative integer 15351: 1536 beq t3, zero, result_fs_w # is result exact? 1537/* 1538 * Handle inexact exception. 1539 */ 1540inexact_w: 1541 or a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT 1542 and v0, a1, MIPS_FPU_ENABLE_INEXACT 1543 bne v0, zero, fpe_trap 1544 ctc1 a1, MIPS_FPU_CSR # save exceptions 1545 b result_fs_w 1546 1547/* 1548 * Conversions to integer which overflow will trap (if enabled), 1549 * or generate an inexact trap (if enabled), 1550 * or generate an invalid exception. 1551 */ 1552overflow_w: 1553 or a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW 1554 and v0, a1, MIPS_FPU_ENABLE_OVERFLOW 1555 bne v0, zero, fpe_trap 1556 and v0, a1, MIPS_FPU_ENABLE_INEXACT 1557 bne v0, zero, inexact_w # inexact traps enabled? 1558 b invalid_w 1559 1560/* 1561 * Conversions to integer which underflow will trap (if enabled), 1562 * or generate an inexact trap (if enabled), 1563 * or generate an invalid exception. 1564 */ 1565underflow_w: 1566 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 1567 and v0, a1, MIPS_FPU_ENABLE_UNDERFLOW 1568 bne v0, zero, fpe_trap 1569 and v0, a1, MIPS_FPU_ENABLE_INEXACT 1570 bne v0, zero, inexact_w # inexact traps enabled? 1571 b invalid_w 1572 1573/* 1574 * Compare single. 1575 */ 1576cmp_s: 1577 jal get_cmp_s 1578 bne t1, SEXP_INF, 1f # is FS an infinity? 1579 bne t2, zero, unordered # FS is a NAN 15801: 1581 bne ta1, SEXP_INF, 2f # is FT an infinity? 1582 bne ta2, zero, unordered # FT is a NAN 15832: 1584 sll t1, t1, 23 # reassemble exp & frac 1585 or t1, t1, t2 1586 sll ta1, ta1, 23 # reassemble exp & frac 1587 or ta1, ta1, ta2 1588 beq t0, zero, 1f # is FS positive? 1589 negu t1 15901: 1591 beq ta0, zero, 1f # is FT positive? 1592 negu ta1 15931: 1594 li v0, COND_LESS 1595 blt t1, ta1, test_cond # is FS < FT? 1596 li v0, COND_EQUAL 1597 beq t1, ta1, test_cond # is FS == FT? 1598 move v0, zero # FS > FT 1599 b test_cond 1600 1601/* 1602 * Compare double. 1603 */ 1604cmp_d: 1605 jal get_cmp_d 1606 bne t1, DEXP_INF, 1f # is FS an infinity? 1607 bne t2, zero, unordered 1608 bne t3, zero, unordered # FS is a NAN 16091: 1610 bne ta1, DEXP_INF, 2f # is FT an infinity? 1611 bne ta2, zero, unordered 1612 bne ta3, zero, unordered # FT is a NAN 16132: 1614 sll t1, t1, 20 # reassemble exp & frac 1615 or t1, t1, t2 1616 sll ta1, ta1, 20 # reassemble exp & frac 1617 or ta1, ta1, ta2 1618 beq t0, zero, 1f # is FS positive? 1619 not t3 # negate t1,t3 1620 not t1 1621 addu t3, t3, 1 1622 seq v0, t3, zero # compute carry 1623 addu t1, t1, v0 16241: 1625 beq ta0, zero, 1f # is FT positive? 1626 not ta3 # negate ta1,ta3 1627 not ta1 1628 addu ta3, ta3, 1 1629 seq v0, ta3, zero # compute carry 1630 addu ta1, ta1, v0 16311: 1632 li v0, COND_LESS 1633 blt t1, ta1, test_cond # is FS(MSW) < FT(MSW)? 1634 move v0, zero 1635 bne t1, ta1, test_cond # is FS(MSW) > FT(MSW)? 1636 li v0, COND_LESS 1637 bltu t3, ta3, test_cond # is FS(LSW) < FT(LSW)? 1638 li v0, COND_EQUAL 1639 beq t3, ta3, test_cond # is FS(LSW) == FT(LSW)? 1640 move v0, zero # FS > FT 1641test_cond: 1642 and v0, v0, a0 # condition match instruction? 1643set_cond: 1644 bne v0, zero, 1f 1645 and a1, a1, ~MIPS_FPU_COND_BIT # clear condition bit 1646 b 2f 16471: 1648 or a1, a1, MIPS_FPU_COND_BIT # set condition bit 16492: 1650 ctc1 a1, MIPS_FPU_CSR # save condition bit 1651 b done 1652 1653unordered: 1654 and v0, a0, COND_UNORDERED # this cmp match unordered? 1655 bne v0, zero, 1f 1656 and a1, a1, ~MIPS_FPU_COND_BIT # clear condition bit 1657 b 2f 16581: 1659 or a1, a1, MIPS_FPU_COND_BIT # set condition bit 16602: 1661 and v0, a0, COND_SIGNAL 1662 beq v0, zero, 1f # is this a signaling cmp? 1663 or a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID 1664 and v0, a1, MIPS_FPU_ENABLE_INVALID 1665 bne v0, zero, fpe_trap 16661: 1667 ctc1 a1, MIPS_FPU_CSR # save condition bit 1668 b done 1669 1670/* 1671 * Determine the amount to shift the fraction in order to restore the 1672 * normalized position. After that, round and handle exceptions. 1673 */ 1674norm_s: 1675 move v0, t2 1676 move t9, zero # t9 = num of leading zeros 1677 bne t2, zero, 1f 1678 move v0, t8 1679 addu t9, 32 16801: 1681 srl v1, v0, 16 1682 bne v1, zero, 1f 1683 addu t9, 16 1684 sll v0, 16 16851: 1686 srl v1, v0, 24 1687 bne v1, zero, 1f 1688 addu t9, 8 1689 sll v0, 8 16901: 1691 srl v1, v0, 28 1692 bne v1, zero, 1f 1693 addu t9, 4 1694 sll v0, 4 16951: 1696 srl v1, v0, 30 1697 bne v1, zero, 1f 1698 addu t9, 2 1699 sll v0, 2 17001: 1701 srl v1, v0, 31 1702 bne v1, zero, 1f 1703 addu t9, 1 1704/* 1705 * Now shift t2,t8 the correct number of bits. 1706 */ 17071: 1708 subu t9, t9, SLEAD_ZEROS # dont count leading zeros 1709 subu t1, t1, t9 # adjust the exponent 1710 beq t9, zero, norm_noshift_s 1711 li v1, 32 1712 blt t9, zero, 1f # if shift < 0, shift right 1713 subu v1, v1, t9 1714 sll t2, t2, t9 # shift t2,t8 left 1715 srl v0, t8, v1 # save bits shifted out 1716 or t2, t2, v0 1717 sll t8, t8, t9 1718 b norm_noshift_s 17191: 1720 negu t9 # shift t2,t8 right by t9 1721 subu v1, v1, t9 1722 sll v0, t8, v1 # save bits shifted out 1723 sltu v0, zero, v0 # be sure to save any one bits 1724 srl t8, t8, t9 1725 or t8, t8, v0 1726 sll v0, t2, v1 # save bits shifted out 1727 or t8, t8, v0 1728 srl t2, t2, t9 1729norm_noshift_s: 1730 move ta1, t1 # save unrounded exponent 1731 move ta2, t2 # save unrounded fraction 1732 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1733 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 1734 beq v0, MIPS_FPU_ROUND_RZ, 5f # round to zero (truncate) 1735 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 1736 beq t0, zero, 5f # if sign is positive, truncate 1737 b 2f 17381: 1739 bne t0, zero, 5f # if sign is negative, truncate 17402: 1741 beq t8, zero, 5f # if exact, continue 1742 addu t2, t2, 1 # add rounding bit 1743 bne t2, SIMPL_ONE<<1, 5f # need to adjust exponent? 1744 addu t1, t1, 1 # adjust exponent 1745 srl t2, t2, 1 # renormalize fraction 1746 b 5f 17473: 1748 li v0, GUARDBIT # load guard bit for rounding 1749 addu v0, v0, t8 # add remainder 1750 sltu v1, v0, t8 # compute carry out 1751 beq v1, zero, 4f # if no carry, continue 1752 addu t2, t2, 1 # add carry to result 1753 bne t2, SIMPL_ONE<<1, 4f # need to adjust exponent? 1754 addu t1, t1, 1 # adjust exponent 1755 srl t2, t2, 1 # renormalize fraction 17564: 1757 bne v0, zero, 5f # if rounded remainder is zero 1758 and t2, t2, ~1 # clear LSB (round to nearest) 17595: 1760 bgt t1, SEXP_MAX, overflow_s # overflow? 1761 blt t1, SEXP_MIN, underflow_s # underflow? 1762 bne t8, zero, inexact_s # is result inexact? 1763 addu t1, t1, SEXP_BIAS # bias exponent 1764 and t2, t2, ~SIMPL_ONE # clear implied one bit 1765 b result_fs_s 1766 1767/* 1768 * Handle inexact exception. 1769 */ 1770inexact_s: 1771 addu t1, t1, SEXP_BIAS # bias exponent 1772 and t2, t2, ~SIMPL_ONE # clear implied one bit 1773inexact_nobias_s: 1774 jal set_fd_s # save result 1775 or a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT 1776 and v0, a1, MIPS_FPU_ENABLE_INEXACT 1777 bne v0, zero, fpe_trap 1778 ctc1 a1, MIPS_FPU_CSR # save exceptions 1779 b done 1780 1781/* 1782 * Overflow will trap (if enabled), 1783 * or generate an inexact trap (if enabled), 1784 * or generate an infinity. 1785 */ 1786overflow_s: 1787 or a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW 1788 and v0, a1, MIPS_FPU_ENABLE_OVERFLOW 1789 beq v0, zero, 1f 1790 subu t1, t1, 192 # bias exponent 1791 and t2, t2, ~SIMPL_ONE # clear implied one bit 1792 jal set_fd_s # save result 1793 b fpe_trap 17941: 1795 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1796 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 1797 beq v0, MIPS_FPU_ROUND_RZ, 1f # round to zero (truncate) 1798 beq v0, MIPS_FPU_ROUND_RP, 2f # round to +infinity 1799 bne t0, zero, 3f 18001: 1801 li t1, SEXP_MAX # result is max finite 1802 li t2, 0x007fffff 1803 b inexact_s 18042: 1805 bne t0, zero, 1b 18063: 1807 li t1, SEXP_MAX + 1 # result is infinity 1808 move t2, zero 1809 b inexact_s 1810 1811/* 1812 * In this implementation, "tininess" is detected "after rounding" and 1813 * "loss of accuracy" is detected as "an inexact result". 1814 */ 1815underflow_s: 1816 and v0, a1, MIPS_FPU_ENABLE_UNDERFLOW 1817 beq v0, zero, 1f 1818/* 1819 * Underflow is enabled so compute the result and trap. 1820 */ 1821 addu t1, t1, 192 # bias exponent 1822 and t2, t2, ~SIMPL_ONE # clear implied one bit 1823 jal set_fd_s # save result 1824 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 1825 b fpe_trap 1826/* 1827 * Underflow is not enabled so compute the result, 1828 * signal inexact result (if it is) and trap (if enabled). 1829 */ 18301: 1831 move t1, ta1 # get unrounded exponent 1832 move t2, ta2 # get unrounded fraction 1833 li t9, SEXP_MIN # compute shift amount 1834 subu t9, t9, t1 # shift t2,t8 right by t9 1835 blt t9, SFRAC_BITS+2, 3f # shift all the bits out? 1836 move t1, zero # result is inexact zero 1837 move t2, zero 1838 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 1839/* 1840 * Now round the zero result. 1841 * Only need to worry about rounding to +- infinity when the sign matches. 1842 */ 1843 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1844 beq v0, MIPS_FPU_ROUND_RN, inexact_nobias_s # round to nearest 1845 beq v0, MIPS_FPU_ROUND_RZ, inexact_nobias_s # round to zero 1846 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 1847 beq t0, zero, inexact_nobias_s # if sign is positive, truncate 1848 b 2f 18491: 1850 bne t0, zero, inexact_nobias_s # if sign is negative, truncate 18512: 1852 addu t2, t2, 1 # add rounding bit 1853 b inexact_nobias_s 18543: 1855 li v1, 32 1856 subu v1, v1, t9 1857 sltu v0, zero, t8 # be sure to save any one bits 1858 sll t8, t2, v1 # save bits shifted out 1859 or t8, t8, v0 # include sticky bits 1860 srl t2, t2, t9 1861/* 1862 * Now round the denormalized result. 1863 */ 1864 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1865 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 1866 beq v0, MIPS_FPU_ROUND_RZ, 5f # round to zero (truncate) 1867 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 1868 beq t0, zero, 5f # if sign is positive, truncate 1869 b 2f 18701: 1871 bne t0, zero, 5f # if sign is negative, truncate 18722: 1873 beq t8, zero, 5f # if exact, continue 1874 addu t2, t2, 1 # add rounding bit 1875 b 5f 18763: 1877 li v0, GUARDBIT # load guard bit for rounding 1878 addu v0, v0, t8 # add remainder 1879 sltu v1, v0, t8 # compute carry out 1880 beq v1, zero, 4f # if no carry, continue 1881 addu t2, t2, 1 # add carry to result 18824: 1883 bne v0, zero, 5f # if rounded remainder is zero 1884 and t2, t2, ~1 # clear LSB (round to nearest) 18855: 1886 move t1, zero # denorm or zero exponent 1887 jal set_fd_s # save result 1888 beq t8, zero, done # check for exact result 1889 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 1890 or a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT 1891 and v0, a1, MIPS_FPU_ENABLE_INEXACT 1892 bne v0, zero, fpe_trap 1893 ctc1 a1, MIPS_FPU_CSR # save exceptions 1894 b done 1895 1896/* 1897 * Determine the amount to shift the fraction in order to restore the 1898 * normalized position. After that, round and handle exceptions. 1899 */ 1900norm_d: 1901 move v0, t2 1902 move t9, zero # t9 = num of leading zeros 1903 bne t2, zero, 1f 1904 move v0, t3 1905 addu t9, 32 1906 bne t3, zero, 1f 1907 move v0, t8 1908 addu t9, 32 19091: 1910 srl v1, v0, 16 1911 bne v1, zero, 1f 1912 addu t9, 16 1913 sll v0, 16 19141: 1915 srl v1, v0, 24 1916 bne v1, zero, 1f 1917 addu t9, 8 1918 sll v0, 8 19191: 1920 srl v1, v0, 28 1921 bne v1, zero, 1f 1922 addu t9, 4 1923 sll v0, 4 19241: 1925 srl v1, v0, 30 1926 bne v1, zero, 1f 1927 addu t9, 2 1928 sll v0, 2 19291: 1930 srl v1, v0, 31 1931 bne v1, zero, 1f 1932 addu t9, 1 1933/* 1934 * Now shift t2,t3,t8 the correct number of bits. 1935 */ 19361: 1937 subu t9, t9, DLEAD_ZEROS # dont count leading zeros 1938 subu t1, t1, t9 # adjust the exponent 1939 beq t9, zero, norm_noshift_d 1940 li v1, 32 1941 blt t9, zero, 2f # if shift < 0, shift right 1942 blt t9, v1, 1f # shift by < 32? 1943 subu t9, t9, v1 # shift by >= 32 1944 subu v1, v1, t9 1945 sll t2, t3, t9 # shift left by t9 1946 srl v0, t8, v1 # save bits shifted out 1947 or t2, t2, v0 1948 sll t3, t8, t9 1949 move t8, zero 1950 b norm_noshift_d 19511: 1952 subu v1, v1, t9 1953 sll t2, t2, t9 # shift left by t9 1954 srl v0, t3, v1 # save bits shifted out 1955 or t2, t2, v0 1956 sll t3, t3, t9 1957 srl v0, t8, v1 # save bits shifted out 1958 or t3, t3, v0 1959 sll t8, t8, t9 1960 b norm_noshift_d 19612: 1962 negu t9 # shift right by t9 1963 subu v1, v1, t9 # (known to be < 32 bits) 1964 sll v0, t8, v1 # save bits shifted out 1965 sltu v0, zero, v0 # be sure to save any one bits 1966 srl t8, t8, t9 1967 or t8, t8, v0 1968 sll v0, t3, v1 # save bits shifted out 1969 or t8, t8, v0 1970 srl t3, t3, t9 1971 sll v0, t2, v1 # save bits shifted out 1972 or t3, t3, v0 1973 srl t2, t2, t9 1974norm_noshift_d: 1975 move ta1, t1 # save unrounded exponent 1976 move ta2, t2 # save unrounded fraction (MS) 1977 move ta3, t3 # save unrounded fraction (LS) 1978 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 1979 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 1980 beq v0, MIPS_FPU_ROUND_RZ, 5f # round to zero (truncate) 1981 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 1982 beq t0, zero, 5f # if sign is positive, truncate 1983 b 2f 19841: 1985 bne t0, zero, 5f # if sign is negative, truncate 19862: 1987 beq t8, zero, 5f # if exact, continue 1988 addu t3, t3, 1 # add rounding bit 1989 bne t3, zero, 5f # branch if no carry 1990 addu t2, t2, 1 # add carry 1991 bne t2, DIMPL_ONE<<1, 5f # need to adjust exponent? 1992 addu t1, t1, 1 # adjust exponent 1993 srl t2, t2, 1 # renormalize fraction 1994 b 5f 19953: 1996 li v0, GUARDBIT # load guard bit for rounding 1997 addu v0, v0, t8 # add remainder 1998 sltu v1, v0, t8 # compute carry out 1999 beq v1, zero, 4f # branch if no carry 2000 addu t3, t3, 1 # add carry 2001 bne t3, zero, 4f # branch if no carry 2002 addu t2, t2, 1 # add carry to result 2003 bne t2, DIMPL_ONE<<1, 4f # need to adjust exponent? 2004 addu t1, t1, 1 # adjust exponent 2005 srl t2, t2, 1 # renormalize fraction 20064: 2007 bne v0, zero, 5f # if rounded remainder is zero 2008 and t3, t3, ~1 # clear LSB (round to nearest) 20095: 2010 bgt t1, DEXP_MAX, overflow_d # overflow? 2011 blt t1, DEXP_MIN, underflow_d # underflow? 2012 bne t8, zero, inexact_d # is result inexact? 2013 addu t1, t1, DEXP_BIAS # bias exponent 2014 and t2, t2, ~DIMPL_ONE # clear implied one bit 2015 b result_fs_d 2016 2017/* 2018 * Handle inexact exception. 2019 */ 2020inexact_d: 2021 addu t1, t1, DEXP_BIAS # bias exponent 2022 and t2, t2, ~DIMPL_ONE # clear implied one bit 2023inexact_nobias_d: 2024 jal set_fd_d # save result 2025 or a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT 2026 and v0, a1, MIPS_FPU_ENABLE_INEXACT 2027 bne v0, zero, fpe_trap 2028 ctc1 a1, MIPS_FPU_CSR # save exceptions 2029 b done 2030 2031/* 2032 * Overflow will trap (if enabled), 2033 * or generate an inexact trap (if enabled), 2034 * or generate an infinity. 2035 */ 2036overflow_d: 2037 or a1, a1, MIPS_FPU_EXCEPTION_OVERFLOW | MIPS_FPU_STICKY_OVERFLOW 2038 and v0, a1, MIPS_FPU_ENABLE_OVERFLOW 2039 beq v0, zero, 1f 2040 subu t1, t1, 1536 # bias exponent 2041 and t2, t2, ~DIMPL_ONE # clear implied one bit 2042 jal set_fd_d # save result 2043 b fpe_trap 20441: 2045 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 2046 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 2047 beq v0, MIPS_FPU_ROUND_RZ, 1f # round to zero (truncate) 2048 beq v0, MIPS_FPU_ROUND_RP, 2f # round to +infinity 2049 bne t0, zero, 3f 20501: 2051 li t1, DEXP_MAX # result is max finite 2052 li t2, 0x000fffff 2053 li t3, 0xffffffff 2054 b inexact_d 20552: 2056 bne t0, zero, 1b 20573: 2058 li t1, DEXP_MAX + 1 # result is infinity 2059 move t2, zero 2060 move t3, zero 2061 b inexact_d 2062 2063/* 2064 * In this implementation, "tininess" is detected "after rounding" and 2065 * "loss of accuracy" is detected as "an inexact result". 2066 */ 2067underflow_d: 2068 and v0, a1, MIPS_FPU_ENABLE_UNDERFLOW 2069 beq v0, zero, 1f 2070/* 2071 * Underflow is enabled so compute the result and trap. 2072 */ 2073 addu t1, t1, 1536 # bias exponent 2074 and t2, t2, ~DIMPL_ONE # clear implied one bit 2075 jal set_fd_d # save result 2076 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 2077 b fpe_trap 2078/* 2079 * Underflow is not enabled so compute the result, 2080 * signal inexact result (if it is) and trap (if enabled). 2081 */ 20821: 2083 move t1, ta1 # get unrounded exponent 2084 move t2, ta2 # get unrounded fraction (MS) 2085 move t3, ta3 # get unrounded fraction (LS) 2086 li t9, DEXP_MIN # compute shift amount 2087 subu t9, t9, t1 # shift t2,t8 right by t9 2088 blt t9, DFRAC_BITS+2, 3f # shift all the bits out? 2089 move t1, zero # result is inexact zero 2090 move t2, zero 2091 move t3, zero 2092 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 2093/* 2094 * Now round the zero result. 2095 * Only need to worry about rounding to +- infinity when the sign matches. 2096 */ 2097 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 2098 beq v0, MIPS_FPU_ROUND_RN, inexact_nobias_d # round to nearest 2099 beq v0, MIPS_FPU_ROUND_RZ, inexact_nobias_d # round to zero 2100 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 2101 beq t0, zero, inexact_nobias_d # if sign is positive, truncate 2102 b 2f 21031: 2104 bne t0, zero, inexact_nobias_d # if sign is negative, truncate 21052: 2106 addu t3, t3, 1 # add rounding bit 2107 b inexact_nobias_d 21083: 2109 li v1, 32 2110 blt t9, v1, 1f # shift by < 32? 2111 subu t9, t9, v1 # shift right by >= 32 2112 subu v1, v1, t9 2113 sltu v0, zero, t8 # be sure to save any one bits 2114 sll t8, t2, v1 # save bits shifted out 2115 or t8, t8, v0 # include sticky bits 2116 srl t3, t2, t9 2117 move t2, zero 2118 b 2f 21191: 2120 subu v1, v1, t9 # shift right by t9 2121 sltu v0, zero, t8 # be sure to save any one bits 2122 sll t8, t3, v1 # save bits shifted out 2123 or t8, t8, v0 # include sticky bits 2124 srl t3, t3, t9 2125 sll v0, t2, v1 # save bits shifted out 2126 or t3, t3, v0 2127 srl t2, t2, t9 2128/* 2129 * Now round the denormalized result. 2130 */ 21312: 2132 and v0, a1, MIPS_FPU_ROUNDING_BITS # get rounding mode 2133 beq v0, MIPS_FPU_ROUND_RN, 3f # round to nearest 2134 beq v0, MIPS_FPU_ROUND_RZ, 5f # round to zero (truncate) 2135 beq v0, MIPS_FPU_ROUND_RP, 1f # round to +infinity 2136 beq t0, zero, 5f # if sign is positive, truncate 2137 b 2f 21381: 2139 bne t0, zero, 5f # if sign is negative, truncate 21402: 2141 beq t8, zero, 5f # if exact, continue 2142 addu t3, t3, 1 # add rounding bit 2143 bne t3, zero, 5f # if no carry, continue 2144 addu t2, t2, 1 # add carry 2145 b 5f 21463: 2147 li v0, GUARDBIT # load guard bit for rounding 2148 addu v0, v0, t8 # add remainder 2149 sltu v1, v0, t8 # compute carry out 2150 beq v1, zero, 4f # if no carry, continue 2151 addu t3, t3, 1 # add rounding bit 2152 bne t3, zero, 4f # if no carry, continue 2153 addu t2, t2, 1 # add carry 21544: 2155 bne v0, zero, 5f # if rounded remainder is zero 2156 and t3, t3, ~1 # clear LSB (round to nearest) 21575: 2158 move t1, zero # denorm or zero exponent 2159 jal set_fd_d # save result 2160 beq t8, zero, done # check for exact result 2161 or a1, a1, MIPS_FPU_EXCEPTION_UNDERFLOW | MIPS_FPU_STICKY_UNDERFLOW 2162 or a1, a1, MIPS_FPU_EXCEPTION_INEXACT | MIPS_FPU_STICKY_INEXACT 2163 and v0, a1, MIPS_FPU_ENABLE_INEXACT 2164 bne v0, zero, fpe_trap 2165 ctc1 a1, MIPS_FPU_CSR # save exceptions 2166 b done 2167 2168/* 2169 * Signal an invalid operation if the trap is enabled; otherwise, 2170 * the result is a quiet NAN. 2171 */ 2172invalid_s: # trap invalid operation 2173 or a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID 2174 and v0, a1, MIPS_FPU_ENABLE_INVALID 2175 bne v0, zero, fpe_trap 2176 ctc1 a1, MIPS_FPU_CSR # save exceptions 2177 move t0, zero # result is a quiet NAN 2178 li t1, SEXP_INF 2179 li t2, SQUIET_NAN 2180 jal set_fd_s # save result (in t0,t1,t2) 2181 b done 2182 2183/* 2184 * Signal an invalid operation if the trap is enabled; otherwise, 2185 * the result is a quiet NAN. 2186 */ 2187invalid_d: # trap invalid operation 2188 or a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID 2189 and v0, a1, MIPS_FPU_ENABLE_INVALID 2190 bne v0, zero, fpe_trap 2191 ctc1 a1, MIPS_FPU_CSR # save exceptions 2192 move t0, zero # result is a quiet NAN 2193 li t1, DEXP_INF 2194 li t2, DQUIET_NAN0 2195 li t3, DQUIET_NAN1 2196 jal set_fd_d # save result (in t0,t1,t2,t3) 2197 b done 2198 2199/* 2200 * Signal an invalid operation if the trap is enabled; otherwise, 2201 * the result is INT_MAX or INT_MIN. 2202 */ 2203invalid_w: # trap invalid operation 2204 or a1, a1, MIPS_FPU_EXCEPTION_INVALID | MIPS_FPU_STICKY_INVALID 2205 and v0, a1, MIPS_FPU_ENABLE_INVALID 2206 bne v0, zero, fpe_trap 2207 ctc1 a1, MIPS_FPU_CSR # save exceptions 2208 bne t0, zero, 1f 2209 li t2, INT_MAX # result is INT_MAX 2210 b result_fs_w 22111: 2212 li t2, INT_MIN # result is INT_MIN 2213 b result_fs_w 2214 2215/* 2216 * Trap if the hardware should have handled this case. 2217 */ 2218fpe_trap: 2219 move a2, a1 # code = FP CSR 2220 ctc1 a1, MIPS_FPU_CSR # save exceptions 2221 break 0 2222 2223/* 2224 * Send an illegal instruction signal to the current process. 2225 */ 2226ill: 2227 ctc1 a1, MIPS_FPU_CSR # save exceptions 2228 move a2, a0 # code = FP instruction 2229 break 0 2230 2231result_ft_s: 2232 move t0, ta0 # result is FT 2233 move t1, ta1 2234 move t2, ta2 2235result_fs_s: # result is FS 2236 jal set_fd_s # save result (in t0,t1,t2) 2237 b done 2238 2239result_fs_w: 2240 jal set_fd_word # save result (in t2) 2241 b done 2242 2243result_ft_d: 2244 move t0, ta0 # result is FT 2245 move t1, ta1 2246 move t2, ta2 2247 move t3, ta3 2248result_fs_d: # result is FS 2249 jal set_fd_d # save result (in t0,t1,t2,t3) 2250 2251done: 2252 lw ra, CALLFRAME_RA(sp) 2253 addu sp, sp, CALLFRAME_SIZ 2254 j ra 2255END(MipsEmulateFP) 2256 2257/*---------------------------------------------------------------------------- 2258 * get_fs_int -- 2259 * 2260 * Read (integer) the FS register (bits 15-11). 2261 * This is an internal routine used by MipsEmulateFP only. 2262 * 2263 * Results: 2264 * t0 contains the sign 2265 * t2 contains the fraction 2266 * 2267 *---------------------------------------------------------------------------- 2268 */ 2269LEAF(get_fs_int) 2270 srl a3, a0, 12 - 2 # get FS field (even regs only) 2271 and a3, a3, 0xF << 2 # mask FS field 2272 lw a3, get_fs_int_tbl(a3) # switch on register number 2273 j a3 2274 2275 .rdata 2276get_fs_int_tbl: 2277 .word get_fs_int_f0 2278 .word get_fs_int_f2 2279 .word get_fs_int_f4 2280 .word get_fs_int_f6 2281 .word get_fs_int_f8 2282 .word get_fs_int_f10 2283 .word get_fs_int_f12 2284 .word get_fs_int_f14 2285 .word get_fs_int_f16 2286 .word get_fs_int_f18 2287 .word get_fs_int_f20 2288 .word get_fs_int_f22 2289 .word get_fs_int_f24 2290 .word get_fs_int_f26 2291 .word get_fs_int_f28 2292 .word get_fs_int_f30 2293 .text 2294 2295get_fs_int_f0: 2296 mfc1 t2, $f0 2297 b get_fs_int_done 2298get_fs_int_f2: 2299 mfc1 t2, $f2 2300 b get_fs_int_done 2301get_fs_int_f4: 2302 mfc1 t2, $f4 2303 b get_fs_int_done 2304get_fs_int_f6: 2305 mfc1 t2, $f6 2306 b get_fs_int_done 2307get_fs_int_f8: 2308 mfc1 t2, $f8 2309 b get_fs_int_done 2310get_fs_int_f10: 2311 mfc1 t2, $f10 2312 b get_fs_int_done 2313get_fs_int_f12: 2314 mfc1 t2, $f12 2315 b get_fs_int_done 2316get_fs_int_f14: 2317 mfc1 t2, $f14 2318 b get_fs_int_done 2319get_fs_int_f16: 2320 mfc1 t2, $f16 2321 b get_fs_int_done 2322get_fs_int_f18: 2323 mfc1 t2, $f18 2324 b get_fs_int_done 2325get_fs_int_f20: 2326 mfc1 t2, $f20 2327 b get_fs_int_done 2328get_fs_int_f22: 2329 mfc1 t2, $f22 2330 b get_fs_int_done 2331get_fs_int_f24: 2332 mfc1 t2, $f24 2333 b get_fs_int_done 2334get_fs_int_f26: 2335 mfc1 t2, $f26 2336 b get_fs_int_done 2337get_fs_int_f28: 2338 mfc1 t2, $f28 2339 b get_fs_int_done 2340get_fs_int_f30: 2341 mfc1 t2, $f30 2342get_fs_int_done: 2343 srl t0, t2, 31 # init the sign bit 2344 bge t2, zero, 1f 2345 negu t2 23461: 2347 j ra 2348END(get_fs_int) 2349 2350/*---------------------------------------------------------------------------- 2351 * get_ft_fs_s -- 2352 * 2353 * Read (single precision) the FT register (bits 20-16) and 2354 * the FS register (bits 15-11) and break up into fields. 2355 * This is an internal routine used by MipsEmulateFP only. 2356 * 2357 * Results: 2358 * t0 contains the FS sign 2359 * t1 contains the FS (biased) exponent 2360 * t2 contains the FS fraction 2361 * ta0 contains the FT sign 2362 * ta1 contains the FT (biased) exponent 2363 * ta2 contains the FT fraction 2364 * 2365 *---------------------------------------------------------------------------- 2366 */ 2367LEAF(get_ft_fs_s) 2368 srl a3, a0, 17 - 2 # get FT field (even regs only) 2369 and a3, a3, 0xF << 2 # mask FT field 2370 lw a3, get_ft_s_tbl(a3) # switch on register number 2371 j a3 2372 2373 .rdata 2374get_ft_s_tbl: 2375 .word get_ft_s_f0 2376 .word get_ft_s_f2 2377 .word get_ft_s_f4 2378 .word get_ft_s_f6 2379 .word get_ft_s_f8 2380 .word get_ft_s_f10 2381 .word get_ft_s_f12 2382 .word get_ft_s_f14 2383 .word get_ft_s_f16 2384 .word get_ft_s_f18 2385 .word get_ft_s_f20 2386 .word get_ft_s_f22 2387 .word get_ft_s_f24 2388 .word get_ft_s_f26 2389 .word get_ft_s_f28 2390 .word get_ft_s_f30 2391 .text 2392 2393get_ft_s_f0: 2394 mfc1 ta0, $f0 2395 b get_ft_s_done 2396get_ft_s_f2: 2397 mfc1 ta0, $f2 2398 b get_ft_s_done 2399get_ft_s_f4: 2400 mfc1 ta0, $f4 2401 b get_ft_s_done 2402get_ft_s_f6: 2403 mfc1 ta0, $f6 2404 b get_ft_s_done 2405get_ft_s_f8: 2406 mfc1 ta0, $f8 2407 b get_ft_s_done 2408get_ft_s_f10: 2409 mfc1 ta0, $f10 2410 b get_ft_s_done 2411get_ft_s_f12: 2412 mfc1 ta0, $f12 2413 b get_ft_s_done 2414get_ft_s_f14: 2415 mfc1 ta0, $f14 2416 b get_ft_s_done 2417get_ft_s_f16: 2418 mfc1 ta0, $f16 2419 b get_ft_s_done 2420get_ft_s_f18: 2421 mfc1 ta0, $f18 2422 b get_ft_s_done 2423get_ft_s_f20: 2424 mfc1 ta0, $f20 2425 b get_ft_s_done 2426get_ft_s_f22: 2427 mfc1 ta0, $f22 2428 b get_ft_s_done 2429get_ft_s_f24: 2430 mfc1 ta0, $f24 2431 b get_ft_s_done 2432get_ft_s_f26: 2433 mfc1 ta0, $f26 2434 b get_ft_s_done 2435get_ft_s_f28: 2436 mfc1 ta0, $f28 2437 b get_ft_s_done 2438get_ft_s_f30: 2439 mfc1 ta0, $f30 2440get_ft_s_done: 2441 srl ta1, ta0, 23 # get exponent 2442 and ta1, ta1, 0xFF 2443 and ta2, ta0, 0x7FFFFF # get fraction 2444 srl ta0, ta0, 31 # get sign 2445 bne ta1, SEXP_INF, 1f # is it a signaling NAN? 2446 and v0, ta2, SSIGNAL_NAN 2447 bne v0, zero, invalid_s 24481: 2449 /* fall through to get FS */ 2450 2451/*---------------------------------------------------------------------------- 2452 * get_fs_s -- 2453 * 2454 * Read (single precision) the FS register (bits 15-11) and 2455 * break up into fields. 2456 * This is an internal routine used by MipsEmulateFP only. 2457 * 2458 * Results: 2459 * t0 contains the sign 2460 * t1 contains the (biased) exponent 2461 * t2 contains the fraction 2462 * 2463 *---------------------------------------------------------------------------- 2464 */ 2465XLEAF(get_fs_s) 2466 srl a3, a0, 12 - 2 # get FS field (even regs only) 2467 and a3, a3, 0xF << 2 # mask FS field 2468 lw a3, get_fs_s_tbl(a3) # switch on register number 2469 j a3 2470 2471 .rdata 2472get_fs_s_tbl: 2473 .word get_fs_s_f0 2474 .word get_fs_s_f2 2475 .word get_fs_s_f4 2476 .word get_fs_s_f6 2477 .word get_fs_s_f8 2478 .word get_fs_s_f10 2479 .word get_fs_s_f12 2480 .word get_fs_s_f14 2481 .word get_fs_s_f16 2482 .word get_fs_s_f18 2483 .word get_fs_s_f20 2484 .word get_fs_s_f22 2485 .word get_fs_s_f24 2486 .word get_fs_s_f26 2487 .word get_fs_s_f28 2488 .word get_fs_s_f30 2489 .text 2490 2491get_fs_s_f0: 2492 mfc1 t0, $f0 2493 b get_fs_s_done 2494get_fs_s_f2: 2495 mfc1 t0, $f2 2496 b get_fs_s_done 2497get_fs_s_f4: 2498 mfc1 t0, $f4 2499 b get_fs_s_done 2500get_fs_s_f6: 2501 mfc1 t0, $f6 2502 b get_fs_s_done 2503get_fs_s_f8: 2504 mfc1 t0, $f8 2505 b get_fs_s_done 2506get_fs_s_f10: 2507 mfc1 t0, $f10 2508 b get_fs_s_done 2509get_fs_s_f12: 2510 mfc1 t0, $f12 2511 b get_fs_s_done 2512get_fs_s_f14: 2513 mfc1 t0, $f14 2514 b get_fs_s_done 2515get_fs_s_f16: 2516 mfc1 t0, $f16 2517 b get_fs_s_done 2518get_fs_s_f18: 2519 mfc1 t0, $f18 2520 b get_fs_s_done 2521get_fs_s_f20: 2522 mfc1 t0, $f20 2523 b get_fs_s_done 2524get_fs_s_f22: 2525 mfc1 t0, $f22 2526 b get_fs_s_done 2527get_fs_s_f24: 2528 mfc1 t0, $f24 2529 b get_fs_s_done 2530get_fs_s_f26: 2531 mfc1 t0, $f26 2532 b get_fs_s_done 2533get_fs_s_f28: 2534 mfc1 t0, $f28 2535 b get_fs_s_done 2536get_fs_s_f30: 2537 mfc1 t0, $f30 2538get_fs_s_done: 2539 srl t1, t0, 23 # get exponent 2540 and t1, t1, 0xFF 2541 and t2, t0, 0x7FFFFF # get fraction 2542 srl t0, t0, 31 # get sign 2543 bne t1, SEXP_INF, 1f # is it a signaling NAN? 2544 and v0, t2, SSIGNAL_NAN 2545 bne v0, zero, invalid_s 25461: 2547 j ra 2548END(get_ft_fs_s) 2549 2550/*---------------------------------------------------------------------------- 2551 * get_ft_fs_d -- 2552 * 2553 * Read (double precision) the FT register (bits 20-16) and 2554 * the FS register (bits 15-11) and break up into fields. 2555 * This is an internal routine used by MipsEmulateFP only. 2556 * 2557 * Results: 2558 * t0 contains the FS sign 2559 * t1 contains the FS (biased) exponent 2560 * t2 contains the FS fraction 2561 * t3 contains the FS remaining fraction 2562 * ta0 contains the FT sign 2563 * ta1 contains the FT (biased) exponent 2564 * ta2 contains the FT fraction 2565 * ta3 contains the FT remaining fraction 2566 * 2567 *---------------------------------------------------------------------------- 2568 */ 2569LEAF(get_ft_fs_d) 2570 srl a3, a0, 17 - 2 # get FT field (even regs only) 2571 and a3, a3, 0xF << 2 # mask FT field 2572 lw a3, get_ft_d_tbl(a3) # switch on register number 2573 j a3 2574 2575 .rdata 2576get_ft_d_tbl: 2577 .word get_ft_d_f0 2578 .word get_ft_d_f2 2579 .word get_ft_d_f4 2580 .word get_ft_d_f6 2581 .word get_ft_d_f8 2582 .word get_ft_d_f10 2583 .word get_ft_d_f12 2584 .word get_ft_d_f14 2585 .word get_ft_d_f16 2586 .word get_ft_d_f18 2587 .word get_ft_d_f20 2588 .word get_ft_d_f22 2589 .word get_ft_d_f24 2590 .word get_ft_d_f26 2591 .word get_ft_d_f28 2592 .word get_ft_d_f30 2593 .text 2594 2595get_ft_d_f0: 2596 mfc1 ta3, $f0 2597 mfc1 ta0, $f1 2598 b get_ft_d_done 2599get_ft_d_f2: 2600 mfc1 ta3, $f2 2601 mfc1 ta0, $f3 2602 b get_ft_d_done 2603get_ft_d_f4: 2604 mfc1 ta3, $f4 2605 mfc1 ta0, $f5 2606 b get_ft_d_done 2607get_ft_d_f6: 2608 mfc1 ta3, $f6 2609 mfc1 ta0, $f7 2610 b get_ft_d_done 2611get_ft_d_f8: 2612 mfc1 ta3, $f8 2613 mfc1 ta0, $f9 2614 b get_ft_d_done 2615get_ft_d_f10: 2616 mfc1 ta3, $f10 2617 mfc1 ta0, $f11 2618 b get_ft_d_done 2619get_ft_d_f12: 2620 mfc1 ta3, $f12 2621 mfc1 ta0, $f13 2622 b get_ft_d_done 2623get_ft_d_f14: 2624 mfc1 ta3, $f14 2625 mfc1 ta0, $f15 2626 b get_ft_d_done 2627get_ft_d_f16: 2628 mfc1 ta3, $f16 2629 mfc1 ta0, $f17 2630 b get_ft_d_done 2631get_ft_d_f18: 2632 mfc1 ta3, $f18 2633 mfc1 ta0, $f19 2634 b get_ft_d_done 2635get_ft_d_f20: 2636 mfc1 ta3, $f20 2637 mfc1 ta0, $f21 2638 b get_ft_d_done 2639get_ft_d_f22: 2640 mfc1 ta3, $f22 2641 mfc1 ta0, $f23 2642 b get_ft_d_done 2643get_ft_d_f24: 2644 mfc1 ta3, $f24 2645 mfc1 ta0, $f25 2646 b get_ft_d_done 2647get_ft_d_f26: 2648 mfc1 ta3, $f26 2649 mfc1 ta0, $f27 2650 b get_ft_d_done 2651get_ft_d_f28: 2652 mfc1 ta3, $f28 2653 mfc1 ta0, $f29 2654 b get_ft_d_done 2655get_ft_d_f30: 2656 mfc1 ta3, $f30 2657 mfc1 ta0, $f31 2658get_ft_d_done: 2659 srl ta1, ta0, 20 # get exponent 2660 and ta1, ta1, 0x7FF 2661 and ta2, ta0, 0xFFFFF # get fraction 2662 srl ta0, ta0, 31 # get sign 2663 bne ta1, DEXP_INF, 1f # is it a signaling NAN? 2664 and v0, ta2, DSIGNAL_NAN 2665 bne v0, zero, invalid_d 26661: 2667 /* fall through to get FS */ 2668 2669/*---------------------------------------------------------------------------- 2670 * get_fs_d -- 2671 * 2672 * Read (double precision) the FS register (bits 15-11) and 2673 * break up into fields. 2674 * This is an internal routine used by MipsEmulateFP only. 2675 * 2676 * Results: 2677 * t0 contains the sign 2678 * t1 contains the (biased) exponent 2679 * t2 contains the fraction 2680 * t3 contains the remaining fraction 2681 * 2682 *---------------------------------------------------------------------------- 2683 */ 2684XLEAF(get_fs_d) 2685 srl a3, a0, 12 - 2 # get FS field (even regs only) 2686 and a3, a3, 0xF << 2 # mask FS field 2687 lw a3, get_fs_d_tbl(a3) # switch on register number 2688 j a3 2689 2690 .rdata 2691get_fs_d_tbl: 2692 .word get_fs_d_f0 2693 .word get_fs_d_f2 2694 .word get_fs_d_f4 2695 .word get_fs_d_f6 2696 .word get_fs_d_f8 2697 .word get_fs_d_f10 2698 .word get_fs_d_f12 2699 .word get_fs_d_f14 2700 .word get_fs_d_f16 2701 .word get_fs_d_f18 2702 .word get_fs_d_f20 2703 .word get_fs_d_f22 2704 .word get_fs_d_f24 2705 .word get_fs_d_f26 2706 .word get_fs_d_f28 2707 .word get_fs_d_f30 2708 .text 2709 2710get_fs_d_f0: 2711 mfc1 t3, $f0 2712 mfc1 t0, $f1 2713 b get_fs_d_done 2714get_fs_d_f2: 2715 mfc1 t3, $f2 2716 mfc1 t0, $f3 2717 b get_fs_d_done 2718get_fs_d_f4: 2719 mfc1 t3, $f4 2720 mfc1 t0, $f5 2721 b get_fs_d_done 2722get_fs_d_f6: 2723 mfc1 t3, $f6 2724 mfc1 t0, $f7 2725 b get_fs_d_done 2726get_fs_d_f8: 2727 mfc1 t3, $f8 2728 mfc1 t0, $f9 2729 b get_fs_d_done 2730get_fs_d_f10: 2731 mfc1 t3, $f10 2732 mfc1 t0, $f11 2733 b get_fs_d_done 2734get_fs_d_f12: 2735 mfc1 t3, $f12 2736 mfc1 t0, $f13 2737 b get_fs_d_done 2738get_fs_d_f14: 2739 mfc1 t3, $f14 2740 mfc1 t0, $f15 2741 b get_fs_d_done 2742get_fs_d_f16: 2743 mfc1 t3, $f16 2744 mfc1 t0, $f17 2745 b get_fs_d_done 2746get_fs_d_f18: 2747 mfc1 t3, $f18 2748 mfc1 t0, $f19 2749 b get_fs_d_done 2750get_fs_d_f20: 2751 mfc1 t3, $f20 2752 mfc1 t0, $f21 2753 b get_fs_d_done 2754get_fs_d_f22: 2755 mfc1 t3, $f22 2756 mfc1 t0, $f23 2757 b get_fs_d_done 2758get_fs_d_f24: 2759 mfc1 t3, $f24 2760 mfc1 t0, $f25 2761 b get_fs_d_done 2762get_fs_d_f26: 2763 mfc1 t3, $f26 2764 mfc1 t0, $f27 2765 b get_fs_d_done 2766get_fs_d_f28: 2767 mfc1 t3, $f28 2768 mfc1 t0, $f29 2769 b get_fs_d_done 2770get_fs_d_f30: 2771 mfc1 t3, $f30 2772 mfc1 t0, $f31 2773get_fs_d_done: 2774 srl t1, t0, 20 # get exponent 2775 and t1, t1, 0x7FF 2776 and t2, t0, 0xFFFFF # get fraction 2777 srl t0, t0, 31 # get sign 2778 bne t1, DEXP_INF, 1f # is it a signaling NAN? 2779 and v0, t2, DSIGNAL_NAN 2780 bne v0, zero, invalid_d 27811: 2782 j ra 2783END(get_ft_fs_d) 2784 2785/*---------------------------------------------------------------------------- 2786 * get_cmp_s -- 2787 * 2788 * Read (single precision) the FS register (bits 15-11) and 2789 * the FT register (bits 20-16) and break up into fields. 2790 * This is an internal routine used by MipsEmulateFP only. 2791 * 2792 * Results: 2793 * t0 contains the sign 2794 * t1 contains the (biased) exponent 2795 * t2 contains the fraction 2796 * ta0 contains the sign 2797 * ta1 contains the (biased) exponent 2798 * ta2 contains the fraction 2799 * 2800 *---------------------------------------------------------------------------- 2801 */ 2802LEAF(get_cmp_s) 2803 srl a3, a0, 12 - 2 # get FS field (even regs only) 2804 and a3, a3, 0xF << 2 # mask FS field 2805 lw a3, cmp_fs_s_tbl(a3) # switch on register number 2806 j a3 2807 2808 .rdata 2809cmp_fs_s_tbl: 2810 .word cmp_fs_s_f0 2811 .word cmp_fs_s_f2 2812 .word cmp_fs_s_f4 2813 .word cmp_fs_s_f6 2814 .word cmp_fs_s_f8 2815 .word cmp_fs_s_f10 2816 .word cmp_fs_s_f12 2817 .word cmp_fs_s_f14 2818 .word cmp_fs_s_f16 2819 .word cmp_fs_s_f18 2820 .word cmp_fs_s_f20 2821 .word cmp_fs_s_f22 2822 .word cmp_fs_s_f24 2823 .word cmp_fs_s_f26 2824 .word cmp_fs_s_f28 2825 .word cmp_fs_s_f30 2826 .text 2827 2828cmp_fs_s_f0: 2829 mfc1 t0, $f0 2830 b cmp_fs_s_done 2831cmp_fs_s_f2: 2832 mfc1 t0, $f2 2833 b cmp_fs_s_done 2834cmp_fs_s_f4: 2835 mfc1 t0, $f4 2836 b cmp_fs_s_done 2837cmp_fs_s_f6: 2838 mfc1 t0, $f6 2839 b cmp_fs_s_done 2840cmp_fs_s_f8: 2841 mfc1 t0, $f8 2842 b cmp_fs_s_done 2843cmp_fs_s_f10: 2844 mfc1 t0, $f10 2845 b cmp_fs_s_done 2846cmp_fs_s_f12: 2847 mfc1 t0, $f12 2848 b cmp_fs_s_done 2849cmp_fs_s_f14: 2850 mfc1 t0, $f14 2851 b cmp_fs_s_done 2852cmp_fs_s_f16: 2853 mfc1 t0, $f16 2854 b cmp_fs_s_done 2855cmp_fs_s_f18: 2856 mfc1 t0, $f18 2857 b cmp_fs_s_done 2858cmp_fs_s_f20: 2859 mfc1 t0, $f20 2860 b cmp_fs_s_done 2861cmp_fs_s_f22: 2862 mfc1 t0, $f22 2863 b cmp_fs_s_done 2864cmp_fs_s_f24: 2865 mfc1 t0, $f24 2866 b cmp_fs_s_done 2867cmp_fs_s_f26: 2868 mfc1 t0, $f26 2869 b cmp_fs_s_done 2870cmp_fs_s_f28: 2871 mfc1 t0, $f28 2872 b cmp_fs_s_done 2873cmp_fs_s_f30: 2874 mfc1 t0, $f30 2875cmp_fs_s_done: 2876 srl t1, t0, 23 # get exponent 2877 and t1, t1, 0xFF 2878 and t2, t0, 0x7FFFFF # get fraction 2879 srl t0, t0, 31 # get sign 2880 2881 srl a3, a0, 17 - 2 # get FT field (even regs only) 2882 and a3, a3, 0xF << 2 # mask FT field 2883 lw a3, cmp_ft_s_tbl(a3) # switch on register number 2884 j a3 2885 2886 .rdata 2887cmp_ft_s_tbl: 2888 .word cmp_ft_s_f0 2889 .word cmp_ft_s_f2 2890 .word cmp_ft_s_f4 2891 .word cmp_ft_s_f6 2892 .word cmp_ft_s_f8 2893 .word cmp_ft_s_f10 2894 .word cmp_ft_s_f12 2895 .word cmp_ft_s_f14 2896 .word cmp_ft_s_f16 2897 .word cmp_ft_s_f18 2898 .word cmp_ft_s_f20 2899 .word cmp_ft_s_f22 2900 .word cmp_ft_s_f24 2901 .word cmp_ft_s_f26 2902 .word cmp_ft_s_f28 2903 .word cmp_ft_s_f30 2904 .text 2905 2906cmp_ft_s_f0: 2907 mfc1 ta0, $f0 2908 b cmp_ft_s_done 2909cmp_ft_s_f2: 2910 mfc1 ta0, $f2 2911 b cmp_ft_s_done 2912cmp_ft_s_f4: 2913 mfc1 ta0, $f4 2914 b cmp_ft_s_done 2915cmp_ft_s_f6: 2916 mfc1 ta0, $f6 2917 b cmp_ft_s_done 2918cmp_ft_s_f8: 2919 mfc1 ta0, $f8 2920 b cmp_ft_s_done 2921cmp_ft_s_f10: 2922 mfc1 ta0, $f10 2923 b cmp_ft_s_done 2924cmp_ft_s_f12: 2925 mfc1 ta0, $f12 2926 b cmp_ft_s_done 2927cmp_ft_s_f14: 2928 mfc1 ta0, $f14 2929 b cmp_ft_s_done 2930cmp_ft_s_f16: 2931 mfc1 ta0, $f16 2932 b cmp_ft_s_done 2933cmp_ft_s_f18: 2934 mfc1 ta0, $f18 2935 b cmp_ft_s_done 2936cmp_ft_s_f20: 2937 mfc1 ta0, $f20 2938 b cmp_ft_s_done 2939cmp_ft_s_f22: 2940 mfc1 ta0, $f22 2941 b cmp_ft_s_done 2942cmp_ft_s_f24: 2943 mfc1 ta0, $f24 2944 b cmp_ft_s_done 2945cmp_ft_s_f26: 2946 mfc1 ta0, $f26 2947 b cmp_ft_s_done 2948cmp_ft_s_f28: 2949 mfc1 ta0, $f28 2950 b cmp_ft_s_done 2951cmp_ft_s_f30: 2952 mfc1 ta0, $f30 2953cmp_ft_s_done: 2954 srl ta1, ta0, 23 # get exponent 2955 and ta1, ta1, 0xFF 2956 and ta2, ta0, 0x7FFFFF # get fraction 2957 srl ta0, ta0, 31 # get sign 2958 j ra 2959END(get_cmp_s) 2960 2961/*---------------------------------------------------------------------------- 2962 * get_cmp_d -- 2963 * 2964 * Read (double precision) the FS register (bits 15-11) and 2965 * the FT register (bits 20-16) and break up into fields. 2966 * This is an internal routine used by MipsEmulateFP only. 2967 * 2968 * Results: 2969 * t0 contains the sign 2970 * t1 contains the (biased) exponent 2971 * t2 contains the fraction 2972 * t3 contains the remaining fraction 2973 * ta0 contains the sign 2974 * ta1 contains the (biased) exponent 2975 * ta2 contains the fraction 2976 * ta3 contains the remaining fraction 2977 * 2978 *---------------------------------------------------------------------------- 2979 */ 2980LEAF(get_cmp_d) 2981 srl a3, a0, 12 - 2 # get FS field (even regs only) 2982 and a3, a3, 0xF << 2 # mask FS field 2983 lw a3, cmp_fs_d_tbl(a3) # switch on register number 2984 j a3 2985 2986 .rdata 2987cmp_fs_d_tbl: 2988 .word cmp_fs_d_f0 2989 .word cmp_fs_d_f2 2990 .word cmp_fs_d_f4 2991 .word cmp_fs_d_f6 2992 .word cmp_fs_d_f8 2993 .word cmp_fs_d_f10 2994 .word cmp_fs_d_f12 2995 .word cmp_fs_d_f14 2996 .word cmp_fs_d_f16 2997 .word cmp_fs_d_f18 2998 .word cmp_fs_d_f20 2999 .word cmp_fs_d_f22 3000 .word cmp_fs_d_f24 3001 .word cmp_fs_d_f26 3002 .word cmp_fs_d_f28 3003 .word cmp_fs_d_f30 3004 .text 3005 3006cmp_fs_d_f0: 3007 mfc1 t3, $f0 3008 mfc1 t0, $f1 3009 b cmp_fs_d_done 3010cmp_fs_d_f2: 3011 mfc1 t3, $f2 3012 mfc1 t0, $f3 3013 b cmp_fs_d_done 3014cmp_fs_d_f4: 3015 mfc1 t3, $f4 3016 mfc1 t0, $f5 3017 b cmp_fs_d_done 3018cmp_fs_d_f6: 3019 mfc1 t3, $f6 3020 mfc1 t0, $f7 3021 b cmp_fs_d_done 3022cmp_fs_d_f8: 3023 mfc1 t3, $f8 3024 mfc1 t0, $f9 3025 b cmp_fs_d_done 3026cmp_fs_d_f10: 3027 mfc1 t3, $f10 3028 mfc1 t0, $f11 3029 b cmp_fs_d_done 3030cmp_fs_d_f12: 3031 mfc1 t3, $f12 3032 mfc1 t0, $f13 3033 b cmp_fs_d_done 3034cmp_fs_d_f14: 3035 mfc1 t3, $f14 3036 mfc1 t0, $f15 3037 b cmp_fs_d_done 3038cmp_fs_d_f16: 3039 mfc1 t3, $f16 3040 mfc1 t0, $f17 3041 b cmp_fs_d_done 3042cmp_fs_d_f18: 3043 mfc1 t3, $f18 3044 mfc1 t0, $f19 3045 b cmp_fs_d_done 3046cmp_fs_d_f20: 3047 mfc1 t3, $f20 3048 mfc1 t0, $f21 3049 b cmp_fs_d_done 3050cmp_fs_d_f22: 3051 mfc1 t3, $f22 3052 mfc1 t0, $f23 3053 b cmp_fs_d_done 3054cmp_fs_d_f24: 3055 mfc1 t3, $f24 3056 mfc1 t0, $f25 3057 b cmp_fs_d_done 3058cmp_fs_d_f26: 3059 mfc1 t3, $f26 3060 mfc1 t0, $f27 3061 b cmp_fs_d_done 3062cmp_fs_d_f28: 3063 mfc1 t3, $f28 3064 mfc1 t0, $f29 3065 b cmp_fs_d_done 3066cmp_fs_d_f30: 3067 mfc1 t3, $f30 3068 mfc1 t0, $f31 3069cmp_fs_d_done: 3070 srl t1, t0, 20 # get exponent 3071 and t1, t1, 0x7FF 3072 and t2, t0, 0xFFFFF # get fraction 3073 srl t0, t0, 31 # get sign 3074 3075 srl a3, a0, 17 - 2 # get FT field (even regs only) 3076 and a3, a3, 0xF << 2 # mask FT field 3077 lw a3, cmp_ft_d_tbl(a3) # switch on register number 3078 j a3 3079 3080 .rdata 3081cmp_ft_d_tbl: 3082 .word cmp_ft_d_f0 3083 .word cmp_ft_d_f2 3084 .word cmp_ft_d_f4 3085 .word cmp_ft_d_f6 3086 .word cmp_ft_d_f8 3087 .word cmp_ft_d_f10 3088 .word cmp_ft_d_f12 3089 .word cmp_ft_d_f14 3090 .word cmp_ft_d_f16 3091 .word cmp_ft_d_f18 3092 .word cmp_ft_d_f20 3093 .word cmp_ft_d_f22 3094 .word cmp_ft_d_f24 3095 .word cmp_ft_d_f26 3096 .word cmp_ft_d_f28 3097 .word cmp_ft_d_f30 3098 .text 3099 3100cmp_ft_d_f0: 3101 mfc1 ta3, $f0 3102 mfc1 ta0, $f1 3103 b cmp_ft_d_done 3104cmp_ft_d_f2: 3105 mfc1 ta3, $f2 3106 mfc1 ta0, $f3 3107 b cmp_ft_d_done 3108cmp_ft_d_f4: 3109 mfc1 ta3, $f4 3110 mfc1 ta0, $f5 3111 b cmp_ft_d_done 3112cmp_ft_d_f6: 3113 mfc1 ta3, $f6 3114 mfc1 ta0, $f7 3115 b cmp_ft_d_done 3116cmp_ft_d_f8: 3117 mfc1 ta3, $f8 3118 mfc1 ta0, $f9 3119 b cmp_ft_d_done 3120cmp_ft_d_f10: 3121 mfc1 ta3, $f10 3122 mfc1 ta0, $f11 3123 b cmp_ft_d_done 3124cmp_ft_d_f12: 3125 mfc1 ta3, $f12 3126 mfc1 ta0, $f13 3127 b cmp_ft_d_done 3128cmp_ft_d_f14: 3129 mfc1 ta3, $f14 3130 mfc1 ta0, $f15 3131 b cmp_ft_d_done 3132cmp_ft_d_f16: 3133 mfc1 ta3, $f16 3134 mfc1 ta0, $f17 3135 b cmp_ft_d_done 3136cmp_ft_d_f18: 3137 mfc1 ta3, $f18 3138 mfc1 ta0, $f19 3139 b cmp_ft_d_done 3140cmp_ft_d_f20: 3141 mfc1 ta3, $f20 3142 mfc1 ta0, $f21 3143 b cmp_ft_d_done 3144cmp_ft_d_f22: 3145 mfc1 ta3, $f22 3146 mfc1 ta0, $f23 3147 b cmp_ft_d_done 3148cmp_ft_d_f24: 3149 mfc1 ta3, $f24 3150 mfc1 ta0, $f25 3151 b cmp_ft_d_done 3152cmp_ft_d_f26: 3153 mfc1 ta3, $f26 3154 mfc1 ta0, $f27 3155 b cmp_ft_d_done 3156cmp_ft_d_f28: 3157 mfc1 ta3, $f28 3158 mfc1 ta0, $f29 3159 b cmp_ft_d_done 3160cmp_ft_d_f30: 3161 mfc1 ta3, $f30 3162 mfc1 ta0, $f31 3163cmp_ft_d_done: 3164 srl ta1, ta0, 20 # get exponent 3165 and ta1, ta1, 0x7FF 3166 and ta2, ta0, 0xFFFFF # get fraction 3167 srl ta0, ta0, 31 # get sign 3168 j ra 3169END(get_cmp_d) 3170 3171/*---------------------------------------------------------------------------- 3172 * set_fd_s -- 3173 * 3174 * Write (single precision) the FD register (bits 10-6). 3175 * This is an internal routine used by MipsEmulateFP only. 3176 * 3177 * Arguments: 3178 * a0 contains the FP instruction 3179 * t0 contains the sign 3180 * t1 contains the (biased) exponent 3181 * t2 contains the fraction 3182 * 3183 * set_fd_word -- 3184 * 3185 * Write (integer) the FD register (bits 10-6). 3186 * This is an internal routine used by MipsEmulateFP only. 3187 * 3188 * Arguments: 3189 * a0 contains the FP instruction 3190 * t2 contains the integer 3191 * 3192 *---------------------------------------------------------------------------- 3193 */ 3194LEAF(set_fd_s) 3195 sll t0, t0, 31 # position sign 3196 sll t1, t1, 23 # position exponent 3197 or t2, t2, t0 3198 or t2, t2, t1 3199XLEAF(set_fd_word) 3200 srl a3, a0, 7 - 2 # get FD field (even regs only) 3201 and a3, a3, 0xF << 2 # mask FT field 3202 lw a3, set_fd_s_tbl(a3) # switch on register number 3203 j a3 3204 3205 .rdata 3206set_fd_s_tbl: 3207 .word set_fd_s_f0 3208 .word set_fd_s_f2 3209 .word set_fd_s_f4 3210 .word set_fd_s_f6 3211 .word set_fd_s_f8 3212 .word set_fd_s_f10 3213 .word set_fd_s_f12 3214 .word set_fd_s_f14 3215 .word set_fd_s_f16 3216 .word set_fd_s_f18 3217 .word set_fd_s_f20 3218 .word set_fd_s_f22 3219 .word set_fd_s_f24 3220 .word set_fd_s_f26 3221 .word set_fd_s_f28 3222 .word set_fd_s_f30 3223 .text 3224 3225set_fd_s_f0: 3226 mtc1 t2, $f0 3227 j ra 3228set_fd_s_f2: 3229 mtc1 t2, $f2 3230 j ra 3231set_fd_s_f4: 3232 mtc1 t2, $f4 3233 j ra 3234set_fd_s_f6: 3235 mtc1 t2, $f6 3236 j ra 3237set_fd_s_f8: 3238 mtc1 t2, $f8 3239 j ra 3240set_fd_s_f10: 3241 mtc1 t2, $f10 3242 j ra 3243set_fd_s_f12: 3244 mtc1 t2, $f12 3245 j ra 3246set_fd_s_f14: 3247 mtc1 t2, $f14 3248 j ra 3249set_fd_s_f16: 3250 mtc1 t2, $f16 3251 j ra 3252set_fd_s_f18: 3253 mtc1 t2, $f18 3254 j ra 3255set_fd_s_f20: 3256 mtc1 t2, $f20 3257 j ra 3258set_fd_s_f22: 3259 mtc1 t2, $f22 3260 j ra 3261set_fd_s_f24: 3262 mtc1 t2, $f24 3263 j ra 3264set_fd_s_f26: 3265 mtc1 t2, $f26 3266 j ra 3267set_fd_s_f28: 3268 mtc1 t2, $f28 3269 j ra 3270set_fd_s_f30: 3271 mtc1 t2, $f30 3272 j ra 3273END(set_fd_s) 3274 3275/*---------------------------------------------------------------------------- 3276 * set_fd_d -- 3277 * 3278 * Write (double precision) the FT register (bits 10-6). 3279 * This is an internal routine used by MipsEmulateFP only. 3280 * 3281 * Arguments: 3282 * a0 contains the FP instruction 3283 * t0 contains the sign 3284 * t1 contains the (biased) exponent 3285 * t2 contains the fraction 3286 * t3 contains the remaining fraction 3287 * 3288 *---------------------------------------------------------------------------- 3289 */ 3290LEAF(set_fd_d) 3291 sll t0, t0, 31 # set sign 3292 sll t1, t1, 20 # set exponent 3293 or t0, t0, t1 3294 or t0, t0, t2 # set fraction 3295 srl a3, a0, 7 - 2 # get FD field (even regs only) 3296 and a3, a3, 0xF << 2 # mask FD field 3297 lw a3, set_fd_d_tbl(a3) # switch on register number 3298 j a3 3299 3300 .rdata 3301set_fd_d_tbl: 3302 .word set_fd_d_f0 3303 .word set_fd_d_f2 3304 .word set_fd_d_f4 3305 .word set_fd_d_f6 3306 .word set_fd_d_f8 3307 .word set_fd_d_f10 3308 .word set_fd_d_f12 3309 .word set_fd_d_f14 3310 .word set_fd_d_f16 3311 .word set_fd_d_f18 3312 .word set_fd_d_f20 3313 .word set_fd_d_f22 3314 .word set_fd_d_f24 3315 .word set_fd_d_f26 3316 .word set_fd_d_f28 3317 .word set_fd_d_f30 3318 .text 3319 3320set_fd_d_f0: 3321 mtc1 t3, $f0 3322 mtc1 t0, $f1 3323 j ra 3324set_fd_d_f2: 3325 mtc1 t3, $f2 3326 mtc1 t0, $f3 3327 j ra 3328set_fd_d_f4: 3329 mtc1 t3, $f4 3330 mtc1 t0, $f5 3331 j ra 3332set_fd_d_f6: 3333 mtc1 t3, $f6 3334 mtc1 t0, $f7 3335 j ra 3336set_fd_d_f8: 3337 mtc1 t3, $f8 3338 mtc1 t0, $f9 3339 j ra 3340set_fd_d_f10: 3341 mtc1 t3, $f10 3342 mtc1 t0, $f11 3343 j ra 3344set_fd_d_f12: 3345 mtc1 t3, $f12 3346 mtc1 t0, $f13 3347 j ra 3348set_fd_d_f14: 3349 mtc1 t3, $f14 3350 mtc1 t0, $f15 3351 j ra 3352set_fd_d_f16: 3353 mtc1 t3, $f16 3354 mtc1 t0, $f17 3355 j ra 3356set_fd_d_f18: 3357 mtc1 t3, $f18 3358 mtc1 t0, $f19 3359 j ra 3360set_fd_d_f20: 3361 mtc1 t3, $f20 3362 mtc1 t0, $f21 3363 j ra 3364set_fd_d_f22: 3365 mtc1 t3, $f22 3366 mtc1 t0, $f23 3367 j ra 3368set_fd_d_f24: 3369 mtc1 t3, $f24 3370 mtc1 t0, $f25 3371 j ra 3372set_fd_d_f26: 3373 mtc1 t3, $f26 3374 mtc1 t0, $f27 3375 j ra 3376set_fd_d_f28: 3377 mtc1 t3, $f28 3378 mtc1 t0, $f29 3379 j ra 3380set_fd_d_f30: 3381 mtc1 t3, $f30 3382 mtc1 t0, $f31 3383 j ra 3384END(set_fd_d) 3385 3386/*---------------------------------------------------------------------------- 3387 * renorm_fs_s -- 3388 * 3389 * Results: 3390 * t1 unbiased exponent 3391 * t2 normalized fraction 3392 * 3393 *---------------------------------------------------------------------------- 3394 */ 3395LEAF(renorm_fs_s) 3396/* 3397 * Find out how many leading zero bits are in t2 and put in t9. 3398 */ 3399 move v0, t2 3400 move t9, zero 3401 srl v1, v0, 16 3402 bne v1, zero, 1f 3403 addu t9, 16 3404 sll v0, 16 34051: 3406 srl v1, v0, 24 3407 bne v1, zero, 1f 3408 addu t9, 8 3409 sll v0, 8 34101: 3411 srl v1, v0, 28 3412 bne v1, zero, 1f 3413 addu t9, 4 3414 sll v0, 4 34151: 3416 srl v1, v0, 30 3417 bne v1, zero, 1f 3418 addu t9, 2 3419 sll v0, 2 34201: 3421 srl v1, v0, 31 3422 bne v1, zero, 1f 3423 addu t9, 1 3424/* 3425 * Now shift t2 the correct number of bits. 3426 */ 34271: 3428 subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros 3429 li t1, SEXP_MIN 3430 subu t1, t1, t9 # adjust exponent 3431 sll t2, t2, t9 3432 j ra 3433END(renorm_fs_s) 3434 3435/*---------------------------------------------------------------------------- 3436 * renorm_fs_d -- 3437 * 3438 * Results: 3439 * t1 unbiased exponent 3440 * t2,t3 normalized fraction 3441 * 3442 *---------------------------------------------------------------------------- 3443 */ 3444LEAF(renorm_fs_d) 3445/* 3446 * Find out how many leading zero bits are in t2,t3 and put in t9. 3447 */ 3448 move v0, t2 3449 move t9, zero 3450 bne t2, zero, 1f 3451 move v0, t3 3452 addu t9, 32 34531: 3454 srl v1, v0, 16 3455 bne v1, zero, 1f 3456 addu t9, 16 3457 sll v0, 16 34581: 3459 srl v1, v0, 24 3460 bne v1, zero, 1f 3461 addu t9, 8 3462 sll v0, 8 34631: 3464 srl v1, v0, 28 3465 bne v1, zero, 1f 3466 addu t9, 4 3467 sll v0, 4 34681: 3469 srl v1, v0, 30 3470 bne v1, zero, 1f 3471 addu t9, 2 3472 sll v0, 2 34731: 3474 srl v1, v0, 31 3475 bne v1, zero, 1f 3476 addu t9, 1 3477/* 3478 * Now shift t2,t3 the correct number of bits. 3479 */ 34801: 3481 subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros 3482 li t1, DEXP_MIN 3483 subu t1, t1, t9 # adjust exponent 3484 li v0, 32 3485 blt t9, v0, 1f 3486 subu t9, t9, v0 # shift fraction left >= 32 bits 3487 sll t2, t3, t9 3488 move t3, zero 3489 j ra 34901: 3491 subu v0, v0, t9 # shift fraction left < 32 bits 3492 sll t2, t2, t9 3493 srl v1, t3, v0 3494 or t2, t2, v1 3495 sll t3, t3, t9 3496 j ra 3497END(renorm_fs_d) 3498 3499/*---------------------------------------------------------------------------- 3500 * renorm_ft_s -- 3501 * 3502 * Results: 3503 * ta1 unbiased exponent 3504 * ta2 normalized fraction 3505 * 3506 *---------------------------------------------------------------------------- 3507 */ 3508LEAF(renorm_ft_s) 3509/* 3510 * Find out how many leading zero bits are in ta2 and put in t9. 3511 */ 3512 move v0, ta2 3513 move t9, zero 3514 srl v1, v0, 16 3515 bne v1, zero, 1f 3516 addu t9, 16 3517 sll v0, 16 35181: 3519 srl v1, v0, 24 3520 bne v1, zero, 1f 3521 addu t9, 8 3522 sll v0, 8 35231: 3524 srl v1, v0, 28 3525 bne v1, zero, 1f 3526 addu t9, 4 3527 sll v0, 4 35281: 3529 srl v1, v0, 30 3530 bne v1, zero, 1f 3531 addu t9, 2 3532 sll v0, 2 35331: 3534 srl v1, v0, 31 3535 bne v1, zero, 1f 3536 addu t9, 1 3537/* 3538 * Now shift ta2 the correct number of bits. 3539 */ 35401: 3541 subu t9, t9, SLEAD_ZEROS # dont count normal leading zeros 3542 li ta1, SEXP_MIN 3543 subu ta1, ta1, t9 # adjust exponent 3544 sll ta2, ta2, t9 3545 j ra 3546END(renorm_ft_s) 3547 3548/*---------------------------------------------------------------------------- 3549 * renorm_ft_d -- 3550 * 3551 * Results: 3552 * ta1 unbiased exponent 3553 * ta2,ta3 normalized fraction 3554 * 3555 *---------------------------------------------------------------------------- 3556 */ 3557LEAF(renorm_ft_d) 3558/* 3559 * Find out how many leading zero bits are in ta2,ta3 and put in t9. 3560 */ 3561 move v0, ta2 3562 move t9, zero 3563 bne ta2, zero, 1f 3564 move v0, ta3 3565 addu t9, 32 35661: 3567 srl v1, v0, 16 3568 bne v1, zero, 1f 3569 addu t9, 16 3570 sll v0, 16 35711: 3572 srl v1, v0, 24 3573 bne v1, zero, 1f 3574 addu t9, 8 3575 sll v0, 8 35761: 3577 srl v1, v0, 28 3578 bne v1, zero, 1f 3579 addu t9, 4 3580 sll v0, 4 35811: 3582 srl v1, v0, 30 3583 bne v1, zero, 1f 3584 addu t9, 2 3585 sll v0, 2 35861: 3587 srl v1, v0, 31 3588 bne v1, zero, 1f 3589 addu t9, 1 3590/* 3591 * Now shift ta2,ta3 the correct number of bits. 3592 */ 35931: 3594 subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros 3595 li ta1, DEXP_MIN 3596 subu ta1, ta1, t9 # adjust exponent 3597 li v0, 32 3598 blt t9, v0, 1f 3599 subu t9, t9, v0 # shift fraction left >= 32 bits 3600 sll ta2, ta3, t9 3601 move ta3, zero 3602 j ra 36031: 3604 subu v0, v0, t9 # shift fraction left < 32 bits 3605 sll ta2, ta2, t9 3606 srl v1, ta3, v0 3607 or ta2, ta2, v1 3608 sll ta3, ta3, t9 3609 j ra 3610END(renorm_ft_d) 3611