Annotation of 3BSD/cmd/lisp/adbig.s, revision 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.