|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.