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