xref: /plan9/sys/src/libc/sparc/muldivrt.s (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1*80ee5cbfSDavid du Colombier/*
2*80ee5cbfSDavid du Colombier *	ulong
3*80ee5cbfSDavid du Colombier *	_udiv(ulong num, ulong den)
4*80ee5cbfSDavid du Colombier *	{
5*80ee5cbfSDavid du Colombier *		int i;
6*80ee5cbfSDavid du Colombier *		ulong quo;
7*80ee5cbfSDavid du Colombier *
8*80ee5cbfSDavid du Colombier *		if(den == 0)
9*80ee5cbfSDavid du Colombier *			*(ulong*)-1 = 0;
10*80ee5cbfSDavid du Colombier *		quo = num;
11*80ee5cbfSDavid du Colombier *		if(quo > 1<<(32-1))
12*80ee5cbfSDavid du Colombier *			quo = 1<<(32-1);
13*80ee5cbfSDavid du Colombier *		for(i=0; den<quo; i++)
14*80ee5cbfSDavid du Colombier *			den <<= 1;
15*80ee5cbfSDavid du Colombier *		quo = 0;
16*80ee5cbfSDavid du Colombier *		for(; i>=0; i--) {
17*80ee5cbfSDavid du Colombier *			quo <<= 1;
18*80ee5cbfSDavid du Colombier *			if(num >= den) {
19*80ee5cbfSDavid du Colombier *				num -= den;
20*80ee5cbfSDavid du Colombier *				quo |= 1;
21*80ee5cbfSDavid du Colombier *			}
22*80ee5cbfSDavid du Colombier *			den >>= 1;
23*80ee5cbfSDavid du Colombier *		}
24*80ee5cbfSDavid du Colombier *		return quo::num;
25*80ee5cbfSDavid du Colombier *	}
26*80ee5cbfSDavid du Colombier */
27*80ee5cbfSDavid du Colombier
28*80ee5cbfSDavid du Colombier#define	NOPROF	1
29*80ee5cbfSDavid du Colombier
30*80ee5cbfSDavid du Colombier/*
31*80ee5cbfSDavid du Colombier * calling sequence:
32*80ee5cbfSDavid du Colombier *	num: 4(R1)
33*80ee5cbfSDavid du Colombier *	den: 8(R1)
34*80ee5cbfSDavid du Colombier * returns
35*80ee5cbfSDavid du Colombier *	quo: 4(R1)
36*80ee5cbfSDavid du Colombier *	rem: 8(R1)
37*80ee5cbfSDavid du Colombier */
38*80ee5cbfSDavid du ColombierTEXT	_udivmod(SB), NOPROF, $-4
39*80ee5cbfSDavid du Colombier
40*80ee5cbfSDavid du Colombier	MOVW	$(1<<31), R11
41*80ee5cbfSDavid du Colombier	MOVW	4(R1), R13	/* numerator */
42*80ee5cbfSDavid du Colombier	MOVW	8(R1), R10	/* denominator */
43*80ee5cbfSDavid du Colombier	CMP	R10, R0
44*80ee5cbfSDavid du Colombier	BNE	udm20
45*80ee5cbfSDavid du Colombier	MOVW	R0, -1(R0)	/* fault -- divide by zero */
46*80ee5cbfSDavid du Colombierudm20:
47*80ee5cbfSDavid du Colombier	MOVW	R13, R12
48*80ee5cbfSDavid du Colombier	CMP	R13, R11
49*80ee5cbfSDavid du Colombier	BLEU	udm34
50*80ee5cbfSDavid du Colombier	MOVW	R11, R12
51*80ee5cbfSDavid du Colombierudm34:
52*80ee5cbfSDavid du Colombier	MOVW	R0, R11
53*80ee5cbfSDavid du Colombierudm38:
54*80ee5cbfSDavid du Colombier	CMP	R10, R12
55*80ee5cbfSDavid du Colombier	BCC	udm54
56*80ee5cbfSDavid du Colombier	SLL	$1, R10
57*80ee5cbfSDavid du Colombier	ADD	$1, R11
58*80ee5cbfSDavid du Colombier	BA	udm38
59*80ee5cbfSDavid du Colombierudm54:
60*80ee5cbfSDavid du Colombier	MOVW	R0, R12
61*80ee5cbfSDavid du Colombierudm58:
62*80ee5cbfSDavid du Colombier	CMP	R11, R0
63*80ee5cbfSDavid du Colombier	BL	udm8c
64*80ee5cbfSDavid du Colombier	SLL	$1, R12
65*80ee5cbfSDavid du Colombier	CMP	R13, R10
66*80ee5cbfSDavid du Colombier	BCS	udm7c
67*80ee5cbfSDavid du Colombier	SUB	R10, R13
68*80ee5cbfSDavid du Colombier	OR	$1, R12
69*80ee5cbfSDavid du Colombierudm7c:
70*80ee5cbfSDavid du Colombier	SRL	$1, R10
71*80ee5cbfSDavid du Colombier	SUB	$1, R11
72*80ee5cbfSDavid du Colombier	BA	udm58
73*80ee5cbfSDavid du Colombierudm8c:
74*80ee5cbfSDavid du Colombier	MOVW	R12, 4(R1)	/* quotent */
75*80ee5cbfSDavid du Colombier	MOVW	R13, 8(R1)	/* remainder */
76*80ee5cbfSDavid du Colombier	JMPL	8(R15)
77*80ee5cbfSDavid du Colombier
78*80ee5cbfSDavid du Colombier/*
79*80ee5cbfSDavid du Colombier * save working registers
80*80ee5cbfSDavid du Colombier * and bring in num/den parameters
81*80ee5cbfSDavid du Colombier */
82*80ee5cbfSDavid du ColombierTEXT	_unsarg(SB), NOPROF, $-4
83*80ee5cbfSDavid du Colombier	MOVW	R10, 12(R1)
84*80ee5cbfSDavid du Colombier	MOVW	R11, 16(R1)
85*80ee5cbfSDavid du Colombier	MOVW	R12, 20(R1)
86*80ee5cbfSDavid du Colombier	MOVW	R13, 24(R1)
87*80ee5cbfSDavid du Colombier
88*80ee5cbfSDavid du Colombier	MOVW	R14, 4(R1)
89*80ee5cbfSDavid du Colombier	MOVW	32(R1), R14
90*80ee5cbfSDavid du Colombier	MOVW	R14, 8(R1)
91*80ee5cbfSDavid du Colombier
92*80ee5cbfSDavid du Colombier	JMPL	8(R15)
93*80ee5cbfSDavid du Colombier
94*80ee5cbfSDavid du Colombier/*
95*80ee5cbfSDavid du Colombier * save working registers
96*80ee5cbfSDavid du Colombier * and bring in absolute value
97*80ee5cbfSDavid du Colombier * of num/den parameters
98*80ee5cbfSDavid du Colombier */
99*80ee5cbfSDavid du ColombierTEXT	_absarg(SB), NOPROF, $-4
100*80ee5cbfSDavid du Colombier	MOVW	R10, 12(R1)
101*80ee5cbfSDavid du Colombier	MOVW	R11, 16(R1)
102*80ee5cbfSDavid du Colombier	MOVW	R12, 20(R1)
103*80ee5cbfSDavid du Colombier	MOVW	R13, 24(R1)
104*80ee5cbfSDavid du Colombier
105*80ee5cbfSDavid du Colombier	MOVW	R14, 28(R1)
106*80ee5cbfSDavid du Colombier	CMP	R14, R0
107*80ee5cbfSDavid du Colombier	BGE	ab1
108*80ee5cbfSDavid du Colombier	SUB	R14, R0, R14
109*80ee5cbfSDavid du Colombierab1:
110*80ee5cbfSDavid du Colombier	MOVW	R14, 4(R1)	/* numerator */
111*80ee5cbfSDavid du Colombier
112*80ee5cbfSDavid du Colombier	MOVW	32(R1), R14
113*80ee5cbfSDavid du Colombier	CMP	R14, R0
114*80ee5cbfSDavid du Colombier	BGE	ab2
115*80ee5cbfSDavid du Colombier	SUB	R14, R0, R14
116*80ee5cbfSDavid du Colombierab2:
117*80ee5cbfSDavid du Colombier	MOVW	R14, 8(R1)	/* denominator */
118*80ee5cbfSDavid du Colombier	JMPL	8(R15)
119*80ee5cbfSDavid du Colombier
120*80ee5cbfSDavid du Colombier/*
121*80ee5cbfSDavid du Colombier * restore registers and
122*80ee5cbfSDavid du Colombier * return to original caller
123*80ee5cbfSDavid du Colombier * answer is in R14
124*80ee5cbfSDavid du Colombier */
125*80ee5cbfSDavid du ColombierTEXT	_retarg(SB), NOPROF, $-4
126*80ee5cbfSDavid du Colombier	MOVW	12(R1), R10
127*80ee5cbfSDavid du Colombier	MOVW	16(R1), R11
128*80ee5cbfSDavid du Colombier	MOVW	20(R1), R12
129*80ee5cbfSDavid du Colombier	MOVW	24(R1), R13
130*80ee5cbfSDavid du Colombier	MOVW	0(R1), R15
131*80ee5cbfSDavid du Colombier
132*80ee5cbfSDavid du Colombier	ADD	$28, R1
133*80ee5cbfSDavid du Colombier	JMP	8(R15)		/* back to main sequence */
134*80ee5cbfSDavid du Colombier
135*80ee5cbfSDavid du Colombier/*
136*80ee5cbfSDavid du Colombier * calling sequence
137*80ee5cbfSDavid du Colombier *	num: R14
138*80ee5cbfSDavid du Colombier *	den: 8(R1)
139*80ee5cbfSDavid du Colombier * returns
140*80ee5cbfSDavid du Colombier *	quo: R14
141*80ee5cbfSDavid du Colombier */
142*80ee5cbfSDavid du ColombierTEXT	_div(SB), NOPROF, $-4
143*80ee5cbfSDavid du Colombier	SUB	$28, R1		/* 4 reg save, 2 parameters, link */
144*80ee5cbfSDavid du Colombier	MOVW	R15, 0(R1)
145*80ee5cbfSDavid du Colombier
146*80ee5cbfSDavid du Colombier	JMPL	_absarg(SB)
147*80ee5cbfSDavid du Colombier	JMPL	_udivmod(SB)
148*80ee5cbfSDavid du Colombier	MOVW	4(R1), R14
149*80ee5cbfSDavid du Colombier
150*80ee5cbfSDavid du Colombier	MOVW	28(R1), R10	/* clean up the sign */
151*80ee5cbfSDavid du Colombier	MOVW	32(R1), R11
152*80ee5cbfSDavid du Colombier	XORCC	R11, R10, R0
153*80ee5cbfSDavid du Colombier	BGE	div1
154*80ee5cbfSDavid du Colombier	SUB	R14, R0, R14
155*80ee5cbfSDavid du Colombierdiv1:
156*80ee5cbfSDavid du Colombier
157*80ee5cbfSDavid du Colombier	JMPL	_retarg(SB)
158*80ee5cbfSDavid du Colombier	JMP	8(R15)		/* not executed */
159*80ee5cbfSDavid du Colombier
160*80ee5cbfSDavid du Colombier/*
161*80ee5cbfSDavid du Colombier * calling sequence
162*80ee5cbfSDavid du Colombier *	num: R14
163*80ee5cbfSDavid du Colombier *	den: 8(R1)
164*80ee5cbfSDavid du Colombier * returns
165*80ee5cbfSDavid du Colombier *	quo: R14
166*80ee5cbfSDavid du Colombier */
167*80ee5cbfSDavid du ColombierTEXT	_divl(SB), NOPROF, $-4
168*80ee5cbfSDavid du Colombier	SUB	$((4+2+1)*4), R1	/* 4 reg save, 2 parameters, link */
169*80ee5cbfSDavid du Colombier	MOVW	R15, 0(R1)
170*80ee5cbfSDavid du Colombier
171*80ee5cbfSDavid du Colombier	JMPL	_unsarg(SB)
172*80ee5cbfSDavid du Colombier	JMPL	_udivmod(SB)
173*80ee5cbfSDavid du Colombier	MOVW	4(R1), R14
174*80ee5cbfSDavid du Colombier
175*80ee5cbfSDavid du Colombier	JMPL	_retarg(SB)
176*80ee5cbfSDavid du Colombier	JMP	8(R15)		/* not executed */
177*80ee5cbfSDavid du Colombier
178*80ee5cbfSDavid du Colombier/*
179*80ee5cbfSDavid du Colombier * calling sequence
180*80ee5cbfSDavid du Colombier *	num: R14
181*80ee5cbfSDavid du Colombier *	den: 8(R1)
182*80ee5cbfSDavid du Colombier * returns
183*80ee5cbfSDavid du Colombier *	rem: R14
184*80ee5cbfSDavid du Colombier */
185*80ee5cbfSDavid du ColombierTEXT	_mod(SB), NOPROF, $-4
186*80ee5cbfSDavid du Colombier	SUB	$28, R1		/* 4 reg save, 2 parameters, link */
187*80ee5cbfSDavid du Colombier
188*80ee5cbfSDavid du Colombier	MOVW	R15, 0(R1)
189*80ee5cbfSDavid du Colombier	JMPL	_absarg(SB)
190*80ee5cbfSDavid du Colombier	JMPL	_udivmod(SB)
191*80ee5cbfSDavid du Colombier	MOVW	8(R1), R14
192*80ee5cbfSDavid du Colombier
193*80ee5cbfSDavid du Colombier	MOVW	28(R1), R10	/* clean up the sign */
194*80ee5cbfSDavid du Colombier	CMP	R10, R0
195*80ee5cbfSDavid du Colombier	BGE	mod1
196*80ee5cbfSDavid du Colombier	SUB	R14, R0, R14
197*80ee5cbfSDavid du Colombiermod1:
198*80ee5cbfSDavid du Colombier
199*80ee5cbfSDavid du Colombier	JMPL	_retarg(SB)
200*80ee5cbfSDavid du Colombier	JMP	8(R15)		/* not executed */
201*80ee5cbfSDavid du Colombier
202*80ee5cbfSDavid du Colombier/*
203*80ee5cbfSDavid du Colombier * calling sequence
204*80ee5cbfSDavid du Colombier *	num: R14
205*80ee5cbfSDavid du Colombier *	den: 8(R1)
206*80ee5cbfSDavid du Colombier * returns
207*80ee5cbfSDavid du Colombier *	rem: R14
208*80ee5cbfSDavid du Colombier */
209*80ee5cbfSDavid du ColombierTEXT	_modl(SB), NOPROF, $-4
210*80ee5cbfSDavid du Colombier	SUB	$28, R1		/* 4 reg save, 2 parameters, link */
211*80ee5cbfSDavid du Colombier
212*80ee5cbfSDavid du Colombier
213*80ee5cbfSDavid du Colombier	MOVW	R15, 0(R1)
214*80ee5cbfSDavid du Colombier	JMPL	_unsarg(SB)
215*80ee5cbfSDavid du Colombier	JMPL	_udivmod(SB)
216*80ee5cbfSDavid du Colombier	MOVW	8(R1), R14
217*80ee5cbfSDavid du Colombier
218*80ee5cbfSDavid du Colombier	JMPL	_retarg(SB)
219*80ee5cbfSDavid du Colombier	JMP	8(R15)		/* not executed */
220*80ee5cbfSDavid du Colombier
221*80ee5cbfSDavid du Colombier/*
222*80ee5cbfSDavid du Colombier * special calling sequence:
223*80ee5cbfSDavid du Colombier *	arg1 in R14
224*80ee5cbfSDavid du Colombier *	arg2 in 4(R1),    will save R9
225*80ee5cbfSDavid du Colombier *	nothing in 0(R1), will save R8
226*80ee5cbfSDavid du Colombier * 	result in R14
227*80ee5cbfSDavid du Colombier */
228*80ee5cbfSDavid du ColombierTEXT	_mul+0(SB), NOPROF, $-4
229*80ee5cbfSDavid du Colombier
230*80ee5cbfSDavid du Colombier	/*
231*80ee5cbfSDavid du Colombier	 * exchange stack and registers
232*80ee5cbfSDavid du Colombier	 */
233*80ee5cbfSDavid du Colombier	MOVW	R8, 0(R1)
234*80ee5cbfSDavid du Colombier	MOVW	4(R1), R8
235*80ee5cbfSDavid du Colombier	MOVW	R9, 4(R1)
236*80ee5cbfSDavid du Colombier
237*80ee5cbfSDavid du Colombier	CMP	R14, R8
238*80ee5cbfSDavid du Colombier	BLE	mul1
239*80ee5cbfSDavid du Colombier	MOVW	R14, R9
240*80ee5cbfSDavid du Colombier	MOVW	R8, R14
241*80ee5cbfSDavid du Colombier	MOVW	R9, R8
242*80ee5cbfSDavid du Colombiermul1:
243*80ee5cbfSDavid du Colombier	MOVW	R14, Y
244*80ee5cbfSDavid du Colombier	ANDNCC	$0xFFF, R14, R0
245*80ee5cbfSDavid du Colombier	BE	mul_shortway
246*80ee5cbfSDavid du Colombier	ANDCC	R0, R0, R9	/* zero partial product and clear N and V cond's */
247*80ee5cbfSDavid du Colombier
248*80ee5cbfSDavid du Colombier	/* long multiply */
249*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 0 */
250*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 1 */
251*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 2 */
252*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 3 */
253*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 4 */
254*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 5 */
255*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 6 */
256*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 7 */
257*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 8 */
258*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 9 */
259*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 10 */
260*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 11 */
261*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 12 */
262*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 13 */
263*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 14 */
264*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 15 */
265*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 16 */
266*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 17 */
267*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 18 */
268*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 19 */
269*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 20 */
270*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 21 */
271*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 22 */
272*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 23 */
273*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 24 */
274*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 25 */
275*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 26 */
276*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 27 */
277*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 28 */
278*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 29 */
279*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 30 */
280*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 31 */
281*80ee5cbfSDavid du Colombier	MULSCC	R0, R9, R9		/* 32; shift only */
282*80ee5cbfSDavid du Colombier
283*80ee5cbfSDavid du Colombier	MOVW	Y, R14			/* get low part */
284*80ee5cbfSDavid du Colombier	BA	mul_return
285*80ee5cbfSDavid du Colombier
286*80ee5cbfSDavid du Colombiermul_shortway:
287*80ee5cbfSDavid du Colombier	ANDCC	R0, R0, R9	/* zero partial product and clear N and V cond's */
288*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  0 */
289*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  1 */
290*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  2 */
291*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  3 */
292*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  4 */
293*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  5 */
294*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  6 */
295*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  7 */
296*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  8 */
297*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/*  9 */
298*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 10 */
299*80ee5cbfSDavid du Colombier	MULSCC	R8, R9, R9		/* 11 */
300*80ee5cbfSDavid du Colombier	MULSCC	R0, R9, R9		/* 12; shift only */
301*80ee5cbfSDavid du Colombier
302*80ee5cbfSDavid du Colombier	MOVW	Y, R8
303*80ee5cbfSDavid du Colombier	SLL	$12, R9
304*80ee5cbfSDavid du Colombier	SRL	$20, R8
305*80ee5cbfSDavid du Colombier	OR	R8, R9, R14
306*80ee5cbfSDavid du Colombier
307*80ee5cbfSDavid du Colombiermul_return:
308*80ee5cbfSDavid du Colombier	MOVW	0(R1), R8
309*80ee5cbfSDavid du Colombier	MOVW	4(R1), R9
310*80ee5cbfSDavid du Colombier	JMP	8(R15)
311