xref: /openbsd/sys/arch/hppa/spmath/divu.S (revision 09467b48)
1/*	$OpenBSD: divu.S,v 1.11 2011/04/16 20:52:12 deraadt Exp $	*/
2/*
3  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4  To anyone who acknowledges that this file is provided "AS IS"
5  without any express or implied warranty:
6      permission to use, copy, modify, and distribute this file
7  for any purpose is hereby granted without fee, provided that
8  the above copyright notice and this notice appears in all
9  copies, and that the name of Hewlett-Packard Company not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific, written prior permission.
12  Hewlett-Packard Company makes no representations about the
13  suitability of this software for any purpose.
14*/
15/* @(#)divu.s: Revision: 1.11.88.1 Date: 93/12/07 15:06:01 */
16
17#include <machine/asm.h>
18#include <machine/frame.h>
19
20;************************************************************************
21; Implement an integer divide routine for 32-bit operands and 32-bit quotient
22; and remainder with operand values of zero (divisor only) treated specially.
23;
24;****************************************************************************
25; Definitions
26;****************************************************************************
27;
28;	General registers
29;
30gr0	.reg		%r0		; General register zero
31rem	.reg		%r3		; remainder and upper part of dividend
32quo	.reg		%r4		; quotient and lower part of dividend
33dvr	.reg		%r5		; divisor
34tp	.reg		%r6		; temp. reg.
35
36;******************************************************************************
37	.text
38LEAF_ENTRY(divu)
39	stws,ma		rem,4(sp)		; save registers on stack
40	stws,ma		quo,4(sp)		; save registers on stack
41	stws,ma		dvr,4(sp)		; save registers on stack
42	stws,ma		tp,4(sp)		; save registers on stack
43
44	addi		0,arg2,dvr		; get divisor
45	addi		0,arg1,quo		; get lower dividend
46	addi		0,arg0,rem		; get upper dividend
47
48	comib,>,n	0,dvr,hibit		; check for dvr >= 2**31
49	addi		-1,gr0,tp		; set V-bit to 1
50	ds		0,tp,0
51	add		quo,quo,quo		; shift msb bit into carry
52	ds		rem,dvr,rem		; 1st divide step, if carry
53						;   out, msb of quotient = 0
54	addc		quo,quo,quo		; shift quo with/into carry
55	ds		rem,dvr,rem		; 2nd divide step
56	addc		quo,quo,quo		; shift quo with/into carry
57	ds		rem,dvr,rem		; 3rd divide step
58	addc		quo,quo,quo		; shift quo with/into carry
59	ds		rem,dvr,rem		; 4th divide step
60	addc		quo,quo,quo		; shift quo with/into carry
61	ds		rem,dvr,rem		; 5th divide step
62	addc		quo,quo,quo		; shift quo with/into carry
63	ds		rem,dvr,rem		; 6th divide step
64	addc		quo,quo,quo		; shift quo with/into carry
65	ds		rem,dvr,rem		; 7th divide step
66	addc		quo,quo,quo		; shift quo with/into carry
67	ds		rem,dvr,rem		; 8th divide step
68	addc		quo,quo,quo		; shift quo with/into carry
69	ds		rem,dvr,rem		; 9th divide step
70	addc		quo,quo,quo		; shift quo with/into carry
71	ds		rem,dvr,rem		; 10th divide step
72	addc		quo,quo,quo		; shift quo with/into carry
73	ds		rem,dvr,rem		; 11th divide step
74	addc		quo,quo,quo		; shift quo with/into carry
75	ds		rem,dvr,rem		; 12th divide step
76	addc		quo,quo,quo		; shift quo with/into carry
77	ds		rem,dvr,rem		; 13th divide step
78	addc		quo,quo,quo		; shift quo with/into carry
79	ds		rem,dvr,rem		; 14th divide step
80	addc		quo,quo,quo		; shift quo with/into carry
81	ds		rem,dvr,rem		; 15th divide step
82	addc		quo,quo,quo		; shift quo with/into carry
83	ds		rem,dvr,rem		; 16th divide step
84	addc		quo,quo,quo		; shift quo with/into carry
85	ds		rem,dvr,rem		; 17th divide step
86	addc		quo,quo,quo		; shift quo with/into carry
87	ds		rem,dvr,rem		; 18th divide step
88	addc		quo,quo,quo		; shift quo with/into carry
89	ds		rem,dvr,rem		; 19th divide step
90	addc		quo,quo,quo		; shift quo with/into carry
91	ds		rem,dvr,rem		; 20th divide step
92	addc		quo,quo,quo		; shift quo with/into carry
93	ds		rem,dvr,rem		; 21st divide step
94	addc		quo,quo,quo		; shift quo with/into carry
95	ds		rem,dvr,rem		; 22nd divide step
96	addc		quo,quo,quo		; shift quo with/into carry
97	ds		rem,dvr,rem		; 23rd divide step
98	addc		quo,quo,quo		; shift quo with/into carry
99	ds		rem,dvr,rem		; 24th divide step
100	addc		quo,quo,quo		; shift quo with/into carry
101	ds		rem,dvr,rem		; 25th divide step
102	addc		quo,quo,quo		; shift quo with/into carry
103	ds		rem,dvr,rem		; 26th divide step
104	addc		quo,quo,quo		; shift quo with/into carry
105	ds		rem,dvr,rem		; 27th divide step
106	addc		quo,quo,quo		; shift quo with/into carry
107	ds		rem,dvr,rem		; 28th divide step
108	addc		quo,quo,quo		; shift quo with/into carry
109	ds		rem,dvr,rem		; 29th divide step
110	addc		quo,quo,quo		; shift quo with/into carry
111	ds		rem,dvr,rem		; 30th divide step
112	addc		quo,quo,quo		; shift quo with/into carry
113	ds		rem,dvr,rem		; 31st divide step
114	addc		quo,quo,quo		; shift quo with/into carry
115	ds		rem,dvr,rem		; 32nd divide step,
116	addc		quo,quo,quo		; shift last quo bit into quo
117	addb,>=,n	rem,0,finish		; branch if pos. rem
118	add,<		dvr,0,0			; if dvr > 0, add dvr
119	add,tr		rem,dvr,rem		;   for correcting rem.
120	sub		rem,dvr,rem		; else subtract dvr
121;
122;	end of divide routine
123;
124finish	stws		rem,0(arg3)		; save remainder in high part
125						;   of result
126	stws		quo,4(arg3)		; save quotient in low part
127						;   of result
128	ldws,mb		-4(sp),tp		; restore registers
129	ldws,mb		-4(sp),dvr		; restore registers
130	ldws,mb		-4(sp),quo		; restore registers
131	bv		0(rp)			; return
132	ldws,mb		-4(sp),rem		; restore registers
133;
134hibit	ldo		32(0),tp		; initialize loop counter
135	add		quo,quo,quo		; shift high bit into carry
136loop	addc		rem,rem,rem		; shift in high bit of dvdl
137	addc,<>		0,0,0			; if bit shifted out of dvdu,
138						;   want to do subtract
139	comb,<<,n	rem,dvr,nosub		; if upper dividend > dvr,
140	sub		rem,dvr,rem		;   subtract and
141	add,tr		dvr,dvr,0		;   set carry
142nosub	addi		0,0,0			; otherwise clear carry
143	addib,>		-1,tp,loop		; inc. counter; finished?
144	addc		quo,quo,quo		; shift bit of result into dvdl
145	b		finish+4		; finish up
146	stws		rem,0(arg3)		; save remainder in high part
147						;   of result
148EXIT(divu)
149
150	.end
151