|
|
1.1 root 1: # 3B1 Assembler - primitives for multi-precision math on the MC68010
2: #
3: # Written by Rob Stampfli 19-Oct-92 for 3B1
4: # Assembler: 3B1 native assembler
5: #
6: # Note that the function P_SETP of the Intel primitives is not used.
7: # `set_precision' has to be defined just like in `PORTABLE' mode.
8:
9: global global_precision
10: global P_ADDC
11: global P_SUBB
12: global P_ROTL
13: global P_SETP
14: global P_SMUL
15:
16: text
17:
18: #boolean P_ADDC(unitptr r1, unitptr r2, boolean carry);
19: # /* multiprecision add with carry r2 to r1, result in r1 */
20: #Parameters: A0.l: r1, A1.l: r2, D0.b: carry
21: #Result: D0.b: new carry
22: #Modifies: D0-D2/A0-A1
23:
24: P_ADDC: mov.l 4(%sp),%a0 # fetch first argument: r1
25: mov.l 8(%sp),%a1 # fetch second argument: r2
26: mov.l 12(%sp),%d1 # fetch third argument: carry
27: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
28: mov.w global_precision,%d2 # fetch # of 16 bit units
29: mov.w %d2,%d0 # copy units
30: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
31: add.w %d0,%a0 # point r1 to 1 past least significant unit
32: add.w %d0,%a1 # point r2 to 1 past least significant unit
33: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
34: and.w &15,%d2 # = (units%16); # times thru loop2
35: lsr.b &1,%d1 # set X-bit as specified by carry arg
36: bra adbf1
37: aloop1: #REPT 8 # 16 units per loop
38: addx.l -(%a1),-(%a0)
39: addx.l -(%a1),-(%a0)
40: addx.l -(%a1),-(%a0)
41: addx.l -(%a1),-(%a0)
42: addx.l -(%a1),-(%a0)
43: addx.l -(%a1),-(%a0)
44: addx.l -(%a1),-(%a0)
45: addx.l -(%a1),-(%a0)
46: adbf1: dbf %d0,aloop1
47: bra adbf2
48: aloop2: addx.w -(%a1),-(%a0)
49: adbf2: dbf %d2,aloop2
50: scs %d0 #set returned carry
51: mov.l (%sp)+,%d2 # restore d2
52: rts
53:
54: #boolean P_SUBB(unitptr r1, unitptr r2, boolean borrow);
55: # /* multiprecision subtract with borrow, r2 from r1, result in r1 */
56: #Parameters: A0.l: r1, A1.l: r2, D0.b: borrow
57: #Result: D0.b: new borrow
58: #Modifies: D0-D2/A0/A1
59:
60: P_SUBB: mov.l 4(%sp),%a0 # fetch first argument: r1
61: mov.l 8(%sp),%a1 # fetch second argument: r2
62: mov.l 12(%sp),%d1 # fetch third argument: carry
63: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
64: mov.w global_precision,%d2 # fetch # of 16 bit units
65: mov.w %d2,%d0 # copy units
66: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
67: add.w %d0,%a0 # point r1 to 1 past least significant unit
68: add.w %d0,%a1 # point r2 to 1 past least significant unit
69: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
70: and.w &15,%d2 # = (units%16); # times thru loop2
71: lsr.b &1,%d1 # set X-bit as specified by carry arg
72: bra bdbf1
73: bloop1: #REPT 8 # 16 units per loop
74: subx.l -(%a1),-(%a0)
75: subx.l -(%a1),-(%a0)
76: subx.l -(%a1),-(%a0)
77: subx.l -(%a1),-(%a0)
78: subx.l -(%a1),-(%a0)
79: subx.l -(%a1),-(%a0)
80: subx.l -(%a1),-(%a0)
81: subx.l -(%a1),-(%a0)
82: bdbf1: dbf %d0,bloop1
83: bra bdbf2
84: bloop2: subx.w -(%a1),-(%a0)
85: bdbf2: dbf %d2,bloop2
86: scs %d0 # set returned carry
87: mov.l (%sp)+,%d2 # restore d2
88: rts
89:
90: #boolean P_ROTL(unitptr r1, boolean carry);
91: # /* multiprecision rotate left 1 bit with carry, result in r1. */
92: #Parameters: A0.l: r1, D0.b: carry
93: #Result: D0.b: new carry
94: #Modifies: D0-D2/A0
95:
96: P_ROTL: mov.l 4(%sp),%a0 # fetch first argument: r1
97: mov.l 8(%sp),%d1 # fetch second argument: carry
98: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
99: mov.w global_precision,%d2 # fetch # of 16 bit units
100: mov.w %d2,%d0 # copy units
101: lsl.w &1,%d0 # convert units to bytes (1 unit = 2 bytes)
102: add.w %d0,%a0 # point r1 to 1 past least significant unit
103: lsr.w &5,%d0 # conv bytes to (units/16); # times thru loop1
104: and.w &15,%d2 # = (units%16); # times thru loop2
105: lsr.b &1,%d1 # set X-bit as specified by carry arg
106: bra cdbf1
107: cloop1: #REPT 16 # note roxl.l not valid on 68010
108: roxl.w &1,-(%a0)
109: roxl.w &1,-(%a0)
110: roxl.w &1,-(%a0)
111: roxl.w &1,-(%a0)
112: roxl.w &1,-(%a0)
113: roxl.w &1,-(%a0)
114: roxl.w &1,-(%a0)
115: roxl.w &1,-(%a0)
116: roxl.w &1,-(%a0)
117: roxl.w &1,-(%a0)
118: roxl.w &1,-(%a0)
119: roxl.w &1,-(%a0)
120: roxl.w &1,-(%a0)
121: roxl.w &1,-(%a0)
122: roxl.w &1,-(%a0)
123: roxl.w &1,-(%a0)
124: cdbf1: dbf %d0,cloop1
125: bra cdbf2
126: cloop2: roxl.w &1,-(%a0)
127: cdbf2: dbf %d2,cloop2
128: scs %d0 # set returned carry
129: mov.l (%sp)+,%d2 # restore d2
130: rts
131:
132: #void P_SETP(short nbits);
133: # /* sets working precision to specified number of bits. */
134: # /* only to minimize portation differences */
135: #Parameters: --
136: #Result: --
137:
138: P_SETP: rts
139:
140: #void P_SMUL(MULTUNIT *prod, MULTUNIT *multiplicand, MULTUNIT multiplier)
141: # /* multiprecision multiply */
142: #Parameters: A0.l: prod, A1.l: multiplicand, D0.w: multiplier
143: #Modifies: D0-D4/A0-A1
144: #Result: --
145: #Note: prod and multiplicand have already been adjusted to point to LSB
146: # prior to making the call.
147:
148: P_SMUL: mov.l 4(%sp),%a0 # fetch first argument: prod
149: mov.l 8(%sp),%a1 # fetch second argument: multiplicand
150: mov.l 12(%sp),%d0 # fetch third argument: multiplier
151: mov.l %d2,-(%sp) # save d2 -- not a Unix-PC scratch reg
152: mov.l %d3,-(%sp) # save d3 -- not a Unix-PC scratch reg
153: mov.l %d4,-(%sp) # save d4 -- not a Unix-PC scratch reg
154: clr.l %d2 # clear the carry register
155: clr.l %d4 # clear upper half of temp reg for prod
156: add.w &2,%a0 # position prod to 1 beyond LSB
157: add.w &2,%a1 # position multiplicand to 1 beyond LSB
158: mov.w global_precision,%d3 # fetch size of multiplicand
159: bra ddbf1
160:
161: dloop: mov.w -(%a1),%d1 # fetch multiplicand
162: mulu.w %d0,%d1 # multiply by multiplier
163: mov.w -(%a0),%d4 # fetch prod
164: add.l %d4,%d1 # add in prod
165: add.l %d2,%d1 # add in carry
166: mov.w %d1,(%a0) # store result back to prod
167: swap.w %d1 # fetch carry info (upper 16 bits of mult)
168: mov.w %d1,%d2 # and move it into carry
169: ddbf1: dbf %d3,dloop
170:
171: mov.w %d2,-(%a0) # store carry
172: mov.l (%sp)+,%d4
173: mov.l (%sp)+,%d3
174: mov.l (%sp)+,%d2
175: rts
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.