xref: /netbsd/sys/arch/hppa/spmath/divu.S (revision c4a72b64)
1/*	$NetBSD: divu.S,v 1.1 2002/06/05 01:04:25 fredette Exp $	*/
2
3/*	$OpenBSD: divu.S,v 1.5 2001/03/29 03:58:18 mickey Exp $	*/
4
5/*
6 * Copyright 1996 1995 by Open Software Foundation, Inc.
7 *              All Rights Reserved
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby granted,
11 * provided that the above copyright notice appears in all copies and
12 * that both the copyright notice and this permission notice appear in
13 * supporting documentation.
14 *
15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 */
26/*
27 * pmk1.1
28 */
29/*
30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
31 *
32 * To anyone who acknowledges that this file is provided "AS IS"
33 * without any express or implied warranty:
34 *     permission to use, copy, modify, and distribute this file
35 * for any purpose is hereby granted without fee, provided that
36 * the above copyright notice and this notice appears in all
37 * copies, and that the name of Hewlett-Packard Company not be
38 * used in advertising or publicity pertaining to distribution
39 * of the software without specific, written prior permission.
40 * Hewlett-Packard Company makes no representations about the
41 * suitability of this software for any purpose.
42 */
43
44#include <machine/asm.h>
45
46/**************************************************************************
47 * Implement an integer divide routine for 32-bit operands and 32-bit quotient
48 * and remainder with operand values of zero (divisor only) treated specially.
49 *
50 ***************************************************************************/
51/*
52 *	General registers
53 */
54gr0	.reg		%r0	/* General register zero */
55rem	.reg		%r3	/* remainder and upper part of dividend */
56quo	.reg		%r4	/* quotient and lower part of dividend */
57dvr	.reg		%r5	/* divisor */
58tp	.reg		%r6	/* temp. reg. */
59
60	.text
61
62/*****************************************************************************/
63ENTRY(divu,16)
64	stws,ma		rem,4(sp)		; save registers on stack
65	stws,ma		quo,4(sp)		; save registers on stack
66	stws,ma		dvr,4(sp)		; save registers on stack
67	stws,ma		tp,4(sp)		; save registers on stack
68
69	addi		0,arg2,dvr		; get divisor
70	addi		0,arg1,quo		; get lower dividend
71	addi		0,arg0,rem		; get upper dividend
72
73	comib,>,n	0,dvr,hibit		; check for dvr >= 2**31
74	addi		-1,gr0,tp		; set V-bit to 1
75	ds		0,tp,0
76	add		quo,quo,quo		; shift msb bit into carry
77	ds		rem,dvr,rem		; 1st divide step, if carry
78						;   out, msb of quotient = 0
79	addc		quo,quo,quo		; shift quo with/into carry
80	ds		rem,dvr,rem		; 2nd divide step
81	addc		quo,quo,quo		; shift quo with/into carry
82	ds		rem,dvr,rem		; 3rd divide step
83	addc		quo,quo,quo		; shift quo with/into carry
84	ds		rem,dvr,rem		; 4th divide step
85	addc		quo,quo,quo		; shift quo with/into carry
86	ds		rem,dvr,rem		; 5th divide step
87	addc		quo,quo,quo		; shift quo with/into carry
88	ds		rem,dvr,rem		; 6th divide step
89	addc		quo,quo,quo		; shift quo with/into carry
90	ds		rem,dvr,rem		; 7th divide step
91	addc		quo,quo,quo		; shift quo with/into carry
92	ds		rem,dvr,rem		; 8th divide step
93	addc		quo,quo,quo		; shift quo with/into carry
94	ds		rem,dvr,rem		; 9th divide step
95	addc		quo,quo,quo		; shift quo with/into carry
96	ds		rem,dvr,rem		; 10th divide step
97	addc		quo,quo,quo		; shift quo with/into carry
98	ds		rem,dvr,rem		; 11th divide step
99	addc		quo,quo,quo		; shift quo with/into carry
100	ds		rem,dvr,rem		; 12th divide step
101	addc		quo,quo,quo		; shift quo with/into carry
102	ds		rem,dvr,rem		; 13th divide step
103	addc		quo,quo,quo		; shift quo with/into carry
104	ds		rem,dvr,rem		; 14th divide step
105	addc		quo,quo,quo		; shift quo with/into carry
106	ds		rem,dvr,rem		; 15th divide step
107	addc		quo,quo,quo		; shift quo with/into carry
108	ds		rem,dvr,rem		; 16th divide step
109	addc		quo,quo,quo		; shift quo with/into carry
110	ds		rem,dvr,rem		; 17th divide step
111	addc		quo,quo,quo		; shift quo with/into carry
112	ds		rem,dvr,rem		; 18th divide step
113	addc		quo,quo,quo		; shift quo with/into carry
114	ds		rem,dvr,rem		; 19th divide step
115	addc		quo,quo,quo		; shift quo with/into carry
116	ds		rem,dvr,rem		; 20th divide step
117	addc		quo,quo,quo		; shift quo with/into carry
118	ds		rem,dvr,rem		; 21st divide step
119	addc		quo,quo,quo		; shift quo with/into carry
120	ds		rem,dvr,rem		; 22nd divide step
121	addc		quo,quo,quo		; shift quo with/into carry
122	ds		rem,dvr,rem		; 23rd divide step
123	addc		quo,quo,quo		; shift quo with/into carry
124	ds		rem,dvr,rem		; 24th divide step
125	addc		quo,quo,quo		; shift quo with/into carry
126	ds		rem,dvr,rem		; 25th divide step
127	addc		quo,quo,quo		; shift quo with/into carry
128	ds		rem,dvr,rem		; 26th divide step
129	addc		quo,quo,quo		; shift quo with/into carry
130	ds		rem,dvr,rem		; 27th divide step
131	addc		quo,quo,quo		; shift quo with/into carry
132	ds		rem,dvr,rem		; 28th divide step
133	addc		quo,quo,quo		; shift quo with/into carry
134	ds		rem,dvr,rem		; 29th divide step
135	addc		quo,quo,quo		; shift quo with/into carry
136	ds		rem,dvr,rem		; 30th divide step
137	addc		quo,quo,quo		; shift quo with/into carry
138	ds		rem,dvr,rem		; 31st divide step
139	addc		quo,quo,quo		; shift quo with/into carry
140	ds		rem,dvr,rem		; 32nd divide step,
141	addc		quo,quo,quo		; shift last quo bit into quo
142	addb,>=,n	rem,0,finish		; branch if pos. rem
143	add,<		dvr,0,0			; if dvr > 0, add dvr
144	add,tr		rem,dvr,rem		;   for correcting rem.
145	sub		rem,dvr,rem		; else subtract dvr
146;
147;	end of divide routine
148;
149finish	stws		rem,0(arg3)		; save remainder in high part
150						;   of result
151	stws		quo,4(arg3)		; save quotient in low part
152						;   of result
153	ldws,mb		-4(sp),tp		; restore registers
154	ldws,mb		-4(sp),dvr		; restore registers
155	ldws,mb		-4(sp),quo		; restore registers
156	bv		0(rp)			; return
157	ldws,mb		-4(sp),rem		; restore registers
158;
159hibit	ldo		32(0),tp		; initialize loop counter
160	add		quo,quo,quo		; shift high bit into carry
161loop	addc		rem,rem,rem		; shift in high bit of dvdl
162	addc,<>		0,0,0			; if bit shifted out of dvdu,
163						;   want to do subtract
164	comb,<<,n	rem,dvr,nosub		; if upper dividend > dvr,
165	sub		rem,dvr,rem		;   subtract and
166	add,tr		dvr,dvr,0		;   set carry
167nosub	addi		0,0,0			; otherwise clear carry
168	addib,>		-1,tp,loop		; inc. counter; finished?
169	addc		quo,quo,quo		; shift bit of result into dvdl
170	b		finish+4		; finish up
171	stws		rem,0(arg3)		; save remainder in high part
172						;   of result
173
174EXIT(divu)
175	.end
176