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