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