Annotation of researchv9/libc/sun/Fmuls.s, revision 1.1.1.1

1.1       root        1:        .data
                      2:        .asciz  "@(#)Fmuls.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:  *     ieee single floating multiply
                     12:  *     copyright 1981, 1982 Richard E. James III
                     13:  *     translated to SUN idiom 14 March 1983 rt
                     14:  */
                     15: 
                     16: /*
                     17:  *     entry conditions:
                     18:  *         first argument in d0
                     19:  *         second argument in d1
                     20:  *     exit conditions:
                     21:  *         result (4 bytes) in d0
                     22:  *
                     23:  *     register conventions:
                     24:  *         d0          operand1/upper1
                     25:  *         d1          operand2/upper2
                     26:  *         d2          9/lower1
                     27:  *         d3          lower2
                     28:  *         d4          exponent
                     29:  *         d5          sign
                     30:  */
                     31:        SAVEMASK = 0x3c00       | registers d2-d5
                     32:        RESTMASK = 0x3c
                     33:        NSAVED   = 6*4          | 6 registers * sizeof(register)
                     34: 
                     35: RTENTRY(Fsqrs)
                     36:        movel   d0,d1           | Copy second argument.
                     37:        bras    Fmuls2
                     38: RTENTRY(Fmuls)
                     39: |      save registers
                     40: Fmuls2:
                     41:        moveml  #SAVEMASK,sp@-  | registers d2-d7
                     42:        | save sign of result
                     43:        movl    d0,d5
                     44:        eorl    d1,d5           | sign of result
                     45:        asll    #1,d0           | toss sign
                     46:        asll    #1,d1           | EEmmmm0
                     47:        cmpl    d1,d0
                     48:        | order operands (exponents at least)
                     49:        blss    eswap
                     50:        exg     d0,d1           | d1 = larger
                     51:        | extract and check exponents
                     52: eswap: roll    #8,d0
                     53:        roll    #8,d1           | mmmmm0ee
                     54:        clrw    d4
                     55:        movb    d0,d4
                     56:        clrw    d3
                     57:        movb    d1,d3
                     58:        addw    d3,d4           | result exp
                     59:        cmpb    #0xff, d1
                     60:        beqs    ofl             | infinity or nan
                     61:        tstb    d0
                     62:        beqs    ufl             | 0 or gu (denormalized)
                     63:        | clear exponent; set hidden bit
                     64:        movb    #1,d0
                     65:        rorl    #1,d0
                     66: back:  movb    #1,d1
                     67:        rorl    #1,d1
                     68:        
                     69:        movl    d0,d2           | d2 gets x.
                     70:        movl    d1,d3           | d3 gets y.
                     71:        swap    d0              | d0 gets xu.
                     72:        swap    d1              | d1 gets yu.
                     73:        movw    d1,d5           | d5 gets yu.
                     74:        mulu    d2,d1           | d1 gets xl*yu.
                     75:        mulu    d3,d2           | d2 gets xl*yl.
                     76:        mulu    d0,d3           | d3 gets xu*yl.
                     77:        mulu    d5,d0           | d0 gets xu*yu.
                     78:        addl    d3,d1           | d1 gets middle = xu*yl+xl*yu.
                     79:        bccs    1$              | Branch if no carry occurred.
                     80:        addl    #0x10000,d0     | Propagate carry to upper product.
                     81: 1$:
                     82:        swap    d1              | d1 gets middle(m) (ml,mu).
                     83:        clrl    d3              
                     84:        movw    d1,d3           | d3 gets (0,mu).
                     85:        clrw    d1              | d1 gets (ml,0).
                     86:        addl    d2,d1           | d1 gets lower part of final product.
                     87:        addxl   d3,d0           | d0 gets upper part of final product.
                     88:        tstl    d1
                     89:        beqs    2$              | Branch if lower part is exact.
                     90:        bset    #0,d0           | Set sticky bit if lower part has bits.
                     91: 2$:            
                     92:        subw    #126,d4         | toss extra bias
                     93:        jbsr    f_rcp           | round check, pack
                     94: 
                     95:        | build answer
                     96: mbuild:        rorl    #8,d0
                     97:        roxll   #1,d5
                     98:        roxrl   #1,d0           | append sign
                     99: 
                    100:        | answer in d0
                    101: mexit: moveml  sp@+,#RESTMASK
                    102:        RET
                    103: 
                    104:        | EXCEPTION HANDLING
                    105: ofl:   clrb    d1
                    106:        tstl    d1              | larger mantissa
                    107:        bnes    mni             | user larger nan
                    108:        tstl    d0
                    109:        beqs    m_gennan                | 0*inf
                    110: mni:   movb    #0xff,d1        | inf or nan
                    111:        movl    d1,d0
                    112:        bras    mbuild
                    113: ufl:   tstl    d0              | mantissa of smaller
                    114:        beqs    mbuild
                    115:        | normalizing mode is embodied int the next few lines:
                    116:        bmis    back
                    117: normden:subql  #1,d4           | adj exponent
                    118:        lsll    #1,d0
                    119:        bpls    normden
                    120:        bras    back
                    121: 
                    122: m_gennan:movl  #0x7f800002, d0
                    123:        bras    mexit
                    124: 
                    125: /*
                    126:  *     ieee single floating divide
                    127:  *     copyright 1981, Richard E. James III
                    128:  *     translated to SUN idiom 14 March 1983 rt
                    129:  */
                    130: 
                    131: /*
                    132:  *     entry conditions:
                    133:  *         first argument in d0
                    134:  *         second argument in d1
                    135:  *     exit conditions:
                    136:  *         result (4 bytes) in d0
                    137:  *
                    138:  *     register conventions:
                    139:  *         d0          top; ab;  rq
                    140:  *         d1          bot; c
                    141:  *         d2               q
                    142:  *         d3          bottom exp; d
                    143:  *         d4          top/ final exp
                    144:  *         d5          sign 
                    145:  */
                    146: |
                    147: |      same as for multiply, above
                    148: |      SAVEMASK = 0x3c00       | registers d2-d5
                    149: |      RESTMASK = 0x3c
                    150: |      NSAVED   = 4*4          | 4 registers * sizeof(register)
                    151: 
                    152: RTENTRY(Fdivs)
                    153: |      save registers
                    154:        moveml  #SAVEMASK,sp@-  | registers d2-d5
                    155:        | determine sign
                    156:        movl    d0,d5
                    157:        eorl    d1,d5           | sign in bit 31
                    158:        | split out exponent
                    159:        roll    #1,d0
                    160:        roll    #1,d1
                    161:        roll    #8,d0
                    162:        roll    #8,d1
                    163:        clrw    d3
                    164:        clrw    d4
                    165:        movb    d0,d4           | exp of top
                    166:        movb    d1,d3           | exp of bottom
                    167:        andw    #0xfe00,d0      | clear out s, exp
                    168:        andw    #0xfe00,d1      | clear out s, exp
                    169:        | test exponents
                    170:        addqb   #1,d4           | top
                    171:        subqw   #1,d4
                    172:        bles    toperr
                    173:        addqb   #1,d0           | hidden bit
                    174: backtop:addqb  #1,d3
                    175:        subqw   #1,d3           | bottom
                    176:        bles    boterr
                    177:        addqb   #1,d1           | hidden bit
                    178:        | position mantissas
                    179: backbot:rorl   #2,d1           | 01X...
                    180:        rorl    #4,d0           | 0001X...
                    181:        | compute tentative exponent
                    182:        subw    d3,d4
                    183:        | to compute ab/cd:
                    184:        |    first do ab/c -> q, remainder -> r
                    185:        movw    d1,d3           | save d
                    186:        movw    d3,d5           | d5 saves d.
                    187:        swap    d1              | get c
                    188:        divu    d1,d0           | ab/c 29/15->15 bits
                    189:        movw    d0,d2           | save q
                    190:        mulu    d2,d3           | q*d
                    191:        clrw    d0              | r in top
                    192:        subl    d3,d0           | r-q*d = +-31
                    193:        asrl    #2,d0           | avoid ofl
                    194:        divs    d1,d0           | more quotient
                    195:        movl    d0,d1           | d1 gets remainder in upper word.
                    196:        movw    d5,d3           | d3 gets d.
                    197:        muls    d0,d3           | d3 gets signed(q2)*unsigned(d).
                    198:        btst    #15,d5
                    199:        beqs    99$             | Branch if d appeared positive in muls.
                    200:        swap    d3              | If d appeared negative, correct product.
                    201:        addw    d0,d3
                    202:        swap    d3
                    203: 99$:                           |
                    204:        extl    d2              | q
                    205:        extl    d0              | second quot
                    206:        swap    d2
                    207:        asll    #2,d0
                    208:        addl    d2,d0
                    209:        asll    #1,d0
                    210:        clrw    d1              | d1 gets remainder in upper, 0 lower.
                    211:        subl    d3,d1           | d1 gets revised remainder.
                    212:        beqs    adjexp          | Branch if exact.
                    213:        bmis    decr            | Branch if remainder negative.
                    214:        bset    #0,d0           | inexact => set sticky.
                    215:        bras    adjexp
                    216: decr:
                    217:        subql   #1,d0           | Subtract sticky bit for negative remainder.
                    218:                
                    219: adjexp:                        | adjust exponent, round, check extremes, pack
                    220:        addw    #127,d4
                    221:        jbsr    f_rcp
                    222:        | reposition and append sign
                    223: drepk: rorl    #8,d0
                    224:        lsll    #1,d5           | sign -> x
                    225:        roxrl   #1,d0           | insert sign
                    226: dexit: moveml  sp@+,#RESTMASK
                    227:        RET
                    228: 
                    229:        | EXCEPTIONS
                    230: toperr:        bnes    2$
                    231:        |top is 0 or gu, normalize and return
                    232: 1$:    subqw   #1,d4
                    233:        roll    #1,d0
                    234:        bhis    1$              | loop til normalized, fall if 0
                    235:        addqw   #1,d4
                    236:        bras    backtop         | 0 or gu
                    237: 
                    238:        | top is inf or nan
                    239: 2$:    cmpb    d3,d4
                    240:        beqs    dinvop          | both inf/nan -> nan
                    241:        tstl    d0
                    242:        beqs    geninf          | inf/ ... = +- inf
                    243:        bras    dinvop          | nan/...  =    nan
                    244: 
                    245: boterr:        beqs    botlow          | .../(0|gu)
                    246:                                | .../(inf|nan)
                    247:        tstl    d1
                    248:        bnes    dinvop          | .../nan = nan
                    249:        clrl    d0              | .../inf = +-0
                    250:        bras    drepk
                    251: botlow:        tstl    d1
                    252:        beqs    5$              | .../0
                    253:                                | .../gu:
                    254: 4$:    subqw   #1,d3
                    255:        roll    #1,d1
                    256:        bccs    4$              | loop til normalized
                    257:        addqw   #1,d3
                    258:        jra     backbot
                    259: 
                    260:        | bottom is zero
                    261: 5$:    tstl    d0
                    262:        beqs    d_gennan                | 0/0       =   nan
                    263:                                | nonzero/0 = +-inf
                    264:        | generate infinity for answer
                    265: geninf:        movl    #0xff,d0
                    266:        bras    drepk
                    267: 
                    268:        | invalid operand/ operation
                    269: dinvop:        cmpl    d0,d1
                    270:        bcss    8$              | use larger nan
                    271:        tstl    d1
                    272:        beqs    d_gennan        | both are infinity, generate a nan
                    273:        exg     d1,d0           | larger nan
                    274: 8$:    lsrl    #8,d0
                    275:        lsrl    #1,d0
                    276:        bras    bldnan          | return nan
                    277: 
                    278: d_gennan:moveq #4,d0           | nan 4
                    279: bldnan:        orl     #0x7f800000,d0
                    280:        bras    dexit
                    281: 
                    282:        SAVEMASK = 0x3f00
                    283:        RESTMASK = 0x00fc
                    284: 
                    285:        EXP     = d2
                    286:        TYPE    = d3
                    287:        /* type values: */
                    288:            ZERO  = 1 | wonderful
                    289:            GU    = 2
                    290:            PLAIN = 3
                    291:            INF   = 4
                    292:            NAN   = 5
                    293: 
                    294: RTENTRY(Fscaleis)
                    295:        moveml  #SAVEMASK,sp@-  | state save
                    296:        movel   d1,d4           | Save argument i.
                    297:        movel   d0,d1           | What a crock!
                    298:        jbsr    f_unpk
                    299:        cmpb    #PLAIN,TYPE     | is it a funny number?
                    300:        bgts    gohome          | yes -- return argument
                    301:        cmpb    #ZERO,TYPE
                    302:        beqs    gohome          | is zero -- return arg
                    303:        | normal path through here
                    304:        movw    EXP,d7          
                    305:        extl    d7              | d7 gets long exponent.
                    306:        addl    d4,d7           | d7 gets modified exponent.
                    307:        bvcs    nooflo          | Branch if no overflow.
                    308:        bmis    posov           | Branch if positive overflow to -.
                    309:                                | Branch if negative overflow to +.
                    310: negov:
                    311:        movw    #-2000,EXP
                    312:        bras    gohome
                    313: posov: 
                    314:        movw    #2000,EXP
                    315:        bras    gohome
                    316: nooflo:
                    317:        cmpl    #2000,d7
                    318:        bges    posov
                    319:        cmpl    #-2000,d7
                    320:        bles    negov
                    321:        movw    d7,EXP          | Final OK exponent.
                    322: gohome:
                    323:        jbsr    f_pack
                    324:        movel   d1,d0           | What a crock!
                    325: gone:  moveml  sp@+,#RESTMASK
                    326:        RET

unix.superglobalmegacorp.com

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