xref: /plan9/sys/src/ape/lib/ap/arm/div.s (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1Q	= 0
2N	= 1
3D	= 2
4CC	= 3
5TMP	= 11
6
7TEXT	save<>(SB), 1, $0
8	MOVW	R(Q), 0(FP)
9	MOVW	R(N), 4(FP)
10	MOVW	R(D), 8(FP)
11	MOVW	R(CC), 12(FP)
12
13	MOVW	R(TMP), R(Q)		/* numerator */
14	MOVW	20(FP), R(D)		/* denominator */
15	CMP	$0, R(D)
16	BNE	s1
17	MOVW	-1(R(D)), R(TMP)	/* divide by zero fault */
18s1:	RET
19
20TEXT	rest<>(SB), 1, $0
21	MOVW	0(FP), R(Q)
22	MOVW	4(FP), R(N)
23	MOVW	8(FP), R(D)
24	MOVW	12(FP), R(CC)
25/*
26 * return to caller
27 * of rest<>
28 */
29	MOVW	0(R13), R14
30	ADD	$20, R13
31	B	(R14)
32
33TEXT	div<>(SB), 1, $0
34	MOVW	$32, R(CC)
35/*
36 * skip zeros 8-at-a-time
37 */
38e1:
39	AND.S	$(0xff<<24),R(Q), R(N)
40	BNE	e2
41	SLL	$8, R(Q)
42	SUB.S	$8, R(CC)
43	BNE	e1
44	RET
45e2:
46	MOVW	$0, R(N)
47
48loop:
49/*
50 * shift R(N||Q) left one
51 */
52	SLL	$1, R(N)
53	CMP	$0, R(Q)
54	ORR.LT	$1, R(N)
55	SLL	$1, R(Q)
56
57/*
58 * compare numerator to denominator
59 * if less, subtract and set quotent bit
60 */
61	CMP	R(D), R(N)
62	ORR.HS	$1, R(Q)
63	SUB.HS	R(D), R(N)
64	SUB.S	$1, R(CC)
65	BNE	loop
66	RET
67
68TEXT	_div(SB), 1, $16
69	BL	save<>(SB)
70	CMP	$0, R(Q)
71	BGE	d1
72	RSB	$0, R(Q), R(Q)
73	CMP	$0, R(D)
74	BGE	d2
75	RSB	$0, R(D), R(D)
76d0:
77	BL	div<>(SB)		/* none/both neg */
78	MOVW	R(Q), R(TMP)
79	B	out
80d1:
81	CMP	$0, R(D)
82	BGE	d0
83	RSB	$0, R(D), R(D)
84d2:
85	BL	div<>(SB)		/* one neg */
86	RSB	$0, R(Q), R(TMP)
87	B	out
88
89TEXT	_mod(SB), 1, $16
90	BL	save<>(SB)
91	CMP	$0, R(D)
92	RSB.LT	$0, R(D), R(D)
93	CMP	$0, R(Q)
94	BGE	m1
95	RSB	$0, R(Q), R(Q)
96	BL	div<>(SB)		/* neg numerator */
97	RSB	$0, R(N), R(TMP)
98	B	out
99m1:
100	BL	div<>(SB)		/* pos numerator */
101	MOVW	R(N), R(TMP)
102	B	out
103
104TEXT	_divu(SB), 1, $16
105	BL	save<>(SB)
106	BL	div<>(SB)
107	MOVW	R(Q), R(TMP)
108	B	out
109
110TEXT	_modu(SB), 1, $16
111	BL	save<>(SB)
112	BL	div<>(SB)
113	MOVW	R(N), R(TMP)
114	B	out
115
116out:
117	BL	rest<>(SB)
118	B	out
119