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