[BACK]Return to fp.S CVS log [TXT][DIR] Up to [local] / sys / arch / mips64 / mips64

Annotation of sys/arch/mips64/mips64/fp.S, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: fp.S,v 1.7 2004/11/02 18:54:45 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. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *     This product includes software developed by the University of
        !            20:  *     California, Berkeley and its contributors.
        !            21:  * 4. Neither the name of the University nor the names of its contributors
        !            22:  *    may be used to endorse or promote products derived from this software
        !            23:  *    without specific prior written permission.
        !            24:  *
        !            25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            35:  * SUCH DAMAGE.
        !            36:  *
        !            37:  *     from: @(#)fp.s  8.1 (Berkeley) 6/10/93
        !            38:  *      $Id: fp.S,v 1.7 2004/11/02 18:54:45 pefo Exp $
        !            39:  */
        !            40:
        !            41: /*
        !            42:  * Standard header stuff.
        !            43:  */
        !            44:
        !            45: #include <machine/regdef.h>
        !            46: #include <machine/asm.h>
        !            47: #include <machine/regnum.h>
        !            48: #include <machine/cpu.h>
        !            49:
        !            50: #include "assym.h"
        !            51:
        !            52: #define SEXP_INF       0xff
        !            53: #define DEXP_INF       0x7ff
        !            54: #define SEXP_BIAS      127
        !            55: #define DEXP_BIAS      1023
        !            56: #define SEXP_MIN       -126
        !            57: #define DEXP_MIN       -1022
        !            58: #define SEXP_MAX       127
        !            59: #define DEXP_MAX       1023
        !            60: #define WEXP_MAX       30              /* maximum unbiased exponent for int */
        !            61: #define WEXP_MIN       -1              /* minimum unbiased exponent for int */
        !            62: #define SFRAC_BITS     23
        !            63: #define DFRAC_BITS     52
        !            64: #define SIMPL_ONE      0x00800000
        !            65: #define DIMPL_ONE      0x0010000000000000
        !            66: #define SLEAD_ZEROS    63 - 55
        !            67: #define DLEAD_ZEROS    63 - 52
        !            68: #define STICKYBIT      1
        !            69: #define GUARDBIT       0x0000000080000000
        !            70: #define DGUARDBIT      0x8000000000000000
        !            71:
        !            72: #define SSIGNAL_NAN    0x00400000
        !            73: #define DSIGNAL_NAN    0x00080000
        !            74: #define SQUIET_NAN     0x003fffff
        !            75: #define DQUIET_NAN     0x0007ffffffffffff
        !            76: #define INT_MIN                0x80000000
        !            77: #define INT_MAX                0x7fffffff
        !            78:
        !            79: #define COND_UNORDERED 0x1
        !            80: #define COND_EQUAL     0x2
        !            81: #define COND_LESS      0x4
        !            82: #define COND_SIGNAL    0x8
        !            83:
        !            84: /*----------------------------------------------------------------------------
        !            85:  *
        !            86:  * MipsEmulateFP --
        !            87:  *
        !            88:  *     Emulate unimplemented floating point operations.
        !            89:  *     This routine should only be called by MipsFPInterrupt()
        !            90:  *     and only if this is a COP1 instruction.
        !            91:  *
        !            92:  *     MipsEmulateFP(instr)
        !            93:  *             unsigned instr;
        !            94:  *
        !            95:  * Results:
        !            96:  *     None.
        !            97:  *
        !            98:  * Side effects:
        !            99:  *     Floating point registers are modified according to instruction.
        !           100:  *
        !           101:  *----------------------------------------------------------------------------
        !           102:  */
        !           103: NON_LEAF(MipsEmulateFP, FRAMESZ(CF_SZ), ra)
        !           104:        PTR_SUB sp, sp, FRAMESZ(CF_SZ)
        !           105:        PTR_S   ra, CF_RA_OFFS(sp)
        !           106:
        !           107:        srl     v0, a0, 21                      # get FMT field
        !           108:        and     v0, v0, 0x1f                    # mask FMT field
        !           109:        dla     a3, func_s
        !           110:        beq     v0, 0x10, 1f
        !           111:        dla     a3, func_d
        !           112:        beq     v0, 0x11, 1f
        !           113:        dla     a3, func_w
        !           114:        beq     v0, 0x14, 1f
        !           115:        dla     a3, func_l
        !           116:        beq     v0, 0x15, 1f
        !           117:        b       ill                             # illegal format
        !           118:
        !           119: 1:
        !           120:        and     v1, a0, 0x3f                    # mask FUNC field
        !           121:        sll     v1, v1, 3                       # align for table lookup
        !           122:        daddu   v1, a3
        !           123:        cfc1    a1, FPC_CSR                     # get exception register
        !           124:        ld      a3, (v1)                        # switch on FUNC & FMT
        !           125:        and     a1, a1, ~FPC_EXCEPTION_UNIMPL   # clear exception
        !           126:        ctc1    a1, FPC_CSR
        !           127:        j       a3
        !           128:
        !           129:        .rdata
        !           130: func_s:
        !           131:        .dword  add_s           # 0
        !           132:        .dword  sub_s           # 1
        !           133:        .dword  mul_s           # 2
        !           134:        .dword  div_s           # 3
        !           135:        .dword  ill             # 4
        !           136:        .dword  abs_s           # 5
        !           137:        .dword  mov_s           # 6
        !           138:        .dword  neg_s           # 7
        !           139:        .dword  ill             # 8
        !           140:        .dword  ill             # 9
        !           141:        .dword  ill             # 10
        !           142:        .dword  ill             # 11
        !           143:        .dword  round_w_s       # 12
        !           144:        .dword  trunc_w_s       # 13
        !           145:        .dword  ceil_w_s        # 14
        !           146:        .dword  floor_w_s       # 15
        !           147:        .dword  ill             # 16
        !           148:        .dword  ill             # 17
        !           149:        .dword  ill             # 18
        !           150:        .dword  ill             # 19
        !           151:        .dword  ill             # 20
        !           152:        .dword  ill             # 21
        !           153:        .dword  ill             # 22
        !           154:        .dword  ill             # 23
        !           155:        .dword  ill             # 24
        !           156:        .dword  ill             # 25
        !           157:        .dword  ill             # 26
        !           158:        .dword  ill             # 27
        !           159:        .dword  ill             # 28
        !           160:        .dword  ill             # 29
        !           161:        .dword  ill             # 30
        !           162:        .dword  ill             # 31
        !           163:        .dword  ill             # 32
        !           164:        .dword  cvt_d_s         # 33
        !           165:        .dword  ill             # 34
        !           166:        .dword  ill             # 35
        !           167:        .dword  cvt_w_s         # 36
        !           168:        .dword  ill             # 37
        !           169:        .dword  ill             # 38
        !           170:        .dword  ill             # 39
        !           171:        .dword  ill             # 40
        !           172:        .dword  ill             # 41
        !           173:        .dword  ill             # 42
        !           174:        .dword  ill             # 43
        !           175:        .dword  ill             # 44
        !           176:        .dword  ill             # 45
        !           177:        .dword  ill             # 46
        !           178:        .dword  ill             # 47
        !           179:        .dword  cmp_s           # 48
        !           180:        .dword  cmp_s           # 49
        !           181:        .dword  cmp_s           # 50
        !           182:        .dword  cmp_s           # 51
        !           183:        .dword  cmp_s           # 52
        !           184:        .dword  cmp_s           # 53
        !           185:        .dword  cmp_s           # 54
        !           186:        .dword  cmp_s           # 55
        !           187:        .dword  cmp_s           # 56
        !           188:        .dword  cmp_s           # 57
        !           189:        .dword  cmp_s           # 58
        !           190:        .dword  cmp_s           # 59
        !           191:        .dword  cmp_s           # 60
        !           192:        .dword  cmp_s           # 61
        !           193:        .dword  cmp_s           # 62
        !           194:        .dword  cmp_s           # 63
        !           195:
        !           196: func_d:
        !           197:        .dword  add_d           # 0
        !           198:        .dword  sub_d           # 1
        !           199:        .dword  mul_d           # 2
        !           200:        .dword  div_d           # 3
        !           201:        .dword  ill             # 4
        !           202:        .dword  abs_d           # 5
        !           203:        .dword  mov_d           # 6
        !           204:        .dword  neg_d           # 7
        !           205:        .dword  ill             # 8
        !           206:        .dword  ill             # 9
        !           207:        .dword  ill             # 10
        !           208:        .dword  ill             # 11
        !           209:        .dword  round_w_d       # 12
        !           210:        .dword  trunc_w_d       # 13
        !           211:        .dword  ceil_w_d        # 14
        !           212:        .dword  floor_w_d       # 15
        !           213:        .dword  ill             # 16
        !           214:        .dword  ill             # 17
        !           215:        .dword  ill             # 18
        !           216:        .dword  ill             # 19
        !           217:        .dword  ill             # 20
        !           218:        .dword  ill             # 21
        !           219:        .dword  ill             # 22
        !           220:        .dword  ill             # 23
        !           221:        .dword  ill             # 24
        !           222:        .dword  ill             # 25
        !           223:        .dword  ill             # 26
        !           224:        .dword  ill             # 27
        !           225:        .dword  ill             # 28
        !           226:        .dword  ill             # 29
        !           227:        .dword  ill             # 30
        !           228:        .dword  ill             # 31
        !           229:        .dword  cvt_s_d         # 32
        !           230:        .dword  ill             # 33
        !           231:        .dword  ill             # 34
        !           232:        .dword  ill             # 35
        !           233:        .dword  cvt_w_d         # 36
        !           234:        .dword  ill             # 37
        !           235:        .dword  ill             # 38
        !           236:        .dword  ill             # 39
        !           237:        .dword  ill             # 40
        !           238:        .dword  ill             # 41
        !           239:        .dword  ill             # 42
        !           240:        .dword  ill             # 43
        !           241:        .dword  ill             # 44
        !           242:        .dword  ill             # 45
        !           243:        .dword  ill             # 46
        !           244:        .dword  ill             # 47
        !           245:        .dword  cmp_d           # 48
        !           246:        .dword  cmp_d           # 49
        !           247:        .dword  cmp_d           # 50
        !           248:        .dword  cmp_d           # 51
        !           249:        .dword  cmp_d           # 52
        !           250:        .dword  cmp_d           # 53
        !           251:        .dword  cmp_d           # 54
        !           252:        .dword  cmp_d           # 55
        !           253:        .dword  cmp_d           # 56
        !           254:        .dword  cmp_d           # 57
        !           255:        .dword  cmp_d           # 58
        !           256:        .dword  cmp_d           # 59
        !           257:        .dword  cmp_d           # 60
        !           258:        .dword  cmp_d           # 61
        !           259:        .dword  cmp_d           # 62
        !           260:        .dword  cmp_d           # 63
        !           261:
        !           262: func_w:
        !           263:        .dword  ill             # 0
        !           264:        .dword  ill             # 1
        !           265:        .dword  ill             # 2
        !           266:        .dword  ill             # 3
        !           267:        .dword  ill             # 4
        !           268:        .dword  ill             # 5
        !           269:        .dword  ill             # 6
        !           270:        .dword  ill             # 7
        !           271:        .dword  ill             # 8
        !           272:        .dword  ill             # 9
        !           273:        .dword  ill             # 10
        !           274:        .dword  ill             # 11
        !           275:        .dword  ill             # 12
        !           276:        .dword  ill             # 13
        !           277:        .dword  ill             # 14
        !           278:        .dword  ill             # 15
        !           279:        .dword  ill             # 16
        !           280:        .dword  ill             # 17
        !           281:        .dword  ill             # 18
        !           282:        .dword  ill             # 19
        !           283:        .dword  ill             # 20
        !           284:        .dword  ill             # 21
        !           285:        .dword  ill             # 22
        !           286:        .dword  ill             # 23
        !           287:        .dword  ill             # 24
        !           288:        .dword  ill             # 25
        !           289:        .dword  ill             # 26
        !           290:        .dword  ill             # 27
        !           291:        .dword  ill             # 28
        !           292:        .dword  ill             # 29
        !           293:        .dword  ill             # 30
        !           294:        .dword  ill             # 31
        !           295:        .dword  cvt_s_w         # 32
        !           296:        .dword  cvt_d_w         # 33
        !           297:        .dword  ill             # 34
        !           298:        .dword  ill             # 35
        !           299:        .dword  ill             # 36
        !           300:        .dword  ill             # 37
        !           301:        .dword  ill             # 38
        !           302:        .dword  ill             # 39
        !           303:        .dword  ill             # 40
        !           304:        .dword  ill             # 41
        !           305:        .dword  ill             # 42
        !           306:        .dword  ill             # 43
        !           307:        .dword  ill             # 44
        !           308:        .dword  ill             # 45
        !           309:        .dword  ill             # 46
        !           310:        .dword  ill             # 47
        !           311:        .dword  ill             # 48
        !           312:        .dword  ill             # 49
        !           313:        .dword  ill             # 50
        !           314:        .dword  ill             # 51
        !           315:        .dword  ill             # 52
        !           316:        .dword  ill             # 53
        !           317:        .dword  ill             # 54
        !           318:        .dword  ill             # 55
        !           319:        .dword  ill             # 56
        !           320:        .dword  ill             # 57
        !           321:        .dword  ill             # 58
        !           322:        .dword  ill             # 59
        !           323:        .dword  ill             # 60
        !           324:        .dword  ill             # 61
        !           325:        .dword  ill             # 62
        !           326:        .dword  ill             # 63
        !           327:
        !           328: func_l:
        !           329:        .dword  ill             # 0
        !           330:        .dword  ill             # 1
        !           331:        .dword  ill             # 2
        !           332:        .dword  ill             # 3
        !           333:        .dword  ill             # 4
        !           334:        .dword  ill             # 5
        !           335:        .dword  ill             # 6
        !           336:        .dword  ill             # 7
        !           337:        .dword  ill             # 8
        !           338:        .dword  ill             # 9
        !           339:        .dword  ill             # 10
        !           340:        .dword  ill             # 11
        !           341:        .dword  ill             # 12
        !           342:        .dword  ill             # 13
        !           343:        .dword  ill             # 14
        !           344:        .dword  ill             # 15
        !           345:        .dword  ill             # 16
        !           346:        .dword  ill             # 17
        !           347:        .dword  ill             # 18
        !           348:        .dword  ill             # 19
        !           349:        .dword  ill             # 20
        !           350:        .dword  ill             # 21
        !           351:        .dword  ill             # 22
        !           352:        .dword  ill             # 23
        !           353:        .dword  ill             # 24
        !           354:        .dword  ill             # 25
        !           355:        .dword  ill             # 26
        !           356:        .dword  ill             # 27
        !           357:        .dword  ill             # 28
        !           358:        .dword  ill             # 29
        !           359:        .dword  ill             # 30
        !           360:        .dword  ill             # 31
        !           361:        .dword  cvt_s_l         # 32
        !           362:        .dword  cvt_d_l         # 33
        !           363:        .dword  ill             # 34
        !           364:        .dword  ill             # 35
        !           365:        .dword  ill             # 36
        !           366:        .dword  ill             # 37
        !           367:        .dword  ill             # 38
        !           368:        .dword  ill             # 39
        !           369:        .dword  ill             # 40
        !           370:        .dword  ill             # 41
        !           371:        .dword  ill             # 42
        !           372:        .dword  ill             # 43
        !           373:        .dword  ill             # 44
        !           374:        .dword  ill             # 45
        !           375:        .dword  ill             # 46
        !           376:        .dword  ill             # 47
        !           377:        .dword  ill             # 48
        !           378:        .dword  ill             # 49
        !           379:        .dword  ill             # 50
        !           380:        .dword  ill             # 51
        !           381:        .dword  ill             # 52
        !           382:        .dword  ill             # 53
        !           383:        .dword  ill             # 54
        !           384:        .dword  ill             # 55
        !           385:        .dword  ill             # 56
        !           386:        .dword  ill             # 57
        !           387:        .dword  ill             # 58
        !           388:        .dword  ill             # 59
        !           389:        .dword  ill             # 60
        !           390:        .dword  ill             # 61
        !           391:        .dword  ill             # 62
        !           392:        .dword  ill             # 63
        !           393:
        !           394:        .text
        !           395:
        !           396: /*
        !           397:  * Single precision subtract.
        !           398:  */
        !           399: sub_s:
        !           400:        jal     get_ft_fs_s
        !           401:        xor     ta0, 1                          # negate FT sign bit
        !           402:        b       add_sub_s
        !           403: /*
        !           404:  * Single precision add.
        !           405:  */
        !           406: add_s:
        !           407:        jal     get_ft_fs_s
        !           408: add_sub_s:
        !           409:        bne     t1, SEXP_INF, 1f                # is FS an infinity?
        !           410:        bne     ta1, SEXP_INF, result_fs_s      # if FT is not inf, result=FS
        !           411:        bne     t2, zero, result_fs_s           # if FS is NAN, result is FS
        !           412:        bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
        !           413:        bne     t0, ta0, invalid_s              # both infinities same sign?
        !           414:        b       result_fs_s                     # result is in FS
        !           415: 1:
        !           416:        beq     ta1, SEXP_INF, result_ft_s      # if FT is inf, result=FT
        !           417:        bne     t1, zero, 4f                    # is FS a denormalized num?
        !           418:        beq     t2, zero, 3f                    # is FS zero?
        !           419:        bne     ta1, zero, 2f                   # is FT a denormalized num?
        !           420:        beq     ta2, zero, result_fs_s          # FT is zero, result=FS
        !           421:        jal     renorm_fs_s
        !           422:        jal     renorm_ft_s
        !           423:        b       5f
        !           424: 2:
        !           425:        jal     renorm_fs_s
        !           426:        subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
        !           427:        or      ta2, ta2, SIMPL_ONE             # set implied one bit
        !           428:        b       5f
        !           429: 3:
        !           430:        bne     ta1, zero, result_ft_s          # if FT != 0, result=FT
        !           431:        bne     ta2, zero, result_ft_s
        !           432:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !           433:        bne     v0, FPC_ROUND_RM, 1f    # round to -infinity?
        !           434:        or      t0, t0, ta0                     # compute result sign
        !           435:        b       result_fs_s
        !           436: 1:
        !           437:        and     t0, ta0                         # compute result sign
        !           438:        b       result_fs_s
        !           439: 4:
        !           440:        bne     ta1, zero, 2f                   # is FT a denormalized num?
        !           441:        beq     ta2, zero, result_fs_s          # FT is zero, result=FS
        !           442:        subu    t1, SEXP_BIAS                   # unbias FS exponent
        !           443:        or      t2, SIMPL_ONE                   # set implied one bit
        !           444:        jal     renorm_ft_s
        !           445:        b       5f
        !           446: 2:
        !           447:        subu    t1, SEXP_BIAS                   # unbias FS exponent
        !           448:        or      t2, SIMPL_ONE                   # set implied one bit
        !           449:        subu    ta1, SEXP_BIAS                  # unbias FT exponent
        !           450:        or      ta2, SIMPL_ONE                  # set implied one bit
        !           451: /*
        !           452:  * Perform the addition.
        !           453:  */
        !           454: 5:
        !           455:        move    t8, zero                        # no shifted bits (sticky reg)
        !           456:        beq     t1, ta1, 4f                     # exp equal, no shift needed
        !           457:        subu    v0, t1, ta1                     # v0 = difference of exponents
        !           458:        move    v1, v0                          # v1 = abs(difference)
        !           459:        bge     v0, zero, 1f
        !           460:        negu    v1
        !           461: 1:
        !           462:        ble     v1, SFRAC_BITS+2, 2f            # is difference too great?
        !           463:        li      t8, STICKYBIT                   # set the sticky bit
        !           464:        bge     v0, zero, 1f                    # check which exp is larger
        !           465:        move    t1, ta1                         # result exp is FTs
        !           466:        move    t2, zero                        # FSs fraction shifted is zero
        !           467:        b       4f
        !           468: 1:
        !           469:        move    ta2, zero                       # FTs fraction shifted is zero
        !           470:        b       4f
        !           471: 2:
        !           472:        li      t9, 32                          # compute 32 - abs(exp diff)
        !           473:        subu    t9, t9, v1
        !           474:        bgt     v0, zero, 3f                    # if FS > FT, shift FTs frac
        !           475:        move    t1, ta1                         # FT > FS, result exp is FTs
        !           476:        sll     t8, t2, t9                      # save bits shifted out
        !           477:        srl     t2, t2, v1                      # shift FSs fraction
        !           478:        b       4f
        !           479: 3:
        !           480:        sll     t8, ta2, t9                     # save bits shifted out
        !           481:        srl     ta2, ta2, v1                    # shift FTs fraction
        !           482: 4:
        !           483:        bne     t0, ta0, 1f                     # if signs differ, subtract
        !           484:        addu    t2, t2, ta2                     # add fractions
        !           485:        b       norm_s
        !           486: 1:
        !           487:        blt     t2, ta2, 3f                     # subtract larger from smaller
        !           488:        bne     t2, ta2, 2f                     # if same, result=0
        !           489:        move    t1, zero                        # result=0
        !           490:        move    t2, zero
        !           491:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !           492:        bne     v0, FPC_ROUND_RM, 1f    # round to -infinity?
        !           493:        or      t0, t0, ta0                     # compute result sign
        !           494:        b       result_fs_s
        !           495: 1:
        !           496:        and     t0, t0, ta0                     # compute result sign
        !           497:        b       result_fs_s
        !           498: 2:
        !           499:        sltu    t9, zero, t8                    # compute t2:zero - ta2:t8
        !           500:        subu    t8, zero, t8
        !           501:        subu    t2, t2, ta2                     # subtract fractions
        !           502:        subu    t2, t2, t9                      # subtract barrow
        !           503:        b       norm_s
        !           504: 3:
        !           505:        move    t0, ta0                         # sign of result = FTs
        !           506:        sltu    t9, zero, t8                    # compute ta2:zero - t2:t8
        !           507:        subu    t8, zero, t8
        !           508:        subu    t2, ta2, t2                     # subtract fractions
        !           509:        subu    t2, t2, t9                      # subtract barrow
        !           510:        b       norm_s
        !           511:
        !           512: /*
        !           513:  * Double precision subtract.
        !           514:  */
        !           515: sub_d:
        !           516:        jal     get_ft_fs_d
        !           517:        xor     ta0, ta0, 1                     # negate sign bit
        !           518:        b       add_sub_d
        !           519: /*
        !           520:  * Double precision add.
        !           521:  */
        !           522: add_d:
        !           523:        jal     get_ft_fs_d
        !           524: add_sub_d:
        !           525:        bne     t1, DEXP_INF, 1f                # is FS an infinity?
        !           526:        bne     ta1, DEXP_INF, result_fs_d      # if FT is not inf, result=FS
        !           527:        bne     t2, zero, result_fs_d           # if FS is NAN, result is FS
        !           528:        bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
        !           529:        bne     t0, ta0, invalid_d              # both infinities same sign?
        !           530:        b       result_fs_d                     # result is in FS
        !           531: 1:
        !           532:        beq     ta1, DEXP_INF, result_ft_d      # if FT is inf, result=FT
        !           533:        bne     t1, zero, 4f                    # is FS a denormalized num?
        !           534:        beq     t2, zero, 3f                    # is FS zero?
        !           535:        bne     ta1, zero, 2f                   # is FT a denormalized num?
        !           536:        beq     ta2, zero, result_fs_d          # FT is zero, result=FS
        !           537:        jal     renorm_fs_d
        !           538:        jal     renorm_ft_d
        !           539:        b       5f
        !           540: 2:
        !           541:        jal     renorm_fs_d
        !           542:        subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
        !           543:        or      ta2, ta2, DIMPL_ONE             # set implied one bit
        !           544:        b       5f
        !           545: 3:
        !           546:        bne     ta1, zero, result_ft_d          # if FT != 0, result=FT
        !           547:        bne     ta2, zero, result_ft_d
        !           548:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !           549:        bne     v0, FPC_ROUND_RM, 1f    # round to -infinity?
        !           550:        or      t0, t0, ta0                     # compute result sign
        !           551:        b       result_fs_d
        !           552: 1:
        !           553:        and     t0, t0, ta0                     # compute result sign
        !           554:        b       result_fs_d
        !           555: 4:
        !           556:        bne     ta1, zero, 2f                   # is FT a denormalized num?
        !           557:        beq     ta2, zero, result_fs_d          # FT is zero, result=FS
        !           558:        subu    t1, t1, DEXP_BIAS               # unbias FS exponent
        !           559:        or      t2, t2, DIMPL_ONE               # set implied one bit
        !           560:        jal     renorm_ft_d
        !           561:        b       5f
        !           562: 2:
        !           563:        subu    t1, t1, DEXP_BIAS               # unbias FS exponent
        !           564:        or      t2, t2, DIMPL_ONE               # set implied one bit
        !           565:        subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
        !           566:        or      ta2, ta2, DIMPL_ONE             # set implied one bit
        !           567: /*
        !           568:  * Perform the addition.
        !           569:  */
        !           570: 5:
        !           571:        move    t8, zero                        # no shifted bits (sticky reg)
        !           572:        beq     t1, ta1, 4f                     # no shift needed
        !           573:        subu    v0, t1, ta1                     # v0 = difference of exponents
        !           574:        move    v1, v0                          # v1 = abs(difference)
        !           575:        bge     v0, zero, 1f
        !           576:        negu    v1
        !           577: 1:
        !           578:        ble     v1, DFRAC_BITS+2, 2f            # is difference too great?
        !           579:        li      t8, STICKYBIT                   # set the sticky bit
        !           580:        bge     v0, zero, 1f                    # check which exp is larger
        !           581:        move    t1, ta1                         # result exp is FTs
        !           582:        move    t2, zero                        # FSs fraction shifted is zero
        !           583:        b       4f
        !           584: 1:
        !           585:        move    ta2, zero                       # FTs fraction shifted is zero
        !           586:        b       4f
        !           587: 2:
        !           588:        li      t9, 64
        !           589:        subu    t9, t9, v1
        !           590:        bge     v0, zero, 3f                    # if FS > FT, shift FTs frac
        !           591:        move    t1, ta1                         # FT > FS, result exp is FTs
        !           592:        dsll    t8, t2, t9                      # save bits shifted out
        !           593:        dsrl    t2, t2, v1
        !           594:        b       4f
        !           595: 3:
        !           596:        dsll    t8, ta2, t9                     # save bits shifted out
        !           597:        dsrl    ta2, ta2, v1
        !           598: 4:
        !           599:        bne     t0, ta0, 1f                     # if signs differ, subtract
        !           600:        daddu   t2, ta2                         # add fractions
        !           601:        b       norm_d
        !           602: 1:
        !           603:        blt     t2, ta2, 3f                     # subtract larger from smaller
        !           604:        bne     t2, ta2, 2f
        !           605:        move    t1, zero                        # result=0
        !           606:        move    t2, zero
        !           607:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !           608:        bne     v0, FPC_ROUND_RM, 1f    # round to -infinity?
        !           609:        or      t0, t0, ta0                     # compute result sign
        !           610:        b       result_fs_d
        !           611: 1:
        !           612:        and     t0, t0, ta0                     # compute result sign
        !           613:        b       result_fs_d
        !           614: 2:
        !           615:        sltu    t9, zero, t8                    # compute t2:zero - ta2:t8
        !           616:        dsubu   t8, zero, t8
        !           617:        dsubu   t2, t2, ta2                     # subtract fractions
        !           618:        dsubu   t2, t2, t9                      # subtract barrow
        !           619:        b       norm_d
        !           620: 3:
        !           621:        move    t0, ta0                         # sign of result = FTs
        !           622:        sltu    t9, zero, t8
        !           623:        dsubu   t2, ta2, t2                     # subtract fractions
        !           624:        dsubu   t2, t2, t9                      # subtract barrow
        !           625:        b       norm_d
        !           626:
        !           627: /*
        !           628:  * Single precision multiply.
        !           629:  */
        !           630: mul_s:
        !           631:        jal     get_ft_fs_s
        !           632:        xor     t0, t0, ta0                     # compute sign of result
        !           633:        move    ta0, t0
        !           634:        bne     t1, SEXP_INF, 2f                # is FS an infinity?
        !           635:        bne     t2, zero, result_fs_s           # if FS is a NAN, result=FS
        !           636:        bne     ta1, SEXP_INF, 1f               # FS is inf, is FT an infinity?
        !           637:        bne     ta2, zero, result_ft_s          # if FT is a NAN, result=FT
        !           638:        b       result_fs_s                     # result is infinity
        !           639: 1:
        !           640:        bne     ta1, zero, result_fs_s          # inf * zero? if no, result=FS
        !           641:        bne     ta2, zero, result_fs_s
        !           642:        b       invalid_s                       # infinity * zero is invalid
        !           643: 2:
        !           644:        bne     ta1, SEXP_INF, 1f               # FS != inf, is FT an infinity?
        !           645:        bne     t1, zero, result_ft_s           # zero * inf? if no, result=FT
        !           646:        bne     t2, zero, result_ft_s
        !           647:        bne     ta2, zero, result_ft_s          # if FT is a NAN, result=FT
        !           648:        b       invalid_s                       # zero * infinity is invalid
        !           649: 1:
        !           650:        bne     t1, zero, 1f                    # is FS zero?
        !           651:        beq     t2, zero, result_fs_s           # result is zero
        !           652:        jal     renorm_fs_s
        !           653:        b       2f
        !           654: 1:
        !           655:        subu    t1, t1, SEXP_BIAS               # unbias FS exponent
        !           656:        or      t2, t2, SIMPL_ONE               # set implied one bit
        !           657: 2:
        !           658:        bne     ta1, zero, 1f                   # is FT zero?
        !           659:        beq     ta2, zero, result_ft_s          # result is zero
        !           660:        jal     renorm_ft_s
        !           661:        b       2f
        !           662: 1:
        !           663:        subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
        !           664:        or      ta2, ta2, SIMPL_ONE             # set implied one bit
        !           665: 2:
        !           666:        addu    t1, t1, ta1                     # compute result exponent
        !           667:        addu    t1, t1, 9                       # account for binary point
        !           668:        multu   t2, ta2                         # multiply fractions
        !           669:        mflo    t8
        !           670:        mfhi    t2
        !           671:        b       norm_s
        !           672:
        !           673: /*
        !           674:  * Double precision multiply.
        !           675:  */
        !           676: mul_d:
        !           677:        jal     get_ft_fs_d
        !           678:        xor     t0, t0, ta0                     # compute sign of result
        !           679:        move    ta0, t0
        !           680:        bne     t1, DEXP_INF, 2f                # is FS an infinity?
        !           681:        bne     t2, zero, result_fs_d           # if FS is a NAN, result=FS
        !           682:        bne     ta1, DEXP_INF, 1f               # FS is inf, is FT an infinity?
        !           683:        bne     ta2, zero, result_ft_d          # if FT is a NAN, result=FT
        !           684:        b       result_fs_d                     # result is infinity
        !           685: 1:
        !           686:        bne     ta1, zero, result_fs_d          # inf * zero? if no, result=FS
        !           687:        bne     ta2, zero, result_fs_d
        !           688:        b       invalid_d                       # infinity * zero is invalid
        !           689: 2:
        !           690:        bne     ta1, DEXP_INF, 1f               # FS != inf, is FT an infinity?
        !           691:        bne     t1, zero, result_ft_d           # zero * inf? if no, result=FT
        !           692:        bne     t2, zero, result_ft_d           # if FS is a NAN, result=FS
        !           693:        bne     ta2, zero, result_ft_d          # if FT is a NAN, result=FT
        !           694:        b       invalid_d                       # zero * infinity is invalid
        !           695: 1:
        !           696:        bne     t1, zero, 2f                    # is FS zero?
        !           697:        beq     t2, zero, result_fs_d           # result is zero
        !           698:        jal     renorm_fs_d
        !           699:        b       3f
        !           700: 2:
        !           701:        subu    t1, t1, DEXP_BIAS               # unbias FS exponent
        !           702:        or      t2, t2, DIMPL_ONE               # set implied one bit
        !           703: 3:
        !           704:        bne     ta1, zero, 2f                   # is FT zero?
        !           705:        beq     ta2, zero, result_ft_d          # result is zero
        !           706:        jal     renorm_ft_d
        !           707:        b       3f
        !           708: 2:
        !           709:        subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
        !           710:        or      ta2, ta2, DIMPL_ONE             # set implied one bit
        !           711: 3:
        !           712:        addu    t1, t1, ta1                     # compute result exponent
        !           713:        addu    t1, t1, 12                      # ???
        !           714:        dmultu  t2, ta2                         # multiply fractions
        !           715:        mflo    t8
        !           716:        mfhi    t2
        !           717:        b       norm_d
        !           718:
        !           719: /*
        !           720:  * Single precision divide.
        !           721:  */
        !           722: div_s:
        !           723:        jal     get_ft_fs_s
        !           724:        xor     t0, t0, ta0                     # compute sign of result
        !           725:        move    ta0, t0
        !           726:        bne     t1, SEXP_INF, 1f                # is FS an infinity?
        !           727:        bne     t2, zero, result_fs_s           # if FS is NAN, result is FS
        !           728:        bne     ta1, SEXP_INF, result_fs_s      # is FT an infinity?
        !           729:        bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
        !           730:        b       invalid_s                       # infinity/infinity is invalid
        !           731: 1:
        !           732:        bne     ta1, SEXP_INF, 1f               # is FT an infinity?
        !           733:        bne     ta2, zero, result_ft_s          # if FT is NAN, result is FT
        !           734:        move    t1, zero                        # x / infinity is zero
        !           735:        move    t2, zero
        !           736:        b       result_fs_s
        !           737: 1:
        !           738:        bne     t1, zero, 2f                    # is FS zero?
        !           739:        bne     t2, zero, 1f
        !           740:        bne     ta1, zero, result_fs_s          # FS=zero, is FT zero?
        !           741:        beq     ta2, zero, invalid_s            # 0 / 0
        !           742:        b       result_fs_s                     # result = zero
        !           743: 1:
        !           744:        jal     renorm_fs_s
        !           745:        b       3f
        !           746: 2:
        !           747:        subu    t1, t1, SEXP_BIAS               # unbias FS exponent
        !           748:        or      t2, t2, SIMPL_ONE               # set implied one bit
        !           749: 3:
        !           750:        bne     ta1, zero, 2f                   # is FT zero?
        !           751:        bne     ta2, zero, 1f
        !           752:        or      a1, a1, FPC_EXCEPTION_DIV0 | FPC_STICKY_DIV0
        !           753:        and     v0, a1, FPC_ENABLE_DIV0 # trap enabled?
        !           754:        bne     v0, zero, fpe_trap
        !           755:        ctc1    a1, FPC_CSR             # save exceptions
        !           756:        li      t1, SEXP_INF                    # result is infinity
        !           757:        move    t2, zero
        !           758:        b       result_fs_s
        !           759: 1:
        !           760:        jal     renorm_ft_s
        !           761:        b       3f
        !           762: 2:
        !           763:        subu    ta1, ta1, SEXP_BIAS             # unbias FT exponent
        !           764:        or      ta2, ta2, SIMPL_ONE             # set implied one bit
        !           765: 3:
        !           766:        subu    t1, t1, ta1                     # compute exponent
        !           767:        subu    t1, t1, 3                       # compensate for result position
        !           768:        li      v0, SFRAC_BITS+3                # number of bits to divide
        !           769:        move    t8, t2                          # init dividend
        !           770:        move    t2, zero                        # init result
        !           771: 1:
        !           772:        bltu    t8, ta2, 3f                     # is dividend >= divisor?
        !           773: 2:
        !           774:        subu    t8, t8, ta2                     # subtract divisor from dividend
        !           775:        or      t2, t2, 1                       # remember that we did
        !           776:        bne     t8, zero, 3f                    # if not done, continue
        !           777:        sll     t2, t2, v0                      # shift result to final position
        !           778:        b       norm_s
        !           779: 3:
        !           780:        sll     t8, t8, 1                       # shift dividend
        !           781:        sll     t2, t2, 1                       # shift result
        !           782:        subu    v0, v0, 1                       # are we done?
        !           783:        bne     v0, zero, 1b                    # no, continue
        !           784:        b       norm_s
        !           785:
        !           786: /*
        !           787:  * Double precision divide.
        !           788:  */
        !           789: div_d:
        !           790:        jal     get_ft_fs_d
        !           791:        xor     t0, t0, ta0                     # compute sign of result
        !           792:        move    ta0, t0
        !           793:        bne     t1, DEXP_INF, 1f                # is FS an infinity?
        !           794:        bne     t2, zero, result_fs_d           # if FS is NAN, result is FS
        !           795:        bne     ta1, DEXP_INF, result_fs_d      # is FT an infinity?
        !           796:        bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
        !           797:        b       invalid_d                       # infinity/infinity is invalid
        !           798: 1:
        !           799:        bne     ta1, DEXP_INF, 1f               # is FT an infinity?
        !           800:        bne     ta2, zero, result_ft_d          # if FT is NAN, result is FT
        !           801:        move    t1, zero                        # x / infinity is zero
        !           802:        move    t2, zero
        !           803:        b       result_fs_d
        !           804: 1:
        !           805:        bne     t1, zero, 2f                    # is FS zero?
        !           806:        bne     t2, zero, 1f
        !           807:        bne     ta1, zero, result_fs_d          # FS=zero, is FT zero?
        !           808:        beq     ta2, zero, invalid_d            # 0 / 0
        !           809:        b       result_fs_d                     # result = zero
        !           810: 1:
        !           811:        jal     renorm_fs_d
        !           812:        b       3f
        !           813: 2:
        !           814:        subu    t1, t1, DEXP_BIAS               # unbias FS exponent
        !           815:        or      t2, t2, DIMPL_ONE               # set implied one bit
        !           816: 3:
        !           817:        bne     ta1, zero, 2f                   # is FT zero?
        !           818:        bne     ta2, zero, 1f
        !           819:        or      a1, a1, FPC_EXCEPTION_DIV0 | FPC_STICKY_DIV0
        !           820:        and     v0, a1, FPC_ENABLE_DIV0 # trap enabled?
        !           821:        bne     v0, zero, fpe_trap
        !           822:        ctc1    a1, FPC_CSR                     # Save exceptions
        !           823:        li      t1, DEXP_INF                    # result is infinity
        !           824:        move    t2, zero
        !           825:        b       result_fs_d
        !           826: 1:
        !           827:        jal     renorm_ft_d
        !           828:        b       3f
        !           829: 2:
        !           830:        subu    ta1, ta1, DEXP_BIAS             # unbias FT exponent
        !           831:        or      ta2, ta2, DIMPL_ONE             # set implied one bit
        !           832: 3:
        !           833:        subu    t1, t1, ta1                     # compute exponent
        !           834:        subu    t1, t1, 3                       # compensate for result position
        !           835:        li      v0, DFRAC_BITS+3                # number of bits to divide
        !           836:        move    t8, t2                          # init dividend
        !           837:        move    t2, zero                        # init result
        !           838: 1:
        !           839:        bltu    t8, ta2, 3f                     # is dividend >= divisor?
        !           840: 2:
        !           841:        dsubu   t8, t8, ta2                     # subtract divisor from dividend
        !           842:        or      t2, t2, 1                       # remember that we did
        !           843:        bne     t8, zero, 3f                    # if not done, continue
        !           844:        dsll    t2, t2, v0                      # shift upper part
        !           845:        b       norm_d
        !           846: 3:
        !           847:        dsll    t8, t8, 1                       # shift dividend
        !           848:        dsll    t2, t2, 1                       # shift result
        !           849:        subu    v0, v0, 1                       # are we done?
        !           850:        bne     v0, zero, 1b                    # no, continue
        !           851:        b       norm_d
        !           852:
        !           853: /*
        !           854:  * Single precision absolute value.
        !           855:  */
        !           856: abs_s:
        !           857:        jal     get_fs_s
        !           858:        move    t0, zero                        # set sign positive
        !           859:        b       result_fs_s
        !           860:
        !           861: /*
        !           862:  * Double precision absolute value.
        !           863:  */
        !           864: abs_d:
        !           865:        jal     get_fs_d
        !           866:        move    t0, zero                        # set sign positive
        !           867:        b       result_fs_d
        !           868:
        !           869: /*
        !           870:  * Single precision move.
        !           871:  */
        !           872: mov_s:
        !           873:        jal     get_fs_s
        !           874:        b       result_fs_s
        !           875:
        !           876: /*
        !           877:  * Double precision move.
        !           878:  */
        !           879: mov_d:
        !           880:        jal     get_fs_d
        !           881:        b       result_fs_d
        !           882:
        !           883: /*
        !           884:  * Single precision negate.
        !           885:  */
        !           886: neg_s:
        !           887:        jal     get_fs_s
        !           888:        xor     t0, t0, 1                       # reverse sign
        !           889:        b       result_fs_s
        !           890:
        !           891: /*
        !           892:  * Double precision negate.
        !           893:  */
        !           894: neg_d:
        !           895:        jal     get_fs_d
        !           896:        xor     t0, t0, 1                       # reverse sign
        !           897:        b       result_fs_d
        !           898:
        !           899: /*
        !           900:  * Convert double to single.
        !           901:  */
        !           902: cvt_s_d:
        !           903:        jal     get_fs_d
        !           904:        bne     t1, DEXP_INF, 1f                # is FS an infinity?
        !           905:        li      t1, SEXP_INF                    # convert to single
        !           906:        dsll    t2, t2, 3                       # convert D fraction to S
        !           907:        b       result_fs_s
        !           908: 1:
        !           909:        bne     t1, zero, 2f                    # is FS zero?
        !           910:        beq     t2, zero, result_fs_s           # result=0
        !           911:        jal     renorm_fs_d
        !           912:        subu    t1, t1, 3                       # correct exp for shift below
        !           913:        b       3f
        !           914: 2:
        !           915:        subu    t1, t1, DEXP_BIAS               # unbias exponent
        !           916:        or      t2, t2, DIMPL_ONE               # add implied one bit
        !           917: 3:
        !           918:        dsll    t2, t2, 3                       # convert D fraction to S
        !           919:        b       norm_noshift_s
        !           920:
        !           921: /*
        !           922:  * Convert long integer to single.
        !           923:  */
        !           924: cvt_s_l:
        !           925:        jal     get_fs_long
        !           926:        b       cvt_s_int
        !           927: /*
        !           928:  * Convert integer to single.
        !           929:  */
        !           930: cvt_s_w:
        !           931:        jal     get_fs_int
        !           932: cvt_s_int:
        !           933:        bne     t2, zero, 1f                    # check for zero
        !           934:        move    t1, zero
        !           935:        b       result_fs_s
        !           936: /*
        !           937:  * Find out how many leading zero bits are in t2 and put in t9.
        !           938:  */
        !           939: 1:
        !           940:        move    v0, t2
        !           941:        move    t9, zero
        !           942:        dsrl    v1, v0, 32
        !           943:        bne     v1, zero, 1f
        !           944:        addu    t9, 32
        !           945:        dsll    v0, 32
        !           946: 1:
        !           947:        dsrl    v1, v0, 16
        !           948:        bne     v1, zero, 1f
        !           949:        addu    t9, 16
        !           950:        dsll    v0, 16
        !           951: 1:
        !           952:        dsrl    v1, v0, 24
        !           953:        bne     v1, zero, 1f
        !           954:        addu    t9, 8
        !           955:        dsll    v0, 8
        !           956: 1:
        !           957:        dsrl    v1, v0, 28
        !           958:        bne     v1, zero, 1f
        !           959:        addu    t9, 4
        !           960:        dsll    v0, 4
        !           961: 1:
        !           962:        dsrl    v1, v0, 30
        !           963:        bne     v1, zero, 1f
        !           964:        addu    t9, 2
        !           965:        dsll    v0, 2
        !           966: 1:
        !           967:        dsrl    v1, v0, 31
        !           968:        bne     v1, zero, 1f
        !           969:        addu    t9, 1
        !           970: /*
        !           971:  * Now shift t2 the correct number of bits.
        !           972:  */
        !           973: 1:
        !           974:        subu    t9, SLEAD_ZEROS                 # dont count leading zeros
        !           975:        li      t1, 23+32                       # init exponent
        !           976:        subu    t1, t1, t9                      # compute exponent
        !           977:        beq     t9, zero, 1f
        !           978:        li      v0, 32
        !           979:        blt     t9, zero, 2f                    # if shift < 0, shift right
        !           980:        subu    v0, v0, t9
        !           981:        sll     t2, t2, t9                      # shift left
        !           982: 1:
        !           983:        add     t1, t1, SEXP_BIAS               # bias exponent
        !           984:        and     t2, t2, ~SIMPL_ONE              # clear implied one bit
        !           985:        b       result_fs_s
        !           986: 2:
        !           987:        negu    t9                              # shift right by t9
        !           988:        subu    v0, v0, t9
        !           989:        sll     t8, t2, v0                      # save bits shifted out
        !           990:        srl     t2, t2, t9
        !           991:        b       norm_noshift_s
        !           992:
        !           993: /*
        !           994:  * Convert single to double.
        !           995:  */
        !           996: cvt_d_s:
        !           997:        jal     get_fs_s
        !           998:        dsll    t2, 32
        !           999:        bne     t1, SEXP_INF, 1f                # is FS an infinity?
        !          1000:        li      t1, DEXP_INF                    # convert to double
        !          1001:        b       result_fs_d
        !          1002: 1:
        !          1003:        bne     t1, zero, 2f                    # is FS denormalized or zero?
        !          1004:        beq     t2, zero, result_fs_d           # is FS zero?
        !          1005:        jal     renorm_fs_s
        !          1006:        move    t8, zero
        !          1007:        b       norm_d
        !          1008: 2:
        !          1009:        addu    t1, t1, DEXP_BIAS - SEXP_BIAS   # bias exponent correctly
        !          1010:        dsrl    t2, t2, 3
        !          1011:        b       result_fs_d
        !          1012:
        !          1013: /*
        !          1014:  * Convert long integer to double.
        !          1015:  */
        !          1016: cvt_d_l:
        !          1017:        jal     get_fs_long
        !          1018:        b       cvt_d_int
        !          1019: /*
        !          1020:  * Convert integer to double.
        !          1021:  */
        !          1022: cvt_d_w:
        !          1023:        jal     get_fs_int
        !          1024: cvt_d_int:
        !          1025:        bne     t2, zero, 1f                    # check for zero
        !          1026:        move    t1, zero                        # result=0
        !          1027:        b       result_fs_d
        !          1028: /*
        !          1029:  * Find out how many leading zero bits are in t2 and put in t9.
        !          1030:  */
        !          1031: 1:
        !          1032:        move    v0, t2
        !          1033:        move    t9, zero
        !          1034:        dsrl    v1, v0, 32
        !          1035:        bne     v1, zero, 1f
        !          1036:        addu    t9, 32
        !          1037:        dsll    v0, 32
        !          1038: 1:
        !          1039:        dsrl    v1, v0, 16
        !          1040:        bne     v1, zero, 1f
        !          1041:        addu    t9, 16
        !          1042:        dsll    v0, 16
        !          1043: 1:
        !          1044:        dsrl    v1, v0, 24
        !          1045:        bne     v1, zero, 1f
        !          1046:        addu    t9, 8
        !          1047:        dsll    v0, 8
        !          1048: 1:
        !          1049:        dsrl    v1, v0, 28
        !          1050:        bne     v1, zero, 1f
        !          1051:        addu    t9, 4
        !          1052:        dsll    v0, 4
        !          1053: 1:
        !          1054:        dsrl    v1, v0, 30
        !          1055:        bne     v1, zero, 1f
        !          1056:        addu    t9, 2
        !          1057:        dsll    v0, 2
        !          1058: 1:
        !          1059:        dsrl    v1, v0, 31
        !          1060:        bne     v1, zero, 1f
        !          1061:        addu    t9, 1
        !          1062: /*
        !          1063:  * Now shift t2 the correct number of bits.
        !          1064:  */
        !          1065: 1:
        !          1066:        subu    t9, t9, DLEAD_ZEROS             # dont count leading zeros
        !          1067:        li      t1, DEXP_BIAS + 20              # init exponent
        !          1068:        subu    t1, t1, t9                      # compute exponent
        !          1069:        beq     t9, zero, 1f
        !          1070:        li      v0, 64
        !          1071:        blt     t9, zero, 2f                    # if shift < 0, shift right
        !          1072:        subu    v0, v0, t9
        !          1073:        dsll    t2, t2, t9                      # shift left
        !          1074: 1:
        !          1075:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1076:        b       result_fs_d
        !          1077: 2:
        !          1078:        negu    t9                              # shift right by t9
        !          1079:        subu    v0, v0, t9
        !          1080:        dsrl    t2, t2, t9
        !          1081:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1082:        b       result_fs_d
        !          1083:
        !          1084: /*
        !          1085:  * Convert single to integer with specific rounding.
        !          1086:  */
        !          1087: round_w_s:
        !          1088:        li      t3, FPC_ROUND_RN
        !          1089:        b       do_cvt_w_s
        !          1090: trunc_w_s:
        !          1091:        li      t3, FPC_ROUND_RZ
        !          1092:        b       do_cvt_w_s
        !          1093: ceil_w_s:
        !          1094:        li      t3, FPC_ROUND_RP
        !          1095:        b       do_cvt_w_s
        !          1096: floor_w_s:
        !          1097:        li      t3, FPC_ROUND_RM
        !          1098:        b       do_cvt_w_s
        !          1099:
        !          1100: /*
        !          1101:  * Convert single to integer.
        !          1102:  */
        !          1103: cvt_w_s:
        !          1104:        and     t3, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1105: do_cvt_w_s:
        !          1106:        jal     get_fs_s
        !          1107:        bne     t1, SEXP_INF, 1f                # is FS an infinity?
        !          1108:        bne     t2, zero, invalid_w             # invalid conversion
        !          1109: 1:
        !          1110:        bne     t1, zero, 1f                    # is FS zero?
        !          1111:        beq     t2, zero, result_fs_w           # result is zero
        !          1112:        move    t2, zero                        # result is an inexact zero
        !          1113:        b       inexact_w
        !          1114: 1:
        !          1115:        subu    t1, t1, SEXP_BIAS               # unbias exponent
        !          1116:        or      t2, t2, SIMPL_ONE               # add implied one bit
        !          1117:        dsll    t2, t2, 32 - 3                  # convert S fraction to D
        !          1118:        b       cvt_w
        !          1119:
        !          1120: /*
        !          1121:  * Convert single to integer with specific rounding.
        !          1122:  */
        !          1123: round_w_d:
        !          1124:        li      t3, FPC_ROUND_RN
        !          1125:        b       do_cvt_w_d
        !          1126: trunc_w_d:
        !          1127:        li      t3, FPC_ROUND_RZ
        !          1128:        b       do_cvt_w_d
        !          1129: ceil_w_d:
        !          1130:        li      t3, FPC_ROUND_RP
        !          1131:        b       do_cvt_w_d
        !          1132: floor_w_d:
        !          1133:        li      t3, FPC_ROUND_RM
        !          1134:        b       do_cvt_w_d
        !          1135:
        !          1136: /*
        !          1137:  * Convert double to integer.
        !          1138:  */
        !          1139: cvt_w_d:
        !          1140:        and     t3, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1141: do_cvt_w_d:
        !          1142:        jal     get_fs_d
        !          1143:        bne     t1, DEXP_INF, 1f                # is FS an infinity?
        !          1144:        bne     t2, zero, invalid_w             # invalid conversion
        !          1145: 1:
        !          1146:        bne     t1, zero, 2f                    # is FS zero?
        !          1147:        beq     t2, zero, result_fs_w           # result is zero
        !          1148:        move    t2, zero                        # result is an inexact zero
        !          1149:        b       inexact_w
        !          1150: 2:
        !          1151:        subu    t1, t1, DEXP_BIAS               # unbias exponent
        !          1152:        or      t2, t2, DIMPL_ONE               # add implied one bit
        !          1153: cvt_w:
        !          1154:        blt     t1, WEXP_MIN, underflow_w       # is exponent too small?
        !          1155:        li      v0, WEXP_MAX+1
        !          1156:        bgt     t1, v0, overflow_w              # is exponent too large?
        !          1157:        bne     t1, v0, 1f                      # special check for INT_MIN
        !          1158:        beq     t0, zero, overflow_w            # if positive, overflow
        !          1159:        bne     t2, DIMPL_ONE, overflow_w
        !          1160:        li      t2, INT_MIN                     # result is INT_MIN
        !          1161:        b       result_fs_w
        !          1162: 1:
        !          1163:        subu    v0, t1, 20                      # compute amount to shift
        !          1164:        beq     v0, zero, 2f                    # is shift needed?
        !          1165:        li      v1, 64
        !          1166:        blt     v0, zero, 1f                    # if shift < 0, shift right
        !          1167:        subu    v1, v1, v0                      # shift left
        !          1168:        dsll    t2, t2, v0
        !          1169:        b       2f
        !          1170: 1:
        !          1171:        negu    v0                              # shift right by v0
        !          1172:        subu    v1, v1, v0
        !          1173:        dsll    t8, t2, v1                      # save bits shifted out
        !          1174:        sltu    t8, zero, t8                    # dont lose any ones
        !          1175:        dsrl    t2, t2, v0
        !          1176: /*
        !          1177:  * round (t0 is sign, t2:63-32 is integer part, t2:31-0 is fractional part).
        !          1178:  */
        !          1179: 2:
        !          1180:        beq     t3, FPC_ROUND_RN, 3f            # round to nearest
        !          1181:        beq     t3, FPC_ROUND_RZ, 5f            # round to zero (truncate)
        !          1182:        beq     t3, FPC_ROUND_RP, 1f            # round to +infinity
        !          1183:        beq     t0, zero, 5f                    # if sign is positive, truncate
        !          1184:        b       2f
        !          1185: 1:
        !          1186:        bne     t0, zero, 5f                    # if sign is negative, truncate
        !          1187: 2:
        !          1188:        daddu   t2, t2, GUARDBIT                # add in fractional
        !          1189:        blt     t2, zero, overflow_w            # overflow?
        !          1190:        b       5f
        !          1191: 3:
        !          1192:        daddu   t2, t2, GUARDBIT                # add in fractional
        !          1193:        blt     t2, zero, overflow_w            # overflow?
        !          1194: 4:
        !          1195:        bne     v0, zero, 5f                    # if rounded remainder is zero
        !          1196:        and     t2, 0xfffffffe00000000          #  clear LSB (round to nearest)
        !          1197: 5:
        !          1198:        beq     t0, zero, 1f                    # result positive?
        !          1199:        negu    t2                              # convert to negative integer
        !          1200: 1:
        !          1201:        dsll    v0, 32                          # save fraction
        !          1202:        dsrl    t2, 32                          # shift out fractional part
        !          1203:        beq     v0, zero, result_fs_w           # is result exact?
        !          1204: /*
        !          1205:  * Handle inexact exception.
        !          1206:  */
        !          1207: inexact_w:
        !          1208:        or      a1, a1, FPC_EXCEPTION_INEXACT | FPC_STICKY_INEXACT
        !          1209:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1210:        bne     v0, zero, fpe_trap
        !          1211:        ctc1    a1, FPC_CSR             # save exceptions
        !          1212:        b       result_fs_w
        !          1213:
        !          1214: /*
        !          1215:  * Conversions to integer which overflow will trap (if enabled),
        !          1216:  * or generate an inexact trap (if enabled),
        !          1217:  * or generate an invalid exception.
        !          1218:  */
        !          1219: overflow_w:
        !          1220:        or      a1, a1, FPC_EXCEPTION_OVERFLOW | FPC_STICKY_OVERFLOW
        !          1221:        and     v0, a1, FPC_ENABLE_OVERFLOW
        !          1222:        bne     v0, zero, fpe_trap
        !          1223:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1224:        bne     v0, zero, inexact_w             # inexact traps enabled?
        !          1225:        b       invalid_w
        !          1226:
        !          1227: /*
        !          1228:  * Conversions to integer which underflow will trap (if enabled),
        !          1229:  * or generate an inexact trap (if enabled),
        !          1230:  * or generate an invalid exception.
        !          1231:  */
        !          1232: underflow_w:
        !          1233:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1234:        and     v0, a1, FPC_ENABLE_UNDERFLOW
        !          1235:        bne     v0, zero, fpe_trap
        !          1236:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1237:        bne     v0, zero, inexact_w             # inexact traps enabled?
        !          1238:        b       invalid_w
        !          1239:
        !          1240: /*
        !          1241:  * Compare single.
        !          1242:  */
        !          1243: cmp_s:
        !          1244:        jal     get_cmp_s
        !          1245:        bne     t1, SEXP_INF, 1f                # is FS an infinity?
        !          1246:        bne     t2, zero, unordered             # FS is a NAN
        !          1247: 1:
        !          1248:        bne     ta1, SEXP_INF, 2f               # is FT an infinity?
        !          1249:        bne     ta2, zero, unordered            # FT is a NAN
        !          1250: 2:
        !          1251:        sll     t1, t1, 23                      # reassemble exp & frac
        !          1252:        or      t1, t1, t2
        !          1253:        sll     ta1, ta1, 23                    # reassemble exp & frac
        !          1254:        or      ta1, ta1, ta2
        !          1255:        beq     t0, zero, 1f                    # is FS positive?
        !          1256:        negu    t1
        !          1257: 1:
        !          1258:        beq     ta0, zero, 1f                   # is FT positive?
        !          1259:        negu    ta1
        !          1260: 1:
        !          1261:        li      v0, COND_LESS
        !          1262:        blt     t1, ta1, test_cond              # is FS < FT?
        !          1263:        li      v0, COND_EQUAL
        !          1264:        beq     t1, ta1, test_cond              # is FS == FT?
        !          1265:        move    v0, zero                        # FS > FT
        !          1266:        b       test_cond
        !          1267:
        !          1268: /*
        !          1269:  * Compare double.
        !          1270:  */
        !          1271: cmp_d:
        !          1272:        jal     get_cmp_d
        !          1273:        bne     t1, DEXP_INF, 1f                # is FS an infinity?
        !          1274:        bne     t2, zero, unordered             # FS is a NAN
        !          1275: 1:
        !          1276:        bne     ta1, DEXP_INF, 2f               # is FT an infinity?
        !          1277:        bne     ta2, zero, unordered            # FT is a NAN
        !          1278: 2:
        !          1279:        dsll    t1, t1, 52                      # reassemble exp & frac
        !          1280:        or      t1, t1, t2
        !          1281:        dsll    ta1, ta1, 52                    # reassemble exp & frac
        !          1282:        or      ta1, ta1, ta2
        !          1283:        beq     t0, zero, 1f                    # is FS positive?
        !          1284:        dnegu   t1                              # negate t1
        !          1285: 1:
        !          1286:        beq     ta0, zero, 1f                   # is FT positive?
        !          1287:        dnegu   ta1
        !          1288: 1:
        !          1289:        li      v0, COND_LESS
        !          1290:        blt     t1, ta1, test_cond              # is FS(MSW) < FT(MSW)?
        !          1291:        li      v0, COND_EQUAL
        !          1292:        beq     t1, ta1, test_cond              # is FS(LSW) == FT(LSW)?
        !          1293:        move    v0, zero                        # FS > FT
        !          1294: test_cond:
        !          1295:        and     v0, v0, a0                      # condition match instruction?
        !          1296: set_cond:
        !          1297:        bne     v0, zero, 1f
        !          1298:        and     a1, a1, ~FPC_COND_BIT   # clear condition bit
        !          1299:        b       2f
        !          1300: 1:
        !          1301:        or      a1, a1, FPC_COND_BIT    # set condition bit
        !          1302: 2:
        !          1303:        ctc1    a1, FPC_CSR             # save condition bit
        !          1304:        b       done
        !          1305:
        !          1306: unordered:
        !          1307:        and     v0, a0, COND_UNORDERED          # this cmp match unordered?
        !          1308:        bne     v0, zero, 1f
        !          1309:        and     a1, a1, ~FPC_COND_BIT   # clear condition bit
        !          1310:        b       2f
        !          1311: 1:
        !          1312:        or      a1, a1, FPC_COND_BIT    # set condition bit
        !          1313: 2:
        !          1314:        and     v0, a0, COND_SIGNAL
        !          1315:        beq     v0, zero, 1f                    # is this a signaling cmp?
        !          1316:        or      a1, a1, FPC_EXCEPTION_INVALID | FPC_STICKY_INVALID
        !          1317:        and     v0, a1, FPC_ENABLE_INVALID
        !          1318:        bne     v0, zero, fpe_trap
        !          1319: 1:
        !          1320:        ctc1    a1, FPC_CSR             # save condition bit
        !          1321:        b       done
        !          1322:
        !          1323: /*
        !          1324:  * Determine the amount to shift the fraction in order to restore the
        !          1325:  * normalized position. After that, round and handle exceptions.
        !          1326:  */
        !          1327: norm_s:
        !          1328:        move    v0, t2
        !          1329:        move    t9, zero                        # t9 = num of leading zeros
        !          1330:        bne     t2, zero, 1f
        !          1331:        move    v0, t8
        !          1332:        addu    t9, 32
        !          1333: 1:
        !          1334:        srl     v1, v0, 16
        !          1335:        bne     v1, zero, 1f
        !          1336:        addu    t9, 16
        !          1337:        sll     v0, 16
        !          1338: 1:
        !          1339:        srl     v1, v0, 24
        !          1340:        bne     v1, zero, 1f
        !          1341:        addu    t9, 8
        !          1342:        sll     v0, 8
        !          1343: 1:
        !          1344:        srl     v1, v0, 28
        !          1345:        bne     v1, zero, 1f
        !          1346:        addu    t9, 4
        !          1347:        sll     v0, 4
        !          1348: 1:
        !          1349:        srl     v1, v0, 30
        !          1350:        bne     v1, zero, 1f
        !          1351:        addu    t9, 2
        !          1352:        sll     v0, 2
        !          1353: 1:
        !          1354:        srl     v1, v0, 31
        !          1355:        bne     v1, zero, 1f
        !          1356:        addu    t9, 1
        !          1357: /*
        !          1358:  * Now shift t2,t8 the correct number of bits.
        !          1359:  */
        !          1360: 1:
        !          1361:        subu    t9, t9, SLEAD_ZEROS             # dont count leading zeros
        !          1362:        subu    t1, t1, t9                      # adjust the exponent
        !          1363:        beq     t9, zero, norm_noshift_s
        !          1364:        li      v1, 32
        !          1365:        blt     t9, zero, 1f                    # if shift < 0, shift right
        !          1366:        subu    v1, v1, t9
        !          1367:        sll     t2, t2, t9                      # shift t2,t8 left
        !          1368:        srl     v0, t8, v1                      # save bits shifted out
        !          1369:        or      t2, t2, v0
        !          1370:        sll     t8, t8, t9
        !          1371:        b       norm_noshift_s
        !          1372: 1:
        !          1373:        negu    t9                              # shift t2,t8 right by t9
        !          1374:        subu    v1, v1, t9
        !          1375:        sll     v0, t8, v1                      # save bits shifted out
        !          1376:        sltu    v0, zero, v0                    # be sure to save any one bits
        !          1377:        srl     t8, t8, t9
        !          1378:        or      t8, t8, v0
        !          1379:        sll     v0, t2, v1                      # save bits shifted out
        !          1380:        or      t8, t8, v0
        !          1381:        srl     t2, t2, t9
        !          1382: norm_noshift_s:
        !          1383:        move    ta1, t1                         # save unrounded exponent
        !          1384:        move    ta2, t2                         # save unrounded fraction
        !          1385:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1386:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1387:        beq     v0, FPC_ROUND_RZ, 5f    # round to zero (truncate)
        !          1388:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1389:        beq     t0, zero, 5f                    # if sign is positive, truncate
        !          1390:        b       2f
        !          1391: 1:
        !          1392:        bne     t0, zero, 5f                    # if sign is negative, truncate
        !          1393: 2:
        !          1394:        beq     t8, zero, 5f                    # if exact, continue
        !          1395:        addu    t2, t2, 1                       # add rounding bit
        !          1396:        bne     t2, SIMPL_ONE<<1, 5f            # need to adjust exponent?
        !          1397:        addu    t1, t1, 1                       # adjust exponent
        !          1398:        srl     t2, t2, 1                       # renormalize fraction
        !          1399:        b       5f
        !          1400: 3:
        !          1401:        li      v0, GUARDBIT                    # load guard bit for rounding
        !          1402:        addu    v0, v0, t8                      # add remainder
        !          1403:        sltu    v1, v0, t8                      # compute carry out
        !          1404:        beq     v1, zero, 4f                    # if no carry, continue
        !          1405:        addu    t2, t2, 1                       # add carry to result
        !          1406:        bne     t2, SIMPL_ONE<<1, 4f            # need to adjust exponent?
        !          1407:        addu    t1, t1, 1                       # adjust exponent
        !          1408:        srl     t2, t2, 1                       # renormalize fraction
        !          1409: 4:
        !          1410:        bne     v0, zero, 5f                    # if rounded remainder is zero
        !          1411:        and     t2, t2, ~1                      #  clear LSB (round to nearest)
        !          1412: 5:
        !          1413:        bgt     t1, SEXP_MAX, overflow_s        # overflow?
        !          1414:        blt     t1, SEXP_MIN, underflow_s       # underflow?
        !          1415:        bne     t8, zero, inexact_s             # is result inexact?
        !          1416:        addu    t1, t1, SEXP_BIAS               # bias exponent
        !          1417:        and     t2, t2, ~SIMPL_ONE              # clear implied one bit
        !          1418:        b       result_fs_s
        !          1419:
        !          1420: /*
        !          1421:  * Handle inexact exception.
        !          1422:  */
        !          1423: inexact_s:
        !          1424:        addu    t1, t1, SEXP_BIAS               # bias exponent
        !          1425:        and     t2, t2, ~SIMPL_ONE              # clear implied one bit
        !          1426: inexact_nobias_s:
        !          1427:        jal     set_fd_s                        # save result
        !          1428:        or      a1, a1, FPC_EXCEPTION_INEXACT | FPC_STICKY_INEXACT
        !          1429:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1430:        bne     v0, zero, fpe_trap
        !          1431:        ctc1    a1, FPC_CSR             # save exceptions
        !          1432:        b       done
        !          1433:
        !          1434: /*
        !          1435:  * Overflow will trap (if enabled),
        !          1436:  * or generate an inexact trap (if enabled),
        !          1437:  * or generate an infinity.
        !          1438:  */
        !          1439: overflow_s:
        !          1440:        or      a1, a1, FPC_EXCEPTION_OVERFLOW | FPC_STICKY_OVERFLOW
        !          1441:        and     v0, a1, FPC_ENABLE_OVERFLOW
        !          1442:        beq     v0, zero, 1f
        !          1443:        subu    t1, t1, 192                     # bias exponent
        !          1444:        and     t2, t2, ~SIMPL_ONE              # clear implied one bit
        !          1445:        jal     set_fd_s                        # save result
        !          1446:        b       fpe_trap
        !          1447: 1:
        !          1448:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1449:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1450:        beq     v0, FPC_ROUND_RZ, 1f    # round to zero (truncate)
        !          1451:        beq     v0, FPC_ROUND_RP, 2f    # round to +infinity
        !          1452:        bne     t0, zero, 3f
        !          1453: 1:
        !          1454:        li      t1, SEXP_MAX                    # result is max finite
        !          1455:        li      t2, 0x007fffff
        !          1456:        b       inexact_s
        !          1457: 2:
        !          1458:        bne     t0, zero, 1b
        !          1459: 3:
        !          1460:        li      t1, SEXP_MAX + 1                # result is infinity
        !          1461:        move    t2, zero
        !          1462:        b       inexact_s
        !          1463:
        !          1464: /*
        !          1465:  * In this implementation, "tininess" is detected "after rounding" and
        !          1466:  * "loss of accuracy" is detected as "an inexact result".
        !          1467:  */
        !          1468: underflow_s:
        !          1469:        and     v0, a1, FPC_ENABLE_UNDERFLOW
        !          1470:        beq     v0, zero, 1f
        !          1471: /*
        !          1472:  * Underflow is enabled so compute the result and trap.
        !          1473:  */
        !          1474:        addu    t1, t1, 192                     # bias exponent
        !          1475:        and     t2, t2, ~SIMPL_ONE              # clear implied one bit
        !          1476:        jal     set_fd_s                        # save result
        !          1477:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1478:        b       fpe_trap
        !          1479: /*
        !          1480:  * Underflow is not enabled so compute the result,
        !          1481:  * signal inexact result (if it is) and trap (if enabled).
        !          1482:  */
        !          1483: 1:
        !          1484:        move    t1, ta1                         # get unrounded exponent
        !          1485:        move    t2, ta2                         # get unrounded fraction
        !          1486:        li      t9, SEXP_MIN                    # compute shift amount
        !          1487:        subu    t9, t9, t1                      # shift t2,t8 right by t9
        !          1488:        blt     t9, SFRAC_BITS+2, 3f            # shift all the bits out?
        !          1489:        move    t1, zero                        # result is inexact zero
        !          1490:        move    t2, zero
        !          1491:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1492: /*
        !          1493:  * Now round the zero result.
        !          1494:  * Only need to worry about rounding to +- infinity when the sign matches.
        !          1495:  */
        !          1496:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1497:        beq     v0, FPC_ROUND_RN, inexact_nobias_s      # round to nearest
        !          1498:        beq     v0, FPC_ROUND_RZ, inexact_nobias_s      # round to zero
        !          1499:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1500:        beq     t0, zero, inexact_nobias_s      # if sign is positive, truncate
        !          1501:        b       2f
        !          1502: 1:
        !          1503:        bne     t0, zero, inexact_nobias_s      # if sign is negative, truncate
        !          1504: 2:
        !          1505:        addu    t2, t2, 1                       # add rounding bit
        !          1506:        b       inexact_nobias_s
        !          1507: 3:
        !          1508:        li      v1, 32
        !          1509:        subu    v1, v1, t9
        !          1510:        sltu    v0, zero, t8                    # be sure to save any one bits
        !          1511:        sll     t8, t2, v1                      # save bits shifted out
        !          1512:        or      t8, t8, v0                      # include sticky bits
        !          1513:        srl     t2, t2, t9
        !          1514: /*
        !          1515:  * Now round the denormalized result.
        !          1516:  */
        !          1517:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1518:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1519:        beq     v0, FPC_ROUND_RZ, 5f    # round to zero (truncate)
        !          1520:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1521:        beq     t0, zero, 5f                    # if sign is positive, truncate
        !          1522:        b       2f
        !          1523: 1:
        !          1524:        bne     t0, zero, 5f                    # if sign is negative, truncate
        !          1525: 2:
        !          1526:        beq     t8, zero, 5f                    # if exact, continue
        !          1527:        addu    t2, t2, 1                       # add rounding bit
        !          1528:        b       5f
        !          1529: 3:
        !          1530:        li      v0, GUARDBIT                    # load guard bit for rounding
        !          1531:        addu    v0, v0, t8                      # add remainder
        !          1532:        sltu    v1, v0, t8                      # compute carry out
        !          1533:        beq     v1, zero, 4f                    # if no carry, continue
        !          1534:        addu    t2, t2, 1                       # add carry to result
        !          1535: 4:
        !          1536:        bne     v0, zero, 5f                    # if rounded remainder is zero
        !          1537:        and     t2, t2, ~1                      #  clear LSB (round to nearest)
        !          1538: 5:
        !          1539:        move    t1, zero                        # denorm or zero exponent
        !          1540:        jal     set_fd_s                        # save result
        !          1541:        beq     t8, zero, done                  # check for exact result
        !          1542:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1543:        or      a1, a1, FPC_EXCEPTION_INEXACT | FPC_STICKY_INEXACT
        !          1544:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1545:        bne     v0, zero, fpe_trap
        !          1546:        ctc1    a1, FPC_CSR             # save exceptions
        !          1547:        b       done
        !          1548:
        !          1549: /*
        !          1550:  * Determine the amount to shift the fraction in order to restore the
        !          1551:  * normalized position. After that, round and handle exceptions.
        !          1552:  */
        !          1553: norm_d:
        !          1554:        move    v0, t2
        !          1555:        move    t9, zero                        # t9 = num of leading zeros
        !          1556:        dsrl    v1, v0, 32
        !          1557:        bne     v1, zero, 1f
        !          1558:        addu    t9, 32
        !          1559:        dsll    v0, 32
        !          1560: 1:
        !          1561:        dsrl    v1, v0, 16
        !          1562:        bne     v1, zero, 1f
        !          1563:        addu    t9, 16
        !          1564:        dsll    v0, 16
        !          1565: 1:
        !          1566:        dsrl    v1, v0, 24
        !          1567:        bne     v1, zero, 1f
        !          1568:        addu    t9, 8
        !          1569:        dsll    v0, 8
        !          1570: 1:
        !          1571:        dsrl    v1, v0, 28
        !          1572:        bne     v1, zero, 1f
        !          1573:        addu    t9, 4
        !          1574:        dsll    v0, 4
        !          1575: 1:
        !          1576:        dsrl    v1, v0, 30
        !          1577:        bne     v1, zero, 1f
        !          1578:        addu    t9, 2
        !          1579:        dsll    v0, 2
        !          1580: 1:
        !          1581:        dsrl    v1, v0, 31
        !          1582:        bne     v1, zero, 1f
        !          1583:        addu    t9, 1
        !          1584: /*
        !          1585:  * Now shift t2,t8 the correct number of bits.
        !          1586:  */
        !          1587: 1:
        !          1588:        subu    t9, t9, DLEAD_ZEROS             # dont count leading zeros
        !          1589:        subu    t1, t1, t9                      # adjust the exponent
        !          1590:        beq     t9, zero, norm_noshift_d
        !          1591:        li      v1, 64
        !          1592:        blt     t9, zero, 2f                    # if shift < 0, shift right
        !          1593:        subu    v1, v1, t9
        !          1594:        dsll    t2, t2, t9                      # shift left by t9
        !          1595:        dsrl    v0, t8, v1                      # save bits shifted out
        !          1596:        or      t2, t2, v0
        !          1597:        dsll    t8, t8, t9
        !          1598:        b       norm_noshift_d
        !          1599: 2:
        !          1600:        negu    t9                              # shift right by t9
        !          1601:        subu    v1, v1, t9                      #  (known to be < 32 bits)
        !          1602:        dsll    v0, t8, v1                      # save bits shifted out
        !          1603:        sltu    v0, zero, v0                    # be sure to save any one bits
        !          1604:        dsrl    t8, t8, t9
        !          1605:        or      t8, t8, v0
        !          1606:        dsll    v0, t2, v1                      # save bits shifted out
        !          1607:        or      t8, t8, v0
        !          1608:        dsrl    t2, t2, t9
        !          1609: norm_noshift_d:
        !          1610:        move    ta1, t1                         # save unrounded exponent
        !          1611:        move    ta2, t2                         # save unrounded fraction (MS)
        !          1612:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1613:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1614:        beq     v0, FPC_ROUND_RZ, 5f    # round to zero (truncate)
        !          1615:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1616:        beq     t0, zero, 5f                    # if sign is positive, truncate
        !          1617:        b       2f
        !          1618: 1:
        !          1619:        bne     t0, zero, 5f                    # if sign is negative, truncate
        !          1620: 2:
        !          1621:        beq     t8, zero, 5f                    # if exact, continue
        !          1622:        daddu   t2, t2, 1                       # add rounding bit
        !          1623:        bne     t2, DIMPL_ONE<<1, 5f            # need to adjust exponent?
        !          1624:        addu    t1, t1, 1                       # adjust exponent
        !          1625:        dsrl    t2, t2, 1                       # renormalize fraction
        !          1626:        b       5f
        !          1627: 3:
        !          1628:        dli     v0, DGUARDBIT                   # load guard bit for rounding
        !          1629:        addu    v0, v0, t8                      # add remainder
        !          1630:        sltu    v1, v0, t8                      # compute carry out
        !          1631:        beq     v1, zero, 4f                    # branch if no carry
        !          1632:        daddu   t2, t2, 1                       # add carry to result
        !          1633:        bne     t2, DIMPL_ONE<<1, 4f            # need to adjust exponent?
        !          1634:        addu    t1, t1, 1                       # adjust exponent
        !          1635:        srl     t2, t2, 1                       # renormalize fraction
        !          1636: 4:
        !          1637:        bne     v0, zero, 5f                    # if rounded remainder is zero
        !          1638:        and     t2, t2, ~1                      #  clear LSB (round to nearest)
        !          1639: 5:
        !          1640:        bgt     t1, DEXP_MAX, overflow_d        # overflow?
        !          1641:        blt     t1, DEXP_MIN, underflow_d       # underflow?
        !          1642:        bne     t8, zero, inexact_d             # is result inexact?
        !          1643:        addu    t1, t1, DEXP_BIAS               # bias exponent
        !          1644:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1645:        b       result_fs_d
        !          1646:
        !          1647: /*
        !          1648:  * Handle inexact exception.
        !          1649:  */
        !          1650: inexact_d:
        !          1651:        addu    t1, t1, DEXP_BIAS               # bias exponent
        !          1652:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1653: inexact_nobias_d:
        !          1654:        jal     set_fd_d                        # save result
        !          1655:        or      a1, a1, FPC_EXCEPTION_INEXACT | FPC_STICKY_INEXACT
        !          1656:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1657:        bne     v0, zero, fpe_trap
        !          1658:        ctc1    a1, FPC_CSR             # save exceptions
        !          1659:        b       done
        !          1660:
        !          1661: /*
        !          1662:  * Overflow will trap (if enabled),
        !          1663:  * or generate an inexact trap (if enabled),
        !          1664:  * or generate an infinity.
        !          1665:  */
        !          1666: overflow_d:
        !          1667:        or      a1, a1, FPC_EXCEPTION_OVERFLOW | FPC_STICKY_OVERFLOW
        !          1668:        and     v0, a1, FPC_ENABLE_OVERFLOW
        !          1669:        beq     v0, zero, 1f
        !          1670:        subu    t1, t1, 1536                    # bias exponent
        !          1671:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1672:        jal     set_fd_d                        # save result
        !          1673:        b       fpe_trap
        !          1674: 1:
        !          1675:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1676:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1677:        beq     v0, FPC_ROUND_RZ, 1f    # round to zero (truncate)
        !          1678:        beq     v0, FPC_ROUND_RP, 2f    # round to +infinity
        !          1679:        bne     t0, zero, 3f
        !          1680: 1:
        !          1681:        li      t1, DEXP_MAX                    # result is max finite
        !          1682:        dli     t2, 0x000fffffffffffff
        !          1683:        b       inexact_d
        !          1684: 2:
        !          1685:        bne     t0, zero, 1b
        !          1686: 3:
        !          1687:        li      t1, DEXP_MAX + 1                # result is infinity
        !          1688:        move    t2, zero
        !          1689:        b       inexact_d
        !          1690:
        !          1691: /*
        !          1692:  * In this implementation, "tininess" is detected "after rounding" and
        !          1693:  * "loss of accuracy" is detected as "an inexact result".
        !          1694:  */
        !          1695: underflow_d:
        !          1696:        and     v0, a1, FPC_ENABLE_UNDERFLOW
        !          1697:        beq     v0, zero, 1f
        !          1698: /*
        !          1699:  * Underflow is enabled so compute the result and trap.
        !          1700:  */
        !          1701:        addu    t1, t1, 1536                    # bias exponent
        !          1702:        and     t2, t2, ~DIMPL_ONE              # clear implied one bit
        !          1703:        jal     set_fd_d                        # save result
        !          1704:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1705:        b       fpe_trap
        !          1706: /*
        !          1707:  * Underflow is not enabled so compute the result,
        !          1708:  * signal inexact result (if it is) and trap (if enabled).
        !          1709:  */
        !          1710: 1:
        !          1711:        move    t1, ta1                         # get unrounded exponent
        !          1712:        move    t2, ta2                         # get unrounded fraction (MS)
        !          1713:        li      t9, DEXP_MIN                    # compute shift amount
        !          1714:        subu    t9, t9, t1                      # shift t2,t8 right by t9
        !          1715:        blt     t9, DFRAC_BITS+2, 3f            # shift all the bits out?
        !          1716:        move    t1, zero                        # result is inexact zero
        !          1717:        move    t2, zero
        !          1718:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1719: /*
        !          1720:  * Now round the zero result.
        !          1721:  * Only need to worry about rounding to +- infinity when the sign matches.
        !          1722:  */
        !          1723:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1724:        beq     v0, FPC_ROUND_RN, inexact_nobias_d      # round to nearest
        !          1725:        beq     v0, FPC_ROUND_RZ, inexact_nobias_d      # round to zero
        !          1726:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1727:        beq     t0, zero, inexact_nobias_d      # if sign is positive, truncate
        !          1728:        b       2f
        !          1729: 1:
        !          1730:        bne     t0, zero, inexact_nobias_d      # if sign is negative, truncate
        !          1731: 2:
        !          1732:        daddu   t2, t2, 1                       # add rounding bit
        !          1733:        b       inexact_nobias_d
        !          1734: 3:
        !          1735:        li      v1, 64
        !          1736:        subu    v1, v1, t9
        !          1737:        sltu    v0, zero, t8                    # be sure to save any one bits
        !          1738:        dsll    t8, t2, v1                      # save bits shifted out
        !          1739:        or      t8, t8, v0                      # include sticky bits
        !          1740:        dsrl    t2, t2, t9
        !          1741: /*
        !          1742:  * Now round the denormalized result.
        !          1743:  */
        !          1744:        and     v0, a1, FPC_ROUNDING_BITS       # get rounding mode
        !          1745:        beq     v0, FPC_ROUND_RN, 3f    # round to nearest
        !          1746:        beq     v0, FPC_ROUND_RZ, 5f    # round to zero (truncate)
        !          1747:        beq     v0, FPC_ROUND_RP, 1f    # round to +infinity
        !          1748:        beq     t0, zero, 5f                    # if sign is positive, truncate
        !          1749:        b       2f
        !          1750: 1:
        !          1751:        bne     t0, zero, 5f                    # if sign is negative, truncate
        !          1752: 2:
        !          1753:        beq     t8, zero, 5f                    # if exact, continue
        !          1754:        daddu   t2, t2, 1                       # add rounding bit
        !          1755:        b       5f
        !          1756: 3:
        !          1757:        dli     v0, DGUARDBIT                   # load guard bit for rounding
        !          1758:        daddu   v0, v0, t8                      # add remainder
        !          1759:        sltu    v1, v0, t8                      # compute carry out
        !          1760:        beq     v1, zero, 4f                    # if no carry, continue
        !          1761:        daddu   t2, t2, 1                       # add carry
        !          1762: 4:
        !          1763:        bne     v0, zero, 5f                    # if rounded remainder is zero
        !          1764:        and     t2, t2, ~1                      #  clear LSB (round to nearest)
        !          1765: 5:
        !          1766:        move    t1, zero                        # denorm or zero exponent
        !          1767:        jal     set_fd_d                        # save result
        !          1768:        beq     t8, zero, done                  # check for exact result
        !          1769:        or      a1, a1, FPC_EXCEPTION_UNDERFLOW | FPC_STICKY_UNDERFLOW
        !          1770:        or      a1, a1, FPC_EXCEPTION_INEXACT | FPC_STICKY_INEXACT
        !          1771:        and     v0, a1, FPC_ENABLE_INEXACT
        !          1772:        bne     v0, zero, fpe_trap
        !          1773:        ctc1    a1, FPC_CSR             # save exceptions
        !          1774:        b       done
        !          1775:
        !          1776: /*
        !          1777:  * Signal an invalid operation if the trap is enabled; otherwise,
        !          1778:  * the result is a quiet NAN.
        !          1779:  */
        !          1780: invalid_s:                                     # trap invalid operation
        !          1781:        or      a1, a1, FPC_EXCEPTION_INVALID | FPC_STICKY_INVALID
        !          1782:        and     v0, a1, FPC_ENABLE_INVALID
        !          1783:        bne     v0, zero, fpe_trap
        !          1784:        ctc1    a1, FPC_CSR             # save exceptions
        !          1785:        move    t0, zero                        # result is a quiet NAN
        !          1786:        li      t1, SEXP_INF
        !          1787:        li      t2, SQUIET_NAN
        !          1788:        jal     set_fd_s                        # save result (in t0,t1,t2)
        !          1789:        b       done
        !          1790:
        !          1791: /*
        !          1792:  * Signal an invalid operation if the trap is enabled; otherwise,
        !          1793:  * the result is a quiet NAN.
        !          1794:  */
        !          1795: invalid_d:                                     # trap invalid operation
        !          1796:        or      a1, a1, FPC_EXCEPTION_INVALID | FPC_STICKY_INVALID
        !          1797:        and     v0, a1, FPC_ENABLE_INVALID
        !          1798:        bne     v0, zero, fpe_trap
        !          1799:        ctc1    a1, FPC_CSR             # save exceptions
        !          1800:        move    t0, zero                        # result is a quiet NAN
        !          1801:        li      t1, DEXP_INF
        !          1802:        dli     t2, DQUIET_NAN
        !          1803:        jal     set_fd_d                        # save result (in t0,t1,t2)
        !          1804:        b       done
        !          1805:
        !          1806: /*
        !          1807:  * Signal an invalid operation if the trap is enabled; otherwise,
        !          1808:  * the result is INT_MAX or INT_MIN.
        !          1809:  */
        !          1810: invalid_w:                                     # trap invalid operation
        !          1811:        or      a1, a1, FPC_EXCEPTION_INVALID | FPC_STICKY_INVALID
        !          1812:        and     v0, a1, FPC_ENABLE_INVALID
        !          1813:        bne     v0, zero, fpe_trap
        !          1814:        ctc1    a1, FPC_CSR                     # save exceptions
        !          1815:        bne     t0, zero, 1f
        !          1816:        li      t2, INT_MAX                     # result is INT_MAX
        !          1817:        b       result_fs_w
        !          1818: 1:
        !          1819:        li      t2, INT_MIN                     # result is INT_MIN
        !          1820:        b       result_fs_w
        !          1821:
        !          1822: /*
        !          1823:  * Trap if the hardware should have handled this case.
        !          1824:  */
        !          1825: fpe_trap:
        !          1826:        move    a2, a1                          # code = FP CSR
        !          1827:        ctc1    a1, FPC_CSR                     # save exceptions
        !          1828:        li      v0, 1
        !          1829:        b       done_err
        !          1830:
        !          1831: /*
        !          1832:  * Send an illegal instruction signal to the current process.
        !          1833:  */
        !          1834: ill:
        !          1835:        ctc1    a1, FPC_CSR                     # save exceptions
        !          1836:        move    a2, a0                          # code = FP instruction
        !          1837:        li      v0, 1
        !          1838:        b       done_err
        !          1839:
        !          1840: result_ft_s:
        !          1841:        move    t0, ta0                         # result is FT
        !          1842:        move    t1, ta1
        !          1843:        move    t2, ta2
        !          1844: result_fs_s:                                   # result is FS
        !          1845:        jal     set_fd_s                        # save result (in t0,t1,t2)
        !          1846:        b       done
        !          1847:
        !          1848: result_fs_w:
        !          1849:        jal     set_fd_word                     # save result (in t2)
        !          1850:        b       done
        !          1851:
        !          1852: result_ft_d:
        !          1853:        move    t0, ta0                         # result is FT
        !          1854:        move    t1, ta1
        !          1855:        move    t2, ta2
        !          1856: result_fs_d:                                   # result is FS
        !          1857:        jal     set_fd_d                        # save result (in t0,t1,t2)
        !          1858:
        !          1859: done:
        !          1860:        li      v0, 0
        !          1861: done_err:
        !          1862:        PTR_L   ra, CF_RA_OFFS(sp)
        !          1863:        PTR_ADD sp, sp, FRAMESZ(CF_SZ)
        !          1864:        j       ra
        !          1865: END(MipsEmulateFP)
        !          1866:
        !          1867: /*----------------------------------------------------------------------------
        !          1868:  * get_fs_int --
        !          1869:  *
        !          1870:  *     Read (integer) the FS register (bits 15-11).
        !          1871:  *     This is an internal routine used by MipsEmulateFP only.
        !          1872:  *
        !          1873:  * Results:
        !          1874:  *     t0      contains the sign
        !          1875:  *     t2      contains the fraction
        !          1876:  *
        !          1877:  *----------------------------------------------------------------------------
        !          1878:  */
        !          1879: #define GET_FS_INT(n) \
        !          1880:        .rdata;                         \
        !          1881:        .dword  get_fs_int_/**/n;       \
        !          1882:        .text;                          \
        !          1883: get_fs_int_/**/n:                      \
        !          1884:        mfc1    t2, $/**/n;             \
        !          1885:        b       get_fs_int_done
        !          1886:
        !          1887: LEAF(get_fs_int, 0)
        !          1888:        srl     a3, a0, 11 - 3                  # get FS field
        !          1889:        and     a3, a3, 0x1f << 3               # mask FS field
        !          1890:        ld      a3, get_fs_int_tbl(a3)          # switch on register number
        !          1891:        j       a3
        !          1892:
        !          1893:        .rdata
        !          1894: get_fs_int_tbl:
        !          1895:        .text
        !          1896:
        !          1897:        GET_FS_INT(f0)
        !          1898:        GET_FS_INT(f1)
        !          1899:        GET_FS_INT(f2)
        !          1900:        GET_FS_INT(f3)
        !          1901:        GET_FS_INT(f4)
        !          1902:        GET_FS_INT(f5)
        !          1903:        GET_FS_INT(f6)
        !          1904:        GET_FS_INT(f7)
        !          1905:        GET_FS_INT(f8)
        !          1906:        GET_FS_INT(f9)
        !          1907:        GET_FS_INT(f10)
        !          1908:        GET_FS_INT(f11)
        !          1909:        GET_FS_INT(f12)
        !          1910:        GET_FS_INT(f13)
        !          1911:        GET_FS_INT(f14)
        !          1912:        GET_FS_INT(f15)
        !          1913:        GET_FS_INT(f16)
        !          1914:        GET_FS_INT(f17)
        !          1915:        GET_FS_INT(f18)
        !          1916:        GET_FS_INT(f19)
        !          1917:        GET_FS_INT(f20)
        !          1918:        GET_FS_INT(f21)
        !          1919:        GET_FS_INT(f22)
        !          1920:        GET_FS_INT(f23)
        !          1921:        GET_FS_INT(f24)
        !          1922:        GET_FS_INT(f25)
        !          1923:        GET_FS_INT(f26)
        !          1924:        GET_FS_INT(f27)
        !          1925:        GET_FS_INT(f28)
        !          1926:        GET_FS_INT(f29)
        !          1927:        GET_FS_INT(f30)
        !          1928:        GET_FS_INT(f31)
        !          1929:
        !          1930: get_fs_int_done:
        !          1931:        srl     t0, t2, 31              # init the sign bit
        !          1932:        bge     t2, zero, 1f
        !          1933:        negu    t2
        !          1934:        dsll    t2, 33
        !          1935:        dsrl    t2, 33
        !          1936: 1:
        !          1937:        j       ra
        !          1938: END(get_fs_int)
        !          1939:
        !          1940: /*----------------------------------------------------------------------------
        !          1941:  * get_fs_long --
        !          1942:  *
        !          1943:  *     Read (long integer) the FS register (bits 15-11).
        !          1944:  *     This is an internal routine used by MipsEmulateFP only.
        !          1945:  *
        !          1946:  * Results:
        !          1947:  *     t0      contains the sign
        !          1948:  *     t2      contains the fraction
        !          1949:  *
        !          1950:  *----------------------------------------------------------------------------
        !          1951:  */
        !          1952: #define GET_FS_LONG(n) \
        !          1953:        .rdata;                         \
        !          1954:        .dword  get_fs_long_/**/n;      \
        !          1955:        .text;                          \
        !          1956: get_fs_long_/**/n:                     \
        !          1957:        dmfc1   t2, $/**/n;             \
        !          1958:        b       get_fs_long_done
        !          1959:
        !          1960: LEAF(get_fs_long, 0)
        !          1961:        srl     a3, a0, 11 - 3                  # get FS field
        !          1962:        and     a3, a3, 0x1f << 3               # mask FS field
        !          1963:        ld      a3, get_fs_long_tbl(a3)         # switch on register number
        !          1964:        j       a3
        !          1965:
        !          1966:        .rdata
        !          1967: get_fs_long_tbl:
        !          1968:        .text
        !          1969:
        !          1970:        GET_FS_LONG(f0)
        !          1971:        GET_FS_LONG(f1)
        !          1972:        GET_FS_LONG(f2)
        !          1973:        GET_FS_LONG(f3)
        !          1974:        GET_FS_LONG(f4)
        !          1975:        GET_FS_LONG(f5)
        !          1976:        GET_FS_LONG(f6)
        !          1977:        GET_FS_LONG(f7)
        !          1978:        GET_FS_LONG(f8)
        !          1979:        GET_FS_LONG(f9)
        !          1980:        GET_FS_LONG(f10)
        !          1981:        GET_FS_LONG(f11)
        !          1982:        GET_FS_LONG(f12)
        !          1983:        GET_FS_LONG(f13)
        !          1984:        GET_FS_LONG(f14)
        !          1985:        GET_FS_LONG(f15)
        !          1986:        GET_FS_LONG(f16)
        !          1987:        GET_FS_LONG(f17)
        !          1988:        GET_FS_LONG(f18)
        !          1989:        GET_FS_LONG(f19)
        !          1990:        GET_FS_LONG(f20)
        !          1991:        GET_FS_LONG(f21)
        !          1992:        GET_FS_LONG(f22)
        !          1993:        GET_FS_LONG(f23)
        !          1994:        GET_FS_LONG(f24)
        !          1995:        GET_FS_LONG(f25)
        !          1996:        GET_FS_LONG(f26)
        !          1997:        GET_FS_LONG(f27)
        !          1998:        GET_FS_LONG(f28)
        !          1999:        GET_FS_LONG(f29)
        !          2000:        GET_FS_LONG(f30)
        !          2001:        GET_FS_LONG(f31)
        !          2002:
        !          2003: get_fs_long_done:
        !          2004:        dsrl    t0, t2, 63              # init the sign bit
        !          2005:        bge     t2, zero, 1f
        !          2006:        dnegu   t2
        !          2007: 1:
        !          2008:        j       ra
        !          2009: END(get_fs_long)
        !          2010:
        !          2011: /*----------------------------------------------------------------------------
        !          2012:  * get_ft_fs_s --
        !          2013:  *
        !          2014:  *     Read (single precision) the FT register (bits 20-16) and
        !          2015:  *     the FS register (bits 15-11) and break up into fields.
        !          2016:  *     This is an internal routine used by MipsEmulateFP only.
        !          2017:  *
        !          2018:  * Results:
        !          2019:  *     t0      contains the FS sign
        !          2020:  *     t1      contains the FS (biased) exponent
        !          2021:  *     t2      contains the FS fraction
        !          2022:  *     ta0     contains the FT sign
        !          2023:  *     ta1     contains the FT (biased) exponent
        !          2024:  *     ta2     contains the FT fraction
        !          2025:  *
        !          2026:  *----------------------------------------------------------------------------
        !          2027:  */
        !          2028: #define GET_FT_S(n) \
        !          2029:        .rdata;                         \
        !          2030:        .dword  get_ft_s_/**/n;         \
        !          2031:        .text;                          \
        !          2032: get_ft_s_/**/n:                                \
        !          2033:        mfc1    ta0, $/**/n;            \
        !          2034:        b       get_ft_s_done
        !          2035:
        !          2036: LEAF(get_ft_fs_s, 0)
        !          2037:        srl     a3, a0, 16 - 3                  # get FT field
        !          2038:        and     a3, a3, 0x1f << 3               # mask FT field
        !          2039:        ld      a3, get_ft_s_tbl(a3)            # switch on register number
        !          2040:        j       a3
        !          2041:
        !          2042:        .rdata
        !          2043: get_ft_s_tbl:
        !          2044:        .text
        !          2045:
        !          2046:        GET_FT_S(f0)
        !          2047:        GET_FT_S(f1)
        !          2048:        GET_FT_S(f2)
        !          2049:        GET_FT_S(f3)
        !          2050:        GET_FT_S(f4)
        !          2051:        GET_FT_S(f5)
        !          2052:        GET_FT_S(f6)
        !          2053:        GET_FT_S(f7)
        !          2054:        GET_FT_S(f8)
        !          2055:        GET_FT_S(f9)
        !          2056:        GET_FT_S(f10)
        !          2057:        GET_FT_S(f11)
        !          2058:        GET_FT_S(f12)
        !          2059:        GET_FT_S(f13)
        !          2060:        GET_FT_S(f14)
        !          2061:        GET_FT_S(f15)
        !          2062:        GET_FT_S(f16)
        !          2063:        GET_FT_S(f17)
        !          2064:        GET_FT_S(f18)
        !          2065:        GET_FT_S(f19)
        !          2066:        GET_FT_S(f20)
        !          2067:        GET_FT_S(f21)
        !          2068:        GET_FT_S(f22)
        !          2069:        GET_FT_S(f23)
        !          2070:        GET_FT_S(f24)
        !          2071:        GET_FT_S(f25)
        !          2072:        GET_FT_S(f26)
        !          2073:        GET_FT_S(f27)
        !          2074:        GET_FT_S(f28)
        !          2075:        GET_FT_S(f29)
        !          2076:        GET_FT_S(f30)
        !          2077:        GET_FT_S(f31)
        !          2078:
        !          2079: get_ft_s_done:
        !          2080:        srl     ta1, ta0, 23                    # get exponent
        !          2081:        and     ta1, ta1, 0xFF
        !          2082:        and     ta2, ta0, 0x7FFFFF              # get fraction
        !          2083:        srl     ta0, ta0, 31                    # get sign
        !          2084:        bne     ta1, SEXP_INF, 1f               # is it a signaling NAN?
        !          2085:        and     v0, ta2, SSIGNAL_NAN
        !          2086:        bne     v0, zero, invalid_s
        !          2087: 1:
        !          2088:        /* fall through to get FS */
        !          2089:
        !          2090: /*----------------------------------------------------------------------------
        !          2091:  * get_fs_s --
        !          2092:  *
        !          2093:  *     Read (single precision) the FS register (bits 15-11) and
        !          2094:  *     break up into fields.
        !          2095:  *     This is an internal routine used by MipsEmulateFP only.
        !          2096:  *
        !          2097:  * Results:
        !          2098:  *     t0      contains the sign
        !          2099:  *     t1      contains the (biased) exponent
        !          2100:  *     t2      contains the fraction
        !          2101:  *
        !          2102:  *----------------------------------------------------------------------------
        !          2103:  */
        !          2104: #define GET_FS_S(n) \
        !          2105:        .rdata;                         \
        !          2106:        .dword  get_fs_s_/**/n;         \
        !          2107:        .text;                          \
        !          2108: get_fs_s_/**/n:                                \
        !          2109:        mfc1    t0, $/**/n;             \
        !          2110:        b       get_fs_s_done
        !          2111:
        !          2112: ALEAF(get_fs_s)
        !          2113:        srl     a3, a0, 11 - 3                  # get FS field
        !          2114:        and     a3, a3, 0x1f << 3               # mask FS field
        !          2115:        ld      a3, get_fs_s_tbl(a3)            # switch on register number
        !          2116:        j       a3
        !          2117:
        !          2118:        .rdata
        !          2119: get_fs_s_tbl:
        !          2120:        .text
        !          2121:
        !          2122:        GET_FS_S(f0)
        !          2123:        GET_FS_S(f1)
        !          2124:        GET_FS_S(f2)
        !          2125:        GET_FS_S(f3)
        !          2126:        GET_FS_S(f4)
        !          2127:        GET_FS_S(f5)
        !          2128:        GET_FS_S(f6)
        !          2129:        GET_FS_S(f7)
        !          2130:        GET_FS_S(f8)
        !          2131:        GET_FS_S(f9)
        !          2132:        GET_FS_S(f10)
        !          2133:        GET_FS_S(f11)
        !          2134:        GET_FS_S(f12)
        !          2135:        GET_FS_S(f13)
        !          2136:        GET_FS_S(f14)
        !          2137:        GET_FS_S(f15)
        !          2138:        GET_FS_S(f16)
        !          2139:        GET_FS_S(f17)
        !          2140:        GET_FS_S(f18)
        !          2141:        GET_FS_S(f19)
        !          2142:        GET_FS_S(f20)
        !          2143:        GET_FS_S(f21)
        !          2144:        GET_FS_S(f22)
        !          2145:        GET_FS_S(f23)
        !          2146:        GET_FS_S(f24)
        !          2147:        GET_FS_S(f25)
        !          2148:        GET_FS_S(f26)
        !          2149:        GET_FS_S(f27)
        !          2150:        GET_FS_S(f28)
        !          2151:        GET_FS_S(f29)
        !          2152:        GET_FS_S(f30)
        !          2153:        GET_FS_S(f31)
        !          2154:
        !          2155: get_fs_s_done:
        !          2156:        srl     t1, t0, 23                      # get exponent
        !          2157:        and     t1, t1, 0xFF
        !          2158:        and     t2, t0, 0x7FFFFF                # get fraction
        !          2159:        srl     t0, t0, 31                      # get sign
        !          2160:        bne     t1, SEXP_INF, 1f                # is it a signaling NAN?
        !          2161:        and     v0, t2, SSIGNAL_NAN
        !          2162:        bne     v0, zero, invalid_s
        !          2163: 1:
        !          2164:        j       ra
        !          2165: END(get_ft_fs_s)
        !          2166:
        !          2167: /*----------------------------------------------------------------------------
        !          2168:  * get_ft_fs_d --
        !          2169:  *
        !          2170:  *     Read (double precision) the FT register (bits 20-16) and
        !          2171:  *     the FS register (bits 15-11) and break up into fields.
        !          2172:  *     This is an internal routine used by MipsEmulateFP only.
        !          2173:  *
        !          2174:  * Results:
        !          2175:  *     t0      contains the FS sign
        !          2176:  *     t1      contains the FS (biased) exponent
        !          2177:  *     t2      contains the FS fraction
        !          2178:  *     ta0     contains the FT sign
        !          2179:  *     ta1     contains the FT (biased) exponent
        !          2180:  *     ta2     contains the FT fraction
        !          2181:  *
        !          2182:  *----------------------------------------------------------------------------
        !          2183:  */
        !          2184: #define GET_FT_FS_D(n) \
        !          2185:        .rdata;                         \
        !          2186:        .dword  get_ft_fs_d_/**/n;      \
        !          2187:        .text;                          \
        !          2188: get_ft_fs_d_/**/n:                     \
        !          2189:        dmfc1   ta2, $/**/n;            \
        !          2190:        b       get_ft_d_done
        !          2191:
        !          2192: LEAF(get_ft_fs_d, 0)
        !          2193:        srl     a3, a0, 16 - 3                  # get FT field
        !          2194:        and     a3, a3, 0x1f << 3               # mask FT field
        !          2195:        ld      a3, get_ft_d_tbl(a3)            # switch on register number
        !          2196:        j       a3
        !          2197:
        !          2198:        .rdata
        !          2199: get_ft_d_tbl:
        !          2200:        .text
        !          2201:
        !          2202:        GET_FT_FS_D(f0)
        !          2203:        GET_FT_FS_D(f1)
        !          2204:        GET_FT_FS_D(f2)
        !          2205:        GET_FT_FS_D(f3)
        !          2206:        GET_FT_FS_D(f4)
        !          2207:        GET_FT_FS_D(f5)
        !          2208:        GET_FT_FS_D(f6)
        !          2209:        GET_FT_FS_D(f7)
        !          2210:        GET_FT_FS_D(f8)
        !          2211:        GET_FT_FS_D(f9)
        !          2212:        GET_FT_FS_D(f10)
        !          2213:        GET_FT_FS_D(f11)
        !          2214:        GET_FT_FS_D(f12)
        !          2215:        GET_FT_FS_D(f13)
        !          2216:        GET_FT_FS_D(f14)
        !          2217:        GET_FT_FS_D(f15)
        !          2218:        GET_FT_FS_D(f16)
        !          2219:        GET_FT_FS_D(f17)
        !          2220:        GET_FT_FS_D(f18)
        !          2221:        GET_FT_FS_D(f19)
        !          2222:        GET_FT_FS_D(f20)
        !          2223:        GET_FT_FS_D(f21)
        !          2224:        GET_FT_FS_D(f22)
        !          2225:        GET_FT_FS_D(f23)
        !          2226:        GET_FT_FS_D(f24)
        !          2227:        GET_FT_FS_D(f25)
        !          2228:        GET_FT_FS_D(f26)
        !          2229:        GET_FT_FS_D(f27)
        !          2230:        GET_FT_FS_D(f28)
        !          2231:        GET_FT_FS_D(f29)
        !          2232:        GET_FT_FS_D(f30)
        !          2233:        GET_FT_FS_D(f31)
        !          2234:
        !          2235: get_ft_d_done:
        !          2236:        dsrl    ta0, ta2, 63                    # get sign
        !          2237:        dsrl    ta1, ta2, 52                    # get exponent
        !          2238:        and     ta1, ta1, 0x7FF
        !          2239:        dsll    ta2, 12
        !          2240:        dsrl    ta2, 12                         # get fraction
        !          2241:        bne     ta1, DEXP_INF, 1f               # is it a signaling NAN?
        !          2242:        and     v0, ta2, DSIGNAL_NAN
        !          2243:        bne     v0, zero, invalid_d
        !          2244: 1:
        !          2245:        /* fall through to get FS */
        !          2246:
        !          2247: /*----------------------------------------------------------------------------
        !          2248:  * get_fs_d --
        !          2249:  *
        !          2250:  *     Read (double precision) the FS register (bits 15-11) and
        !          2251:  *     break up into fields.
        !          2252:  *     This is an internal routine used by MipsEmulateFP only.
        !          2253:  *
        !          2254:  * Results:
        !          2255:  *     t0      contains the sign
        !          2256:  *     t1      contains the (biased) exponent
        !          2257:  *     t2      contains the fraction
        !          2258:  *
        !          2259:  *----------------------------------------------------------------------------
        !          2260:  */
        !          2261: #define GET_FS_D(n) \
        !          2262:        .rdata;                         \
        !          2263:        .dword  get_fs_d_/**/n;         \
        !          2264:        .text;                          \
        !          2265: get_fs_d_/**/n:                                \
        !          2266:        dmfc1   t2, $/**/n;             \
        !          2267:        b       get_fs_d_done
        !          2268:
        !          2269: ALEAF(get_fs_d)
        !          2270:        srl     a3, a0, 11 - 3                  # get FS field
        !          2271:        and     a3, a3, 0x1f << 3               # mask FS field
        !          2272:        ld      a3, get_fs_d_tbl(a3)            # switch on register number
        !          2273:        j       a3
        !          2274:
        !          2275:        .rdata
        !          2276: get_fs_d_tbl:
        !          2277:        .text
        !          2278:
        !          2279:        GET_FS_D(f0)
        !          2280:        GET_FS_D(f1)
        !          2281:        GET_FS_D(f2)
        !          2282:        GET_FS_D(f3)
        !          2283:        GET_FS_D(f4)
        !          2284:        GET_FS_D(f5)
        !          2285:        GET_FS_D(f6)
        !          2286:        GET_FS_D(f7)
        !          2287:        GET_FS_D(f8)
        !          2288:        GET_FS_D(f9)
        !          2289:        GET_FS_D(f10)
        !          2290:        GET_FS_D(f11)
        !          2291:        GET_FS_D(f12)
        !          2292:        GET_FS_D(f13)
        !          2293:        GET_FS_D(f14)
        !          2294:        GET_FS_D(f15)
        !          2295:        GET_FS_D(f16)
        !          2296:        GET_FS_D(f17)
        !          2297:        GET_FS_D(f18)
        !          2298:        GET_FS_D(f19)
        !          2299:        GET_FS_D(f20)
        !          2300:        GET_FS_D(f21)
        !          2301:        GET_FS_D(f22)
        !          2302:        GET_FS_D(f23)
        !          2303:        GET_FS_D(f24)
        !          2304:        GET_FS_D(f25)
        !          2305:        GET_FS_D(f26)
        !          2306:        GET_FS_D(f27)
        !          2307:        GET_FS_D(f28)
        !          2308:        GET_FS_D(f29)
        !          2309:        GET_FS_D(f30)
        !          2310:        GET_FS_D(f31)
        !          2311:
        !          2312: get_fs_d_done:
        !          2313:        dsrl    t0, t2, 63                      # get sign
        !          2314:        dsrl    t1, t2, 52                      # get exponent
        !          2315:        and     t1, t1, 0x7FF
        !          2316:        dsll    t2, 12
        !          2317:        dsrl    t2, 12                          # get fraction
        !          2318:        bne     t1, DEXP_INF, 1f                # is it a signaling NAN?
        !          2319:        and     v0, t2, DSIGNAL_NAN
        !          2320:        bne     v0, zero, invalid_d
        !          2321: 1:
        !          2322:        j       ra
        !          2323: END(get_ft_fs_d)
        !          2324:
        !          2325: /*----------------------------------------------------------------------------
        !          2326:  * get_cmp_s --
        !          2327:  *
        !          2328:  *     Read (single precision) the FS register (bits 15-11) and
        !          2329:  *     the FT register (bits 20-16) and break up into fields.
        !          2330:  *     This is an internal routine used by MipsEmulateFP only.
        !          2331:  *
        !          2332:  * Results:
        !          2333:  *     t0      contains the sign
        !          2334:  *     t1      contains the (biased) exponent
        !          2335:  *     t2      contains the fraction
        !          2336:  *     ta0     contains the sign
        !          2337:  *     ta1     contains the (biased) exponent
        !          2338:  *     ta2     contains the fraction
        !          2339:  *
        !          2340:  *----------------------------------------------------------------------------
        !          2341:  */
        !          2342: #define CMP_FS_S(n) \
        !          2343:        .rdata;                         \
        !          2344:        .dword  cmp_fs_s_/**/n;         \
        !          2345:        .text;                          \
        !          2346: cmp_fs_s_/**/n:                                \
        !          2347:        mfc1    t0, $/**/n;             \
        !          2348:        b       cmp_fs_s_done
        !          2349:
        !          2350: LEAF(get_cmp_s, 0)
        !          2351:        srl     a3, a0, 11 - 3                  # get FS field
        !          2352:        and     a3, a3, 0x1f << 3               # mask FS field
        !          2353:        ld      a3, cmp_fs_s_tbl(a3)            # switch on register number
        !          2354:        j       a3
        !          2355:
        !          2356:        .rdata
        !          2357: cmp_fs_s_tbl:
        !          2358:        .text
        !          2359:
        !          2360:        CMP_FS_S(f0)
        !          2361:        CMP_FS_S(f1)
        !          2362:        CMP_FS_S(f2)
        !          2363:        CMP_FS_S(f3)
        !          2364:        CMP_FS_S(f4)
        !          2365:        CMP_FS_S(f5)
        !          2366:        CMP_FS_S(f6)
        !          2367:        CMP_FS_S(f7)
        !          2368:        CMP_FS_S(f8)
        !          2369:        CMP_FS_S(f9)
        !          2370:        CMP_FS_S(f10)
        !          2371:        CMP_FS_S(f11)
        !          2372:        CMP_FS_S(f12)
        !          2373:        CMP_FS_S(f13)
        !          2374:        CMP_FS_S(f14)
        !          2375:        CMP_FS_S(f15)
        !          2376:        CMP_FS_S(f16)
        !          2377:        CMP_FS_S(f17)
        !          2378:        CMP_FS_S(f18)
        !          2379:        CMP_FS_S(f19)
        !          2380:        CMP_FS_S(f20)
        !          2381:        CMP_FS_S(f21)
        !          2382:        CMP_FS_S(f22)
        !          2383:        CMP_FS_S(f23)
        !          2384:        CMP_FS_S(f24)
        !          2385:        CMP_FS_S(f25)
        !          2386:        CMP_FS_S(f26)
        !          2387:        CMP_FS_S(f27)
        !          2388:        CMP_FS_S(f28)
        !          2389:        CMP_FS_S(f29)
        !          2390:        CMP_FS_S(f30)
        !          2391:        CMP_FS_S(f31)
        !          2392:
        !          2393: cmp_fs_s_done:
        !          2394:        srl     t1, t0, 23                      # get exponent
        !          2395:        and     t1, t1, 0xFF
        !          2396:        and     t2, t0, 0x7FFFFF                # get fraction
        !          2397:        srl     t0, t0, 31                      # get sign
        !          2398:
        !          2399: #define CMP_FT_S(n) \
        !          2400:        .rdata;                         \
        !          2401:        .dword  cmp_ft_s_/**/n;         \
        !          2402:        .text;                          \
        !          2403: cmp_ft_s_/**/n:                                \
        !          2404:        mfc1    ta0, $/**/n;            \
        !          2405:        b       cmp_ft_s_done
        !          2406:
        !          2407:        srl     a3, a0, 16 - 3                  # get FT field
        !          2408:        and     a3, a3, 0x1f << 3               # mask FT field
        !          2409:        ld      a3, cmp_ft_s_tbl(a3)            # switch on register number
        !          2410:        j       a3
        !          2411:
        !          2412:        .rdata
        !          2413: cmp_ft_s_tbl:
        !          2414:        .text
        !          2415:
        !          2416:        CMP_FT_S(f0)
        !          2417:        CMP_FT_S(f1)
        !          2418:        CMP_FT_S(f2)
        !          2419:        CMP_FT_S(f3)
        !          2420:        CMP_FT_S(f4)
        !          2421:        CMP_FT_S(f5)
        !          2422:        CMP_FT_S(f6)
        !          2423:        CMP_FT_S(f7)
        !          2424:        CMP_FT_S(f8)
        !          2425:        CMP_FT_S(f9)
        !          2426:        CMP_FT_S(f10)
        !          2427:        CMP_FT_S(f11)
        !          2428:        CMP_FT_S(f12)
        !          2429:        CMP_FT_S(f13)
        !          2430:        CMP_FT_S(f14)
        !          2431:        CMP_FT_S(f15)
        !          2432:        CMP_FT_S(f16)
        !          2433:        CMP_FT_S(f17)
        !          2434:        CMP_FT_S(f18)
        !          2435:        CMP_FT_S(f19)
        !          2436:        CMP_FT_S(f20)
        !          2437:        CMP_FT_S(f21)
        !          2438:        CMP_FT_S(f22)
        !          2439:        CMP_FT_S(f23)
        !          2440:        CMP_FT_S(f24)
        !          2441:        CMP_FT_S(f25)
        !          2442:        CMP_FT_S(f26)
        !          2443:        CMP_FT_S(f27)
        !          2444:        CMP_FT_S(f28)
        !          2445:        CMP_FT_S(f29)
        !          2446:        CMP_FT_S(f30)
        !          2447:
        !          2448: cmp_ft_s_done:
        !          2449:        srl     ta1, ta0, 23                    # get exponent
        !          2450:        and     ta1, ta1, 0xFF
        !          2451:        and     ta2, ta0, 0x7FFFFF              # get fraction
        !          2452:        srl     ta0, ta0, 31                    # get sign
        !          2453:        j       ra
        !          2454: END(get_cmp_s)
        !          2455:
        !          2456: /*----------------------------------------------------------------------------
        !          2457:  * get_cmp_d --
        !          2458:  *
        !          2459:  *     Read (double precision) the FS register (bits 15-11) and
        !          2460:  *     the FT register (bits 20-16) and break up into fields.
        !          2461:  *     This is an internal routine used by MipsEmulateFP only.
        !          2462:  *
        !          2463:  * Results:
        !          2464:  *     t0      contains the sign
        !          2465:  *     t1      contains the (biased) exponent
        !          2466:  *     t2      contains the fraction
        !          2467:  *     ta0     contains the sign
        !          2468:  *     ta1     contains the (biased) exponent
        !          2469:  *     ta2     contains the fraction
        !          2470:  *
        !          2471:  *----------------------------------------------------------------------------
        !          2472:  */
        !          2473: #define CMP_FS_D(n) \
        !          2474:        .rdata;                         \
        !          2475:        .dword  cmp_fs_d_/**/n;         \
        !          2476:        .text;                          \
        !          2477: cmp_fs_d_/**/n:                                \
        !          2478:        dmfc1   t2, $/**/n;             \
        !          2479:        b       cmp_fs_d_done
        !          2480:
        !          2481: LEAF(get_cmp_d, 0)
        !          2482:        srl     a3, a0, 11 - 3                  # get FS field
        !          2483:        and     a3, a3, 0x1f << 3               # mask FS field
        !          2484:        ld      a3, cmp_fs_d_tbl(a3)            # switch on register number
        !          2485:        j       a3
        !          2486:
        !          2487:        .rdata
        !          2488: cmp_fs_d_tbl:
        !          2489:        .text
        !          2490:
        !          2491:        CMP_FS_D(f0)
        !          2492:        CMP_FS_D(f1)
        !          2493:        CMP_FS_D(f2)
        !          2494:        CMP_FS_D(f3)
        !          2495:        CMP_FS_D(f4)
        !          2496:        CMP_FS_D(f5)
        !          2497:        CMP_FS_D(f6)
        !          2498:        CMP_FS_D(f7)
        !          2499:        CMP_FS_D(f8)
        !          2500:        CMP_FS_D(f9)
        !          2501:        CMP_FS_D(f10)
        !          2502:        CMP_FS_D(f11)
        !          2503:        CMP_FS_D(f12)
        !          2504:        CMP_FS_D(f13)
        !          2505:        CMP_FS_D(f14)
        !          2506:        CMP_FS_D(f15)
        !          2507:        CMP_FS_D(f16)
        !          2508:        CMP_FS_D(f17)
        !          2509:        CMP_FS_D(f18)
        !          2510:        CMP_FS_D(f19)
        !          2511:        CMP_FS_D(f20)
        !          2512:        CMP_FS_D(f21)
        !          2513:        CMP_FS_D(f22)
        !          2514:        CMP_FS_D(f23)
        !          2515:        CMP_FS_D(f24)
        !          2516:        CMP_FS_D(f25)
        !          2517:        CMP_FS_D(f26)
        !          2518:        CMP_FS_D(f27)
        !          2519:        CMP_FS_D(f28)
        !          2520:        CMP_FS_D(f29)
        !          2521:        CMP_FS_D(f30)
        !          2522:        CMP_FS_D(f31)
        !          2523:
        !          2524: cmp_fs_d_done:
        !          2525:        dsrl    t0, t2, 63                      # get sign
        !          2526:        dsrl    t1, t2, 52                      # get exponent
        !          2527:        and     t1, t1, 0x7FF
        !          2528:        dsll    t2, 12
        !          2529:        dsrl    t2, 12                          # get fraction
        !          2530:
        !          2531: #define CMP_FT_D(n) \
        !          2532:        .rdata;                         \
        !          2533:        .dword  cmp_ft_d_/**/n;         \
        !          2534:        .text;                          \
        !          2535: cmp_ft_d_/**/n:                                \
        !          2536:        dmfc1   ta2, $/**/n;            \
        !          2537:        b       cmp_ft_d_done
        !          2538:
        !          2539:        srl     a3, a0, 16 - 3                  # get FT field
        !          2540:        and     a3, a3, 0x1f << 3               # mask FT field
        !          2541:        ld      a3, cmp_ft_d_tbl(a3)            # switch on register number
        !          2542:        j       a3
        !          2543:
        !          2544:        .rdata
        !          2545: cmp_ft_d_tbl:
        !          2546:        .text
        !          2547:
        !          2548:        CMP_FT_D(f0)
        !          2549:        CMP_FT_D(f1)
        !          2550:        CMP_FT_D(f2)
        !          2551:        CMP_FT_D(f3)
        !          2552:        CMP_FT_D(f4)
        !          2553:        CMP_FT_D(f5)
        !          2554:        CMP_FT_D(f6)
        !          2555:        CMP_FT_D(f7)
        !          2556:        CMP_FT_D(f8)
        !          2557:        CMP_FT_D(f9)
        !          2558:        CMP_FT_D(f10)
        !          2559:        CMP_FT_D(f11)
        !          2560:        CMP_FT_D(f12)
        !          2561:        CMP_FT_D(f13)
        !          2562:        CMP_FT_D(f14)
        !          2563:        CMP_FT_D(f15)
        !          2564:        CMP_FT_D(f16)
        !          2565:        CMP_FT_D(f17)
        !          2566:        CMP_FT_D(f18)
        !          2567:        CMP_FT_D(f19)
        !          2568:        CMP_FT_D(f20)
        !          2569:        CMP_FT_D(f21)
        !          2570:        CMP_FT_D(f22)
        !          2571:        CMP_FT_D(f23)
        !          2572:        CMP_FT_D(f24)
        !          2573:        CMP_FT_D(f25)
        !          2574:        CMP_FT_D(f26)
        !          2575:        CMP_FT_D(f27)
        !          2576:        CMP_FT_D(f28)
        !          2577:        CMP_FT_D(f29)
        !          2578:        CMP_FT_D(f30)
        !          2579:        CMP_FT_D(f31)
        !          2580:
        !          2581: cmp_ft_d_done:
        !          2582:        dsrl    ta0, ta2, 63                    # get sign
        !          2583:        dsrl    ta1, ta2, 52                    # get exponent
        !          2584:        and     ta1, ta1, 0x7FF
        !          2585:        dsll    ta2, 12
        !          2586:        dsrl    ta2, 12                         # get fraction
        !          2587:        j       ra
        !          2588: END(get_cmp_d)
        !          2589:
        !          2590: /*----------------------------------------------------------------------------
        !          2591:  * set_fd_s --
        !          2592:  *
        !          2593:  *     Write (single precision) the FD register (bits 10-6).
        !          2594:  *     This is an internal routine used by MipsEmulateFP only.
        !          2595:  *
        !          2596:  * Arguments:
        !          2597:  *     a0      contains the FP instruction
        !          2598:  *     t0      contains the sign
        !          2599:  *     t1      contains the (biased) exponent
        !          2600:  *     t2      contains the fraction
        !          2601:  *
        !          2602:  * set_fd_word --
        !          2603:  *
        !          2604:  *     Write (integer) the FD register (bits 10-6).
        !          2605:  *     This is an internal routine used by MipsEmulateFP only.
        !          2606:  *
        !          2607:  * Arguments:
        !          2608:  *     a0      contains the FP instruction
        !          2609:  *     t2      contains the integer
        !          2610:  *
        !          2611:  *----------------------------------------------------------------------------
        !          2612:  */
        !          2613: #define SET_FD_S(n) \
        !          2614:        .rdata;                         \
        !          2615:        .dword  set_fd_s_/**/n;         \
        !          2616:        .text;                          \
        !          2617: set_fd_s_/**/n:                                \
        !          2618:        mtc1    t2, $/**/n;             \
        !          2619:        j       ra
        !          2620:
        !          2621: LEAF(set_fd_s, 0)
        !          2622:        sll     t0, t0, 31                      # position sign
        !          2623:        sll     t1, t1, 23                      # position exponent
        !          2624:        or      t2, t2, t0
        !          2625:        or      t2, t2, t1
        !          2626: ALEAF(set_fd_word)
        !          2627:        srl     a3, a0, 6 - 3                   # get FD field
        !          2628:        and     a3, a3, 0x1f << 3               # mask FT field
        !          2629:        ld      a3, set_fd_s_tbl(a3)            # switch on register number
        !          2630:        j       a3
        !          2631:
        !          2632:        .rdata
        !          2633: set_fd_s_tbl:
        !          2634:        .text
        !          2635:
        !          2636:        SET_FD_S(f0)
        !          2637:        SET_FD_S(f1)
        !          2638:        SET_FD_S(f2)
        !          2639:        SET_FD_S(f3)
        !          2640:        SET_FD_S(f4)
        !          2641:        SET_FD_S(f5)
        !          2642:        SET_FD_S(f6)
        !          2643:        SET_FD_S(f7)
        !          2644:        SET_FD_S(f8)
        !          2645:        SET_FD_S(f9)
        !          2646:        SET_FD_S(f10)
        !          2647:        SET_FD_S(f11)
        !          2648:        SET_FD_S(f12)
        !          2649:        SET_FD_S(f13)
        !          2650:        SET_FD_S(f14)
        !          2651:        SET_FD_S(f15)
        !          2652:        SET_FD_S(f16)
        !          2653:        SET_FD_S(f17)
        !          2654:        SET_FD_S(f18)
        !          2655:        SET_FD_S(f19)
        !          2656:        SET_FD_S(f20)
        !          2657:        SET_FD_S(f21)
        !          2658:        SET_FD_S(f22)
        !          2659:        SET_FD_S(f23)
        !          2660:        SET_FD_S(f24)
        !          2661:        SET_FD_S(f25)
        !          2662:        SET_FD_S(f26)
        !          2663:        SET_FD_S(f27)
        !          2664:        SET_FD_S(f28)
        !          2665:        SET_FD_S(f29)
        !          2666:        SET_FD_S(f30)
        !          2667:        SET_FD_S(f31)
        !          2668:
        !          2669: END(set_fd_s)
        !          2670:
        !          2671: /*----------------------------------------------------------------------------
        !          2672:  * set_fd_d --
        !          2673:  *
        !          2674:  *     Write (double precision) the FT register (bits 10-6).
        !          2675:  *     This is an internal routine used by MipsEmulateFP only.
        !          2676:  *
        !          2677:  * Arguments:
        !          2678:  *     a0      contains the FP instruction
        !          2679:  *     t0      contains the sign
        !          2680:  *     t1      contains the (biased) exponent
        !          2681:  *     t2      contains the fraction
        !          2682:  *
        !          2683:  *----------------------------------------------------------------------------
        !          2684:  */
        !          2685: #define SET_FD_D(n) \
        !          2686:        .rdata;                         \
        !          2687:        .dword  set_fd_d_/**/n;         \
        !          2688:        .text;                          \
        !          2689: set_fd_d_/**/n:                                \
        !          2690:        dmtc1   t0, $/**/n;             \
        !          2691:        j       ra
        !          2692:
        !          2693: LEAF(set_fd_d, 0)
        !          2694:        dsll    t0, 63                          # set sign
        !          2695:        dsll    t1, t1, 52                      # set exponent
        !          2696:        or      t0, t0, t1
        !          2697:        or      t0, t0, t2                      # set fraction
        !          2698:        srl     a3, a0, 6 - 3                   # get FD field
        !          2699:        and     a3, a3, 0x1f << 3               # mask FD field
        !          2700:        ld      a3, set_fd_d_tbl(a3)            # switch on register number
        !          2701:        j       a3
        !          2702:
        !          2703:        .rdata
        !          2704: set_fd_d_tbl:
        !          2705:        .text
        !          2706:
        !          2707:        SET_FD_D(f0)
        !          2708:        SET_FD_D(f1)
        !          2709:        SET_FD_D(f2)
        !          2710:        SET_FD_D(f3)
        !          2711:        SET_FD_D(f4)
        !          2712:        SET_FD_D(f5)
        !          2713:        SET_FD_D(f6)
        !          2714:        SET_FD_D(f7)
        !          2715:        SET_FD_D(f8)
        !          2716:        SET_FD_D(f9)
        !          2717:        SET_FD_D(f10)
        !          2718:        SET_FD_D(f11)
        !          2719:        SET_FD_D(f12)
        !          2720:        SET_FD_D(f13)
        !          2721:        SET_FD_D(f14)
        !          2722:        SET_FD_D(f15)
        !          2723:        SET_FD_D(f16)
        !          2724:        SET_FD_D(f17)
        !          2725:        SET_FD_D(f18)
        !          2726:        SET_FD_D(f19)
        !          2727:        SET_FD_D(f20)
        !          2728:        SET_FD_D(f21)
        !          2729:        SET_FD_D(f22)
        !          2730:        SET_FD_D(f23)
        !          2731:        SET_FD_D(f24)
        !          2732:        SET_FD_D(f25)
        !          2733:        SET_FD_D(f26)
        !          2734:        SET_FD_D(f27)
        !          2735:        SET_FD_D(f28)
        !          2736:        SET_FD_D(f29)
        !          2737:        SET_FD_D(f30)
        !          2738:        SET_FD_D(f31)
        !          2739:
        !          2740: END(set_fd_d)
        !          2741:
        !          2742: /*----------------------------------------------------------------------------
        !          2743:  * renorm_fs_s --
        !          2744:  *
        !          2745:  * Results:
        !          2746:  *     t1      unbiased exponent
        !          2747:  *     t2      normalized fraction
        !          2748:  *
        !          2749:  *----------------------------------------------------------------------------
        !          2750:  */
        !          2751: LEAF(renorm_fs_s, 0)
        !          2752: /*
        !          2753:  * Find out how many leading zero bits are in t2 and put in t9.
        !          2754:  */
        !          2755:        move    v0, t2
        !          2756:        move    t9, zero
        !          2757:        srl     v1, v0, 16
        !          2758:        bne     v1, zero, 1f
        !          2759:        addu    t9, 16
        !          2760:        sll     v0, 16
        !          2761: 1:
        !          2762:        srl     v1, v0, 24
        !          2763:        bne     v1, zero, 1f
        !          2764:        addu    t9, 8
        !          2765:        sll     v0, 8
        !          2766: 1:
        !          2767:        srl     v1, v0, 28
        !          2768:        bne     v1, zero, 1f
        !          2769:        addu    t9, 4
        !          2770:        sll     v0, 4
        !          2771: 1:
        !          2772:        srl     v1, v0, 30
        !          2773:        bne     v1, zero, 1f
        !          2774:        addu    t9, 2
        !          2775:        sll     v0, 2
        !          2776: 1:
        !          2777:        srl     v1, v0, 31
        !          2778:        bne     v1, zero, 1f
        !          2779:        addu    t9, 1
        !          2780: /*
        !          2781:  * Now shift t2 the correct number of bits.
        !          2782:  */
        !          2783: 1:
        !          2784:        subu    t9, t9, SLEAD_ZEROS     # dont count normal leading zeros
        !          2785:        li      t1, SEXP_MIN
        !          2786:        subu    t1, t1, t9              # adjust exponent
        !          2787:        sll     t2, t2, t9
        !          2788:        j       ra
        !          2789: END(renorm_fs_s)
        !          2790:
        !          2791: /*----------------------------------------------------------------------------
        !          2792:  * renorm_fs_d --
        !          2793:  *
        !          2794:  * Results:
        !          2795:  *     t1      unbiased exponent
        !          2796:  *     t2      normalized fraction
        !          2797:  *
        !          2798:  *----------------------------------------------------------------------------
        !          2799:  */
        !          2800: LEAF(renorm_fs_d, 0)
        !          2801: /*
        !          2802:  * Find out how many leading zero bits are in t2 and put in t9.
        !          2803:  */
        !          2804:        move    v0, t2
        !          2805:        move    t9, zero
        !          2806:        dsrl    v1, v0, 32
        !          2807:        bne     v1, zero, 1f
        !          2808:        addu    t9, 32
        !          2809:        dsll    v0, 32
        !          2810: 1:
        !          2811:        dsrl    v1, v0, 16
        !          2812:        bne     v1, zero, 1f
        !          2813:        addu    t9, 16
        !          2814:        dsll    v0, 16
        !          2815: 1:
        !          2816:        dsrl    v1, v0, 24
        !          2817:        bne     v1, zero, 1f
        !          2818:        addu    t9, 8
        !          2819:        dsll    v0, 8
        !          2820: 1:
        !          2821:        dsrl    v1, v0, 28
        !          2822:        bne     v1, zero, 1f
        !          2823:        addu    t9, 4
        !          2824:        dsll    v0, 4
        !          2825: 1:
        !          2826:        dsrl    v1, v0, 30
        !          2827:        bne     v1, zero, 1f
        !          2828:        addu    t9, 2
        !          2829:        dsll    v0, 2
        !          2830: 1:
        !          2831:        dsrl    v1, v0, 31
        !          2832:        bne     v1, zero, 1f
        !          2833:        addu    t9, 1
        !          2834: /*
        !          2835:  * Now shift t2 the correct number of bits.
        !          2836:  */
        !          2837: 1:
        !          2838:        subu    t9, t9, DLEAD_ZEROS     # dont count normal leading zeros
        !          2839:        li      t1, DEXP_MIN
        !          2840:        subu    t1, t9                  # adjust exponent
        !          2841:        dsll    t2, t9
        !          2842:        j       ra
        !          2843: END(renorm_fs_d)
        !          2844:
        !          2845: /*----------------------------------------------------------------------------
        !          2846:  * renorm_ft_s --
        !          2847:  *
        !          2848:  * Results:
        !          2849:  *     ta1     unbiased exponent
        !          2850:  *     ta2     normalized fraction
        !          2851:  *
        !          2852:  *----------------------------------------------------------------------------
        !          2853:  */
        !          2854: LEAF(renorm_ft_s, 0)
        !          2855: /*
        !          2856:  * Find out how many leading zero bits are in ta2 and put in t9.
        !          2857:  */
        !          2858:        move    v0, ta2
        !          2859:        move    t9, zero
        !          2860:        srl     v1, v0, 16
        !          2861:        bne     v1, zero, 1f
        !          2862:        addu    t9, 16
        !          2863:        sll     v0, 16
        !          2864: 1:
        !          2865:        srl     v1, v0, 24
        !          2866:        bne     v1, zero, 1f
        !          2867:        addu    t9, 8
        !          2868:        sll     v0, 8
        !          2869: 1:
        !          2870:        srl     v1, v0, 28
        !          2871:        bne     v1, zero, 1f
        !          2872:        addu    t9, 4
        !          2873:        sll     v0, 4
        !          2874: 1:
        !          2875:        srl     v1, v0, 30
        !          2876:        bne     v1, zero, 1f
        !          2877:        addu    t9, 2
        !          2878:        sll     v0, 2
        !          2879: 1:
        !          2880:        srl     v1, v0, 31
        !          2881:        bne     v1, zero, 1f
        !          2882:        addu    t9, 1
        !          2883: /*
        !          2884:  * Now shift ta2 the correct number of bits.
        !          2885:  */
        !          2886: 1:
        !          2887:        subu    t9, t9, SLEAD_ZEROS     # dont count normal leading zeros
        !          2888:        li      ta1, SEXP_MIN
        !          2889:        subu    ta1, t9                 # adjust exponent
        !          2890:        sll     ta2, t9
        !          2891:        j       ra
        !          2892: END(renorm_ft_s)
        !          2893:
        !          2894: /*----------------------------------------------------------------------------
        !          2895:  * renorm_ft_d --
        !          2896:  *
        !          2897:  * Results:
        !          2898:  *     ta1     unbiased exponent
        !          2899:  *     ta2     normalized fraction
        !          2900:  *
        !          2901:  *----------------------------------------------------------------------------
        !          2902:  */
        !          2903: LEAF(renorm_ft_d, 0)
        !          2904: /*
        !          2905:  * Find out how many leading zero bits are in ta2 and put in t9.
        !          2906:  */
        !          2907:        move    v0, ta2
        !          2908:        move    t9, zero
        !          2909:        dsrl    v1, v0, 32
        !          2910:        bne     v1, zero, 1f
        !          2911:        addu    t9, 32
        !          2912:        dsll    v0, 32
        !          2913: 1:
        !          2914:        dsrl    v1, v0, 16
        !          2915:        bne     v1, zero, 1f
        !          2916:        addu    t9, 16
        !          2917:        dsll    v0, 16
        !          2918: 1:
        !          2919:        dsrl    v1, v0, 24
        !          2920:        bne     v1, zero, 1f
        !          2921:        addu    t9, 8
        !          2922:        dsll    v0, 8
        !          2923: 1:
        !          2924:        dsrl    v1, v0, 28
        !          2925:        bne     v1, zero, 1f
        !          2926:        addu    t9, 4
        !          2927:        dsll    v0, 4
        !          2928: 1:
        !          2929:        dsrl    v1, v0, 30
        !          2930:        bne     v1, zero, 1f
        !          2931:        addu    t9, 2
        !          2932:        dsll    v0, 2
        !          2933: 1:
        !          2934:        dsrl    v1, v0, 31
        !          2935:        bne     v1, zero, 1f
        !          2936:        addu    t9, 1
        !          2937: /*
        !          2938:  * Now shift ta2 the correct number of bits.
        !          2939:  */
        !          2940: 1:
        !          2941:        subu    t9, t9, DLEAD_ZEROS     # dont count normal leading zeros
        !          2942:        li      ta1, DEXP_MIN
        !          2943:        subu    ta1, t9                 # adjust exponent
        !          2944:        dsll    ta2, t9
        !          2945:        j       ra
        !          2946: END(renorm_ft_d)

CVSweb