Annotation of 41BSD/cmd/lisp/bigmath.s, revision 1.1.1.1

1.1       root        1:        .asciz  "@(#)bigmath.s  34.1    10/3/80"
                      2:        .globl  _dmlad
                      3: #
                      4: #      routine for destructive multiplication and addition to a bignum by
                      5: #      two fixnums.
                      6: #
                      7: #      from C, the invocation is dmlad(sdot,mul,add);
                      8: #      where sdot is the address of the first special cell of the bignum
                      9: #      mul is the multiplier, add is the fixnum to be added (The latter
                     10: #      being passed by value, as is the usual case.
                     11: #
                     12: #
                     13: #      Register assignments:
                     14: #
                     15: #      r11 = current sdot
                     16: #      r10 = carry
                     17: #      r9  = previous sdot, for relinking.
                     18: #
                     19: _dmlad:        .word   0x0e00
                     20:        movl    4(ap),r11               #initialize cell pointer
                     21:        movl    12(ap),r10              #initialize carry
                     22: loop:  emul    8(ap),(r11),r10,r0      #r0 gets cell->car times mul + carry
                     23: #      ediv    $0x40000000,r0,r10,(r11)#cell->car gets prod % 2**30
                     24: #                                      #carry gets quotient
                     25:        extzv   $0,$30,r0,(r11)
                     26:        extv    $30,$32,r0,r10
                     27:        movl    r11,r9                  #save last cell for fixup at end.
                     28:        movl    4(r11),r11              #move to next cell
                     29:        bneq    loop                    #done indicated by 0 for next sdot
                     30:        tstl    r10                     #if carry zero no need to allocate
                     31:        beql    done                    #new bigit
                     32:        mcoml   r10,r3                  #test to see if neg 1.
                     33:        bneq    alloc                   #if not must allocate new cell.
                     34:        tstl    (r9)                    #make sure product isn't -2**30
                     35:        beql    alloc
                     36:        movl    r0,(r9)                 #save old lower half of product.
                     37:        brb     done
                     38: alloc: calls   $0,_newsdot             #otherwise allocate new bigit
                     39:        movl    r10,(r0)                #store carry
                     40:        movl    r0,4(r9)                #save new link cell
                     41: done:  movl    4(ap),r0
                     42:        ret
                     43:        .globl _dodiv
                     44: #
                     45: #      routine to destructively divide array representation of a bignum by 
                     46: #      1000000000
                     47: #
                     48: #      invocation:
                     49: #              remainder = dodiv(top,bottom)
                     50: #              int *top, *bottom;
                     51: #      where *bottom is the address of the biggning of the array, *top is
                     52: #      the top of the array.
                     53: #
                     54: #      register assignments:
                     55: #      r0 = carry
                     56: #      r1 & r2 = 64bit temporary
                     57: #      r3 = pointer
                     58: #
                     59: _dodiv:        .word   0
                     60:        clrl            r0              #no carry to begin.
                     61:        movl            8(ap),r3        #get pointer to array.
                     62: loop2: emul            $0x40000000,r0,(r3),r1
                     63:        ediv            $1000000000,r1,(r3),r0
                     64:        acbl            4(ap),$4,r3,loop2
                     65:        ret
                     66:        .globl  _dsneg
                     67: #
                     68: #      dsneg(top, bot);
                     69: #      int *top, *bot;
                     70: #
                     71: #      routine to destructively negate a bignum stored in array format
                     72: #      lower order stuff at higher addresses. It is assume that the
                     73: #      result will be positive.
                     74: #      
                     75: _dsneg:        .word   0
                     76:        movl    4(ap),r1        #load up address.
                     77:        clrl    r2              #set carry
                     78: loop3: mnegl   (r1),r0         #negate and take carry into account.
                     79:        addl2   r2,r0
                     80:        extzv   $0,$30,r0,(r1)
                     81:        extv    $30,$2,r0,r2
                     82:        acbl    8(ap),$-4,r1,loop3
                     83:                                #decrease r1, and branch back if appropriate.
                     84:        ret
                     85: 
                     86: #      bignum add routine
                     87: #      basic data representation is each bigit is a positive number
                     88: #      less than 2^30, except for the leading bigit, which is in
                     89: #      the range -2^30 < x < 2^30.
                     90: 
                     91:        .globl  _adbig
                     92:        .globl  Bexport
                     93:        .globl  backfr
                     94: #
                     95: #      Initialization section
                     96: #
                     97: _adbig:        .word   0x0fc0          #save registers 6-11
                     98:        movl    4(ap),r1        #arg1 = addr of 1st bignum
                     99:        movl    8(ap),r2        #arg2 = addr of 2nd bignum
                    100:        clrl    r5              #r5   = carry
                    101:        movl    $0xC0000000,r4  #r4   = clear constant.
                    102:        movl    sp,r10          #save start address of bignum on stack.
                    103:                                #note well that this is 4 above the actual
                    104:                                #low order word.
                    105: #
                    106: #      first loop is to waltz through both bignums adding
                    107: #      bigits, pushing them onto stack. 
                    108: #
                    109: loop4: addl3   (r1),(r2),r0    #add bigits
                    110:        addl2   r5,r0           #add carry
                    111:        bicl3   r4,r0,-(sp)     #save sum, no overflow possible
                    112:        extv    $30,$2,r0,r5    #sign extend two high order bits
                    113:                                #to be next carry.
                    114:        movl    4(r1),r1        #get cdr
                    115:        bleq    out1            #negative indicates end of list.
                    116:        movl    4(r2),r2        #get cdr of second bignum
                    117:        bgtr    loop4           #if neither list at end, do it again
                    118: #
                    119: #      second loop propagates carries through higher order words.
                    120: #      It assumes remaining list in r1.
                    121: #
                    122: loop5: addl3   (r1),r5,r0      #add bigits and carry
                    123:        bicl3   r4,r0,-(sp)     #save sum, no overflow possible
                    124:        extv    $30,$2,r0,r5    #sign extend two high order bits
                    125:                                #to be next carry.
                    126:        movl    4(r1),r1        #get cdr
                    127: out2:  bgtr    loop5           #negative indicates end of list.
                    128: out2a: pushl   r5
                    129: #
                    130: #      suppress unnecessary leading zeroes and -1's
                    131: #
                    132: iexport:movl   sp,r11          #more set up for output routine
                    133: ckloop:        
                    134: Bexport:tstl   (r11)           #look at leading bigit
                    135:        bgtr    copyit          #if positive, can allocate storage etc.
                    136:        blss    negchk          #if neg, still a chance we can get by
                    137:        cmpl    r11,r10         #check to see that
                    138:        bgeq    copyit          #we don't pop everything off of stack
                    139:        tstl    (r11)+          #incr r11
                    140:        brb     ckloop          #examine next
                    141: negchk:
                    142:        mcoml   (r11),r3                #r3 is junk register
                    143:        bneq    copyit          #short test for -1
                    144:        tstl    4(r11)          #examine next bigit
                    145:        beql    copyit          #if zero must must leave as is.
                    146:        cmpl    r11,r10         #check to see that
                    147:        bgeq    copyit          #we don't pop everything off of stack
                    148:        tstl    (r11)+          #incr r11
                    149:        bisl2   r4,(r11)        #set high order two bits
                    150:        brb     negchk          #try to supress more leading -1's
                    151: #
                    152: #      The following code is an error exit from the first loop
                    153: #      and is out of place to avoid a jump around a jump.
                    154: #
                    155: out1:  movl    4(r2),r1        #get next addr of list to continue.
                    156:        brb     out2            #if second list simult. exhausted, do
                    157:                                #right thing.
                    158: #
                    159: #      loop6 is a faster version of loop5 when carries are no
                    160: #      longer necessary.
                    161: #
                    162: loop6a: pushl  (r1)            #get datum
                    163: loop6: movl    4(r1),r1        #get cdr
                    164:        bgtr    loop6a          #if not at end get next cell
                    165:        brb     out2a
                    166: 
                    167: #
                    168: #      create linked list representation of bignum
                    169: #
                    170: copyit:        subl3   r11,r10,r2      #see if we can get away with allocating an int
                    171:        bneq    on1             #test for having popped everything
                    172:        subl3   $4,r10,r11      #if so, fix up pointer to bottom
                    173:        brb     intout          #and allocate int.
                    174: on1:   cmpl    r2,$4           #if = 4, then can do
                    175:        beql    intout
                    176:        calls   $0,_newsdot     #get new cell for new bignum
                    177: backfr:        movl    r0,(r6)+        #push address of cell on
                    178:                                #arg stack to save from garbage collection.
                    179:                                #There is guaranteed to be slop for a least one
                    180:                                #push without checking.
                    181:        movl    r0,r8           #r8 = result of adbig
                    182: loop7: movl    -(r10),(r0)     #save bigit
                    183:        movl    r0,r9           #r9 = old cell, to link
                    184:        cmpl    r10,r11         #have we copy'ed all the bigits?
                    185:        bleq    Edone
                    186:        calls   $0,_newsdot     #get new cell for new bignum
                    187:        movl    r0,4(r9)        #link new cell to old
                    188:        brb     loop7
                    189: Edone: 
                    190:        clrl    4(r9)           #indicate end of list with 0
                    191:        movl    -(r6),r0        #give resultant address.
                    192:        ret
                    193: #
                    194: #      export integer
                    195: #
                    196: intout: pushl  (r11)
                    197:        calls   $1,_inewint
                    198:        ret
                    199:        .globl  _mulbig
                    200: #
                    201: #      bignum multiplication routine
                    202: #
                    203: #      Initialization section
                    204: #
                    205: _mulbig:.word  0x0fc0          #save regs 6-11
                    206:        movl    4(ap),r1        #get address of first bignum
                    207:        movl    sp,r11          #save top of 1st bignum
                    208: mloop1:        pushl   (r1)            #get bigit
                    209:        movl    4(r1),r1        #get cdr
                    210:        bgtr    mloop1          #repeat if not done
                    211:        movl    sp,r10          #save bottom of 1st bignum, top of 2nd bignum
                    212:        
                    213:        movl    8(ap),r1        #get address of 2nd bignum
                    214: mloop2:        pushl   (r1)            #get bigit
                    215:        movl    4(r1),r1        #get cdr
                    216:        bgtr    mloop2          #repeat if not done
                    217:        movl    sp,r9           #save bottom of 2nd bignum
                    218:        subl3   r9,r11,r6       #r6 contains sum of lengths of bignums
                    219:        subl2   r6,sp
                    220:        movl    sp,r8           #save bottom of product bignum
                    221: #
                    222: #      Actual multiplication
                    223: #
                    224: m1:    movc5   $0,(r8),$0,r6,(r8)#zap out stack space
                    225:        movl    r9,r7           #r7 = &w[j +n] (+4 for a.d.) through calculation
                    226:        subl3   $4,r10,r4       #r4 = &v[j]
                    227: 
                    228: m3:    movl    r7,r5           #r7 = &w[j+n]
                    229:        subl3   $4,r11,r3       #r3 = &u[i]
                    230:        clrl    r2              #clear carry.
                    231: 
                    232: m4:    addl2   -(r5),r2        #add w[i + j] to carry (no ofl poss)
                    233:        emul    (r3),(r4),r2,r0 #r0 = u[i] * v[j] + sext(carry)
                    234:        extzv   $0,$30,r0,(r5)  #get new bigit
                    235:        extv    $30,$32,r0,r2   #get new carry
                    236: 
                    237: m5:    acbl    r10,$-4,r3,m4   #r3 =- 4; if(r3 >= r10) goto m4; r10 = &[u1];
                    238:        movl    r2,-(r5)        #save w[j] = carry
                    239: 
                    240: m6:    subl2   $4,r7           #add just &w[j+n] (+4 for autodec)
                    241:        acbl    r9,$-4,r4,m3    #r4 =- 4; if(r4>=r9) goto m5; r9 = &v[1]
                    242: 
                    243:        movl    r9,r10          #set up for output routine
                    244:        movl    $0xC0000000,r4  #r4   = clear constant.
                    245:        movq    20(fp),r6       #restor _np and _lbot !
                    246:        brw     iexport         #do it!
                    247: #
                    248: # The remainder of this file are routines used in bignum division.
                    249: # Interested parties should consult Knuth, Vol 2, and divbig.c.
                    250: # These files are here only due to an optimizer bug.
                    251: #
                    252: 
                    253:        .align  1
                    254:        .globl  _calqhat
                    255: _calqhat:
                    256:        .word   .R1
                    257:        movl    4(ap),r11
                    258:        movl    8(ap),r10
                    259:        movl    $0x3fffffff,r0
                    260:        cmpl    (r10),(r11)
                    261:        beql    on3
                    262:        emul    (r11),$0x40000000,4(r11),r1
                    263:        ediv    (r10),r1,r0,r5
                    264: on3:
                    265:        emul    r0,4(r10),$0,r1
                    266:        emul    r5,$0x40000000,8(r11),r3
                    267:        subl2   r3,r1
                    268:        sbwc    r4,r2
                    269:        bleq    out4
                    270:        decl    r0
                    271: out4:
                    272:        ret
                    273:        .set    .R1,0xc00
                    274:        .align  1
                    275:        .globl  _mlsb
                    276: _mlsb:
                    277:        .word   .R2
                    278:        movl    4(ap),r11
                    279:        movl    8(ap),r10
                    280:        movl    12(ap),r9
                    281:        movl    16(ap),r8
                    282:        clrl    r0
                    283: loop8: addl2   (r11),r0
                    284:        emul    r8,-(r9),r0,r2
                    285:        extzv   $0,$30,r2,(r11)
                    286:        extv    $30,$32,r2,r0
                    287:        acbl    r10,$-4,r11,loop8
                    288:        ret
                    289:        .set    .R2,0xf00
                    290:        .align  1
                    291:        .globl  _adback
                    292: _adback:
                    293:        .word   .R3
                    294:        movl    4(ap),r11
                    295:        movl    8(ap),r10
                    296:        movl    12(ap),r9
                    297:        clrl    r0
                    298: loop9: addl2   -(r9),r0
                    299:        addl2   (r11),r0
                    300:        extzv   $0,$30,r0,(r11)
                    301:        extv    $30,$2,r0,r0
                    302:        acbl    r10,$-4,r11,loop9
                    303:        ret
                    304:        .set    .R3,0xe00
                    305:        .align  1
                    306:        .globl  _dsdiv
                    307: _dsdiv:
                    308:        .word   .R4
                    309:        movl    8(ap),r11
                    310:        clrl    r0
                    311: loopa: emul    r0,$0x40000000,(r11),r1
                    312:        ediv    12(ap),r1,(r11),r0
                    313:        acbl    4(ap),$4,r11,loopa
                    314:        ret
                    315:        .set    .R4,0x800
                    316:        .align  1
                    317:        .globl  _dsmult
                    318: _dsmult:
                    319:        .word   .R5
                    320:        movl    4(ap),r11
                    321:        clrl    r0
                    322: loopb: emul    12(ap),(r11),r0,r1
                    323:        extzv   $0,$30,r1,(r11)
                    324:        extv    $30,$32,r1,r0
                    325:        acbl    8(ap),$-4,r11,loopb
                    326:        movl    r1,4(r11)
                    327:        ret
                    328:        .set    .R5,0x800
                    329:        .align  1
                    330:        .globl  _export
                    331: _export:
                    332:        .word   .R6
                    333:        movl    8(ap),r11
                    334:        movl    4(ap),r10
                    335:        movl    $0xC0000000,r4
                    336:        jmp     Bexport
                    337:        ret
                    338:        .set    .R6,0xfc0

unix.superglobalmegacorp.com

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