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

Annotation of sys/arch/m88k/m88k/m88100_fp.S, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: m88100_fp.S,v 1.4 2004/08/09 20:52:11 miod Exp $  */
        !             2: /*
        !             3:  * Mach Operating System
        !             4:  * Copyright (c) 1991 Carnegie Mellon University
        !             5:  * Copyright (c) 1991 OMRON Corporation
        !             6:  * All Rights Reserved.
        !             7:  *
        !             8:  * Permission to use, copy, modify and distribute this software and its
        !             9:  * documentation is hereby granted, provided that both the copyright
        !            10:  * notice and this permission notice appear in all copies of the
        !            11:  * software, derivative works or modified versions, and any portions
        !            12:  * thereof, and that both notices appear in supporting documentation.
        !            13:  *
        !            14:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            15:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
        !            16:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            17:  *
        !            18:  * Carnegie Mellon requests users of this software to return to
        !            19:  *
        !            20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            21:  *  School of Computer Science
        !            22:  *  Carnegie Mellon University
        !            23:  *  Pittsburgh PA 15213-3890
        !            24:  *
        !            25:  * any improvements or extensions that they make and grant Carnegie the
        !            26:  * rights to redistribute these changes.
        !            27:  */
        !            28:
        !            29: /* Floating point trouble routines */
        !            30: #include "assym.h"
        !            31: #include <machine/trap.h>
        !            32: #include <machine/asm.h>
        !            33:
        !            34: #define destsize 10
        !            35:
        !            36: /* Floating-Point Status Register bits */
        !            37: #define inexact 0
        !            38: #define overflow 1
        !            39: #define underflow 2
        !            40: #define divzero 3
        !            41: #define oper 4
        !            42:
        !            43: #define sign 31
        !            44: #define s1size 9
        !            45: #define s2size 7
        !            46: #define dsize 5
        !            47:
        !            48: #define FADDop 0x05
        !            49: #define FSUBop 0x06
        !            50: #define FCMPop 0x07
        !            51: #define FMULop 0x00
        !            52: #define FDIVop 0x0e
        !            53: #define FSQRTop 0x0f
        !            54: #define INTop 0x09
        !            55: #define NINTop 0x0a
        !            56: #define TRNCop 0x0b
        !            57:
        !            58: #define s1nan 7
        !            59: #define s2nan 6
        !            60: #define s1inf 5
        !            61: #define s2inf 4
        !            62: #define s1zero 3
        !            63: #define s2zero 2
        !            64: #define sigbit 19
        !            65:
        !            66: #define modehi 30
        !            67: #define modelo 29
        !            68: #define rndhi 15
        !            69: #define rndlo 14
        !            70: #define efunf 7
        !            71: #define efovf 6
        !            72: #define efinx 5
        !            73:
        !            74: ASENTRY(m88100_Xfp_precise)
        !            75:        or      r29, r3,  r0            /* r29 is now the E.F. */
        !            76:        subu    r31, r31, 16
        !            77:        st      r1,  r31, 8
        !            78:        st      r29, r31, 12
        !            79:
        !            80:        ld      r2, r29, EF_FPSR * 4
        !            81:        ld      r3, r29, EF_FPCR * 4
        !            82:        ld      r4, r29, EF_FPECR * 4
        !            83:        ld      r5, r29, EF_FPHS1 * 4
        !            84:        ld      r6, r29, EF_FPLS1 * 4
        !            85:        ld      r7, r29, EF_FPHS2 * 4
        !            86:        ld      r8, r29, EF_FPLS2 * 4
        !            87:        ld      r9, r29, EF_FPPT * 4
        !            88:
        !            89:
        !            90:        /*
        !            91:         * Load into r1 the return address for the zero handlers. Looking at
        !            92:         * FPECR, branch to the appropriate zero handler. However, if none of
        !            93:         * the zero bits are enabled, then a floating point instruction was
        !            94:         * issued with the floating point unit disabled. This will cause an
        !            95:         * unimplemented opcode 0.
        !            96:         */
        !            97:
        !            98:        or.u    r1,r0,hi16(wrapup)      /* load return address of function */
        !            99:        or      r1,r1,lo16(wrapup)
        !           100:
        !           101:        bb0     6,r4, 3f                /* branch to FPunimp if bit set */
        !           102:        br      FPuimp
        !           103: 3:
        !           104:        bb0     7,r4, 4f                /* branch to FPintover if bit set */
        !           105:        br      FPintover
        !           106: 4:
        !           107: #if 0
        !           108:        bb0     5,r4, 5f                /* branch to FPpriviol if bit set */
        !           109:        br      FPpriviol
        !           110: #endif
        !           111: 5:
        !           112:        bb0     4,r4, 6f                /* branch to FPresoper if bit set */
        !           113:        br      FPresoper
        !           114: 6:
        !           115:        bb0     3,r4, 7f                /* branch to FPdivzero if bit set */
        !           116:        br      FPdivzero
        !           117: 7:
        !           118:        or.u    r4, r4, 0xffff
        !           119:
        !           120: ASLOCAL(FPuimp)
        !           121:        subu    r31,r31,16              /* allocate stack */
        !           122:        st      r1,r31,0                /* save return address */
        !           123:        or      r2,r0,T_FPEPFLT         /* load trap type */
        !           124:        bsr.n   _C_LABEL(m88100_trap)
        !           125:         or     r3, r29, r0
        !           126:        ld      r1,r31,0                /* recover return address */
        !           127:        addu    r31,r31,16              /* deallocate stack */
        !           128:        jmp     r1
        !           129:
        !           130:        /*
        !           131:         * To write back the results to the user registers, disable exceptions
        !           132:         * and the floating point unit. Write FPSR and FPCR and load the SNIP
        !           133:         * and SFIP.
        !           134:         * r5 will contain the upper word of the result
        !           135:         * r6 will contain the lower word of the result
        !           136:         */
        !           137:
        !           138: ASLOCAL(wrapup)
        !           139:        tb1     0,r0,0          /* make sure all floating point operations */
        !           140:                                /* have finished */
        !           141:        ldcr    r10, cr1        /* load the PSR */
        !           142: #if 0
        !           143:        set     r10, r10, 1<PSR_FPU_DISABLE_BIT>
        !           144: #endif
        !           145:        set     r10, r10, 1<PSR_INTERRUPT_DISABLE_BIT>
        !           146:        stcr    r10, cr1
        !           147:
        !           148:        ld      r1, r31, 8
        !           149:        ld      r29, r31, 12
        !           150:        addu    r31, r31, 16
        !           151:
        !           152:        fstcr   r2, FPSR        /* write revised value of FPSR */
        !           153:        fstcr   r3, FPCR        /* write revised value of FPCR */
        !           154:
        !           155:        /* result writeback routine */
        !           156:        addu    r3, r29, EF_R0 * 4
        !           157:        extu    r2, r9, 5<0>            /* get 5 bits of destination register */
        !           158:        bb0     5, r9, writesingle      /* branch if destination is single */
        !           159:
        !           160: /* writedouble here */
        !           161:        st      r5, r3 [r2]             /* write high word */
        !           162:        add     r2, r2, 1               /* for double, the low word is the */
        !           163:        /* unspecified register */
        !           164:        clr     r2, r2, 27<5>           /* perform equivalent of mod 32 */
        !           165: ASLOCAL(writesingle)
        !           166:        jmp.n   r1
        !           167:         st     r6, r3 [r2]             /* write low word into memory */
        !           168:
        !           169: /*
        !           170:  * Check if the numerator is zero. If the numerator is zero, then handle
        !           171:  * this instruction as you would a 0/0 invalid operation.
        !           172:  */
        !           173:
        !           174: ASLOCAL(FPdivzero)
        !           175:        bb1.n   s1size,r9,1f            /* branch if numerator double */
        !           176:         st     r1,r31,0                /* save return address */
        !           177: /* single number */
        !           178:        clr     r10,r5,1<sign>  /* clear sign bit */
        !           179:        extu    r11,r6,3<29>    /* grab upper bits of lower word */
        !           180:        or      r10,r10,r11     /* combine ones of mantissa */
        !           181:        bcnd    eq0,r10,resoper /* numerator is zero, handle reserved operand */
        !           182:        br      setbit          /* set divzero bit */
        !           183: 1:
        !           184: /* double number */
        !           185:        clr     r10,r5,1<sign>  /* clear sign bit */
        !           186:        or      r10,r10,r6      /* or high and low words */
        !           187:        bcnd    ne0,r10,setbit  /* set divzero bit */
        !           188:
        !           189: /*
        !           190:  * The numerator is zero, so handle the invalid operation by setting the
        !           191:  * invalid operation bit and writing a quiet NaN to the destination.
        !           192:  */
        !           193:
        !           194: ASLOCAL(resoper)
        !           195:        set     r2,r2,1<oper>
        !           196:        set     r5,r0,0<0>      /* put a NaN in high word */
        !           197:        set     r6,r0,0<0>      /* put a NaN in low word */
        !           198:        br      FP_div_return
        !           199:                                /* writing to a word which may be ignored */
        !           200:                                /* is just as quick as checking the precision */
        !           201:                                /* of the destination */
        !           202:
        !           203: /*
        !           204:  * The operation is divide by zero, so set the divide by zero bit in the
        !           205:  * FPSR.
        !           206:  * Considering the sign of the numerator and zero, write a correctly
        !           207:  * signed infinity of the proper precision into the destination.
        !           208:  */
        !           209:
        !           210: setbit:
        !           211:        set     r2,r2,1<divzero>
        !           212:        bb1     dsize,r9,FPzero_double  /* branch to handle double result */
        !           213: FPzero_single:
        !           214:        clr     r10,r5,31<0>    /* clear all of S1HI except sign bit */
        !           215:        xor     r10,r7,r10      /* xor the sign bits of the operands */
        !           216:        or.u    r6,r0,0x7f80    /* load single precision infinity */
        !           217:        br.n    FP_div_return
        !           218:         or     r6,r6,r10       /* load correctly signed infinity */
        !           219:
        !           220: FPzero_double:
        !           221:        clr     r10,r5,31<0>    /* clear all of S1HI except sign bit */
        !           222:        xor     r10,r7,r10      /* xor the sign bits of the operands */
        !           223:        or.u    r5,r0,0x7ff0    /* load double precision infinity */
        !           224:        or      r5,r5,r10       /* load correctly signed infinity */
        !           225:        or      r6,r0,r0        /* clear lower word of double */
        !           226:
        !           227: FP_div_return:
        !           228:        ld      r1,r31,0        /* load return address */
        !           229:        jmp     r1
        !           230:
        !           231: /*
        !           232:  * Both NINT and TRNC require a certain rounding mode, so check which
        !           233:  * instruction caused the integer conversion overflow. Use a substitute
        !           234:  * FPCR in r1, and modify the rounding mode if the instruction is NINT
        !           235:  * or TRNC.
        !           236:  */
        !           237: ASLOCAL(FPintover)
        !           238:        extu    r10,r9,5<11>            /* extract opcode */
        !           239:        cmp     r11,r10,INTop           /* see if instruction is INT */
        !           240:        st      r1,r31,0                /* save return address */
        !           241:        bb1.n   eq,r11,checksize        /* instruction is INT, do not modify */
        !           242:                                        /* rounding mode */
        !           243:         or     r1,r0,r3                /* load FPCR into r1 */
        !           244:        cmp     r11,r10,NINTop          /* see if instruction is NINT */
        !           245:        bb1     eq,r11,NINT             /* instruction is NINT */
        !           246: TRNC:
        !           247:        clr     r1,r1,2<rndlo>          /* clear rounding mode bits, */
        !           248:                                        /* instruction is TRNC */
        !           249:        br.n    checksize               /* branch to check size */
        !           250:         set    r1,r1,1<rndlo>          /* make rounding mode round towards */
        !           251:                                        /* zero */
        !           252: NINT:
        !           253:        clr     r1,r1,2<rndlo>          /* make rounding mode round to */
        !           254:                                        /* nearest */
        !           255:
        !           256: /* See whether the source is single or double precision. */
        !           257:
        !           258: checksize:
        !           259:        bb1     s2size,r9,checkdoub     /* S2 is double, branch to see if */
        !           260:                                        /* there is a false alarm */
        !           261:
        !           262: /*
        !           263:  * An integer has more bits than the mantissa of a single precision floating
        !           264:  * point number, so to check for false alarms (i.e. valid conversion), simply
        !           265:  * check the exponents. False alarms are detected for 2**30 to (2**30) - 1
        !           266:  * and -2**30 to -2**31. Only seven bits need to be looked at since an
        !           267:  * exception will not occur for the other half of the numbering system.
        !           268:  * To speed up the processing, first check to see if the exponent is 32 or
        !           269:  * greater.
        !           270:  *
        !           271:  * This code was originally written for the exponent in the control
        !           272:  * register to have the most significant bit (8 - single, 11 - double)
        !           273:  * flipped and sign extended. For precise exceptions, however, the most
        !           274:  * significant bit is only sign extended. Therefore, the code was chopped
        !           275:  * up so that it would work for positive values of real exponent which were
        !           276:  * only sign extended.
        !           277:  */
        !           278:
        !           279: checksing:
        !           280:        extu    r10,r7,7<20>    /* internal representation for single */
        !           281:                                /* precision is IEEE 8 bits sign extended */
        !           282:                                /* to 11 bits; for real exp. = 30, the */
        !           283:                                /* above instruction gives a result exp. */
        !           284:                                /* that has the MSB flipped and sign */
        !           285:                                /* extended like in the IMPCR */
        !           286:        cmp     r11,r10,31      /* compare to 32,but exp. off by 1 */
        !           287:                                /* these 2 instructions to speed up valid */
        !           288:                                /* execution of valid cases */
        !           289:        bb1     ge,r11,overflw  /* valid case, perform overflow routine */
        !           290:        bb1     sign,r7,checksingn /* source operand is negative */
        !           291:
        !           292: /*
        !           293:  * If the number is positve and the exponent is greater than 30, than it is
        !           294:  * overflow.
        !           295:  */
        !           296: checksingp:
        !           297:        cmp     r10,r10,29      /* compare to 30, but exp. off by 1 */
        !           298:        bb1     gt,r10,overflw  /* no false alarm, its overflow */
        !           299:        br      conversionsp    /* finish single precision conversion */
        !           300:
        !           301: /*
        !           302:  * If the number is negative, and the exponent is 30, or 31 with a mantissa
        !           303:  * of 0, then it is a false alarm.
        !           304:  */
        !           305: checksingn:
        !           306:        cmp     r11,r10,30              /* compare to 31,but exp. off by 1 */
        !           307:        bb1     lt,r11,conversionsn     /* exp. less than 31, so convert */
        !           308:        extu    r10,r8,3<29>            /* get upper three bits of lower */
        !           309:                                        /* mantissa */
        !           310:        mak     r12,r7,20<3>            /* get upper 20 bits of mantissa */
        !           311:        or      r10,r10,r12             /* form complete mantissa */
        !           312:        bcnd    eq0,r10,conversionsn    /* complete conversion if mantissa */
        !           313:                                        /* is 0 */
        !           314:        br      overflw                 /* no false alarm, its overflow */
        !           315:
        !           316: /*
        !           317:  * False alarms are detected for 2**30 to (2**30) - 1 and -2**30 to -2**31.
        !           318:  * Only seven bits need to be looked at since an exception will not occur
        !           319:  * for the other half of the numbering system.
        !           320:  * To speed up the processing, first check to see if the exponent is 32 or
        !           321:  * greater. Since there are more mantissa bits than integer bits, rounding
        !           322:  * could cause overflow. (2**31) - 1 needs to be checked so that it does
        !           323:  * not round to 2**31, and -2**31 needs to be checked in case it rounds to
        !           324:  * -((2**31) + 1).
        !           325:  */
        !           326: checkdoub:
        !           327:        extu    r10,r7,10<20>   /* internal representation for double */
        !           328:                                /* precision is the same IEEE 11 bits */
        !           329:                                /* for real exp. = 30, the */
        !           330:                                /* above instruction gives a result exp. */
        !           331:                                /* that has the MSB flipped and sign */
        !           332:                                /* extended like in the IMPCR */
        !           333:        cmp     r11,r10,31      /* compare to 32,but exp. off by 1 */
        !           334:                                /* these 2 instructions to speed up valid */
        !           335:                                /* execution of valid cases */
        !           336:        bb1     ge,r11,overflw  /* valid case, perform overflow routine */
        !           337:        bb1     sign,r7,checkdoubn /* source operand is negative */
        !           338:
        !           339: /*
        !           340:  * If the exponent is not 31, then the floating point number will be rounded
        !           341:  * before the conversion is done. A branch table is set up with bits 4 and 3
        !           342:  * being the rounding mode, and bits 2, 1, and 0 are the guard, round, and
        !           343:  * sticky bits.
        !           344:  */
        !           345: checkdoubp:
        !           346:        cmp     r11,r10,30      /* compare to 31, but exponent off by 1 */
        !           347:        bb1     eq,r11,overflw  /* no false alarm, its overflow */
        !           348:        extu    r12,r8,1<22>    /* get LSB for integer with exp. = 30 */
        !           349:        mak     r12,r12,1<2>    /* start to set up field for branch table */
        !           350:        extu    r11,r8,1<21>    /* get guard bit */
        !           351:        mak     r11,r11,1<1>    /* set up field for branch table */
        !           352:        or      r12,r11,r12     /* set up field for branch table */
        !           353:        extu    r11,r8,21<0>    /* get bits for sticky bit */
        !           354:        bcnd    eq0,r11,nostickyp /* do not set sticky */
        !           355:        set     r12,r12,1<0>    /* set sticky bit */
        !           356: nostickyp:
        !           357:        rot     r11,r1,0<rndlo>         /* shift rounding mode to 2 LSB''s */
        !           358:        mak     r11,r11,2<3>            /* set up field, clear other bits */
        !           359:        or      r12,r11,r12             /* set up field for branch table */
        !           360:        lda     r12,r0[r12]             /* scale r12 */
        !           361:        or.u    r12,r12,hi16(ptable)    /* load pointer into table */
        !           362:        addu    r12,r12,lo16(ptable)
        !           363:        jmp     r12
        !           364:
        !           365: ptable:
        !           366:        br      conversiondp
        !           367:        br      conversiondp
        !           368:        br      conversiondp
        !           369:        br      paddone
        !           370:        br      conversiondp
        !           371:        br      conversiondp
        !           372:        br      paddone
        !           373:        br      paddone
        !           374:        br      conversiondp
        !           375:        br      conversiondp
        !           376:        br      conversiondp
        !           377:        br      conversiondp
        !           378:        br      conversiondp
        !           379:        br      conversiondp
        !           380:        br      conversiondp
        !           381:        br      conversiondp
        !           382:        br      conversiondp
        !           383:        br      conversiondp
        !           384:        br      conversiondp
        !           385:        br      conversiondp
        !           386:        br      conversiondp
        !           387:        br      conversiondp
        !           388:        br      conversiondp
        !           389:        br      conversiondp
        !           390:        br      conversiondp
        !           391:        br      paddone
        !           392:        br      paddone
        !           393:        br      paddone
        !           394:        br      conversiondp
        !           395:        br      paddone
        !           396:        br      paddone
        !           397:        br      paddone
        !           398:
        !           399: /*
        !           400:  * Add one to the bit of the mantissa which corresponds to the LSB of an
        !           401:  * integer. If the mantissa overflows, then there is a valid integer
        !           402:  * overflow conversion; otherwise, the mantissa can be converted to the
        !           403:  * integer.
        !           404:  */
        !           405: paddone:
        !           406:        or      r10,r0,r0       /* clear r10 */
        !           407:        set     r10,r10,1<22>   /* set LSB bit to 1 for adding */
        !           408:        addu.co r8,r8,r10       /* add the 1 obtained from rounding */
        !           409:        clr     r11,r7,12<20>   /* clear exponent and sign */
        !           410:        addu.ci r11,r0,r11      /* add carry */
        !           411:        bb1     20,r11,overflw  /* overflow to 2**31, abort the rest */
        !           412:        br.n    conversiondp    /* since the exp. was 30, and the exp. */
        !           413:                                /* did not round up to 31, the largest */
        !           414:                                /* number that S2 could become is 2**31-1 */
        !           415:         or     r7,r0,r11       /* store r11 into r7 for conversion */
        !           416:
        !           417: /*
        !           418:  * Now check for negative double precision sources. If the exponent is 30,
        !           419:  * then convert the false alarm. If the exponent is 31, then check the
        !           420:  * mantissa bits which correspond to integer bits. If any of them are a one,
        !           421:  * then there is overflow. If they are zero, then check the guard, round,
        !           422:  * and sticky bits.
        !           423:  * Round toward zero and positive will not cause a roundup, but round toward
        !           424:  * nearest and negative may, so perform those roundings. If there is no
        !           425:  * overflow, then convert and return.
        !           426:  */
        !           427: checkdoubn:
        !           428:        cmp     r11,r10,29              /* compare to 30, but exp. off by 1 */
        !           429:        bb1     eq,r11,conversiondn     /* false alarm if exp. = 30 */
        !           430:        extu    r10,r8,11<21>           /* check upper bits of lower mantissa */
        !           431:        bcnd    ne0,r10,overflw         /* one of the bits is a 1, so oflow */
        !           432:        extu    r10,r7,20<0>            /* check upper bits of upper mantissa */
        !           433:        bcnd    ne0,r10,overflw         /* one of the bits is a 1, so oflow */
        !           434:        bb0     rndlo,r1,possround      /* rounding mode is either round near */
        !           435:                                        /* or round negative, which may cause */
        !           436:                                        /* a round */
        !           437:        br.n    FPintov_return          /* round positive, which will not */
        !           438:                                        /* cause a round */
        !           439:         set    r6,r0,1<sign>
        !           440: possround:
        !           441:        extu    r12,r8,1<20>            /* get guard bit */
        !           442:        extu    r11,r8,20<0>            /* get bits for sticky bit */
        !           443:        bcnd.n  eq0,r11,nostickyn       /* do not set sticky */
        !           444:         mak    r12,r12,1<1>            /* set up field for branch table */
        !           445:        set     r12,r12,1<0>            /* set sticky bit */
        !           446: nostickyn:
        !           447:        bb1     rndhi,r1,negative       /* rounding mode is negative */
        !           448: nearest:
        !           449:        cmp     r12,r12,3               /* are both guard and sticky set */
        !           450:        bb1     eq,r12,overflw          /* both guard and sticky are set, */
        !           451:                                        /* so signal overflow */
        !           452:        or      r6,r0,r0                /* clear destination register r6 */
        !           453:        br.n    FPintov_return
        !           454:         set    r6,r6,1<sign>           /* set the sign bit and take care of */
        !           455:                                        /* this special case */
        !           456: negative:
        !           457:        bcnd    ne0,r12,overflw         /* -2**31 will be rounded to */
        !           458:                                        /* -(2**31+1), so signal overflow */
        !           459:        or      r6,r0,r0                /* clear destination register r6 */
        !           460:        br.n    FPintov_return
        !           461:         set    r6,r6,1<sign>           /* set the sign bit and take care of */
        !           462:                                        /* this special case */
        !           463:
        !           464:        /*
        !           465:         * Since the exp. was 30, and there was no round-up, the largest
        !           466:         * number that S2 could have been was 2**31 - 1
        !           467:         */
        !           468:
        !           469:
        !           470:        /* Convert the single precision positive floating point number. */
        !           471:
        !           472: conversionsp:
        !           473:        extu    r6,r8,3<29>     /* extract lower bits of integer */
        !           474:        mak     r6,r6,3<7>      /* shift left to correct place in integer */
        !           475:        mak     r10,r7,20<10>   /* shift left upper bits of integer */
        !           476:        or      r6,r6,r10       /* form most of integer */
        !           477:        br.n    FPintov_return
        !           478:         set    r6,r6,1<30>     /* set hidden one */
        !           479:
        !           480:        /* Convert the single precision negative floating point number. */
        !           481:
        !           482: conversionsn:
        !           483:        bb1     eq,r11,exp31s   /* use old r11 to see if exp. is 31 */
        !           484:        extu    r6,r8,3<29>     /* extract lower bits of mantissa */
        !           485:        mak     r6,r6,3<7>      /* shift left to correct place in integer */
        !           486:        mak     r10,r7,20<10>   /* shift left upper bits of integer */
        !           487:        or      r6,r6,r10       /* form most of integer */
        !           488:        set     r6,r6,1<30>     /* set hidden one */
        !           489:        or.c    r6,r0,r6        /* negate result */
        !           490:        br.n    FPintov_return
        !           491:         addu   r6,r6,1         /* add 1 to get 2''s complement */
        !           492: exp31s:
        !           493:        or      r6,r0,r0        /* clear r6 */
        !           494:        br.n    FPintov_return
        !           495:         set    r6,r6,1<sign>   /* set sign bit */
        !           496:
        !           497:        /* Convert the double precision positive floating point number. */
        !           498:
        !           499: conversiondp:
        !           500:        extu    r6,r8,10<22>    /* extract lower bits of integer */
        !           501:        mak     r10,r7,20<10>   /* shift left upper bits of integer */
        !           502:        or      r6,r6,r10       /* form most of integer */
        !           503:        br.n    FPintov_return
        !           504:         set    r6,r6,1<30>     /* set hidden one */
        !           505:
        !           506:        /*
        !           507:         * Convert the double precision negative floating point number.
        !           508:         * The number, whose exponent is 30, must be rounded before converting.
        !           509:         * Bits 4 and 3 are the rounding mode, and bits 2, 1, and 0 are the
        !           510:         * guard, round, and sticky bits for the branch table.
        !           511:         */
        !           512:
        !           513: conversiondn:
        !           514:        extu    r12,r8,1<22>    /* get LSB for integer with exp. = 30 */
        !           515:        mak     r12,r12,1<2>    /* start to set up field for branch table */
        !           516:        extu    r11,r8,1<21>    /* get guard bit */
        !           517:        mak     r11,r11,1<1>    /* set up field for branch table */
        !           518:        or      r12,r11,r12     /* set up field for branch table */
        !           519:        extu    r11,r8,21<0>    /* get bits for sticky bit */
        !           520:        bcnd    eq0,r11,nostkyn /* do not set sticky */
        !           521:        set     r12,r12,1<0>    /* set sticky bit */
        !           522: nostkyn:
        !           523:        rot     r11,r1,0<rndlo> /* shift rounding mode to 2 LSB''s */
        !           524:        mak     r11,r11,2<3>    /* set up field, clear other bits */
        !           525:        or      r12,r11,r12     /* set up field for branch table */
        !           526:        lda     r12,r0[r12]     /* scale r12 */
        !           527:        or.u    r12,r12,hi16(ntable) /* load pointer into table */
        !           528:        addu    r12,r12,lo16(ntable)
        !           529:        jmp     r12
        !           530:
        !           531: ntable:
        !           532:        br      nnoaddone
        !           533:        br      nnoaddone
        !           534:        br      nnoaddone
        !           535:        br      naddone
        !           536:        br      nnoaddone
        !           537:        br      nnoaddone
        !           538:        br      naddone
        !           539:        br      naddone
        !           540:        br      nnoaddone
        !           541:        br      nnoaddone
        !           542:        br      nnoaddone
        !           543:        br      nnoaddone
        !           544:        br      nnoaddone
        !           545:        br      nnoaddone
        !           546:        br      nnoaddone
        !           547:        br      nnoaddone
        !           548:        br      nnoaddone
        !           549:        br      naddone
        !           550:        br      naddone
        !           551:        br      naddone
        !           552:        br      nnoaddone
        !           553:        br      naddone
        !           554:        br      naddone
        !           555:        br      naddone
        !           556:        br      nnoaddone
        !           557:        br      nnoaddone
        !           558:        br      nnoaddone
        !           559:        br      nnoaddone
        !           560:        br      nnoaddone
        !           561:        br      nnoaddone
        !           562:        br      nnoaddone
        !           563:        br      nnoaddone
        !           564:
        !           565: /*
        !           566:  * Add one to the mantissa, and check to see if it overflows to -2**31.
        !           567:  * The conversion is done in nnoaddone.
        !           568:  */
        !           569:
        !           570: naddone:
        !           571:        or      r10,r0,r0       /* clear r10 */
        !           572:        set     r10,r10,1<22>   /* set LSB bit to 1 for adding */
        !           573:        add.co  r8,r8,r10       /* add the 1 obtained from rounding */
        !           574:        clr     r7,r7,12<20>    /* clear exponent and sign */
        !           575:        add.ci  r7,r0,r7        /* add carry */
        !           576:        bb1     20,r7,maxneg    /* rounded to -2**31,handle separately */
        !           577:                                /* the exponent was originally 30 */
        !           578: nnoaddone:
        !           579:        extu    r6,r8,11<22>    /* extract lower bits of integer */
        !           580:        mak     r10,r7,20<10>   /* shift left upper bits of integer */
        !           581:        or      r6,r6,r10       /* form most of integer */
        !           582:        set     r6,r6,1<30>     /* set hidden one */
        !           583:        or.c    r6,r0,r6        /* negate integer */
        !           584:        br.n    FPintov_return
        !           585:         addu   r6,r6,1         /* add 1 to get 2''s complement */
        !           586:
        !           587: maxneg:
        !           588:        or      r6,r0,r0        /* clear integer */
        !           589:        br.n    FPintov_return
        !           590:         set    r6,r6,1<sign>   /* set sign bit */
        !           591:
        !           592:        /* For valid overflows, write the correctly signed largest integer. */
        !           593: overflw:
        !           594:        set     r2,r2,1<oper>
        !           595:        bb0.n   sign,r7,FPintov_return  /* if positive then return */
        !           596:         set    r6,r6,31<0>             /* set result to largest positive int */
        !           597:        or.c    r6,r0,r6                /* negate r6, giving largest negative */
        !           598:                                        /* integer */
        !           599:
        !           600: FPintov_return:
        !           601:        ld      r1,r31,0                /* load return address from memory */
        !           602:        jmp     r1
        !           603:
        !           604: /*
        !           605:  * Some instructions only have the S2 operations, so clear S1HI and S1LO
        !           606:  * for those instructions so that the previous contents of S1HI and S1LO
        !           607:  * do not influence this instruction.
        !           608:  */
        !           609:
        !           610: ASLOCAL(FPresoper)
        !           611:        st      r1, r31, 0
        !           612:        extu    r10,r9,5<11>    /* extract opcode */
        !           613: #if 0
        !           614:        cmp     r11,r10,FSQRTop /* compare to FSQRT */
        !           615:        bb1     eq,r11,S1clear  /* clear S1 if instruction only had S2 operand */
        !           616: #endif
        !           617:        cmp     r11,r10,INTop   /* compare to INT */
        !           618:        bb1     eq,r11,S1clear  /* clear S1 if instruction only had S2 operand */
        !           619:        cmp     r11,r10,NINTop  /* compare to NINT */
        !           620:        bb1     eq,r11,S1clear  /* clear S1 if instruction only had S2 operand */
        !           621:        cmp     r11,r10,TRNCop  /* compare to TRNC */
        !           622:        bb0     eq,r11,opercheck /* check for reserved operands */
        !           623:
        !           624: ASLOCAL(S1clear)
        !           625:        or      r5,r0,r0        /* clear any NaN''s, denorms, or infinities */
        !           626:        or      r6,r0,r0        /* that may be left in S1HI,S1LO from a */
        !           627:                                /* previous instruction */
        !           628:
        !           629: /*
        !           630:  * r12 contains the following flags:
        !           631:  *   bit 9 -- s1sign
        !           632:  *   bit 8 -- s2sign
        !           633:  *   bit 7 -- s1nan
        !           634:  *   bit 6 -- s2nan
        !           635:  *   bit 5 -- s1inf
        !           636:  *   bit 4 -- s2inf
        !           637:  *   bit 3 -- s1zero
        !           638:  *   bit 2 -- s2zero
        !           639:  *   bit 1 -- s1denorm
        !           640:  *   bit 0 -- s2denorm
        !           641:  */
        !           642:
        !           643: /*
        !           644:  * Using code for both single and double precision, check if S1 is either
        !           645:  * a NaN or infinity and set the appropriate flags in r12. Then check if
        !           646:  * S2 is a NaN or infinity. If it is a NaN, then branch to the NaN routine.
        !           647:  */
        !           648:
        !           649: ASLOCAL(opercheck)
        !           650:        extu    r10,r5,11<20>   /* internal representation for double */
        !           651:        bb1.n   s1size,r9,S1NaNdoub /* S1 is double precision */
        !           652:         or     r12,r0,r0       /* clear operand flag register */
        !           653: ASLOCAL(S1NaNsing)
        !           654:        xor     r10,r10,0x0080  /* internal representation for single */
        !           655:        ext     r10,r10,8<0>    /* precision is IEEE 8 bits sign extended */
        !           656:                                /* to 11 bits; for real exp. > 0, the */
        !           657:                                /* above instructions gives a result exp. */
        !           658:                                /* that has the MSB flipped and sign */
        !           659:                                /* extended like in the IMPCR */
        !           660:        cmp     r11,r10,127     /* Is exponent equal to IEEE 255 (here 127) */
        !           661:        bb1     ne,r11,S2NaN    /* source 1 is not a NaN or infinity */
        !           662:        mak     r10,r5,20<0>    /* load r10 with upper bits of S1 mantissa */
        !           663:        extu    r11,r6,3<29>    /* get 3 upper bits of lower word */
        !           664:        or      r11,r10,r11     /* combine any existing 1 */
        !           665:        bcnd    eq0,r11,noS1NaNs /* since r11 can only hold 0 or a */
        !           666:                                /* > 0 number, branch to noS1NaN when eq0 */
        !           667:        br.n    S2NaN           /* see if S2 has a NaN */
        !           668:         set    r12,r12,1<s1nan> /* indicate that S1 has a NaN */
        !           669: ASLOCAL(noS1NaNs)
        !           670:        br.n    S2NaN           /* check contents of S2 */
        !           671:         set    r12,r0,1<s1inf> /* indicate that S1 has an infinity */
        !           672:
        !           673: ASLOCAL(S1NaNdoub)
        !           674:        xor     r10,r10,0x0400  /* precision is the same IEEE 11 bits */
        !           675:                                /* The above instructions gives a result exp. */
        !           676:                                /* that has the MSB flipped and sign */
        !           677:                                /* extended like in the IMPCR */
        !           678:        cmp     r11,r10,1023    /* Is exp. equal to IEEE 2047 (internal 1023) */
        !           679:        bb1     ne,r11,S2NaN    /* source 1 is not a NaN or infinity */
        !           680:        mak     r10,r5,20<0>    /* load r10 with upper bits of S1 mantissa */
        !           681:        or      r11,r6,r10      /* combine existing 1''s of mantissa */
        !           682:        bcnd    eq0,r11,noS1NaNd /* since r11 can only hold 0 or a > 0 */
        !           683:                                /* number, branch to noS1NaN when eq0 */
        !           684:        br.n    S2NaN           /* see if S2 has a NaN */
        !           685:         set    r12,r12,1<s1nan> /* indicate that S1 has a NaN */
        !           686: ASLOCAL(noS1NaNd)
        !           687:        set     r12,r0,1<s1inf> /* indicate that S1 has an infinity */
        !           688:
        !           689: ASLOCAL(S2NaN)
        !           690:        bb1.n   s2size,r9,S2NaNdoub /* S1 is double precision */
        !           691:         extu   r10,r7,11<20>   /* internal representation for double */
        !           692: ASLOCAL(S2NaNsing)
        !           693:        xor     r10,r10,0x0080  /* internal representation for single */
        !           694:        ext     r10,r10,8<0>    /* precision is IEEE 8 bits sign extended */
        !           695:                                /* to 11 bits; for real exp. > 0, the */
        !           696:                                /* above instruction gives a result exp. */
        !           697:                                /* that has the MSB flipped and sign */
        !           698:                                /* extended like in the IMPCR */
        !           699:        cmp     r11,r10,127     /* Is exponent equal to IEEE 255 (here 127) */
        !           700:        bb1     ne,r11,inf      /* source 2 is not a NaN or infinity */
        !           701:        mak     r10,r7,20<0>    /* load r10 with upper bits of S1 mantissa */
        !           702:        extu    r11,r8,3<29>    /* get 3 upper bits of lower word */
        !           703:        or      r11,r10,r11     /* combine any existing 1''s */
        !           704:        bcnd    eq0,r11,noS2NaNs /* since r11 can only hold 0 or a > 0 */
        !           705:                                /* number, branch to noS2NaNs when eq0 */
        !           706:        br.n    _ASM_LABEL(NaN) /* branch to NaN routine */
        !           707:         set    r12,r12,1<s2nan> /* indicate that s2 has a NaN */
        !           708: ASLOCAL(noS2NaNs)
        !           709:        bb0     s1nan,r12, 1f   /* branch to NaN if S1 is a NaN */
        !           710:        br      _ASM_LABEL(NaN)
        !           711: 1:
        !           712:        br.n    _ASM_LABEL(infinity) /* If S1 had a NaN we would have */
        !           713:                                /* already branched, and S2 does not have a */
        !           714:                                /* NaN, but it does have an infinity, so */
        !           715:                                /* branch to handle the finity */
        !           716:         set    r12,r12,1<s2inf> /* indicate that S2 has an infinity */
        !           717:
        !           718: ASLOCAL(S2NaNdoub)
        !           719:        xor     r10,r10,0x0400  /* precision is the same IEEE 11 bits */
        !           720:                                /* The above instruction gives a result exp. */
        !           721:                                /* that has the MSB flipped and sign */
        !           722:                                /* extended like in the IMPCR */
        !           723:        cmp     r11,r10,1023    /* Is exp. equal to IEEE 2047 (internal 1023) */
        !           724:        bb1     ne,r11,inf      /* source 2 is not a NaN or infinity */
        !           725:        mak     r10,r7,20<0>    /* load r10 with upper bits of S2 mantissa */
        !           726:        or      r11,r8,r10      /* combine existing 1''s of mantissa */
        !           727:        bcnd    eq0,r11,noS2NaNd /* since r11 can only hold 0 or a > 0 */
        !           728:                                /* number, branch to noS2NaNd when eq0 */
        !           729:        br.n    _ASM_LABEL(NaN) /* branch to NaN routine */
        !           730:         set    r12,r12,1<s2nan> /* indicate that s2 has a NaN */
        !           731: ASLOCAL(noS2NaNd)
        !           732:        bb0     s1nan,r12,1f    /* branch to NaN if S1 is a NaN */
        !           733:        br      _ASM_LABEL(NaN)
        !           734: 1:
        !           735:        br.n    _ASM_LABEL(infinity) /* If S1 had a NaN we would have */
        !           736:                                /* already branched, and S2 does not have a */
        !           737:                                /* NaN, but it does have an infinity, so */
        !           738:                                /* branch to handle the finity */
        !           739:         set    r12,r12,1<s2inf> /* indicate that S2 has an infinity */
        !           740:
        !           741: /*
        !           742:  * If S2 was a NaN, the routine would have already branched to NaN. If S1
        !           743:  * is a NaN, then branch to NaN. If S1 is not a NaN and S2 is infinity, then
        !           744:  * we would have already branched to infinity. If S1 is infinity, then branch.
        !           745:  * If the routine still has not branched, then branch to denorm, the only
        !           746:  * reserved operand left.
        !           747:  */
        !           748:
        !           749: ASLOCAL(inf)
        !           750:        bb0     s1nan,r12,1f    /* branch if S1 has a NaN and S2 does not */
        !           751:        br      _ASM_LABEL(NaN)
        !           752: 1:
        !           753:        bb0     s1inf,r12,2f    /* Neither S1 or S2 has a NaN, and we would */
        !           754:                                /* have branched already if S2 had an */
        !           755:                                /* infinity, so branch if S1 is infinity */
        !           756:        br      _ASM_LABEL(infinity)
        !           757: 2:
        !           758:        br      _ASM_LABEL(denorm)      /* branch to denorm, the only */
        !           759:                                        /* remaining alternative */
        !           760:
        !           761: /*
        !           762:  * Branch to the routine to make a denormalized number.
        !           763:  */
        !           764: ASLOCAL(FPunderflow)
        !           765:        st      r1,r31,0        /* save return address */
        !           766:        set     r2,r2,1<underflow>
        !           767:        set     r2,r2,1<inexact>
        !           768:
        !           769: /*
        !           770:  * Now the floating point number, which has an exponent smaller than what
        !           771:  * IEEE allows, must be denormalized. Denormalization is done by calculating
        !           772:  * the difference between a denormalized exponent and an underflow exponent
        !           773:  * and shifting the mantissa by that amount. A one may need to be subtracted
        !           774:  * from the LSB if a one was added during rounding.
        !           775:  * r9 is used to contain the guard, round, sticky, and an inaccuracy bit in
        !           776:  * case some bits were shifted off the mantissa during denormalization.
        !           777:  * r9 will contain:
        !           778:  *   bit 4 -- new addone if one added during rounding after denormalization
        !           779:  *   bit 3 -- inaccuracy flag caused by denormalization or pre-denormalization
        !           780:  *            inexactness
        !           781:  *   bit 2 -- guard bit of result
        !           782:  *   bit 1 -- round bit of result
        !           783:  *   bit 0 -- sticky bit of result
        !           784:  */
        !           785:
        !           786: FPU_denorm:
        !           787:        bb1.n   destsize,r12,Udouble    /* denorm for double */
        !           788:         extu   r9,r10,3<26>    /* load r9 with grs */
        !           789: Usingle:
        !           790:        mak     r5,r10,21<3>    /* extract high 21 bits of mantissa */
        !           791:        extu    r6,r11,3<29>    /* extract low 3 bits of mantissa */
        !           792:        or      r11,r5,r6       /* form 24 bits of mantissa */
        !           793:
        !           794: /* See if the addone bit is set and unround if it is. */
        !           795:        bb0.n   25,r10,nounrounds /* do not unround if addone bit clear */
        !           796:         extu   r6,r12,12<20>   /* extract signed exponent from IMPCR */
        !           797: unrounds:
        !           798:        subu    r11,r11,1       /* subtract 1 from mantissa */
        !           799:
        !           800: /*
        !           801:  * If the hidden bit is cleared after subtracting the one, then the one added
        !           802:  * during the rounding must have propagated through the mantissa. The exponent
        !           803:  * will need to be decremented.
        !           804:  */
        !           805:        bb1     23,r11,nounrounds /* if hidden bit is set,then exponent */
        !           806:                                /* does not need to be decremented */
        !           807: decexps:
        !           808:        sub     r6,r6,1         /* decrement exponent 1 */
        !           809:        set     r11,r11,1<23>   /* set the hidden bit */
        !           810:
        !           811: /*
        !           812:  * For both single and double precision, there are cases where it is easier
        !           813:  * and quicker to make a special case. Examples of this are if the shift
        !           814:  * amount is only 1 or 2, or all the mantissa is shifted off, or all the
        !           815:  * mantissa is shifted off and it is still shifting, or, in the case of
        !           816:  * doubles, if the shift amount is around the boundary of MANTLO and MANTHI.
        !           817:  */
        !           818:
        !           819: nounrounds:
        !           820:        or      r8,r0,lo16(0x00000f81)  /* load r8 with -127 in decimal */
        !           821:                                        /* for lowest 12 bits */
        !           822:        sub     r7,r8,r6        /* find difference between two exponents, */
        !           823:                                /* this amount is the shift amount */
        !           824:        cmp     r6,r7,3         /* check to see if r7 contains 3 or more */
        !           825:        bb1     ge,r6,threesing /* br to code that handles shifts of >=3 */
        !           826:        cmp     r6,r7,2         /* check to see if r7 contains 2 */
        !           827:        bb1     eq,r6,twosing   /* br to code that handles shifts of 2 */
        !           828: one:
        !           829:        rot     r9,r9,0<1>      /* rotate roundoff register once, this places */
        !           830:                                /* guard in round and round in sticky */
        !           831:        bb0     31,r9,nosticky1s /* do not or round and sticky if sticky is */
        !           832:                                /* 0, this lost bit will be cleared later */
        !           833:        set     r9,r9,1<0>      /* or round and sticky */
        !           834: nosticky1s:
        !           835:        bb0     0,r11,guardclr1s /* do not set guard bit if LSB = 0 */
        !           836:        set     r9,r9,1<2>      /* set guard bit */
        !           837: guardclr1s:
        !           838:        extu    r11,r11,31<1>   /* shift mantissa right 1 */
        !           839:        br.n    round           /* round result */
        !           840:         mak    r9,r9,3<0>      /* clear bits lost during rotation */
        !           841:
        !           842: twosing:
        !           843:        rot     r9,r9,0<2>      /* rotate roundff register twice, this places */
        !           844:                                /* guard in sticky */
        !           845:        bb0     30,r9,nosticky2s /* do not or guard and sticky if stick is 0 */
        !           846:                                /* this lost bit will be cleared later */
        !           847:        br.n    noround2s       /* skip or old guard and old round if old */
        !           848:                                /* sticky set */
        !           849:         set    r9,r9,1<0>      /* or guard and sticky */
        !           850: nosticky2s:
        !           851:        bb0     31,r9,noround2s /* do not or guard and round if round is 0 */
        !           852:                                /* this lost bit will be cleared later */
        !           853:        set     r9,r9,1<0>      /* or guard and round */
        !           854: noround2s:
        !           855:        bb0     0,r11,roundclr2s /* do not set round bit if LSB = 0 */
        !           856:        set     r9,r9,1<1>      /* set round bit */
        !           857: roundclr2s:
        !           858:        bb0     1,r11,guardclr2s /* do not set guard bit if LSB + 1 = 0 */
        !           859:        set     r9,r9,1<2>      /* set guard bit */
        !           860: guardclr2s:
        !           861:        extu    r11,r11,30<2>   /* shift mantissa right 2 */
        !           862:        br.n    round           /* round result */
        !           863:         mak    r9,r9,3<0>      /* clear bits lost during rotation */
        !           864:
        !           865: threesing:
        !           866:        bb1     0,r9,noguard3s  /* check sticky initially */
        !           867:                                /* sticky is set, forget most of the oring */
        !           868: nosticky3s:
        !           869:        bb0     1,r9,noround3s  /* check round initially, do not set sticky */
        !           870:        br.n    noguard3s       /* forget most of the rest of oring */
        !           871:         set    r9,r9,1<0>      /* if round is clear,set sticky if round set */
        !           872: noround3s:
        !           873:        bb0.n   2,r9,noguard3s  /* check guard initially, do not set sticky */
        !           874:         clr    r9,r9,2<1>      /* clear the original guard and round for when */
        !           875:                                /* you get to round section */
        !           876:        set     r9,r9,1<0>      /* if guard is clear,set sticky if guard set */
        !           877: noguard3s:
        !           878:        cmp     r6,r7,23        /* check if # of shifts is <=23 */
        !           879:        bb1     gt,r6,s24       /* branch to see if shifts = 24 */
        !           880:        sub     r6,r7,2         /* get number of bits to check for sticky */
        !           881:        mak     r6,r6,5<5>      /* shift width into width field */
        !           882:        mak     r8,r11,r6       /* mask off shifted bits -2 */
        !           883:        ff1     r8,r8           /* see if r8 has any ones */
        !           884:        bb1     5,r8,nostky23   /* do not set sticky if no ones found */
        !           885:        set     r9,r9,1<0>      /* set sticky bit */
        !           886: nostky23:
        !           887:        or      r8,r0,34        /* start code to get new mantissa plus two */
        !           888:                                /* extra bits for new round and new guard */
        !           889:                                /* bits */
        !           890:        subu    r8,r8,r7
        !           891:        mak     r8,r8,5<5>      /* shift field width into second five bits */
        !           892:        extu    r6,r6,5<5>      /* shift previous shifted -2 into offset field */
        !           893:        or      r6,r6,r8        /* complete field */
        !           894:        extu    r11,r11,r6      /* form new mantissa with two extra bits */
        !           895:
        !           896:        bb0     0,r11,nornd3s   /* do not set new round bit */
        !           897:        set     r9,r9,1<1>      /* set new round bit */
        !           898: nornd3s:
        !           899:        bb0     1,r11,nogrd3s   /* do not set new guard bit */
        !           900:        set     r9,r9,1<2>      /* set new guard bit */
        !           901: nogrd3s:
        !           902:        br.n    round           /* round mantissa */
        !           903:         extu   r11,r11,30<2>   /* shift off remaining two bits */
        !           904:
        !           905: s24:
        !           906:        cmp     r6,r7,24        /* check to see if # of shifts is 24 */
        !           907:        bb1     gt,r6,s25       /* branch to see if shifts = 25 */
        !           908:        bb1     0,r9,nostky24   /* skip checking if old sticky set */
        !           909:        extu    r8,r11,22<0>    /* prepare to check bits that will be shifted */
        !           910:                                /* into the sticky */
        !           911:        ff1     r8,r8           /* see if there are any 1''s */
        !           912:        bb1     5,r8,nostky24   /* do not set sticky if no ones found */
        !           913:        set     r9,r9,1<0>      /* set sticky bit */
        !           914: nostky24:
        !           915:        bb0     22,r11,nornd24  /* do not set new round bit */
        !           916:        set     r9,r9,1<1>      /* set new round bit */
        !           917: nornd24:
        !           918:        set     r9,r9,1<2>      /* set new guard bit,this is hidden bit */
        !           919:        br.n    round           /* round mantissa */
        !           920:         or     r11,r0,r0       /* clear r11, all of mantissa shifted off */
        !           921:
        !           922: s25:
        !           923:        cmp     r6,r7,25        /* check to see if # of shifts is 25 */
        !           924:        bb1     gt,r6,s26       /* branch to execute for shifts => 26 */
        !           925:        bb1     0,r9,nostky25   /* skip checking if old sticky set */
        !           926:        extu    r8,r11,23<0>    /* prepare to check bits that will be shifted */
        !           927:                                /* into the sticky */
        !           928:        ff1     r8,r8           /* see if there are any 1''s */
        !           929:        bb1     5,r8,nostky25   /* do not set sticky if no ones found */
        !           930:        set     r9,r9,1<0>      /* set sticky bit */
        !           931: nostky25:
        !           932:        set     r9,r9,1<1>      /* set new round bit,this is hidden bit */
        !           933:        clr     r9,r9,1<2>      /* clear guard bit since nothing shifted in */
        !           934:        br.n    round           /* round and assemble result */
        !           935:         or     r11,r0,r0       /* clear r11, all of mantissa shifted off */
        !           936:
        !           937: s26:
        !           938:        set     r9,r9,1<0>      /* set sticky bit,this contains hidden bit */
        !           939:        clr     r9,r9,2<1>      /* clear guard and round bits since nothing */
        !           940:                                /* shifted in */
        !           941:        br.n    round           /* round and assemble result */
        !           942:         or     r11,r0,r0       /* clear mantissa */
        !           943:
        !           944: Udouble:
        !           945:        mak     r5,r10,21<0>    /* extract upper bits of mantissa */
        !           946:        bb0.n   25,r10,nounroundd /* do not unround if addone bit clear */
        !           947:         extu   r6,r12,12<20>   /* extract signed exponenet from IMPCR */
        !           948: unroundd:
        !           949:        or      r8,r0,1
        !           950:        subu.co r11,r11,r8      /* subtract 1 from mantissa */
        !           951:        subu.ci r5,r5,r0        /* subtract borrow from upper word */
        !           952:        bb1     20,r5,nounroundd /* if hidden bit is set, then exponent does */
        !           953:                                /* not need to be decremented */
        !           954: decexpd:
        !           955:        sub     r6,r6,1         /* decrement exponent 1 */
        !           956:        set     r5,r5,1<20>     /* set the hidden bit */
        !           957:
        !           958: nounroundd:
        !           959:        or      r8,r0,lo16(0x00000c01) /* load r8 with -1023 in decimal */
        !           960:                                /* for lowest 12 bits */
        !           961:        sub     r7,r8,r6        /* find difference between two exponents, */
        !           962:                                /* this amount is the shift amount */
        !           963:        cmp     r6,r7,3         /* check to see if r7 contains 3 or more */
        !           964:        bb1     ge,r6,threedoub /* br to code that handles shifts of >=3 */
        !           965:        cmp     r6,r7,2         /* check to see if r7 contains 2 */
        !           966:        bb1     eq,r6,twodoub   /* br to code that handles shifts of 2 */
        !           967:
        !           968: onedoub:
        !           969:        rot     r9,r9,0<1>      /* rotate roundoff register once, this places */
        !           970:                                /* guard in round and round in sticky */
        !           971:        bb0     31,r9,nosticky1d/* do not or round and sticky if sticky is 0 */
        !           972:                                /* this lost bit will be cleared later */
        !           973:        set     r9,r9,1<0>      /* or old round and old sticky into new sticky */
        !           974: nosticky1d:
        !           975:        bb0     0,r11,guardclr1d /* do not set new guard bit if old LSB = 0 */
        !           976:        set     r9,r9,1<2>      /* set new guard bit */
        !           977: guardclr1d:
        !           978:        extu    r11,r11,31<1>   /* shift lower mantissa over 1 */
        !           979:        mak     r6,r5,1<31>     /* shift off low bit of high mantissa */
        !           980:        or      r11,r6,r11      /* load high bit onto lower mantissa */
        !           981:        extu    r5,r5,20<1>     /* shift right once upper 20 bits of mantissa */
        !           982:        br.n    round           /* round mantissa and assemble result */
        !           983:         mak    r9,r9,3<0>      /* clear bits lost during rotation */
        !           984:
        !           985: twodoub:
        !           986:        rot     r9,r9,0<2>      /* rotate roundoff register twice, this places */
        !           987:                                /* old guard into sticky */
        !           988:        bb0     30,r9,nosticky2d /* do not or old guard and old sticky if */
        !           989:                                /* old sticky is 0 */
        !           990:        br.n    noround2d       /* skip or of old guard and old round if old */
        !           991:                                /* sticky set */
        !           992:         set    r9,r9,1<0>      /* or old guard and old sticky into new sticky */
        !           993: nosticky2d:
        !           994:        bb0     31,r9,noround2d /* do not or old guard and old round if */
        !           995:                                /* old round is 0 */
        !           996:        set     r9,r9,1<0>      /* or old guard and old round into new sticky */
        !           997: noround2d:
        !           998:        bb0     0,r11,roundclr2d /* do not set round bit if old LSB = 0 */
        !           999:        set     r9,r9,1<1>      /* set new round bit */
        !          1000: roundclr2d:
        !          1001:        bb0     1,r11,guardclr2d /* do not set guard bit if old LSB + 1 = 0 */
        !          1002:        set     r9,r9,1<2>      /* set new guard bit */
        !          1003: guardclr2d:
        !          1004:        extu    r11,r11,30<2>   /* shift lower mantissa over 2 */
        !          1005:        mak     r6,r5,2<30>     /* shift off low bits of high mantissa */
        !          1006:        or      r11,r6,r11      /* load high bit onto lower mantissa */
        !          1007:        extu    r5,r5,19<2>     /* shift right twice upper 19 bits of mantissa */
        !          1008:        br.n    round           /* round mantissa and assemble result */
        !          1009:         mak    r9,r9,3<0>      /* clear bits lost during rotation */
        !          1010:
        !          1011: threedoub:
        !          1012:        bb1     0,r9,noguard3d  /* checky sticky initially */
        !          1013:                                /* sticky is set, forget most of rest of oring */
        !          1014: nosticky3d:
        !          1015:        bb0     1,r9,noround3d  /* check old round, do not set sticky if */
        !          1016:                                /* old round is clear, set otherwise */
        !          1017:        br.n    noguard3d       /* sticky is set, forget most of rest of oring */
        !          1018:         set    r9,r9,1<0>      /* set sticky if old round is set */
        !          1019: noround3d:
        !          1020:        bb0     2,r9,noguard3d  /* check old guard, do not set sticky if 0 */
        !          1021:        clr     r9,r9,2<1>      /* clear the original guard and round for when */
        !          1022:                                /* you get to round section */
        !          1023:        set     r9,r9,1<0>      /* set sticky if old guard is set */
        !          1024: noguard3d:
        !          1025:        cmp     r6,r7,32        /* do I need to work with a 1 or 2 word mant. */
        !          1026:                                /* when forming sticky, round and guard */
        !          1027:        bb1     gt,r6,d33       /* jump to code that handles 2 word mantissas */
        !          1028:        sub     r6,r7,2         /* get number of bits to check for sticky */
        !          1029:        mak     r6,r6,5<5>      /* shift width into width field */
        !          1030:        mak     r8,r11,r6       /* mask off shifted bits -2 */
        !          1031:        ff1     r8,r8           /* see if r8 has any ones */
        !          1032:        bb1     5,r8,nostky32   /* do not set sticky if no ones found */
        !          1033:        set     r9,r9,1<0>      /* set sticky bit */
        !          1034: nostky32:
        !          1035:        or      r8,r0,34        /* start code to get new mantissa plus two */
        !          1036:                                /* extra bits for new round and new guard bits, */
        !          1037:                                /* the upper word bits will be shifted after */
        !          1038:                                /* the round and guard bits are handled */
        !          1039:        subu    r8,r8,r7
        !          1040:        mak     r8,r8,5<5>      /* shift field width into second five bits */
        !          1041:        extu    r6,r6,5<5>      /* shift previous shifted -2 into offset field */
        !          1042:        or      r6,r6,r8        /* complete bit field */
        !          1043:        extu    r11,r11,r6      /* partially form new low mantissa with 2 more */
        !          1044:                                /* bits */
        !          1045:        bb0     0,r11,nornd32d  /* do not set new round bit */
        !          1046:        set     r9,r9,1<1>      /* set new round bit */
        !          1047: nornd32d:
        !          1048:        bb0     1,r11,nogrd32d  /* do not set new guard bit */
        !          1049:        set     r9,r9,1<2>      /* set new guard bit */
        !          1050: nogrd32d:
        !          1051:        extu    r11,r11,30<2>   /* shift off remaining two bits */
        !          1052:        mak     r6,r7,5<5>      /* shift field width into second 5 bits, if the */
        !          1053:                                /* width is 32, then these bits will be 0 */
        !          1054:        or      r8,r0,32        /* load word length into r8 */
        !          1055:        sub     r8,r8,r7        /* form offset for high bits moved to low word */
        !          1056:        or      r6,r6,r8        /* form complete bit field */
        !          1057:        mak     r6,r5,r6        /* get shifted bits of high word */
        !          1058:        or      r11,r6,r11      /* form new low word of mantissa */
        !          1059:        bcnd    ne0,r8,regular33 /* do not adjust for special case of r8 */
        !          1060:        br.n    round           /* containing zeros, which would cause */
        !          1061:         or     r5,r0,r0        /* all of the bits to be extracted under */
        !          1062:                                /* the regular method */
        !          1063: regular33:
        !          1064:        mak     r6,r7,5<0>      /* place lower 5 bits of shift into r6 */
        !          1065:        mak     r8,r8,5<5>      /* shift r8 into width field */
        !          1066:        or      r6,r6,r8        /* form field for shifting of upper bits */
        !          1067:        br.n    round           /* round and assemble result */
        !          1068:         extu   r5,r5,r6        /* form new high word mantissa */
        !          1069:
        !          1070: d33:
        !          1071:        cmp     r6,r7,33        /* is the number of bits to be shifted is 33? */
        !          1072:        bb1     gt,r6,d34       /* check to see if # of bits is 34 */
        !          1073:        bb1     0,r9,nostky33   /* skip checking if old sticky set */
        !          1074:        mak     r6,r11,31<0>    /* check bits that will be shifted into sticky */
        !          1075:        ff1     r8,r8           /* check for ones */
        !          1076:        bb1     5,r8,nostky33   /* do not set sticky if there are no ones */
        !          1077:        set     r9,r9,1<0>      /* set new sticky bit */
        !          1078: nostky33:
        !          1079:        bb0     31,r11,nornd33  /* do not set round if bit is not a 1 */
        !          1080:        set     r9,r9,1<1>      /* set new round bit */
        !          1081: nornd33:
        !          1082:        bb0     0,r5,nogrd33    /* do not set guard bit if bit is not a 1 */
        !          1083:        set     r9,r9,1<2>      /* set new guard bit */
        !          1084: nogrd33:
        !          1085:        extu    r11,r5,31<1>    /* shift high bits into low word */
        !          1086:        br.n    round           /* round and assemble result */
        !          1087:         or     r5,r0,r0        /* clear high word */
        !          1088:
        !          1089: d34:
        !          1090:        cmp     r6,r7,34        /* is the number of bits to be shifted 34? */
        !          1091:        bb1     gt,r6,d35       /* check to see if # of bits is >= 35 */
        !          1092:        bb1     0,r9,nostky34   /* skip checking if old sticky set */
        !          1093:        ff1     r8,r11          /* check bits that will be shifted into sticky */
        !          1094:        bb1     5,r8,nostky34   /* do not set sticky if there are no ones */
        !          1095:        set     r9,r9,1<0>      /* set new sticky bit */
        !          1096: nostky34:
        !          1097:        bb0     0,r5,nornd34    /* do not set round if bit is not a 1 */
        !          1098:        set     r9,r9,1<1>      /* set new round bit */
        !          1099: nornd34:
        !          1100:        bb0     1,r5,nogrd34    /* do not set guard bit if bit is not a 1 */
        !          1101:        set     r9,r9,1<2>      /* set new guard bit */
        !          1102: nogrd34:
        !          1103:        extu    r11,r5,30<2>    /* shift high bits into low word */
        !          1104:        br.n    round           /* round and assemble result */
        !          1105:         or     r5,r0,r0        /* clear high word */
        !          1106:
        !          1107: d35:
        !          1108:        cmp     r6,r7,52        /* see if # of shifts is 35 <= X <= 52 */
        !          1109:        bb1     gt,r6,d53       /* check to see if # of shifts is 52 */
        !          1110:        bb1.n   0,r9,nostky35   /* skip checking if old sticky set */
        !          1111:         sub    r7,r7,34        /* subtract 32 from # of shifts so that opera- */
        !          1112:                                /* tions can be done on the upper word, and */
        !          1113:                                /* then subtract two more checking guard and */
        !          1114:                                /* sticky bits */
        !          1115:        ff1     r8,r11          /* see if lower word has a bit for sticky */
        !          1116:        bb1     5,r8,stkycheck35 /* see if upper word has any sticky bits       */
        !          1117:        br.n    nostky35        /* quit checking for sticky */
        !          1118:         set    r9,r9,1<0>      /* set sticky bit */
        !          1119: stkycheck35:
        !          1120:        mak     r6,r7,5<5>      /* place width into width field */
        !          1121:        mak     r8,r5,r6        /* mask off shifted bits - 2 */
        !          1122:        ff1     r8,r8           /* see if r8 has any ones */
        !          1123:        bb1     5,r8,nostky35   /* do not set sticky if no ones found */
        !          1124:        set     r9,r9,1<0>      /* set sticky bit */
        !          1125: nostky35:
        !          1126:        or      r8,r0,32        /* look at what does not get shifted off plus */
        !          1127:                                /* round and sticky, remember that the r7 value */
        !          1128:                                /* was adjusted so that it did not include */
        !          1129:                                /* new round or new sticky in shifted off bits */
        !          1130:        subu    r8,r8,r7        /* complement width */
        !          1131:        mak     r8,r8,5<5>      /* shift width into width field */
        !          1132:        or      r8,r7,r8        /* add offset field */
        !          1133:        extu    r11,r5,r8       /* extract upper bits into low word */
        !          1134:        bb0     0,r11,nornd35   /* do not set new round bit */
        !          1135:        set     r9,r9,1<1>      /* set new round bit */
        !          1136: nornd35:
        !          1137:        bb0     1,r11,nogrd35   /* do not set new guard bit */
        !          1138:        set     r9,r9,1<2>      /* set new guard bit */
        !          1139: nogrd35:
        !          1140:        extu    r11,r11,30<2>   /* shift off remaining guard and round bits */
        !          1141:        br.n    round           /* round and assemble result */
        !          1142:         or     r5,r0,r0        /* clear high word */
        !          1143:
        !          1144: d53:
        !          1145:        cmp     r6,r7,53        /* check to see if # of shifts is 53 */
        !          1146:        bb1     gt,r6,d54       /* branch to see if shifts = 54 */
        !          1147:        bb1     0,r9,nostky53   /* skip checking if old sticky set */
        !          1148:        ff1     r8,r11          /* see if lower word has a bit for sticky */
        !          1149:        bb1     5,r8,stkycheck53 /* see if upper word has any sticky bits       */
        !          1150:        br.n    nostky53        /* quit checking for sticky */
        !          1151:         set    r9,r9,1<0>      /* set sticky bit */
        !          1152: stkycheck53:
        !          1153:        mak     r6,r5,19<0>     /* check bits that are shifted into sticky */
        !          1154:        ff1     r8,r6           /* see if r6 has any ones */
        !          1155:        bb1     5,r8,nostky53   /* do not set sticky if no ones found */
        !          1156:        set     r9,r9,1<0>      /* set sticky bit */
        !          1157: nostky53:
        !          1158:        bb0     19,r5,nornd53   /* do not set new round bit */
        !          1159:        set     r9,r9,1<1>      /* set new round bit */
        !          1160: nornd53:
        !          1161:        set     r9,r9,1<2>      /* set new guard bit,this is hidden bit */
        !          1162:        or      r5,r0,r0        /* clear high word */
        !          1163:        br.n    round           /* round and assemble result */
        !          1164:         or     r11,r0,r0       /* clear low word */
        !          1165:
        !          1166: d54:
        !          1167:        cmp     r6,r7,54        /* check to see if # of shifts is 54 */
        !          1168:        bb1     gt,r6,d55       /* branch to execute for shifts =>55 */
        !          1169:        bb1     0,r9,nostky54   /* skip checking if old sticky set */
        !          1170:        ff1     r8,r11          /* see if lower word has a bit for sticky */
        !          1171:        bb1     5,r8,stkycheck54 /* see if upper word has any sticky bits       */
        !          1172:        br.n    nostky54        /* quit checking for sticky */
        !          1173:         set    r9,r9,1<0>      /* set sticky bit */
        !          1174: stkycheck54:
        !          1175:        mak     r6,r5,20<0>     /* check bits that are shifted into sticky */
        !          1176:        ff1     r8,r6           /* see if r6 has any ones */
        !          1177:        bb1     5,r8,nostky54   /* do not set sticky if no ones found */
        !          1178:        set     r9,r9,1<0>      /* set sticky bit */
        !          1179: nostky54:
        !          1180:        set     r9,r9,1<1>      /* set new round bit,this is hidden bit */
        !          1181:        clr     r9,r9,1<2>      /* clear guard bit since nothing shifted in */
        !          1182:        or      r5,r0,r0        /* clear high word */
        !          1183:        br.n    round           /* round and assemble result */
        !          1184:         or     r11,r0,r0       /* clear low word */
        !          1185:
        !          1186: d55:
        !          1187:        set     r9,r9,1<0>      /* set new sticky bit,this contains hidden bit */
        !          1188:        clr     r9,r9,2<1>      /* clear guard and round bits since nothing */
        !          1189:                                /* shifted in */
        !          1190:        or      r5,r0,r0        /* clear high word */
        !          1191:        or      r11,r0,r0       /* clear low word */
        !          1192:
        !          1193:
        !          1194: /* The first item that the rounding code does is see if either guard, round, */
        !          1195: /* or sticky is set. If all are clear, then there is no denormalization loss */
        !          1196: /* and no need to round, then branch to assemble answer. */
        !          1197: /* For rounding, a branch table is set up. The left two most bits are the */
        !          1198: /* rounding mode. The third bit is either the LSB of the mantissa or the */
        !          1199: /* sign bit, depending on the rounding mode. The three LSB''s are the guard, */
        !          1200: /* round and sticky bits. */
        !          1201:
        !          1202: round:
        !          1203:        ff1     r8,r9           /* see if there is denormalization loss */
        !          1204:        bb1     5,r8,assemble   /* no denormalization loss or inexactness */
        !          1205:        extu    r6,r10,2<modelo> /* extract rounding mode */
        !          1206:        bb1.n   modehi,r10,signext /* use sign bit instead of LSB */
        !          1207:         mak    r6,r6,2<4>      /* shift over rounding mode */
        !          1208:        extu    r7,r11,1<0>     /* extract LSB */
        !          1209:        br.n    grs             /* skip sign extraction */
        !          1210:         mak    r7,r7,1<3>      /* shift over LSB */
        !          1211: signext:
        !          1212:        extu    r7,r10,1<31>    /* extract sign bit */
        !          1213:        mak     r7,r7,1<3>      /* shift sign bit over */
        !          1214: grs:
        !          1215:        or      r6,r6,r7
        !          1216:        or      r6,r6,r9        /* or in guard, round, and sticky */
        !          1217:        or.u    r1,r0,hi16(roundtable) /* form address of branch table */
        !          1218:        or      r1,r1,lo16(roundtable)
        !          1219:        lda     r6,r1[r6]       /* scale offset into branch table */
        !          1220:        jmp.n   r6              /* jump to branch table */
        !          1221:         set    r9,r9,1<3>      /* set inexact flag in r9 */
        !          1222:
        !          1223: roundtable:
        !          1224:        br      noaddone
        !          1225:        br      noaddone
        !          1226:        br      noaddone
        !          1227:        br      noaddone
        !          1228:        br      noaddone
        !          1229:        br      addone
        !          1230:        br      addone
        !          1231:        br      addone
        !          1232:        br      noaddone
        !          1233:        br      noaddone
        !          1234:        br      noaddone
        !          1235:        br      noaddone
        !          1236:        br      addone
        !          1237:        br      addone
        !          1238:        br      addone
        !          1239:        br      addone
        !          1240:        br      noaddone
        !          1241:        br      noaddone
        !          1242:        br      noaddone
        !          1243:        br      noaddone
        !          1244:        br      noaddone
        !          1245:        br      noaddone
        !          1246:        br      noaddone
        !          1247:        br      noaddone
        !          1248:        br      noaddone
        !          1249:        br      noaddone
        !          1250:        br      noaddone
        !          1251:        br      noaddone
        !          1252:        br      noaddone
        !          1253:        br      noaddone
        !          1254:        br      noaddone
        !          1255:        br      noaddone
        !          1256:        br      noaddone
        !          1257:        br      noaddone
        !          1258:        br      noaddone
        !          1259:        br      noaddone
        !          1260:        br      noaddone
        !          1261:        br      noaddone
        !          1262:        br      noaddone
        !          1263:        br      noaddone
        !          1264:        br      noaddone
        !          1265:        br      addone
        !          1266:        br      addone
        !          1267:        br      addone
        !          1268:        br      addone
        !          1269:        br      addone
        !          1270:        br      addone
        !          1271:        br      addone
        !          1272:        br      noaddone
        !          1273:        br      addone
        !          1274:        br      addone
        !          1275:        br      addone
        !          1276:        br      addone
        !          1277:        br      addone
        !          1278:        br      addone
        !          1279:        br      addone
        !          1280:        br      noaddone
        !          1281:        br      noaddone
        !          1282:        br      noaddone
        !          1283:        br      noaddone
        !          1284:        br      noaddone
        !          1285:        br      noaddone
        !          1286:        br      noaddone
        !          1287:        br      noaddone
        !          1288:
        !          1289: /* Round by adding a one to the LSB of the mantissa. */
        !          1290: addone:
        !          1291:        or      r6,r0,1         /* load a 1 into r6 so that add.co can be used */
        !          1292:        add.co  r11,r11,r6      /* add a one to the lower word of result */
        !          1293:        bb0.n   destsize,r12,noaddone /* single result,forget carry */
        !          1294:         set    r9,r9,1<4>      /* indicate that a 1 has been added */
        !          1295:        add.ci  r5,r5,r0        /* propagate carry into high word */
        !          1296:
        !          1297: noaddone:
        !          1298:        set     r2,r2,1<inexact>
        !          1299:        set     r2,r2,1<underflow>
        !          1300:
        !          1301: /* Assemble the result of the denormalization routine for writeback to the */
        !          1302: /* destination register. The exponent of a denormalized number is zero, */
        !          1303: /* so simply assemble the sign and the new mantissa. */
        !          1304:
        !          1305: assemble:
        !          1306:        bb1     destsize,r12,doubassem  /* assemble double result */
        !          1307:        bb0     sign,r10,exassems       /* exit assemble if sign is zero */
        !          1308:        set     r11,r11,1<sign>         /* make result negative */
        !          1309: exassems:
        !          1310:        br      Ureturn
        !          1311:
        !          1312: doubassem:
        !          1313:        bb0.n   sign,r10,signclr        /* do not set sign in r10 */
        !          1314:         or     r10,r5,r0               /* load high word from r5 into r10 */
        !          1315:        set     r10,r10,1<sign>         /* high word with sign loaded */
        !          1316: signclr:
        !          1317:        /* FALLTHROUGH */
        !          1318:        /* br   Ureturn */
        !          1319:
        !          1320: /* Return to fpui. */
        !          1321: Ureturn:
        !          1322:        ld      r1,r31,0        /* load return address */
        !          1323:        jmp     r1
        !          1324:
        !          1325: /*
        !          1326:  * FPoverflow
        !          1327:  */
        !          1328:
        !          1329: ASLOCAL(FPoverflow)
        !          1330:        st      r1,r31,0        /* save return address */
        !          1331:        set     r2,r2,1<overflow>
        !          1332:        set     r2,r2,1<inexact>
        !          1333:
        !          1334: /* Determine which rounding mode to use for the default procedure. */
        !          1335:
        !          1336:        bb1     modehi,r10,signed /* mode is either round toward pos. or neg. */
        !          1337:        bb0     modelo,r10,OFnearest /* rounding mode is round nearest */
        !          1338:        br      OFzero          /* rounding mode is round zero */
        !          1339: signed:
        !          1340:        bb0     modelo,r10,OFnegative /* rounding mode is round negative */
        !          1341:        br      positive        /* rounding mode is round positive */
        !          1342:
        !          1343:
        !          1344: /* In the round toward nearest mode, positive values are rounded to */
        !          1345: /* positive infinity and negative values are loaded toward negative infinity. */
        !          1346: /* The value for single or double precision is loaded from a data table. */
        !          1347:
        !          1348: OFnearest:
        !          1349:        bb1.n   destsize,r12,neardouble /* branch to neardouble of */
        !          1350:                                        /* double result */
        !          1351:         mask.u r5,r10,0x8000           /* mask off sign bit from MANTHI */
        !          1352:        or.u    r11,r0,hi16(0x7f800000) /* load single infinity constant */
        !          1353:        or      r11,r11,lo16(0x7f800000)
        !          1354:        br.n    FPof_return             /* return with result */
        !          1355:         or     r11,r5,r11              /* adjust sign */
        !          1356: neardouble:
        !          1357:        or      r11,r0,r0               /* load lower word of infinity */
        !          1358:        or.u    r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
        !          1359:        or      r10,r10,lo16(0x7ff00000)
        !          1360:        br.n    FPof_return             /* return with result */
        !          1361:         or     r10,r5,r10              /* adjust sign */
        !          1362:
        !          1363:
        !          1364: /* In the round toward zero mode, positive values are rounded to the largest */
        !          1365: /* postive finite number and negative values are rounded toward the largest */
        !          1366: /* negative finite number. */
        !          1367: /* The value for single or double precision is loaded from a data table. */
        !          1368:
        !          1369: OFzero:
        !          1370:        bb1.n   destsize,r12,zerodouble /* branch to zerodouble of */
        !          1371:                                        /* double result */
        !          1372:         mask.u r5,r10,0x8000           /* mask off sign bit from MANTHI */
        !          1373:        or.u    r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
        !          1374:        or      r11,r11,lo16(0x7f7fffff)
        !          1375:        br.n    FPof_return             /* return with result */
        !          1376:         or     r11,r5,r11              /* adjust sign */
        !          1377: zerodouble:
        !          1378:        set     r11,r0,0<0>             /* load lower word of finite number */
        !          1379:        or.u    r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
        !          1380:        or      r10,r10,lo16(0x7fefffff)
        !          1381:        br.n    FPof_return             /* return with result */
        !          1382:         or     r10,r5,r10              /* adjust sign */
        !          1383:
        !          1384:
        !          1385: /* In the round toward positve mode, positive values are rounded to */
        !          1386: /* postive infinity and negative values are loaded toward the largest */
        !          1387: /* negative finite number. */
        !          1388: /* The value for single or double precision is loaded from a data table. */
        !          1389:
        !          1390: positive:
        !          1391:        bb1     destsize,r12,posdouble  /* branch to section for double result */
        !          1392: possingle:
        !          1393:        bb1     sign,r10,possingleneg   /* branch to section for negatives */
        !          1394: possinglepos:
        !          1395:        or.u    r11,r0,hi16(0x7f800000) /* load single infinity constant */
        !          1396:        br.n    FPof_return             /* return with result */
        !          1397:         or     r11,r11,lo16(0x7f800000)
        !          1398: possingleneg:
        !          1399:        or.u    r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
        !          1400:        or      r11,r11,lo16(0x7f7fffff)
        !          1401:        br.n    FPof_return             /* return with result */
        !          1402:         set    r11,r11,1<sign>         /* set sign for negative */
        !          1403: posdouble:
        !          1404:        bb1     sign,r10,posdoubleneg   /* branch to negative double results */
        !          1405: posdoublepos:
        !          1406:        or      r11,r0,r0               /* load lower word of double infinity */
        !          1407:        or.u    r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
        !          1408:        br.n    FPof_return             /* return with result */
        !          1409:         or     r10,r10,lo16(0x7ff00000)
        !          1410: posdoubleneg:
        !          1411:        set     r11,r0,0<0>             /* load lower word of finite number */
        !          1412:        or.u    r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
        !          1413:        or      r10,r10,lo16(0x7fefffff)
        !          1414:        br.n    FPof_return             /* return with result */
        !          1415:         set    r10,r10,1<sign>         /* set sign for negative */
        !          1416:
        !          1417:
        !          1418: /* In the round toward negative mode, positive values are rounded to the largest */
        !          1419: /* postive finite number and negative values are rounded to negative infinity. */
        !          1420: /* The value for single or double precision is loaded from a data table. */
        !          1421:
        !          1422: OFnegative:
        !          1423:        bb1     destsize,r12,negdouble  /* branch to section for double result */
        !          1424: negsingle:
        !          1425:        bb1     sign,r10,negsingleneg   /* branch to section for negatives */
        !          1426: negsinglepos:
        !          1427:        or.u    r11,r0,hi16(0x7f7fffff) /* load single finite number constant */
        !          1428:        br.n    FPof_return             /* return with result */
        !          1429:         or     r11,r11,lo16(0x7f7fffff)
        !          1430: negsingleneg:
        !          1431:        or.u    r11,r0,hi16(0x7f800000) /* load single infinity constant */
        !          1432:        or      r11,r11,lo16(0x7f800000)
        !          1433:        br.n    FPof_return             /* return with result */
        !          1434:         set    r11,r11,1<sign>         /* set sign for negative */
        !          1435: negdouble:
        !          1436:        bb1     sign,r10,negdoubleneg   /* branch to negative double results */
        !          1437: negdoublepos:
        !          1438:        set     r11,r0,0<0>             /* load lower word of finite number */
        !          1439:        or.u    r10,r0,hi16(0x7fefffff) /* load upper word of finite number */
        !          1440:        br.n    FPof_return             /* return with result */
        !          1441:         or     r10,r10,lo16(0x7fefffff)
        !          1442: negdoubleneg:
        !          1443:        or      r11,r0,r0               /* load lower word of double infinity */
        !          1444:        or.u    r10,r0,hi16(0x7ff00000) /* load upper word of infinity */
        !          1445:        or      r10,r10,lo16(0x7ff00000)
        !          1446:        set     r10,r10,1<sign>         /* set sign for negative */
        !          1447:
        !          1448: FPof_return:
        !          1449:        ld      r1,r31,0                /* ld return address */
        !          1450:        jmp     r1
        !          1451:
        !          1452: /* If either S1 or S2 is a signalling NaN, then set the invalid operation */
        !          1453: /* bit of the FPSR. */
        !          1454: /* If S1 is the only NaN or one of two NaN''s, then write */
        !          1455: /* a quiet S1 to the result. A signalling NaN must be made quiet before */
        !          1456: /* it can be written, but a signalling S2 is not modified in this routine */
        !          1457: /* if S1 is a NaN. */
        !          1458: ASLOCAL(NaN)
        !          1459:        bb0.n   s1nan,r12,S2sigcheck    /* S1 is not a NaN */
        !          1460:         st     r1,r31,0                /* save return address */
        !          1461:        bb1     sigbit,r5,S2sigcheck    /* S1 is not a signaling NaN */
        !          1462:        set     r2,r2,1<oper>
        !          1463:        br.n    S1write         /* FPSR bit already set, S1 is made quiet, */
        !          1464:                                /* and since we always write S1 if it is a */
        !          1465:                                /* NaN, write S1 and skip rest of routine */
        !          1466:         set    r5,r5,1<sigbit> /* make S1 a quiet NaN */
        !          1467:
        !          1468: ASLOCAL(S2sigcheck)
        !          1469:        bb0     s2nan,r12,S1write       /* S2 is not a NaN */
        !          1470:        bb1     sigbit,r7,S1write       /* S2 is not a signaling NaN */
        !          1471:        set     r2,r2,1<oper>
        !          1472:        set     r7,r7,1<sigbit>         /* make S2 a quiet NaN */
        !          1473:
        !          1474:
        !          1475: /* Write a single or double precision quiet NaN unless the opeation is FCMP. */
        !          1476: /* If the operation is FCMP, then set the not comparable bit in the result. */
        !          1477:
        !          1478: ASLOCAL(S1write)
        !          1479:        bb0     s1nan,r12,S2write /* do not write S1 if it is not a NaN */
        !          1480:        extu    r10,r9,5<11>    /* extract opcode */
        !          1481:        cmp     r11,r10,FCMPop  /* compare to FCMP */
        !          1482:        bb1     ne,r11,S1noFCMP /* operation is not FCMP */
        !          1483:        set     r6,r0,1<nc>     /* set the not comparable bit */
        !          1484:        br.n    FPnan_return
        !          1485:         set    r6,r6,1<ne>     /* set the not equal bit */
        !          1486: ASLOCAL(S1noFCMP)
        !          1487:        bb1.n   dsize,r9,wrdoubS1 /* double destination */
        !          1488:         set    r5,r5,11<20>    /* set all exponent bits to 1 */
        !          1489: /* The single result will be formed the same way whether S1 is a single or double */
        !          1490: ASLOCAL(wrsingS1)
        !          1491:        mak     r10,r5,28<3>    /* wipe out extra exponent bits */
        !          1492:        extu    r11,r6,3<29>    /* get lower three bits of mantissa */
        !          1493:        or      r10,r10,r11     /* combine all of result except sign */
        !          1494:        clr     r6,r5,31<0>     /* clear all but sign */
        !          1495:        br.n    FPnan_return
        !          1496:         or     r6,r6,r10       /* form result */
        !          1497:
        !          1498: ASLOCAL(wrdoubS1)
        !          1499:        set     r6,r6,29<0>     /* set extra bits of lower word */
        !          1500:        br      FPnan_return    /* no modification necessary for writing */
        !          1501:                                /* double to double, so return */
        !          1502:
        !          1503: ASLOCAL(S2write)
        !          1504:        extu    r10,r9,5<11>    /* extract opcode */
        !          1505:        cmp     r11,r10,FCMPop  /* compare to FCMP */
        !          1506:        bb1.n   ne,r11,S2noFCMP /* operation is not FCMP */
        !          1507:         set    r7,r7,11<20>    /* set all exponent bits to 1 */
        !          1508:        set     r6,r0,1<nc>     /* set the not comparable bit */
        !          1509:        br.n    FPnan_return
        !          1510:         set    r6,r6,1<ne>     /* set the not equal bit */
        !          1511: ASLOCAL(S2noFCMP)
        !          1512:        bb1.n   dsize,r9,wrdoubS2 /* double destination */
        !          1513:         set    r5,r5,11<20>    /* set all exponent bits to 1 */
        !          1514: /* The single result will be formed the same way whether S1 is a single or double */
        !          1515: ASLOCAL(wrsingS2)
        !          1516:        mak     r10,r7,28<3>    /* wipe out extra exponent bits */
        !          1517:        extu    r11,r8,3<29>    /* get lower three bits of mantissa */
        !          1518:        or      r10,r10,r11     /* combine all of result except sign */
        !          1519:        clr     r6,r7,31<0>     /* clear all but sign */
        !          1520:        br.n    FPnan_return
        !          1521:         or     r6,r6,r10       /* form result */
        !          1522:
        !          1523: ASLOCAL(wrdoubS2)
        !          1524:        set     r6,r8,29<0>     /* set extra bits of lower word */
        !          1525:
        !          1526: /* Return from this subroutine with the result. */
        !          1527:
        !          1528: ASLOCAL(FPnan_return)
        !          1529:                                /* no modification necessary for writing */
        !          1530:                                /* double to double, so return */
        !          1531:        ld      r1,r31, 0       /* retrieve return address */
        !          1532:        jmp     r1
        !          1533:
        !          1534: /*
        !          1535:  * infinity
        !          1536:  */
        !          1537:
        !          1538: /* Extract the opcode, compare to a constant, and branch to the code */
        !          1539: /* for the instruction. */
        !          1540:
        !          1541: ASLOCAL(infinity)
        !          1542:        extu    r10,r9,5<11>    /* extract opcode */
        !          1543:        cmp     r11,r10,FADDop  /* compare to FADD */
        !          1544:        bb1.n   eq,r11,FADD     /* operation is FADD */
        !          1545:         st     r1,r31,0        /* save return address */
        !          1546:        cmp     r11,r10,FSUBop  /* compare to FSUB */
        !          1547:        bb1     eq,r11,FSUB     /* operation is FSUB */
        !          1548:        cmp     r11,r10,FCMPop  /* compare to FCMP */
        !          1549:        bb1     eq,r11,FCMP     /* operation is FCMP */
        !          1550:        cmp     r11,r10,FMULop  /* compare to FMUL */
        !          1551:        bb1     eq,r11,FMUL     /* operation is FMUL */
        !          1552:        cmp     r11,r10,FDIVop  /* compare to FDIV */
        !          1553:        bb1     eq,r11,FDIV     /* operation is FDIV */
        !          1554: #if 0
        !          1555:        cmp     r11,r10,FSQRTop /* compare to FSQRT */
        !          1556:        bb1     eq,r11,FSQRT    /* operation is FSQRT */
        !          1557: #endif
        !          1558:        cmp     r11,r10,INTop   /* compare to INT */
        !          1559:        bb1     eq,r11,FP_inf_overflw /* operation is INT */
        !          1560:        cmp     r11,r10,NINTop  /* compare to NINT */
        !          1561:        bb1     eq,r11,FP_inf_overflw /* operation is NINT */
        !          1562:        cmp     r11,r10,TRNCop  /* compare to TRNC */
        !          1563:        bb1     eq,r11,FP_inf_overflw /* operation is TRNC */
        !          1564:
        !          1565:
        !          1566: /* Adding infinities of opposite signs will cause an exception, */
        !          1567: /* but all other operands will result in a correctly signed infinity. */
        !          1568:
        !          1569: FADD:
        !          1570:        bb0     s1inf,r12,addS2write    /* branch if S1 not infinity */
        !          1571:        bb0     s2inf,r12,addS1write    /* S2 is not inf., so branch to write S1 */
        !          1572:        bb1     sign,r5,addS1neg        /* handle case of S1 negative */
        !          1573: addS1pos:
        !          1574:        bb1     sign,r7,excpt           /* adding infinities of different */
        !          1575:                                        /* signs causes an exception */
        !          1576:        br      poswrinf                /* branch to write positive infinity */
        !          1577: addS1neg:
        !          1578:        bb0     sign,r7,excpt           /* adding infinities of different */
        !          1579:                                        /* signs causes an exception */
        !          1580:        br      negwrinf                /* branch to write negative infinity */
        !          1581: addS1write:
        !          1582:        bb0     sign,r5,poswrinf        /* branch to write positive infinity */
        !          1583:        br      negwrinf                /* branch to write negative infinity */
        !          1584: addS2write:
        !          1585:        bb0     sign,r7,poswrinf        /* branch to write positive infinity */
        !          1586:        br      negwrinf                /* branch to write negative infinity */
        !          1587:
        !          1588:
        !          1589: /* Subtracting infinities of the same sign will cause an exception, */
        !          1590: /* but all other operands will result in a correctly signed infinity. */
        !          1591:
        !          1592: FSUB:
        !          1593:        bb0     s1inf,r12,subS2write    /* branch if S1 not infinity */
        !          1594:        bb0     s2inf,r12,subS1write    /* S2 is not inf., so branch to write S1 */
        !          1595:        bb1     sign,r5,subS1neg        /* handle case of S1 negative */
        !          1596: subS1pos:
        !          1597:        bb0     sign,r7,excpt           /* subtracting infinities of the same */
        !          1598:                                        /* sign causes an exception */
        !          1599:        br      poswrinf                /* branch to write positive infinity */
        !          1600: subS1neg:
        !          1601:        bb1     sign,r7,excpt           /* subtracting infinities of the same */
        !          1602:                                        /* sign causes an exception */
        !          1603:        br      negwrinf                /* branch to write negative infinity */
        !          1604: subS1write:
        !          1605:        bb0     sign,r5,poswrinf        /* branch to write positive infinity */
        !          1606:        br      negwrinf                /* branch to write negative infinity */
        !          1607: subS2write:
        !          1608:        bb1     sign,r7,poswrinf        /* branch to write positive infinity */
        !          1609:        br      negwrinf                /* branch to write negative infinity */
        !          1610:
        !          1611:
        !          1612: /* Compare the operands, at least one of which is infinity, and set the */
        !          1613: /* correct bits in the destination register. */
        !          1614:
        !          1615: FCMP:
        !          1616:        bb0.n   s1inf,r12,FCMPS1f       /* branch for finite S1 */
        !          1617:         set    r4,r0,1<cp>             /* since neither S1 or S2 is a NaN, */
        !          1618:                                        /* set cp */
        !          1619: FCMPS1i:
        !          1620:        bb1     sign,r5,FCMPS1ni        /* branch to negative S1i */
        !          1621: FCMPS1pi:
        !          1622:        bb0     s2inf,r12,FCMPS1piS2f   /* branch to finite S2 with S1pi */
        !          1623: FCMPS1piS2i:
        !          1624:        bb1     sign,r7,FCMPS1piS2ni    /* branch to negative S2i with S1pi */
        !          1625: FCMPS1piS2pi:
        !          1626:        set     r4,r4,1<eq>             /* set eq bit */
        !          1627:        set     r4,r4,1<le>             /* set le bit */
        !          1628:        set     r4,r4,1<ge>             /* set ge bit */
        !          1629:        set     r4,r4,1<ib>             /* set ib bit */
        !          1630:        br.n    move
        !          1631:         set    r4,r4,1<ob>             /* set ob bit */
        !          1632: FCMPS1piS2ni:
        !          1633:        set     r4,r4,1<ne>             /* set ne bit */
        !          1634:        set     r4,r4,1<gt>             /* set gt bit */
        !          1635:        br.n    move
        !          1636:         set    r4,r4,1<ge>             /* set ge bit */
        !          1637: FCMPS1piS2f:
        !          1638:        set     r4,r4,1<ne>             /* set ne bit */
        !          1639:        set     r4,r4,1<gt>             /* set gt bit */
        !          1640:        bsr.n   _ASM_LABEL(zero)        /* see if any of the operands are zero */
        !          1641:         set    r4,r4,1<ge>             /* set ge bit */
        !          1642:        bb0     s2zero,r12,FCMPS1piS2nz /* check for negative if s2 not zero */
        !          1643:        set     r4,r4,1<ou>             /* set ou bit */
        !          1644:        br.n    move
        !          1645:         set    r4,r4,1<ob>             /* set ob bit */
        !          1646: FCMPS1piS2nz:
        !          1647:        bb1     sign,r7,move            /* return if s2 is negative */
        !          1648: FCMPS1piS2pf:
        !          1649:        set     r4,r4,1<ou>             /* set ou bit */
        !          1650:        br.n    move
        !          1651:         set    r4,r4,1<ob>             /* set ob bit */
        !          1652: FCMPS1ni:
        !          1653:        bb0     s2inf,r12,FCMPS1niS2f   /* branch to finite S2 with S1ni */
        !          1654: FCMPS1niS2i:
        !          1655:        bb1     sign,r7,FCMPS1niS2ni    /* branch to negative S2i with S1ni */
        !          1656: FCMPS1niS2pi:
        !          1657:        set     r4,r4,1<ne>             /* set eq bit */
        !          1658:        set     r4,r4,1<le>             /* set le bit */
        !          1659:        set     r4,r4,1<lt>             /* set lt bit */
        !          1660:        set     r4,r4,1<ou>             /* set ou bit */
        !          1661:        br.n    move
        !          1662:         set    r4,r4,1<ob>             /* set ob bit */
        !          1663: FCMPS1niS2ni:
        !          1664:        set     r4,r4,1<eq>             /* set eq bit */
        !          1665:        set     r4,r4,1<le>             /* set le bit */
        !          1666:        br.n    move
        !          1667:         set    r4,r4,1<ge>             /* set ge bit */
        !          1668: FCMPS1niS2f:
        !          1669:        set     r4,r4,1<ne>             /* set eq bit */
        !          1670:        set     r4,r4,1<le>             /* set le bit */
        !          1671:        bsr.n   _ASM_LABEL(zero)        /* see if any of the operands are zero */
        !          1672:         set    r4,r4,1<lt>             /* set lt bit */
        !          1673:        bb0     s2zero,r12,FCMPS1niS2nz /* branch if s2 is not zero */
        !          1674:        set     r4,r4,1<ou>             /* set ou bit */
        !          1675:        br.n    move
        !          1676:         set    r4,r4,1<ob>             /* set ob bit */
        !          1677: FCMPS1niS2nz:
        !          1678:        bb1     sign,r7,move            /* return if s2 is negative */
        !          1679:        set     r4,r4,1<ou>             /* set ou bit */
        !          1680:        br.n    move
        !          1681:         set    r4,r4,1<ob>             /* set ob bit */
        !          1682: FCMPS1f:
        !          1683:        bb1     sign,r5,FCMPS1nf        /* branch to negative S1f */
        !          1684: FCMPS1pf:
        !          1685:        bb1.n   sign,r7,FCMPS1pfS2ni    /* branch to negative S2i with S1pf */
        !          1686:         set    r4,r4,1<ne>             /* set ne bit */
        !          1687: FCMPS1pfS2pi:
        !          1688:        set     r4,r4,1<le>             /* set le bit */
        !          1689:        set     r4,r4,1<lt>             /* set lt bit */
        !          1690:        bsr.n   _ASM_LABEL(zero)
        !          1691:         set    r4,r4,1<ib>             /* set ib bit */
        !          1692:        bb0     s1zero,r12,FCMPS1pfS2pinozero
        !          1693: FCMPS1pfS2pizero:
        !          1694:        br.n    move
        !          1695:         set    r4,r4,1<ob>             /* set ob bit */
        !          1696: FCMPS1pfS2pinozero:
        !          1697:        br.n    move
        !          1698:         set    r4,r4,1<in>             /* set in bit */
        !          1699: FCMPS1pfS2ni:
        !          1700:        set     r4,r4,1<gt>             /* set gt bit */
        !          1701:        br.n    move
        !          1702:         set    r4,r4,1<ge>             /* set ge bit */
        !          1703: FCMPS1nf:
        !          1704:        bb1.n   sign,r7,FCMPS1nfS2ni    /* branch to negative S2i with S1nf */
        !          1705:         set    r4,r4,1<ne>             /* set ne bit */
        !          1706:        set     r4,r4,1<le>             /* set gt bit */
        !          1707:        set     r4,r4,1<lt>             /* set ge bit */
        !          1708:        bsr.n   _ASM_LABEL(zero)        /* see which of the operands are zero */
        !          1709:         set    r4,r4,1<ob>             /* set ob bit */
        !          1710:        bb0     s1zero,r12,FCMPS1nfS2pinozero /* no ls and lo */
        !          1711: FCMPS1nfS2pizero:
        !          1712:        br.n    move
        !          1713:         set    r4,r4,1<ib>             /* set ib bit */
        !          1714: FCMPS1nfS2pinozero:
        !          1715:        br.n    move
        !          1716:         set    r4,r4,1<ou>             /* set ou bit */
        !          1717: FCMPS1nfS2ni:
        !          1718:        set     r4,r4,1<gt>             /* set gt bit */
        !          1719:        set     r4,r4,1<ge>             /* set ge bit */
        !          1720:
        !          1721: move:
        !          1722:        br.n    inf_return
        !          1723:         or     r6,r0,r4                /* transfer answer to r6 */
        !          1724:
        !          1725:
        !          1726: /* Multiplying infinity and zero causes an exception, but all other */
        !          1727: /* operations produce a correctly signed infinity. */
        !          1728:
        !          1729: FMUL:
        !          1730:        bsr     _ASM_LABEL(zero)        /* see if any of the operands are zero */
        !          1731:        bb1     s1zero,r12,excpt        /* infinity X 0 causes an exception */
        !          1732:        bb1     s2zero,r12,excpt        /* infinity X 0 causes an exception */
        !          1733:        bb1     sign,r5,FMULS1neg       /* handle negative cases of S1 */
        !          1734:        bb0     sign,r7,poswrinf        /* + X + = + */
        !          1735:        br      negwrinf                /* + X - = - */
        !          1736: FMULS1neg:
        !          1737:        bb1     sign,r7,poswrinf        /* - X - = + */
        !          1738:        br      negwrinf                /* - X + = - */
        !          1739:
        !          1740:
        !          1741: /* Dividing infinity by infinity causes an exception, but dividing */
        !          1742: /* infinity by a finite yields a correctly signed infinity, and */
        !          1743: /* dividing a finite by an infinity produces a correctly signed zero. */
        !          1744:
        !          1745: FDIV:
        !          1746:        bb1     s1inf,r12,FDIVS1inf     /* handle case of S1 being infinity */
        !          1747:        bb1     sign,r5,FDIVS1nf        /* handle cases of S1 being neg. non-inf. */
        !          1748:        bb1     sign,r7,FDIVS1pfS2mi    /* handle case of negative S2 */
        !          1749: FDIVS1pfS2pi:
        !          1750:        br      poswrzero               /* +f / +inf = +0 */
        !          1751: FDIVS1pfS2mi:
        !          1752:        br      negwrzero               /* +f / -inf = -0 */
        !          1753: FDIVS1nf:
        !          1754:        bb1     sign,r7,FDIVS1nfS2mi    /* handle case of negative S2 */
        !          1755: FDIVS1nfS2pi:
        !          1756:        br      negwrzero               /* -f / +inf = -0 */
        !          1757: FDIVS1nfS2mi:
        !          1758:        br      poswrzero               /* -f / -inf = +0 */
        !          1759: FDIVS1inf:
        !          1760:        bb1     s2inf,r12,excpt         /* inf / inf = exception */
        !          1761:        bb1     sign,r5,FDIVS1mi        /* handle cases of S1 being neg. inf. */
        !          1762:        bb1     sign,r7,FDIVS1piS2nf    /* handle case of negative S2 */
        !          1763: FDIVS1piS2pf:
        !          1764:        br      poswrinf                /* +inf / +f = +inf */
        !          1765: FDIVS1piS2nf:
        !          1766:        br      negwrinf                /* +inf / -f = -inf */
        !          1767: FDIVS1mi:
        !          1768:        bb1     sign,r7,FDIVS1miS2nf    /* handle case of negative S2 */
        !          1769: FDIVS1miS2pf:
        !          1770:        br      negwrinf                /* -inf / +f = -inf */
        !          1771: FDIVS1miS2nf:
        !          1772:        br      poswrinf                /* -inf / -f = +inf */
        !          1773:
        !          1774:
        !          1775: /* The square root of positive infinity is positive infinity, */
        !          1776: /* but the square root of negative infinity is a NaN */
        !          1777:
        !          1778: #if 0
        !          1779: FSQRT:
        !          1780:        bb0     sign,r7,poswrinf        /* write sqrt(inf) = inf */
        !          1781:        br      excpt                   /* write sqrt(-inf) = NaN */
        !          1782: #endif
        !          1783:
        !          1784: excpt:
        !          1785:        set     r2,r2,1<oper>
        !          1786:        set     r5,r0,0<0>      /* write NaN into r5 */
        !          1787:        br.n    inf_return
        !          1788:         set    r6,r0,0<0>      /* write NaN into r6, writing NaN''s into */
        !          1789:                                /* both of these registers is quicker than */
        !          1790:                                /* checking for single or double precision */
        !          1791:
        !          1792:
        !          1793: /* Write positive infinity of the correct precision */
        !          1794:
        !          1795: poswrinf:
        !          1796:        bb1     dsize,r9,poswrinfd      /* branch to write double precision inf. */
        !          1797:        br.n    inf_return
        !          1798:         or.u   r6,r0,0x7f80            /* load r6 with single precision pos inf.       */
        !          1799: poswrinfd:
        !          1800:        or.u    r5,r0,0x7ff0            /* load double precision pos inf. */
        !          1801:        br.n    inf_return
        !          1802:         or     r6,r0,r0
        !          1803:
        !          1804:
        !          1805: /* Write negative infinity of the correct precision */
        !          1806:
        !          1807: negwrinf:
        !          1808:        bb1     dsize,r9,negwrinfd      /* branch to write double precision inf. */
        !          1809:        br.n    inf_return
        !          1810:         or.u   r6,r0,0xff80            /* load r6 with single precision pos inf.       */
        !          1811: negwrinfd:
        !          1812:        or.u    r5,r0,0xfff0            /* load double precision pos inf. */
        !          1813:        br.n    inf_return
        !          1814:         or     r6,r0,r0
        !          1815:
        !          1816:
        !          1817: /* Write a positive zero disregarding precision. */
        !          1818:
        !          1819: poswrzero:
        !          1820:        or      r5,r0,r0        /* write to both high word and low word now */
        !          1821:        br.n    inf_return      /* it does not matter that both are written */
        !          1822:         or     r6,r0,r0
        !          1823:
        !          1824:
        !          1825: /* Write a negative zero of the correct precision. */
        !          1826:
        !          1827: negwrzero:
        !          1828:        or      r6,r0,r0        /* clear low word */
        !          1829:        bb1     dsize,r9,negwrzerod /* branch to write double precision zero */
        !          1830:        br.n    inf_return
        !          1831:         set    r6,r6,1<31>     /* set sign bit */
        !          1832: negwrzerod:
        !          1833:        or      r5,r0,r0        /* clear high word */
        !          1834:        br.n    inf_return
        !          1835:         set    r5,r5,1<31>     /* set sign bit */
        !          1836:
        !          1837: FP_inf_overflw:
        !          1838:        set     r2,r2,1<oper>
        !          1839:        set     r2,r2,1<overflow>
        !          1840:        set     r2,r2,1<inexact>
        !          1841:
        !          1842:        bb0.n   sign,r7,inf_return /* if positive then return */
        !          1843:
        !          1844:         set    r6,r6,31<0>     /* set result to largest positive integer */
        !          1845:        or.c    r6,r0,r6        /* negate r6,giving largest negative int. */
        !          1846:
        !          1847: inf_return:
        !          1848:        ld      r1,r31,0        /* load return address */
        !          1849:        jmp     r1
        !          1850:
        !          1851: /*
        !          1852:  * denorm
        !          1853:  */
        !          1854:
        !          1855: /* Check to see if either S1 or S2 is a denormalized number. First */
        !          1856: /* extract the exponent to see if it is zero, and then check to see if */
        !          1857: /* the mantissa is not zero. If the number is denormalized, then set the */
        !          1858: /* 1 or 0 bit 10 r12. */
        !          1859:
        !          1860: ASLOCAL(denorm)
        !          1861:        st      r1,r31,0        /* save return address */
        !          1862: dnmcheckS1:
        !          1863:        extu    r10,r5,11<20>   /* extract exponent */
        !          1864:        bcnd    ne0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
        !          1865:        bb1.n   9,r9,dnmcheckS1d /* S1 is double precision */
        !          1866:         mak    r10,r5,20<3>    /* mak field with only mantissa bits */
        !          1867:                                /* into final result */
        !          1868: dnmcheckS1s:
        !          1869:        extu    r11,r6,3<29>    /* get three low bits of mantissa */
        !          1870:        or      r10,r10,r11     /* assemble all of the mantissa bits */
        !          1871:        bcnd    eq0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
        !          1872:        br      dnmsetS1        /* S1 is a denorm */
        !          1873:
        !          1874: dnmcheckS1d:
        !          1875:        or      r10,r6,r10      /* or all of mantissa bits */
        !          1876:        bcnd    eq0,r10,dnmsetS2 /* S1 is not a denorm, so S2 must be */
        !          1877: dnmsetS1:
        !          1878:        set     r12,r12,1<1>    /* S1 is a denorm */
        !          1879:
        !          1880: dnmcheckS2:
        !          1881:        extu    r10,r7,11<20>   /* extract exponent */
        !          1882:        bcnd    ne0,r10,S1form  /* S2 is not a denorm */
        !          1883:        bb1.n   7,r9,dnmcheckS2d /* S2 is double precision */
        !          1884:         mak    r10,r7,20<3>    /* mak field with only mantissa bits */
        !          1885: dnmcheckS2s:
        !          1886:        extu    r11,r8,3<29>    /* get three low bits of mantissa */
        !          1887:        or      r10,r10,r11     /* assemble all of the mantissa bits */
        !          1888:        bcnd    eq0,r10,S1form  /* S2 is not a denorm */
        !          1889:        br      dnmsetS2        /* S1 is a denorm */
        !          1890: dnmcheckS2d:
        !          1891:        or      r10,r8,r10      /* or all or mantissa bits */
        !          1892:        bcnd    eq0,r10,S1form  /* S2 is not a denorm */
        !          1893: dnmsetS2:
        !          1894:        set     r12,r12,1<0>    /* S2 is a denorm */
        !          1895:
        !          1896:
        !          1897: /* Since the operations are going to be reperformed with modified denorms, */
        !          1898: /* the operands which were initially single precision need to be modified */
        !          1899: /* back to single precision.   */
        !          1900:
        !          1901: S1form:
        !          1902:        bb1     9,r9,S2form     /* S1 is double precision, so do not */
        !          1903:                                /* modify S1 into single format */
        !          1904:        mak     r11,r5,28<3>    /* over final exponent and mantissa */
        !          1905:                                /* eliminating extra 3 bits of exponent */
        !          1906:        extu    r6,r6,3<29>     /* get low 3 bits of mantissa */
        !          1907:        or      r11,r6,r11      /* form complete mantissa and exponent */
        !          1908:        extu    r10,r5,1<31>    /* get the 31 bit */
        !          1909:        mak     r10,r10,1<31>   /* place 31 bit 10 correct position */
        !          1910:        or      r6,r10,r11      /* or 31, exponent, and all of mantissa */
        !          1911:
        !          1912: S2form:
        !          1913:        bb1     7,r9,checkop    /* S2 is double precision, so do not */
        !          1914:                                /* modify S2 into single format */
        !          1915:        mak     r11,r7,28<3>    /* over final exponent and mantissa */
        !          1916:                                /* eliminating extra 3 bits of exponent */
        !          1917:        extu    r8,r8,3<29>     /* get low 3 bits of mantissa */
        !          1918:        or      r11,r8,r11      /* form complete mantissa and exponent */
        !          1919:        extu    r10,r7,1<31>    /* get the 31 bit */
        !          1920:        mak     r10,r10,1<31>   /* place 31 bit 10 correct position */
        !          1921:        or      r8,r10,r11      /* or 31, exponent, and all of mantissa */
        !          1922:
        !          1923:
        !          1924: /* Extract the opcode, compare to a constant, and branch to the code that */
        !          1925: /* deals with that opcode. */
        !          1926:
        !          1927: checkop:
        !          1928:        extu    r10,r9,5<11>    /* extract opcode */
        !          1929:        cmp     r11,r10,0x05    /* compare to FADD */
        !          1930:        bb1     2,r11,denorm_FADD       /* operation is FADD */
        !          1931:        cmp     r11,r10,0x06    /* compare to FSUB */
        !          1932:        bb1     2,r11,denorm_FSUB       /* operation is FSUB */
        !          1933:        cmp     r11,r10,0x07    /* compare to FCMP */
        !          1934:        bb1     2,r11,denorm_FCMP       /* operation is FCMP */
        !          1935:        cmp     r11,r10,0x00    /* compare to FMUL */
        !          1936:        bb1     2,r11,denorm_FMUL       /* operation is FMUL */
        !          1937:        cmp     r11,r10,0x0e    /* compare to FDIV */
        !          1938:        bb1     2,r11,denorm_FDIV       /* operation is FDIV */
        !          1939: #if 0
        !          1940:        cmp     r11,r10,0x0f    /* compare to FSQRT */
        !          1941:        bb1     2,r11,denorm_FSQRT      /* operation is FSQRT */
        !          1942: #endif
        !          1943:        cmp     r11,r10,0x09    /* compare to INT */
        !          1944:        bb1     2,r11,denorm_INT        /* operation is INT */
        !          1945:        cmp     r11,r10,0x0a    /* compare to NINT */
        !          1946:        bb1     2,r11,denorm_NINT       /* operation is NINT */
        !          1947:        cmp     r11,r10,0x0b    /* compare to TRNC */
        !          1948:        bb1     2,r11,denorm_TRNC       /* operation is TRNC */
        !          1949:
        !          1950:
        !          1951: /* For all the following operations, the denormalized number is set to */
        !          1952: /* zero and the operation is reperformed the correct destination and source */
        !          1953: /* sizes. */
        !          1954:
        !          1955: denorm_FADD:
        !          1956:        bb0     1,r12,FADDS2dnm /* S1 is not denorm, so S2 must be */
        !          1957:        or      r5,r0,r0        /* set S1 to zero */
        !          1958:        or      r6,r0,r0
        !          1959: FADDS2chk:
        !          1960:        bb0     0,r12,FADDcalc  /* S2 is not a denorm */
        !          1961: FADDS2dnm:
        !          1962:        or      r7,r0,r0        /* set S2 to zero */
        !          1963:        or      r8,r0,r0
        !          1964: FADDcalc:
        !          1965:        bb1     5,r9,FADDdD     /* branch for double precision destination */
        !          1966: FADDsD:
        !          1967:        bb1     9,r9,FADDsDdS1  /* branch for double precision S1 */
        !          1968: FADDsDsS1:
        !          1969:        bb1     7,r9,FADDsDsS1dS2 /* branch for double precision S2 */
        !          1970: FADDsDsS1sS2:
        !          1971:        br.n    denorm_return
        !          1972:         fadd.sss r6,r6,r8      /* add the two sources and place result 10 S1 */
        !          1973: FADDsDsS1dS2:
        !          1974:        br.n    denorm_return
        !          1975:         fadd.ssd r6,r6,r7      /* add the two sources and place result 10 S1 */
        !          1976: FADDsDdS1:
        !          1977:        bb1     7,r9,FADDsDdS1dS2 /* branch for double precision S2 */
        !          1978: FADDsDdS1sS2:
        !          1979:        br.n    denorm_return
        !          1980:         fadd.sds r6,r5,r8      /* add the two sources and place result 10 S1 */
        !          1981: FADDsDdS1dS2:
        !          1982:        br.n    denorm_return
        !          1983:         fadd.sdd r6,r5,r7      /* add the two sources and place result 10 S1 */
        !          1984: FADDdD:
        !          1985:        bb1     9,r9,FADDdDdS1  /* branch for double precision S1 */
        !          1986: FADDdDsS1:
        !          1987:        bb1     7,r9,FADDdDsS1dS2 /* branch for double precision S2 */
        !          1988: FADDdDsS1sS2:
        !          1989:        br.n    denorm_return
        !          1990:         fadd.dss r5,r6,r8      /* add the two sources and place result 10 S1 */
        !          1991: FADDdDsS1dS2:
        !          1992:        br.n    denorm_return
        !          1993:         fadd.dsd r5,r6,r7      /* add the two sources and place result 10 S1 */
        !          1994: FADDdDdS1:
        !          1995:        bb1     7,r9,FADDdDdS1dS2 /* branch for double precision S2 */
        !          1996: FADDdDdS1sS2:
        !          1997:        br.n    denorm_return
        !          1998:         fadd.dds r5,r5,r8      /* add the two sources and place result 10 S1 */
        !          1999: FADDdDdS1dS2:
        !          2000:        br.n    denorm_return
        !          2001:         fadd.ddd r5,r5,r7      /* add the two sources and place result 10 S1 */
        !          2002:
        !          2003: denorm_FSUB:
        !          2004:        bb0     1,r12,FSUBS2dnm /* S1 is not denorm, so S2 must be */
        !          2005:        or      r5,r0,r0        /* set S1 to zero */
        !          2006:        or      r6,r0,r0
        !          2007: FSUBS2chk:
        !          2008:        bb0     0,r12,FSUBcalc  /* S2 is not a denorm */
        !          2009: FSUBS2dnm:
        !          2010:        or      r7,r0,r0        /* set S2 to zero */
        !          2011:        or      r8,r0,r0
        !          2012: FSUBcalc:
        !          2013:        bb1     5,r9,FSUBdD     /* branch for double precision destination */
        !          2014: FSUBsD:
        !          2015:        bb1     9,r9,FSUBsDdS1  /* branch for double precision S1 */
        !          2016: FSUBsDsS1:
        !          2017:        bb1     7,r9,FSUBsDsS1dS2 /* branch for double precision S2 */
        !          2018: FSUBsDsS1sS2:
        !          2019:        br.n    denorm_return
        !          2020:         fsub.sss r6,r6,r8      /* add the two sources and place result 10 S1 */
        !          2021: FSUBsDsS1dS2:
        !          2022:        br.n    denorm_return
        !          2023:         fsub.ssd r6,r6,r7      /* add the two sources and place result 10 S1 */
        !          2024: FSUBsDdS1:
        !          2025:        bb1     7,r9,FSUBsDdS1dS2 /* branch for double precision S2 */
        !          2026: FSUBsDdS1sS2:
        !          2027:        br.n    denorm_return
        !          2028:         fsub.sds r6,r5,r8      /* add the two sources and place result 10 S1 */
        !          2029: FSUBsDdS1dS2:
        !          2030:        br.n    denorm_return
        !          2031:         fsub.sdd r6,r5,r7      /* add the two sources and place result 10 S1 */
        !          2032: FSUBdD:
        !          2033:        bb1     9,r9,FSUBdDdS1  /* branch for double precision S1 */
        !          2034: FSUBdDsS1:
        !          2035:        bb1     7,r9,FSUBdDsS1dS2 /* branch for double precision S2 */
        !          2036: FSUBdDsS1sS2:
        !          2037:        br.n    denorm_return
        !          2038:         fsub.dss r5,r6,r8      /* add the two sources and place result 10 S1 */
        !          2039: FSUBdDsS1dS2:
        !          2040:        br.n    denorm_return
        !          2041:         fsub.dsd r5,r6,r7      /* add the two sources and place result 10 S1 */
        !          2042: FSUBdDdS1:
        !          2043:        bb1     7,r9,FSUBdDdS1dS2 /* branch for double precision S2 */
        !          2044: FSUBdDdS1sS2:
        !          2045:        br.n    denorm_return
        !          2046:         fsub.dds r5,r5,r8      /* add the two sources and place result 10 S1 */
        !          2047: FSUBdDdS1dS2:
        !          2048:        br.n    denorm_return
        !          2049:         fsub.ddd r5,r5,r7      /* add the two sources and place result 10 S1 */
        !          2050:
        !          2051: denorm_FCMP:
        !          2052:        bb0     1,r12,FCMPS2dnm /* S1 is not denorm, so S2 must be */
        !          2053:        or      r5,r0,r0        /* set S1 to zero */
        !          2054:        or      r6,r0,r0
        !          2055: FCMPS2chk:
        !          2056:        bb0     0,r12,FCMPcalc  /* S2 is not a denorm */
        !          2057: FCMPS2dnm:
        !          2058:        or      r7,r0,r0        /* set S2 to zero */
        !          2059:        or      r8,r0,r0
        !          2060: FCMPcalc:
        !          2061:        bb1     9,r9,FCMPdS1    /* branch for double precision S1 */
        !          2062: FCMPsS1:
        !          2063:        bb1     7,r9,FCMPsS1dS2 /* branch for double precision S2 */
        !          2064: FCMPsS1sS2:
        !          2065:        br.n    denorm_return
        !          2066:         fcmp.sss r6,r6,r8      /* add the two sources and place result 10 S1 */
        !          2067: FCMPsS1dS2:
        !          2068:        br.n    denorm_return
        !          2069:         fcmp.ssd r6,r6,r7      /* add the two sources and place result 10 S1 */
        !          2070: FCMPdS1:
        !          2071:        bb1     7,r9,FCMPdS1dS2 /* branch for double precision S2 */
        !          2072: FCMPdS1sS2:
        !          2073:        br.n    denorm_return
        !          2074:         fcmp.sds r6,r5,r8      /* add the two sources and place result 10 S1 */
        !          2075: FCMPdS1dS2:
        !          2076:        br.n    denorm_return
        !          2077:         fcmp.sdd r6,r5,r7      /* add the two sources and place result 10 S1 */
        !          2078:
        !          2079: denorm_FMUL:
        !          2080:        bb0     1,r12,FMULS2dnm /* S1 is not denorm, so S2 must be */
        !          2081:        or      r5,r0,r0        /* set S1 to zero */
        !          2082:        or      r6,r0,r0
        !          2083: FMULS2chk:
        !          2084:        bb0     0,r12,FMULcalc  /* S2 is not a denorm */
        !          2085: FMULS2dnm:
        !          2086:        or      r7,r0,r0        /* set S2 to zero */
        !          2087:        or      r8,r0,r0
        !          2088: FMULcalc:
        !          2089:        bb1     5,r9,FMULdD     /* branch for double precision destination */
        !          2090: FMULsD:
        !          2091:        bb1     9,r9,FMULsDdS1  /* branch for double precision S1 */
        !          2092: FMULsDsS1:
        !          2093:        bb1     7,r9,FMULsDsS1dS2 /* branch for double precision S2 */
        !          2094: FMULsDsS1sS2:
        !          2095:        br.n    denorm_return
        !          2096:         fmul.sss r6,r6,r8      /* add the two sources and place result 10 S1 */
        !          2097: FMULsDsS1dS2:
        !          2098:        br.n    denorm_return
        !          2099:         fmul.ssd r6,r6,r7      /* add the two sources and place result 10 S1 */
        !          2100: FMULsDdS1:
        !          2101:        bb1     7,r9,FMULsDdS1dS2 /* branch for double precision S2 */
        !          2102: FMULsDdS1sS2:
        !          2103:        br.n    denorm_return
        !          2104:         fmul.sds r6,r5,r8      /* add the two sources and place result 10 S1 */
        !          2105: FMULsDdS1dS2:
        !          2106:        br.n    denorm_return
        !          2107:         fmul.sdd r6,r5,r7      /* add the two sources and place result 10 S1 */
        !          2108: FMULdD:
        !          2109:        bb1     9,r9,FMULdDdS1  /* branch for double precision S1 */
        !          2110: FMULdDsS1:
        !          2111:        bb1     7,r9,FMULdDsS1dS2 /* branch for double precision S2 */
        !          2112: FMULdDsS1sS2:
        !          2113:        br.n    denorm_return
        !          2114:         fmul.dss r5,r6,r8      /* add the two sources and place result 10 S1 */
        !          2115: FMULdDsS1dS2:
        !          2116:        br.n    denorm_return
        !          2117:         fmul.dsd r5,r6,r7      /* add the two sources and place result 10 S1 */
        !          2118: FMULdDdS1:
        !          2119:        bb1     7,r9,FMULdDdS1dS2 /* branch for double precision S2 */
        !          2120: FMULdDdS1sS2:
        !          2121:        br.n    denorm_return
        !          2122:         fmul.dds r5,r5,r8      /* add the two sources and place result 10 S1 */
        !          2123: FMULdDdS1dS2:
        !          2124:        br.n    denorm_return
        !          2125:         fmul.ddd r5,r5,r7      /* add the two sources and place result 10 S1 */
        !          2126:
        !          2127: denorm_FDIV:
        !          2128:        bb0     1,r12,FDIVS2dnm /* S1 is not denorm, so S2 must be */
        !          2129:        or      r5,r0,r0        /* set S1 to zero */
        !          2130:        or      r6,r0,r0
        !          2131: FDIVS2chk:
        !          2132:        bb0     0,r12,FDIVcalc  /* S2 is not a denorm */
        !          2133: FDIVS2dnm:
        !          2134:        or      r7,r0,r0        /* set S2 to zero */
        !          2135:        or      r8,r0,r0
        !          2136: FDIVcalc:
        !          2137:        bb1     5,r9,FDIVdD     /* branch for double precision destination */
        !          2138: FDIVsD:
        !          2139:        bb1     9,r9,FDIVsDdS1  /* branch for double precision S1 */
        !          2140: FDIVsDsS1:
        !          2141:        bb1     7,r9,FDIVsDsS1dS2 /* branch for double precision S2 */
        !          2142: FDIVsDsS1sS2:
        !          2143:        fdiv.sss r6,r6,r8       /* add the two sources and place result 10 S1 */
        !          2144:        br      denorm_return
        !          2145: FDIVsDsS1dS2:
        !          2146:        fdiv.ssd r6,r6,r7       /* add the two sources and place result 10 S1 */
        !          2147:        br      denorm_return
        !          2148: FDIVsDdS1:
        !          2149:        bb1     7,r9,FDIVsDdS1dS2 /* branch for double precision S2 */
        !          2150: FDIVsDdS1sS2:
        !          2151:        fdiv.sds r6,r5,r8       /* add the two sources and place result 10 S1 */
        !          2152:        br      denorm_return
        !          2153: FDIVsDdS1dS2:
        !          2154:        fdiv.sdd r6,r5,r7       /* add the two sources and place result 10 S1 */
        !          2155:        br      denorm_return
        !          2156: FDIVdD:
        !          2157:        bb1     9,r9,FDIVdDdS1  /* branch for double precision S1 */
        !          2158: FDIVdDsS1:
        !          2159:        bb1     7,r9,FDIVdDsS1dS2 /* branch for double precision S2 */
        !          2160: FDIVdDsS1sS2:
        !          2161:        fdiv.dss r5,r6,r8       /* add the two sources and place result 10 S1 */
        !          2162:        br      denorm_return
        !          2163: FDIVdDsS1dS2:
        !          2164:        fdiv.dsd r5,r6,r7       /* add the two sources and place result 10 S1 */
        !          2165:        br      denorm_return
        !          2166: FDIVdDdS1:
        !          2167:        bb1     7,r9,FDIVdDdS1dS2 /* branch for double precision S2 */
        !          2168: FDIVdDdS1sS2:
        !          2169:        fdiv.dds r5,r5,r8       /* add the two sources and place result 10 S1 */
        !          2170:        br      denorm_return
        !          2171: FDIVdDdS1dS2:
        !          2172:        fdiv.ddd r5,r5,r7       /* add the two sources and place result 10 S1 */
        !          2173:        br      denorm_return
        !          2174:
        !          2175: #if 0
        !          2176: denorm_FSQRT:
        !          2177:        or      r7,r0,r0        /* set S2 to zero */
        !          2178:        or      r8,r0,r0
        !          2179: FSQRTcalc:
        !          2180:        bb1     5,r9,FSQRTdD    /* branch for double precision destination */
        !          2181: FSQRTsD:
        !          2182:        bb1     7,r9,FSQRTsDdS2 /* branch for double precision S2 */
        !          2183: FSQRTsDsS2:
        !          2184:        br.n    denorm_return
        !          2185:         fsqrt.ss r6,r8         /* add the two sources and place result 10 S1 */
        !          2186: FSQRTsDdS2:
        !          2187:        br.n    denorm_return
        !          2188:         fsqrt.sd r6,r7         /* add the two sources and place result 10 S1 */
        !          2189: FSQRTdD:
        !          2190:        bb1     7,r9,FSQRTdDdS2 /* branch for double precision S2 */
        !          2191: FSQRTdDsS2:
        !          2192:        br.n    denorm_return
        !          2193:         fsqrt.ds r5,r8         /* add the two sources and place result 10 S1 */
        !          2194: FSQRTdDdS2:
        !          2195:        br.n    denorm_return
        !          2196:         fsqrt.dd r5,r7         /* add the two sources and place result 10 S1 */
        !          2197: #endif
        !          2198:
        !          2199: denorm_INT:
        !          2200:        or      r7,r0,r0        /* set S2 to zero */
        !          2201:        or      r8,r0,r0
        !          2202: INTcalc:
        !          2203:        bb1     7,r9,INTdS2     /* branch for double precision S2 */
        !          2204: INTsS2:
        !          2205:        br.n    denorm_return
        !          2206:         int.ss r6,r8           /* add the two sources and place result 10 S1 */
        !          2207: INTdS2:
        !          2208:        br.n    denorm_return
        !          2209:         int.sd r6,r7           /* add the two sources and place result 10 S1 */
        !          2210:
        !          2211: denorm_NINT:
        !          2212:        or      r7,r0,r0        /* set S2 to zero */
        !          2213:        or      r8,r0,r0
        !          2214: NINTcalc:
        !          2215:        bb1     7,r9,NINTdS2    /* branch for double precision S2 */
        !          2216: NINTsS2:
        !          2217:        br.n    denorm_return
        !          2218:         nint.ss r6,r8          /* add the two sources and place result 10 S1 */
        !          2219: NINTdS2:
        !          2220:        br.n    denorm_return
        !          2221:         nint.sd r6,r7          /* add the two sources and place result 10 S1 */
        !          2222:
        !          2223: denorm_TRNC:
        !          2224:        or      r7,r0,r0        /* set S2 to zero */
        !          2225:        or      r8,r0,r0
        !          2226: TRNCcalc:
        !          2227:        bb1     7,r9,TRNCdS2    /* branch for double precision S2 */
        !          2228: TRNCsS2:
        !          2229:        br.n    denorm_return
        !          2230:         trnc.ss r6,r8          /* add the two sources and place result 10 S1 */
        !          2231: TRNCdS2:
        !          2232:        trnc.sd r6,r7           /* add the two sources and place result 10 S1 */
        !          2233:
        !          2234:
        !          2235: /* Return to the routine that detected the reserved operand. */
        !          2236:
        !          2237: denorm_return:
        !          2238:        ld      r1,r31,0        /* load return address */
        !          2239:        jmp     r1
        !          2240:
        !          2241: /* S1 and/or S2 is an infinity, and the other operand may be a zero. */
        !          2242: /* Knowing which operands are infinity, check the remaining operands for zeros. */
        !          2243:
        !          2244: ASLOCAL(zero)
        !          2245:        bb0     s1inf,r12,S1noinf       /* see if S1 is zero */
        !          2246:        bb0     s2inf,r12,S2noinf       /* see if S2 is zero */
        !          2247:        jmp     r1
        !          2248:
        !          2249: /* See if S1 is zero. Whether or not S1 is a zero, being in this routine */
        !          2250: /* implies that S2 is infinity, so return to subroutine infinity after */
        !          2251: /* completing this code. Set the s1zero flag in r12 if S1 is zero. */
        !          2252:
        !          2253: S1noinf:
        !          2254:        bb1     s1size,r9,S1noinfd      /* work with double precision operand */
        !          2255: S1noinfs:
        !          2256:        or      r10,r0,r5               /* load high word into r10 */
        !          2257:        clr     r10,r10,1<sign>         /* clear the sign bit */
        !          2258:        extu    r11,r6,3<29>            /* extract lower 3 bits of mantissa */
        !          2259:        or      r10,r10,r11             /* or these 3 bits with high word */
        !          2260:        bcnd    ne0,r10,operation       /* do not set zero flag */
        !          2261:        jmp.n   r1                      /* since this operand was not */
        !          2262:                                        /* infinity, S2 must have been, */
        !          2263:                                        /* so return */
        !          2264:         set    r12,r12,1<s1zero>       /* set zeroflag */
        !          2265: S1noinfd:
        !          2266:        clr     r10,r5,1<sign>          /* clear the sign bit */
        !          2267:        or      r10,r6,r10              /* or high and low word */
        !          2268:        bcnd    ne0,r10,operation       /* do not set zero flag */
        !          2269:        jmp.n   r1                      /* since this operand was not */
        !          2270:                                        /* infinity, S2 must have been, */
        !          2271:                                        /* so return */
        !          2272:         set    r12,r12,1<s1zero>       /* set zeroflag */
        !          2273:
        !          2274:
        !          2275: /* Check S2 for zero. If it is zero, then set the s2zero flag in r12. */
        !          2276:
        !          2277: S2noinf:
        !          2278:        bb1     s2size,r9,S2noinfd      /* work with double precision operand */
        !          2279: S2noinfs:
        !          2280:        or      r10,r0,r7               /* load high word into r10 */
        !          2281:        clr     r10,r10,1<sign>         /* clear the sign bit */
        !          2282:        extu    r11,r8,3<29>            /* extract lower 3 bits of mantissa */
        !          2283:        or      r10,r10,r11             /* or these 3 bits with high word */
        !          2284:        bcnd    ne0,r10,operation       /* do not set zero flag */
        !          2285:        jmp.n   r1                      /* since this operand was not */
        !          2286:                                        /* infinity, S1 must have been, */
        !          2287:                                        /* so return */
        !          2288:         set    r12,r12,1<s2zero>       /* set zeroflag */
        !          2289: S2noinfd:
        !          2290:        clr     r10,r7,1<sign>          /* clear the sign bit */
        !          2291:        or      r10,r8,r10              /* or high and low word */
        !          2292:        bcnd    ne0,r10,operation       /* do not set zero flag */
        !          2293:        set     r12,r12,1<s2zero>       /* set zeroflag */
        !          2294:                                        /* since this operand was not */
        !          2295:                                        /* infinity, S1 must have been, */
        !          2296:                                        /* so return */
        !          2297: operation:
        !          2298:        jmp     r1
        !          2299:
        !          2300: ASENTRY(Xfp_imprecise)
        !          2301: /* input: r3 is the exception frame */
        !          2302:        or      r29, r3, r0             /* r29 is now the E.F. */
        !          2303:        subu    r31, r31, 16
        !          2304:        st      r1,  r31, 4
        !          2305:        st      r29, r31, 8
        !          2306:
        !          2307:        ld      r2 , r29, EF_FPSR  * 4
        !          2308:        ld      r3 , r29, EF_FPCR  * 4
        !          2309:        ld      r4 , r29, EF_FPECR * 4
        !          2310:        ld      r10, r29, EF_FPRH  * 4
        !          2311:        ld      r11, r29, EF_FPRL  * 4
        !          2312:        ld      r12, r29, EF_FPIT  * 4
        !          2313:
        !          2314: /* Load into r1 the return address for the exception handlers. Looking */
        !          2315: /* at FPECR, branch to the appropriate exception handler. */
        !          2316:
        !          2317:        or.u    r1,r0,hi16(fpui_wrapup)/* load return address of functions */
        !          2318:        or      r1,r1,lo16(fpui_wrapup)
        !          2319:
        !          2320:        bb0     2,r4,2f                 /* branch to FPunderflow if bit set */
        !          2321:        br      _ASM_LABEL(FPunderflow)
        !          2322: 2:
        !          2323:        bb0     1,r4,3f                 /* branch to FPoverflow if bit set */
        !          2324:        br      _ASM_LABEL(FPoverflow)
        !          2325: 3:
        !          2326:        /* XXX handle inexact!!! */
        !          2327:
        !          2328: fpui_wrapup:
        !          2329:        tb1     0,r0,0          /* make sure all floating point operations */
        !          2330:                                /* have finished */
        !          2331:        ldcr    r4, cr1 /* load the PSR */
        !          2332: #if 0
        !          2333:        set     r4, r4, 1<PSR_FPU_DISABLE_BIT>
        !          2334: #endif
        !          2335:        set     r4, r4, 1<PSR_INTERRUPT_DISABLE_BIT>
        !          2336:        stcr    r4, cr1
        !          2337:        ld      r1, r31, 4
        !          2338:        ld      r29,r31, 8
        !          2339:        addu    r31, r31, 16
        !          2340:
        !          2341:        fstcr   r2, FPSR        /* write revised value of FPSR */
        !          2342:        fstcr   r3, FPCR        /* write revised value of FPCR */
        !          2343:
        !          2344:        /* write back the results */
        !          2345:        extu    r2, r12, 5<0>
        !          2346:        bb0.n   destsize, r12, Iwritesingle
        !          2347:         addu   r3, r29, EF_R0 * 4
        !          2348:        st      r10, r3 [r2]
        !          2349:        addu    r2, r2, 1
        !          2350:        clr     r2, r2, 27<5>
        !          2351: Iwritesingle:
        !          2352:        jmp.n   r1
        !          2353:         st     r11, r3 [r2]

CVSweb