Annotation of 3BSD/cmd/lisp/adbig.s, revision 1.1.1.1

1.1       root        1: 
                      2: #      bignum add routine
                      3: #      basic data representation is each bigit is a positive number
                      4: #      less than 2^30, except for the leading bigit, which is in
                      5: #      the range -2^30 < x < 2^30.
                      6: 
                      7:        .globl  _adbig
                      8:        .globl  Bexport
                      9:        .globl  backfr
                     10: #
                     11: #      Initialization section
                     12: #
                     13: _adbig:        .word   0x0fc0          #save registers 6-11
                     14:        movl    4(ap),r1        #arg1 = addr of 1st bignum
                     15:        movl    8(ap),r2        #arg2 = addr of 2nd bignum
                     16:        clrl    r5              #r5   = carry
                     17:        movl    $0xC0000000,r4  #r4   = clear constant.
                     18:        movl    sp,r10          #save start address of bignum on stack.
                     19:                                #note well that this is 4 above the actual
                     20:                                #low order word.
                     21: #
                     22: #      first loop is to waltz through both bignums adding
                     23: #      bigits, pushing them onto stack. 
                     24: #
                     25: loop1: addl3   (r1),(r2),r0    #add bigits
                     26:        addl2   r5,r0           #add carry
                     27:        bicl3   r4,r0,-(sp)     #save sum, no overflow possible
                     28:        extv    $30,$2,r0,r5    #sign extend two high order bits
                     29:                                #to be next carry.
                     30:        movl    4(r1),r1        #get cdr
                     31:        bleq    out1            #negative indicates end of list.
                     32:        movl    4(r2),r2        #get cdr of second bignum
                     33:        bgtr    loop1           #if neither list at end, do it again
                     34: #
                     35: #      second loop propagates carries through higher order words.
                     36: #      It assumes remaining list in r1.
                     37: #
                     38: loop2: addl3   (r1),r5,r0      #add bigits and carry
                     39:        bicl3   r4,r0,-(sp)     #save sum, no overflow possible
                     40:        extv    $30,$2,r0,r5    #sign extend two high order bits
                     41:                                #to be next carry.
                     42:        movl    4(r1),r1        #get cdr
                     43: out2:  bgtr    loop2           #negative indicates end of list.
                     44: out2a: pushl   r5
                     45: #
                     46: #      suppress unnecessary leading zeroes and -1's
                     47: #
                     48: iexport:movl   sp,r11          #more set up for output routine
                     49: ckloop:        
                     50: Bexport:tstl   (r11)           #look at leading bigit
                     51:        bgtr    copyit          #if positive, can allocate storage etc.
                     52:        blss    negchk          #if neg, still a chance we can get by
                     53:        cmpl    r11,r10         #check to see that
                     54:        bgeq    copyit          #we don't pop everything off of stack
                     55:        tstl    (r11)+          #incr r11
                     56:        brb     ckloop          #examine next
                     57: negchk:
                     58:        mcoml   (r11),r3                #r3 is junk register
                     59:        bneq    copyit          #short test for -1
                     60:        tstl    4(r11)          #examine next bigit
                     61:        beql    copyit          #if zero must must leave as is.
                     62:        cmpl    r11,r10         #check to see that
                     63:        bgeq    copyit          #we don't pop everything off of stack
                     64:        tstl    (r11)+          #incr r11
                     65:        bisl2   r4,(r11)        #set high order two bits
                     66:        brb     negchk          #try to supress more leading -1's
                     67: #
                     68: #      The following code is an error exit from the first loop
                     69: #      and is out of place to avoid a jump around a jump.
                     70: #
                     71: out1:  movl    4(r2),r1        #get next addr of list to continue.
                     72:        brb     out2            #if second list simult. exhausted, do
                     73:                                #right thing.
                     74: #
                     75: #      loop3 is a faster version of loop2 when carries are no
                     76: #      longer necessary.
                     77: #
                     78: loop3a: pushl  (r1)            #get datum
                     79: loop3: movl    4(r1),r1        #get cdr
                     80:        bgtr    loop3a          #if not at end get next cell
                     81:        brb     out2a
                     82: 
                     83: #
                     84: #      create linked list representation of bignum
                     85: #
                     86: copyit:        subl3   r11,r10,r2      #see if we can get away with allocating an int
                     87:        bneq    on1             #test for having popped everything
                     88:        subl3   $4,r10,r11      #if so, fix up pointer to bottom
                     89:        brb     intout          #and allocate int.
                     90: on1:   cmpl    r2,$4           #if = 4, then can do
                     91:        beql    intout
                     92:        calls   $0,_newsdot     #get new cell for new bignum
                     93: backfr:        movl    r0,(r6)+        #push address of cell on
                     94:                                #arg stack to save from garbage collection.
                     95:                                #There is guaranteed to be slop for a least one
                     96:                                #push without checking.
                     97:        movl    r0,r8           #r8 = result of adbig
                     98: loop4: movl    -(r10),(r0)     #save bigit
                     99:        movl    r0,r9           #r9 = old cell, to link
                    100:        cmpl    r10,r11         #have we copy'ed all the bigits?
                    101:        bleq    done
                    102:        calls   $0,_newsdot     #get new cell for new bignum
                    103:        movl    r0,4(r9)        #link new cell to old
                    104:        brb     loop4
                    105: done:  
                    106:        clrl    4(r9)           #indicate end of list with 0
                    107:        movl    -(r6),r0        #give resultant address.
                    108:        ret
                    109: #
                    110: #      export integer
                    111: #
                    112: intout: pushl  (r11)
                    113:        calls   $1,_inewint
                    114:        ret
                    115:        .globl  _mulbig
                    116: #
                    117: #      bignum multiplication routine
                    118: #
                    119: #      Initialization section
                    120: #
                    121: _mulbig:.word  0x0fc0          #save regs 6-11
                    122:        movl    4(ap),r1        #get address of first bignum
                    123:        movl    sp,r11          #save top of 1st bignum
                    124: mloop1:        pushl   (r1)            #get bigit
                    125:        movl    4(r1),r1        #get cdr
                    126:        bgtr    mloop1          #repeat if not done
                    127:        movl    sp,r10          #save bottom of 1st bignum, top of 2nd bignum
                    128:        
                    129:        movl    8(ap),r1        #get address of 2nd bignum
                    130: mloop2:        pushl   (r1)            #get bigit
                    131:        movl    4(r1),r1        #get cdr
                    132:        bgtr    mloop2          #repeat if not done
                    133:        movl    sp,r9           #save bottom of 2nd bignum
                    134:        subl3   r9,r11,r6       #r6 contains sum of lengths of bignums
                    135:        subl2   r6,sp
                    136:        movl    sp,r8           #save bottom of product bignum
                    137: #
                    138: #      Actual multiplication
                    139: #
                    140: m1:    movc5   $0,(r8),$0,r6,(r8)#zap out stack space
                    141:        movl    r9,r7           #r7 = &w[j +n] (+4 for a.d.) through calculation
                    142:        subl3   $4,r10,r4       #r4 = &v[j]
                    143: 
                    144: m3:    movl    r7,r5           #r7 = &w[j+n]
                    145:        subl3   $4,r11,r3       #r3 = &u[i]
                    146:        clrl    r2              #clear carry.
                    147: 
                    148: m4:    addl2   -(r5),r2        #add w[i + j] to carry (no ofl poss)
                    149:        emul    (r3),(r4),r2,r0 #r0 = u[i] * v[j] + sext(carry)
                    150:        extzv   $0,$30,r0,(r5)  #get new bigit
                    151:        extv    $30,$32,r0,r2   #get new carry
                    152: 
                    153: m5:    acbl    r10,$-4,r3,m4   #r3 =- 4; if(r3 >= r10) goto m4; r10 = &[u1];
                    154:        movl    r2,-(r5)        #save w[j] = carry
                    155: 
                    156: m6:    subl2   $4,r7           #add just &w[j+n] (+4 for autodec)
                    157:        acbl    r9,$-4,r4,m3    #r4 =- 4; if(r4>=r9) goto m5; r9 = &v[1]
                    158: 
                    159:        movl    r9,r10          #set up for output routine
                    160:        movl    $0xC0000000,r4  #r4   = clear constant.
                    161:        movq    20(fp),r6       #restor _np and _lbot !
                    162:        brw     iexport         #do it!

unix.superglobalmegacorp.com

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