Annotation of researchv9/libc/sun/Ffloat.s, revision 1.1.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.