Annotation of researchv9/libc/sun/Ffloat.s, revision 1.1

1.1     ! root        1:        .data
        !             2:        .asciz  "@(#)Ffloat.s 1.1 86/02/03 Copyr 1985 Sun Micro"
        !             3:        .even
        !             4:        .text
        !             5: 
        !             6: |      Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7: 
        !             8: #include "fpcrtdefs.h"
        !             9: 
        !            10: /*
        !            11:  *     single-precision utility operations
        !            12:  *
        !            13:  *     copyright 1981, 1982 Richard E. James III
        !            14:  *     translated to SUN idiom 11 March 1983 rt
        !            15:  */
        !            16: 
        !            17:        NSAVED   = 3*4  | save registers d2-d4
        !            18:        SAVEMASK = 0x3c00
        !            19:        RESTMASK = 0x003c
        !            20: 
        !            21: /*
        !            22:  * unpack a single-precision number into the unpacked record format:
        !            23:  *     d0/d1   mantissa
        !            24:  *     d2.w    exponent
        !            25:  *     d3.w    sign in upper bit
        !            26:  *     d3.b    type ( zero, gu, plain, inf, nan )
        !            27:  */
        !            28: 
        !            29: ENTER(f_unpk)
        !            30:        movl    d1,d3
        !            31:        swap    d3      | sign in bit 15
        !            32:        lsll    #1,d1   | toss sign
        !            33:        roll    #8,d1
        !            34:        clrw    d2
        !            35:        movb    d1,d2   | exponent
        !            36:        bnes    1$      | not gu or zero
        !            37:        movb    #1,d3
        !            38:        tstl    d1
        !            39:        beqs    3$
        !            40:        movb    #2,d3   | gu -- gradual underflow unnormalized
        !            41:        bras    3$
        !            42: 1$:    cmpb    #255,d2 | inf or nan
        !            43:        bnes    2$      | nope, plain number
        !            44:        movw    #0x6000,d2
        !            45:        clrb    d1      | erase exponent
        !            46:        movb    #4,d3   | infinity
        !            47:        tstl    d1
        !            48:        beqs    4$
        !            49:        movb    #5,d3   | nan
        !            50:        bras    4$
        !            51: 2$:    movb    #1,d1   | hidden bit
        !            52:        subqw   #1,d2
        !            53:        movb    #3,d3
        !            54: 3$:    subw    #(126+23),d2
        !            55: 4$:    rorl    #1,d1
        !            56:        lsrl    #8,d1
        !            57:        clrl    d0
        !            58:        rts
        !            59: 
        !            60: /*
        !            61:  * reconstruct a single precision number from its pieces
        !            62:  * returns packed value in d0
        !            63:  */
        !            64: 
        !            65: ENTER(f_pack)
        !            66:        movw    d2,d4   | exponent
        !            67:        cmpb    #4,d3   | is type inf or nan ?
        !            68:        blts    1$      | no, then branch
        !            69:        orl     d0,d1
        !            70:        orl     #0x7f800000,d1  | exponent for inf/nan
        !            71:        lsll    #1,d1
        !            72:        bras    6$
        !            73: 1$:
        !            74:        clrb    d2      | for sticky
        !            75:        tstl    d0
        !            76:        beqs    3$
        !            77:        | shift from upper into lower
        !            78: 2$:
        !            79:        orb     d1,d2   | sticky
        !            80:        movb    d0,d1
        !            81:        addqw   #8,d4   | adjust exponent
        !            82:        rorl    #8,d1
        !            83:        lsrl    #8,d0
        !            84:        bnes    2$      | loop until top == 0
        !            85: 3$:    movl    d1,d0
        !            86:        beqs    6$
        !            87:        | find top bit
        !            88:        bmis    5$
        !            89: 4$:    subqw   #1,d4   | adjust exponent
        !            90:        lsll    #1,d0   | normalize
        !            91:        bpls    4$
        !            92: 5$:    addw    #(126+23+9),d4
        !            93:        tstb    d2
        !            94:        beqs    7$      | Branch if no sticky.
        !            95:        bset    #0,d0   | Turn on sticky bit.
        !            96: 7$:
        !            97:        bsrs    f_rcp
        !            98:        rorl    #8,d0
        !            99:        movl    d0,d1
        !           100: 6$:    lslw    #1,d3
        !           101:        roxrl   #1,d1   | append sign
        !           102:        rts
        !           103: 
        !           104: 
        !           105: /*
        !           106:  * round, check for over/underflow, and pack in the exponent.
        !           107:  */
        !           108: 
        !           109: ENTER(f_rcp)
        !           110:        tstl    d0
        !           111:        bmis    f_rcfast
        !           112:        | do extra normalize ( for mul/div)
        !           113:        subqw   #1,d4
        !           114:        lsll    #1,d0   | do one normalize
        !           115: f_rcfast:      
        !           116:        tstw    d4
        !           117:        bgts    2$
        !           118:        | underflow
        !           119:        cmpw    #-24,d4
        !           120:        blts    rcpzero
        !           121:        negb    d4
        !           122:        addqb   #1,d4
        !           123:        movl    d1,sp@-         | Save d1 on stack.
        !           124:        clrl    d1              | d1 gets 0.
        !           125:        bset    d4,d1           | For n bit shift, d1 gets 2**n.
        !           126:        subql   #1,d1           | d1 gets 2**n -1, an n bit field.
        !           127:        andl    d0,d1           | d1 gets bits to be shifted away.
        !           128:        beqs    1f              | Branch if all zero.
        !           129:        bset    d4,d0           | Sticky lsb for bits to be lost.
        !           130: 1:
        !           131:        movl    sp@+,d1         | Restore d1.
        !           132:        lsrl    d4,d0   | denormalize
        !           133:        clrw    d4      | exp == 0
        !           134: 2$:    addl    #0x80,d0        | crude round
        !           135:        bccs    stesteven
        !           136:        | round overflowed
        !           137:        roxrl   #1,d0
        !           138:        addqw   #1,d4
        !           139:        bras    scheckbig
        !           140: stesteven:
        !           141:        tstb    d0      | Check extra bits after round.
        !           142:        bnes    scheckbig | Branch if round was not ambiguous.
        !           143:        bclr    #8,d0   | Force round to even.
        !           144: scheckbig:
        !           145:        cmpw    #0xff,d4        | adjust exponent
        !           146:        bges    rcpinf
        !           147:        lsll    #1,d0   | toss hidden
        !           148:        |scs    d0      | no hidden implies zero or denormalized
        !           149:        |andb   d4,d0
        !           150:        |rts
        !           151:        bccs    rcpsubnorm | Branch if no i bit found, implying zero or subnorm.
        !           152:        movb    d4,d0   | d0 gets exponent.
        !           153:        bnes    rcprts  | Branch if exp was not zero, implying normal result.
        !           154:        movb    #1,d0   | Result was subnormal before round, normal after,
        !           155:                        | so adjust exponent accordingly.
        !           156: rcprts:
        !           157:        rts
        !           158: rcpsubnorm:            | No carry out from shift implies zero or subnormal
        !           159:                        | result after rounding.
        !           160:        clrb    d0      | Set minimum exponent.
        !           161:        rts
        !           162: 
        !           163: rcpzero:       
        !           164:        clrl    d0
        !           165:        rts
        !           166: rcpinf:        
        !           167:        movl    #0xff,d0        | infinity
        !           168:        rts
        !           169: 
        !           170:        NSAVED   = 3*4  | save registers d2-d4
        !           171:        SAVEMASK = 0x3c00
        !           172:        RESTMASK = 0x003c
        !           173:        ARG2PTR  = a0
        !           174: 
        !           175: /*
        !           176:  * split a double floating number into its pieces
        !           177:  * input:
        !           178:  *     d0/d1   double number
        !           179:  * output: (format of an unpacked record)
        !           180:  *     d0/d1   mantissa: array[1..2] of integer;
        !           181:  *     d2.w    exponent:       -32768..32767;
        !           182:  *     d3.w    sign: (bit 15)  0..1;
        !           183:  *     d3.b    type: 1..5; (zero, gu, plain, inf, nan )
        !           184:  */
        !           185: 
        !           186: ENTER(d_unpk)
        !           187:        movl    #0xfff00000,d2  | mask for sign and exponent
        !           188:        movl    d0,d3
        !           189:        swap    d3              | sign
        !           190:        andl    d0,d2           | extract exponent
        !           191:        eorl    d2,d0           | top of mantissa cleared out
        !           192:        movl    d1,d4
        !           193:        orl     d0,d4           | non-zero iff mantissa non-zero
        !           194:        lsll    #1,d2           | toss sign
        !           195:        bnes    1$              | not 0 or gu
        !           196:        movb    #1,d3   
        !           197:        tstl    d4
        !           198:        beqs    3$              | zero
        !           199:        movb    #2,d3
        !           200:        bras    3$              | gu
        !           201: 1$:    swap    d2
        !           202:        lsrw    #(16-11),d2     | exp to bottom of register
        !           203:        cmpw    #0x7ff,d2       | inf or nan
        !           204:        bnes    2$              | plain
        !           205:        movw    #0x6000,d2
        !           206:        movb    #4,d3
        !           207:        tstl    d4
        !           208:        beqs    4$              | inf
        !           209:        movb    #5,d3           | nan
        !           210:        bras    4$
        !           211: 2$:    bset    #20,d0          | hidden bit
        !           212:        subqw   #1,d2
        !           213:        movb    #3,d3
        !           214: 3$:    subw    #(1022+52), d2
        !           215: 4$:    rts
        !           216: 
        !           217: /*
        !           218:  * reconstruct a double precision number from a record containing its pieces.
        !           219:  *
        !           220:  * input:
        !           221:  *     d2      upper
        !           222:  *     d3      lower 
        !           223:  *     d6      exponent
        !           224:  * output:
        !           225:  *     d0/d1   result
        !           226:  */
        !           227: 
        !           228: ENTER(d_pack)
        !           229:        cmpb    #4,d3   | type
        !           230:        blts    1$
        !           231:        orl     d1,d0
        !           232:        lsll    #1,d0
        !           233:        orl     #0xffe00000,d0
        !           234:        bras    2$      | nan or inf
        !           235: 1$:    addw    #(1022+52+12),d2
        !           236:        exg     d0,d2
        !           237:        exg     d0,d6
        !           238:        exg     d1,d3
        !           239:        bsrs    d_norm
        !           240:        bsr     d_rcp
        !           241:        movl    d0,d6
        !           242:        movl    d2,d0
        !           243:        exg     d3,d1
        !           244: 2$:    lslw    #1,d3
        !           245:        roxrl   #1,d0
        !           246:        rts
        !           247: 
        !           248: /*
        !           249:  * normalize a double-precision number
        !           250:  *
        !           251:  * input:
        !           252:  *     d2/d3 mantissa
        !           253:  *     d6    exponent
        !           254:  */
        !           255: 
        !           256: ENTER(d_norm)
        !           257:        tstl    d2      | upper is non-zero
        !           258:        bnes    1$
        !           259:        cmpw    #32,d6
        !           260:        blts    2$      | about to be denormalized
        !           261:        subw    #32,d6
        !           262:        exg     d3,d2   | shift 32
        !           263:        tstl    d2
        !           264:        beqs    4$      | if result == 0
        !           265: 1$:    bmis    3$      | if already normalized
        !           266: 2$:    lsll    #1,d3   | normalize
        !           267:        roxll   #1,d2
        !           268:        dbmi    d6,2$   | loop until normalized
        !           269:        dbpl    d6,3$   | make sure d6 decremented
        !           270: 3$:    rts
        !           271: 4$:    movw    #-2222,d6       | exp == 0 for zero
        !           272:        rts
        !           273: 
        !           274: 
        !           275: /*
        !           276:  * round, check for over/underflow, and pack in the exponent.
        !           277:  * d_rcp rounds the double value and packs the exponent in,
        !           278:  * catching infinity, zero, and denormalized numbers.
        !           279:  * d_usel puts together the larger argument.
        !           280:  *
        !           281:  * input:
        !           282:  *     d2/d3   mantissa (- if norm)
        !           283:  *     d6      biased exponent
        !           284:  *     (need sign, sticky)
        !           285:  * output:
        !           286:  *     d2/d3   most of number, no sign or hidden bit,
        !           287:  *             waiting to shift sign in.
        !           288:  * other:
        !           289:  *     d4      lost
        !           290:  *     d5      unchanged
        !           291:  */
        !           292: 
        !           293: ENTER(d_rcp)
        !           294:        tstw    d6
        !           295:        bgts    2$
        !           296:        | exponent is negative; denormalize before rounding
        !           297:        cmpw    #-53,d6
        !           298:        blts    dsigned0| go all the way with zero
        !           299:        negw    d6
        !           300: 1$:    lsrl    #1,d2   | denormalize
        !           301:        roxrl   #1,d3
        !           302:        bccs    1f      | Check for bit passing out forever.
        !           303:        bset    #0,d3   | Stick it back on the end.
        !           304: 1:     dbra    d6,1$
        !           305:        clrw    d6
        !           306:        | round
        !           307: 2$:    addl    #0x400,d3
        !           308:        bccs    testeven | Branch if round did not overflow lower part.
        !           309:        addql   #1,d2   | carry
        !           310:        bccs    testeven | Branch if round did not overflow significand.
        !           311:        roxrl   #1,d2
        !           312:        roxrl   #1,d3
        !           313:        addqw   #1,d6
        !           314:        bras    checkbig
        !           315: 
        !           316: testeven:              | Test for ambiguous case to force round to even.
        !           317:        movw    #0x7ff,d4 | d4 gets rounding mask.
        !           318:        andw    d3,d4   | d4 gets extra bits left after rounding.
        !           319:        bnes    checkbig | Branch if it wasn't ambiguous case.
        !           320:        bclr    #11,d3  | Ambiguous case: force round to even.
        !           321: 
        !           322: checkbig:
        !           323:        cmpw    #0x7ff,d6
        !           324:        bges    drcpbig
        !           325: ENTER(d_usel)
        !           326:        | rebuild answer
        !           327:        movl    #0xfffff800,d4
        !           328:        andl    d4,d3
        !           329:        andl    d2,d4
        !           330:        eorl    d4,d2
        !           331:        orl     d2,d3
        !           332:        movl    d4,d2
        !           333:        lsll    #1,d2
        !           334:        |bcss   4$
        !           335:        bcss    cout                    | Branch if carry out occurred.
        !           336:        cmpw    #0x7ff,d6
        !           337:        beqs    4$
        !           338:        clrw    d6
        !           339: 4$:    
        !           340: dshiftright:                   | Double shift right to pack.
        !           341:        moveq   #11,d4
        !           342:        rorl    d4,d3
        !           343:        orw     d6,d2
        !           344:        rorl    d4,d2
        !           345:        rts
        !           346: dsigned0:      clrl    d2
        !           347:        clrl    d3
        !           348:        rts
        !           349: drcpbig:movl   #0xffe00000,d2  | infinity
        !           350:        clrl    d3
        !           351:        rts
        !           352: 
        !           353: cout:
        !           354:        tstw    d6
        !           355:        bnes    dshiftright     | Branch if number was not subnormal.
        !           356:        movw    #1,d6           | Subnormal rounded to normal so fix exp.
        !           357:        bras    dshiftright
        !           358: 
        !           359: | utilities used for floating point  routines
        !           360: 
        !           361: ENTER(f_snan)
        !           362:        movl    #0x7fffffff,d0  | Standard 68881 error nan.
        !           363:        rts
        !           364: 
        !           365:        SAVED0D1 = 0x0003
        !           366:        RESTD0D1 = 0x0003
        !           367:        SAVEALL  = 0x3F00       | registers d2-d4
        !           368:        RESTALL  = 0x00fc       
        !           369: 
        !           370: | decode type of arg in d1 and return  1-5 n d0 for zero gu plain inf and nan
        !           371: 
        !           372: ENTER(f_tst)
        !           373:        lsll    #1,d1           | toss sign
        !           374:        roll    #8,d1           | exp in low byte
        !           375:        tstb    d1
        !           376:        bnes    1$                      | branch if not gu or zero
        !           377:        movl    #1,d0           | assume zero
        !           378:        tstl    d1      
        !           379:        beqs    3$                      | it is
        !           380:        movl    #2,d0           | else it's a gu
        !           381:        bras    3$
        !           382: 1$:    cmpb    #255,d1         | inf or nan ?
        !           383:        bnes    2$                      | nope - plain
        !           384:        movl    #4,d0           | assume inf
        !           385:        andl    #0xFFFFFF00,d1  | Clear exponent field.
        !           386:        beqs    3$                      | it is
        !           387:        movl    #5,d0           | else it'a a nan
        !           388:        rts
        !           389: 2$:    movl    #3,d0
        !           390: 3$:    rts
        !           391: 
        !           392: |      Single and double unbiased exponent, d0 to d0.
        !           393: 
        !           394: |      Fexpos(1.0) = 0 = Fexpod(1.0)
        !           395: 
        !           396: RTENTRY(Fexpos)
        !           397:        andl    #0x7f800000,d0  | Clear out extra bits.
        !           398:        roll    #1,d0
        !           399:        roll    #8,d0
        !           400:        subl    #0x7f,d0
        !           401:        RET
        !           402: 
        !           403: RTENTRY(Fexpod)
        !           404:        andl    #0x7ff00000,d0  | Clear out extra bits.
        !           405:        roll    #4,d0
        !           406:        roll    #8,d0
        !           407:        subl    #0x3ff,d0
        !           408:        RET
        !           409: 
        !           410: |      Switch mode and status.
        !           411: 
        !           412: RTENTRY(Fmode)
        !           413:        movel   d0,sp@-
        !           414:        movel   _Fmode,d0
        !           415:        movel   sp@+,_Fmode
        !           416:        RET
        !           417: RTENTRY(Fstatus)
        !           418:        movel   d0,sp@-
        !           419:        movel   _Fstatus,d0
        !           420:        movel   sp@+,_Fstatus
        !           421:        RET

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.