xref: /qemu/tests/tcg/alpha/system/boot.S (revision 8c1ecb590497b0349c550607db923972b37f6963)
1*8d8a8ab5SRichard Henderson/*
2*8d8a8ab5SRichard Henderson * Minimal Alpha system boot code.
3*8d8a8ab5SRichard Henderson *
4*8d8a8ab5SRichard Henderson * Copyright Linaro Ltd 2019
5*8d8a8ab5SRichard Henderson */
6*8d8a8ab5SRichard Henderson
7*8d8a8ab5SRichard Henderson	.set	noat
8*8d8a8ab5SRichard Henderson	.set	nomacro
9*8d8a8ab5SRichard Henderson	.arch	ev6
10*8d8a8ab5SRichard Henderson	.text
11*8d8a8ab5SRichard Henderson
12*8d8a8ab5SRichard Henderson.macro load_pci_io reg
13*8d8a8ab5SRichard Henderson	/* For typhoon, this is
14*8d8a8ab5SRichard Henderson	 *   0xfffffc0000000000  -- kseg identity map
15*8d8a8ab5SRichard Henderson	 * +      0x10000000000  -- typhoon pio base
16*8d8a8ab5SRichard Henderson	 * +        0x1fc000000  -- typhoon pchip0 pci base
17*8d8a8ab5SRichard Henderson	 * = 0xfffffd01fc000000
18*8d8a8ab5SRichard Henderson	 */
19*8d8a8ab5SRichard Henderson	ldah	\reg, -3		/* ff..fd0000 */
20*8d8a8ab5SRichard Henderson	lda	\reg, 0x1fc(\reg)	/* ff..fd01fc */
21*8d8a8ab5SRichard Henderson	sll	\reg, 24, \reg
22*8d8a8ab5SRichard Henderson.endm
23*8d8a8ab5SRichard Henderson
24*8d8a8ab5SRichard Henderson#define com1Rbr 0x3f8
25*8d8a8ab5SRichard Henderson#define com1Thr 0x3f8
26*8d8a8ab5SRichard Henderson#define com1Ier 0x3f9
27*8d8a8ab5SRichard Henderson#define com1Iir 0x3fa
28*8d8a8ab5SRichard Henderson#define com1Lcr 0x3fb
29*8d8a8ab5SRichard Henderson#define com1Mcr 0x3fc
30*8d8a8ab5SRichard Henderson#define com1Lsr 0x3fd
31*8d8a8ab5SRichard Henderson#define com1Msr 0x3fe
32*8d8a8ab5SRichard Henderson#define com1Scr 0x3ff
33*8d8a8ab5SRichard Henderson#define com1Dll 0x3f8
34*8d8a8ab5SRichard Henderson#define com1Dlm 0x3f9
35*8d8a8ab5SRichard Henderson
36*8d8a8ab5SRichard Henderson#define PAL_halt    0
37*8d8a8ab5SRichard Henderson#define PAL_wrent  52
38*8d8a8ab5SRichard Henderson#define PAL_wrkgp  55
39*8d8a8ab5SRichard Henderson
40*8d8a8ab5SRichard Henderson	.text
41*8d8a8ab5SRichard Henderson	.p2align 4
42*8d8a8ab5SRichard Henderson	.globl	_start
43*8d8a8ab5SRichard Henderson	.ent	_start
44*8d8a8ab5SRichard Henderson_start:
45*8d8a8ab5SRichard Henderson	br	$gp, .+4
46*8d8a8ab5SRichard Henderson	ldah	$gp, 0($gp)		!gpdisp!1
47*8d8a8ab5SRichard Henderson	lda	$gp, 0($gp)		!gpdisp!1
48*8d8a8ab5SRichard Henderson
49*8d8a8ab5SRichard Henderson	ldah	$sp, $stack_end($gp)	!gprelhigh
50*8d8a8ab5SRichard Henderson	lda	$sp, $stack_end($sp)	!gprellow
51*8d8a8ab5SRichard Henderson
52*8d8a8ab5SRichard Henderson	/* Install kernel gp for exception handlers.  */
53*8d8a8ab5SRichard Henderson	mov	$gp, $16
54*8d8a8ab5SRichard Henderson	call_pal PAL_wrkgp
55*8d8a8ab5SRichard Henderson
56*8d8a8ab5SRichard Henderson	/* Install exception handlers.  */
57*8d8a8ab5SRichard Henderson	ldah	$16, entInt($gp)	!gprelhigh
58*8d8a8ab5SRichard Henderson	lda	$16, entInt($16)	!gprellow
59*8d8a8ab5SRichard Henderson	lda	$17, 0
60*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
61*8d8a8ab5SRichard Henderson
62*8d8a8ab5SRichard Henderson	ldah	$16, entArith($gp)	!gprelhigh
63*8d8a8ab5SRichard Henderson	lda	$16, entArith($16)	!gprellow
64*8d8a8ab5SRichard Henderson	lda	$17, 1
65*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
66*8d8a8ab5SRichard Henderson
67*8d8a8ab5SRichard Henderson	ldah	$16, entMM($gp)		!gprelhigh
68*8d8a8ab5SRichard Henderson	lda	$16, entMM($16)		!gprellow
69*8d8a8ab5SRichard Henderson	lda	$17, 2
70*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
71*8d8a8ab5SRichard Henderson
72*8d8a8ab5SRichard Henderson	ldah	$16, entIF($gp)		!gprelhigh
73*8d8a8ab5SRichard Henderson	lda	$16, entIF($16)		!gprellow
74*8d8a8ab5SRichard Henderson	lda	$17, 3
75*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
76*8d8a8ab5SRichard Henderson
77*8d8a8ab5SRichard Henderson	ldah	$16, entUna($gp)	!gprelhigh
78*8d8a8ab5SRichard Henderson	lda	$16, entUna($16)	!gprellow
79*8d8a8ab5SRichard Henderson	lda	$17, 4
80*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
81*8d8a8ab5SRichard Henderson
82*8d8a8ab5SRichard Henderson	ldah	$16, entSys($gp)	!gprelhigh
83*8d8a8ab5SRichard Henderson	lda	$16, entSys($16)	!gprellow
84*8d8a8ab5SRichard Henderson	lda	$17, 5
85*8d8a8ab5SRichard Henderson	call_pal PAL_wrent
86*8d8a8ab5SRichard Henderson
87*8d8a8ab5SRichard Henderson	/*
88*8d8a8ab5SRichard Henderson	 * Initialize COM1.
89*8d8a8ab5SRichard Henderson	 */
90*8d8a8ab5SRichard Henderson	load_pci_io $1
91*8d8a8ab5SRichard Henderson	lda	$2, 0x87		/* outb(0x87, com1Lcr); */
92*8d8a8ab5SRichard Henderson	stb	$2, com1Lcr($1)
93*8d8a8ab5SRichard Henderson	stb	$31, com1Dlm($1)	/* outb(0, com1Dlm); */
94*8d8a8ab5SRichard Henderson	lda	$2, 3			/* baudconst 3 => 56000 */
95*8d8a8ab5SRichard Henderson	stb	$2, com1Dll($1)		/* outb(baudconst, com1Dll); */
96*8d8a8ab5SRichard Henderson	lda	$2, 0x07
97*8d8a8ab5SRichard Henderson	stb	$2, com1Lcr($1)		/* outb(0x07, com1Lcr) */
98*8d8a8ab5SRichard Henderson	lda	$2, 0x0f
99*8d8a8ab5SRichard Henderson	stb	$2, com1Mcr($1)		/* outb(0x0f, com1Mcr) */
100*8d8a8ab5SRichard Henderson
101*8d8a8ab5SRichard Henderson	bsr	$26, main		!samegp
102*8d8a8ab5SRichard Henderson
103*8d8a8ab5SRichard Henderson	/* fall through to _exit */
104*8d8a8ab5SRichard Henderson	.end	_start
105*8d8a8ab5SRichard Henderson
106*8d8a8ab5SRichard Henderson	.globl	_exit
107*8d8a8ab5SRichard Henderson	.ent	_exit
108*8d8a8ab5SRichard Henderson_exit:
109*8d8a8ab5SRichard Henderson	.frame	$sp, 0, $26, 0
110*8d8a8ab5SRichard Henderson	.prologue 0
111*8d8a8ab5SRichard Henderson
112*8d8a8ab5SRichard Henderson	/* We cannot return an error code.  */
113*8d8a8ab5SRichard Henderson	call_pal PAL_halt
114*8d8a8ab5SRichard Henderson	.end	_exit
115*8d8a8ab5SRichard Henderson
116*8d8a8ab5SRichard Henderson/*
117*8d8a8ab5SRichard Henderson * We have received an exception that we don't handle.  Log and exit.
118*8d8a8ab5SRichard Henderson */
119*8d8a8ab5SRichard Henderson	.ent	log_exit
120*8d8a8ab5SRichard Hendersonlog_exit:
121*8d8a8ab5SRichard HendersonentInt:
122*8d8a8ab5SRichard HendersonentArith:
123*8d8a8ab5SRichard HendersonentMM:
124*8d8a8ab5SRichard HendersonentIF:
125*8d8a8ab5SRichard HendersonentUna:
126*8d8a8ab5SRichard HendersonentSys:
127*8d8a8ab5SRichard Henderson	ldah	$16, $errormsg($gp)	!gprelhigh
128*8d8a8ab5SRichard Henderson	lda	$16, $errormsg($16)	!gprellow
129*8d8a8ab5SRichard Henderson	bsr	$26, __sys_outs		!samegp
130*8d8a8ab5SRichard Henderson	bsr	$26, _exit		!samegp
131*8d8a8ab5SRichard Henderson	.end	log_exit
132*8d8a8ab5SRichard Henderson
133*8d8a8ab5SRichard Henderson	.section .rodata
134*8d8a8ab5SRichard Henderson$errormsg:
135*8d8a8ab5SRichard Henderson	.string "Terminated by exception.\n"
136*8d8a8ab5SRichard Henderson	.previous
137*8d8a8ab5SRichard Henderson
138*8d8a8ab5SRichard Henderson	/*
139*8d8a8ab5SRichard Henderson	 * Helper Functions
140*8d8a8ab5SRichard Henderson	 */
141*8d8a8ab5SRichard Henderson
142*8d8a8ab5SRichard Henderson	/* Output a single character to serial port */
143*8d8a8ab5SRichard Henderson	.global __sys_outc
144*8d8a8ab5SRichard Henderson	.ent	__sys_outc
145*8d8a8ab5SRichard Henderson__sys_outc:
146*8d8a8ab5SRichard Henderson	.frame	$sp, 0, $26, 0
147*8d8a8ab5SRichard Henderson	.prologue 0
148*8d8a8ab5SRichard Henderson
149*8d8a8ab5SRichard Henderson	load_pci_io $1
150*8d8a8ab5SRichard Henderson
151*8d8a8ab5SRichard Henderson	/*
152*8d8a8ab5SRichard Henderson	 * while ((inb(com1Lsr) & 0x20) == 0)
153*8d8a8ab5SRichard Henderson	 *       continue;
154*8d8a8ab5SRichard Henderson	 */
155*8d8a8ab5SRichard Henderson1:	ldbu	$0, com1Lsr($1)
156*8d8a8ab5SRichard Henderson	and	$0, 0x20, $0
157*8d8a8ab5SRichard Henderson	beq	$0, 1b
158*8d8a8ab5SRichard Henderson
159*8d8a8ab5SRichard Henderson	/* outb(c, com1Thr); */
160*8d8a8ab5SRichard Henderson	stb	$16, com1Thr($1)
161*8d8a8ab5SRichard Henderson	ret
162*8d8a8ab5SRichard Henderson	.end	__sys_outc
163*8d8a8ab5SRichard Henderson
164*8d8a8ab5SRichard Henderson	/* Output a nul-terminated string to serial port */
165*8d8a8ab5SRichard Henderson	.global	__sys_outs
166*8d8a8ab5SRichard Henderson	.ent	__sys_outs
167*8d8a8ab5SRichard Henderson__sys_outs:
168*8d8a8ab5SRichard Henderson	.frame	$sp, 0, $26, 0
169*8d8a8ab5SRichard Henderson	.prologue 0
170*8d8a8ab5SRichard Henderson
171*8d8a8ab5SRichard Henderson	load_pci_io $1
172*8d8a8ab5SRichard Henderson
173*8d8a8ab5SRichard Henderson	ldbu	$2, 0($16)
174*8d8a8ab5SRichard Henderson	beq	$2, 9f
175*8d8a8ab5SRichard Henderson
176*8d8a8ab5SRichard Henderson	/*
177*8d8a8ab5SRichard Henderson	 * while ((inb(com1Lsr) & 0x20) == 0)
178*8d8a8ab5SRichard Henderson	 *       continue;
179*8d8a8ab5SRichard Henderson	 */
180*8d8a8ab5SRichard Henderson1:	ldbu	$0, com1Lsr($1)
181*8d8a8ab5SRichard Henderson	and	$0, 0x20, $0
182*8d8a8ab5SRichard Henderson	beq	$0, 1b
183*8d8a8ab5SRichard Henderson
184*8d8a8ab5SRichard Henderson	/* outb(c, com1Thr); */
185*8d8a8ab5SRichard Henderson	stb	$2, com1Thr($1)
186*8d8a8ab5SRichard Henderson
187*8d8a8ab5SRichard Henderson	addq	$16, 1, $16
188*8d8a8ab5SRichard Henderson	ldbu	$2, 0($16)
189*8d8a8ab5SRichard Henderson	bne	$2, 1b
190*8d8a8ab5SRichard Henderson
191*8d8a8ab5SRichard Henderson9:	ret
192*8d8a8ab5SRichard Henderson	.end	__sys_outs
193*8d8a8ab5SRichard Henderson
194*8d8a8ab5SRichard Henderson/*
195*8d8a8ab5SRichard Henderson * Division routines that are normally in libc.
196*8d8a8ab5SRichard Henderson *
197*8d8a8ab5SRichard Henderson * These do not follow the C calling convention.  Arguments are in $24+$25,
198*8d8a8ab5SRichard Henderson * the result is in $27.  Register $28 may be clobbered; everything else
199*8d8a8ab5SRichard Henderson * must be saved.
200*8d8a8ab5SRichard Henderson *
201*8d8a8ab5SRichard Henderson * We store the remainder in $28, so that we can share code.
202*8d8a8ab5SRichard Henderson *
203*8d8a8ab5SRichard Henderson * We do not signal divide by zero.
204*8d8a8ab5SRichard Henderson */
205*8d8a8ab5SRichard Henderson
206*8d8a8ab5SRichard Henderson/*
207*8d8a8ab5SRichard Henderson * Unsigned 64-bit division.
208*8d8a8ab5SRichard Henderson */
209*8d8a8ab5SRichard Henderson
210*8d8a8ab5SRichard Henderson	.globl	__divqu
211*8d8a8ab5SRichard Henderson	.ent	__divqu
212*8d8a8ab5SRichard Henderson__divqu:
213*8d8a8ab5SRichard Henderson	.frame	$sp, 48, $23
214*8d8a8ab5SRichard Henderson	subq	$sp, 48, $sp
215*8d8a8ab5SRichard Henderson	stq	$0, 0($sp)
216*8d8a8ab5SRichard Henderson	stq	$1, 8($sp)
217*8d8a8ab5SRichard Henderson	stq	$2, 16($sp)
218*8d8a8ab5SRichard Henderson	stq	$3, 24($sp)
219*8d8a8ab5SRichard Henderson	stq	$4, 32($sp)
220*8d8a8ab5SRichard Henderson	.prologue 0
221*8d8a8ab5SRichard Henderson
222*8d8a8ab5SRichard Henderson#define mask     $0
223*8d8a8ab5SRichard Henderson#define divisor  $1
224*8d8a8ab5SRichard Henderson#define compare  $2
225*8d8a8ab5SRichard Henderson#define tmp1     $3
226*8d8a8ab5SRichard Henderson#define tmp2     $4
227*8d8a8ab5SRichard Henderson#define quotient $27
228*8d8a8ab5SRichard Henderson#define modulus  $28
229*8d8a8ab5SRichard Henderson
230*8d8a8ab5SRichard Henderson	mov	$24, modulus
231*8d8a8ab5SRichard Henderson	mov	$25, divisor
232*8d8a8ab5SRichard Henderson	mov	$31, quotient
233*8d8a8ab5SRichard Henderson	mov	1, mask
234*8d8a8ab5SRichard Henderson	beq	$25, 9f
235*8d8a8ab5SRichard Henderson
236*8d8a8ab5SRichard Henderson	/* Shift left until divisor >= modulus.  */
237*8d8a8ab5SRichard Henderson1:	cmpult	divisor, modulus, compare
238*8d8a8ab5SRichard Henderson	blt	divisor, 2f
239*8d8a8ab5SRichard Henderson	addq	divisor, divisor, divisor
240*8d8a8ab5SRichard Henderson	addq	mask, mask, mask
241*8d8a8ab5SRichard Henderson	bne	compare, 1b
242*8d8a8ab5SRichard Henderson
243*8d8a8ab5SRichard Henderson2:	addq	quotient, mask, tmp2
244*8d8a8ab5SRichard Henderson	srl	mask, 1, mask
245*8d8a8ab5SRichard Henderson	cmpule	divisor, modulus, compare
246*8d8a8ab5SRichard Henderson	subq	modulus, divisor, tmp1
247*8d8a8ab5SRichard Henderson	cmovne	compare, tmp2, quotient
248*8d8a8ab5SRichard Henderson	srl	divisor, 1, divisor
249*8d8a8ab5SRichard Henderson	cmovne	compare, tmp1, modulus
250*8d8a8ab5SRichard Henderson	bne	mask, 2b
251*8d8a8ab5SRichard Henderson
252*8d8a8ab5SRichard Henderson9:	ldq	$0, 0($sp)
253*8d8a8ab5SRichard Henderson	ldq	$1, 8($sp)
254*8d8a8ab5SRichard Henderson	ldq	$2, 16($sp)
255*8d8a8ab5SRichard Henderson	ldq	$3, 24($sp)
256*8d8a8ab5SRichard Henderson	ldq	$4, 32($sp)
257*8d8a8ab5SRichard Henderson	addq	$sp, 48, $sp
258*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
259*8d8a8ab5SRichard Henderson
260*8d8a8ab5SRichard Henderson#undef mask
261*8d8a8ab5SRichard Henderson#undef divisor
262*8d8a8ab5SRichard Henderson#undef compare
263*8d8a8ab5SRichard Henderson#undef tmp1
264*8d8a8ab5SRichard Henderson#undef tmp2
265*8d8a8ab5SRichard Henderson#undef quotient
266*8d8a8ab5SRichard Henderson#undef modulus
267*8d8a8ab5SRichard Henderson
268*8d8a8ab5SRichard Henderson	.end	__divqu
269*8d8a8ab5SRichard Henderson
270*8d8a8ab5SRichard Henderson/*
271*8d8a8ab5SRichard Henderson * Unsigned 64-bit remainder.
272*8d8a8ab5SRichard Henderson * Note that __divqu above leaves the result in $28.
273*8d8a8ab5SRichard Henderson */
274*8d8a8ab5SRichard Henderson
275*8d8a8ab5SRichard Henderson	.globl	__remqu
276*8d8a8ab5SRichard Henderson	.ent	__remqu
277*8d8a8ab5SRichard Henderson__remqu:
278*8d8a8ab5SRichard Henderson	.frame	$sp, 16, $23
279*8d8a8ab5SRichard Henderson	subq	$sp, 16, $sp
280*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
281*8d8a8ab5SRichard Henderson	.prologue 0
282*8d8a8ab5SRichard Henderson
283*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
284*8d8a8ab5SRichard Henderson
285*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
286*8d8a8ab5SRichard Henderson	mov	$28, $27
287*8d8a8ab5SRichard Henderson	addq	$sp, 16, $sp
288*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
289*8d8a8ab5SRichard Henderson	.end	__remqu
290*8d8a8ab5SRichard Henderson
291*8d8a8ab5SRichard Henderson/*
292*8d8a8ab5SRichard Henderson * Signed 64-bit division.
293*8d8a8ab5SRichard Henderson */
294*8d8a8ab5SRichard Henderson
295*8d8a8ab5SRichard Henderson	.globl	__divqs
296*8d8a8ab5SRichard Henderson	.ent	__divqs
297*8d8a8ab5SRichard Henderson__divqs:
298*8d8a8ab5SRichard Henderson	.prologue 0
299*8d8a8ab5SRichard Henderson
300*8d8a8ab5SRichard Henderson	/* Common case: both arguments are positive.  */
301*8d8a8ab5SRichard Henderson	bis	$24, $25, $28
302*8d8a8ab5SRichard Henderson	bge	$28, __divqu
303*8d8a8ab5SRichard Henderson
304*8d8a8ab5SRichard Henderson	/* At least one argument is negative.  */
305*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
306*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
307*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
308*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
309*8d8a8ab5SRichard Henderson
310*8d8a8ab5SRichard Henderson	/* Compute absolute values.  */
311*8d8a8ab5SRichard Henderson	subq	$31, $24, $28
312*8d8a8ab5SRichard Henderson	cmovlt	$24, $28, $24
313*8d8a8ab5SRichard Henderson	subq	$31, $25, $28
314*8d8a8ab5SRichard Henderson	cmovlt	$25, $28, $25
315*8d8a8ab5SRichard Henderson
316*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
317*8d8a8ab5SRichard Henderson
318*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
319*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
320*8d8a8ab5SRichard Henderson
321*8d8a8ab5SRichard Henderson	/* -a / b = a / -b = -(a / b) */
322*8d8a8ab5SRichard Henderson	subq	$31, $27, $23
323*8d8a8ab5SRichard Henderson	xor	$24, $25, $28
324*8d8a8ab5SRichard Henderson	cmovlt	$28, $23, $27
325*8d8a8ab5SRichard Henderson
326*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
327*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
328*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
329*8d8a8ab5SRichard Henderson	.end	__divqs
330*8d8a8ab5SRichard Henderson
331*8d8a8ab5SRichard Henderson/*
332*8d8a8ab5SRichard Henderson * Signed 64-bit remainder.
333*8d8a8ab5SRichard Henderson */
334*8d8a8ab5SRichard Henderson
335*8d8a8ab5SRichard Henderson	.globl	__remqs
336*8d8a8ab5SRichard Henderson	.ent	__remqs
337*8d8a8ab5SRichard Henderson__remqs:
338*8d8a8ab5SRichard Henderson	.prologue 0
339*8d8a8ab5SRichard Henderson
340*8d8a8ab5SRichard Henderson	/* Common case: both arguments are positive.  */
341*8d8a8ab5SRichard Henderson	bis	$24, $25, $28
342*8d8a8ab5SRichard Henderson	bge	$28, __remqu
343*8d8a8ab5SRichard Henderson
344*8d8a8ab5SRichard Henderson	/* At least one argument is negative.  */
345*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
346*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
347*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
348*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
349*8d8a8ab5SRichard Henderson
350*8d8a8ab5SRichard Henderson	/* Compute absolute values.  */
351*8d8a8ab5SRichard Henderson	subq	$31, $24, $28
352*8d8a8ab5SRichard Henderson	cmovlt	$24, $28, $24
353*8d8a8ab5SRichard Henderson	subq	$31, $25, $28
354*8d8a8ab5SRichard Henderson	cmovlt	$25, $28, $25
355*8d8a8ab5SRichard Henderson
356*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
357*8d8a8ab5SRichard Henderson
358*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
359*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
360*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
361*8d8a8ab5SRichard Henderson
362*8d8a8ab5SRichard Henderson	/* -a % b = -(a % b); a % -b = a % b.  */
363*8d8a8ab5SRichard Henderson	subq	$31, $28, $27
364*8d8a8ab5SRichard Henderson	cmovge	$24, $28, $27
365*8d8a8ab5SRichard Henderson
366*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
367*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
368*8d8a8ab5SRichard Henderson	.end	__remqs
369*8d8a8ab5SRichard Henderson
370*8d8a8ab5SRichard Henderson/*
371*8d8a8ab5SRichard Henderson * Unsigned 32-bit division.
372*8d8a8ab5SRichard Henderson */
373*8d8a8ab5SRichard Henderson
374*8d8a8ab5SRichard Henderson	.globl	__divlu
375*8d8a8ab5SRichard Henderson	.ent	__divlu
376*8d8a8ab5SRichard Henderson__divlu:
377*8d8a8ab5SRichard Henderson	.frame	$sp, 32, $23
378*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
379*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
380*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
381*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
382*8d8a8ab5SRichard Henderson	.prologue 0
383*8d8a8ab5SRichard Henderson
384*8d8a8ab5SRichard Henderson	/* Zero extend and use the 64-bit routine.  */
385*8d8a8ab5SRichard Henderson	zap	$24, 0xf0, $24
386*8d8a8ab5SRichard Henderson	zap	$25, 0xf0, $25
387*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
388*8d8a8ab5SRichard Henderson
389*8d8a8ab5SRichard Henderson	addl	$27, 0, $27
390*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
391*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
392*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
393*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
394*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
395*8d8a8ab5SRichard Henderson	.end	__divlu
396*8d8a8ab5SRichard Henderson
397*8d8a8ab5SRichard Henderson/*
398*8d8a8ab5SRichard Henderson * Unsigned 32-bit remainder.
399*8d8a8ab5SRichard Henderson */
400*8d8a8ab5SRichard Henderson
401*8d8a8ab5SRichard Henderson	.globl	__remlu
402*8d8a8ab5SRichard Henderson	.ent	__remlu
403*8d8a8ab5SRichard Henderson__remlu:
404*8d8a8ab5SRichard Henderson	.frame	$sp, 32, $23
405*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
406*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
407*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
408*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
409*8d8a8ab5SRichard Henderson	.prologue 0
410*8d8a8ab5SRichard Henderson
411*8d8a8ab5SRichard Henderson	/* Zero extend and use the 64-bit routine.  */
412*8d8a8ab5SRichard Henderson	zap	$24, 0xf0, $24
413*8d8a8ab5SRichard Henderson	zap	$25, 0xf0, $25
414*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
415*8d8a8ab5SRichard Henderson
416*8d8a8ab5SRichard Henderson	/* Recall that the remainder is returned in $28.  */
417*8d8a8ab5SRichard Henderson	addl	$28, 0, $27
418*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
419*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
420*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
421*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
422*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
423*8d8a8ab5SRichard Henderson	.end	__remlu
424*8d8a8ab5SRichard Henderson
425*8d8a8ab5SRichard Henderson/*
426*8d8a8ab5SRichard Henderson * Signed 32-bit division.
427*8d8a8ab5SRichard Henderson */
428*8d8a8ab5SRichard Henderson
429*8d8a8ab5SRichard Henderson	.globl	__divls
430*8d8a8ab5SRichard Henderson	.ent	__divls
431*8d8a8ab5SRichard Henderson__divls:
432*8d8a8ab5SRichard Henderson	.frame	$sp, 32, $23
433*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
434*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
435*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
436*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
437*8d8a8ab5SRichard Henderson	.prologue 0
438*8d8a8ab5SRichard Henderson
439*8d8a8ab5SRichard Henderson	/* Sign extend.  */
440*8d8a8ab5SRichard Henderson	addl	$24, 0, $24
441*8d8a8ab5SRichard Henderson	addl	$25, 0, $25
442*8d8a8ab5SRichard Henderson
443*8d8a8ab5SRichard Henderson	/* Compute absolute values.  */
444*8d8a8ab5SRichard Henderson	subq	$31, $24, $28
445*8d8a8ab5SRichard Henderson	cmovlt	$24, $28, $24
446*8d8a8ab5SRichard Henderson	subq	$31, $25, $28
447*8d8a8ab5SRichard Henderson	cmovlt	$25, $28, $25
448*8d8a8ab5SRichard Henderson
449*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
450*8d8a8ab5SRichard Henderson
451*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
452*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
453*8d8a8ab5SRichard Henderson
454*8d8a8ab5SRichard Henderson	/* Negate the unsigned result, if necessary.  */
455*8d8a8ab5SRichard Henderson	xor	$24, $25, $28
456*8d8a8ab5SRichard Henderson	subl	$31, $27, $23
457*8d8a8ab5SRichard Henderson	addl	$27, 0, $27
458*8d8a8ab5SRichard Henderson	addl	$28, 0, $28
459*8d8a8ab5SRichard Henderson	cmovlt	$28, $23, $27
460*8d8a8ab5SRichard Henderson
461*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
462*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
463*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
464*8d8a8ab5SRichard Henderson	.end	__divls
465*8d8a8ab5SRichard Henderson
466*8d8a8ab5SRichard Henderson/*
467*8d8a8ab5SRichard Henderson * Signed 32-bit remainder.
468*8d8a8ab5SRichard Henderson */
469*8d8a8ab5SRichard Henderson
470*8d8a8ab5SRichard Henderson	.globl	__remls
471*8d8a8ab5SRichard Henderson	.ent	__remls
472*8d8a8ab5SRichard Henderson__remls:
473*8d8a8ab5SRichard Henderson	.frame	$sp, 32, $23
474*8d8a8ab5SRichard Henderson	subq	$sp, 32, $sp
475*8d8a8ab5SRichard Henderson	stq	$23, 0($sp)
476*8d8a8ab5SRichard Henderson	stq	$24, 8($sp)
477*8d8a8ab5SRichard Henderson	stq	$25, 16($sp)
478*8d8a8ab5SRichard Henderson	.prologue 0
479*8d8a8ab5SRichard Henderson
480*8d8a8ab5SRichard Henderson	/* Sign extend.  */
481*8d8a8ab5SRichard Henderson	addl	$24, 0, $24
482*8d8a8ab5SRichard Henderson	addl	$25, 0, $25
483*8d8a8ab5SRichard Henderson
484*8d8a8ab5SRichard Henderson	/* Compute absolute values.  */
485*8d8a8ab5SRichard Henderson	subq	$31, $24, $28
486*8d8a8ab5SRichard Henderson	cmovlt	$24, $28, $24
487*8d8a8ab5SRichard Henderson	subq	$31, $25, $28
488*8d8a8ab5SRichard Henderson	cmovlt	$25, $28, $25
489*8d8a8ab5SRichard Henderson
490*8d8a8ab5SRichard Henderson	bsr	$23, __divqu
491*8d8a8ab5SRichard Henderson
492*8d8a8ab5SRichard Henderson	ldq	$23, 0($sp)
493*8d8a8ab5SRichard Henderson	ldq	$24, 8($sp)
494*8d8a8ab5SRichard Henderson	ldq	$25, 16($sp)
495*8d8a8ab5SRichard Henderson
496*8d8a8ab5SRichard Henderson	/* Negate the unsigned result, if necessary.  */
497*8d8a8ab5SRichard Henderson	subl	$31, $28, $27
498*8d8a8ab5SRichard Henderson	addl	$28, 0, $28
499*8d8a8ab5SRichard Henderson	cmovge	$24, $28, $27
500*8d8a8ab5SRichard Henderson
501*8d8a8ab5SRichard Henderson	addq	$sp, 32, $sp
502*8d8a8ab5SRichard Henderson	ret	$31, ($23), 1
503*8d8a8ab5SRichard Henderson	.end	__remls
504*8d8a8ab5SRichard Henderson
505*8d8a8ab5SRichard Henderson	.data
506*8d8a8ab5SRichard Henderson	.p2align 4
507*8d8a8ab5SRichard Hendersonstack:
508*8d8a8ab5SRichard Henderson	.skip	65536
509*8d8a8ab5SRichard Henderson$stack_end:
510*8d8a8ab5SRichard Henderson	.type	stack,@object
511*8d8a8ab5SRichard Henderson	.size	stack, . - stack
512