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