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