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
151
152
|
/* $OpenBSD: remU.S,v 1.1 1998/06/23 18:56:54 mickey Exp $ */
/*
* (c) Copyright 1985 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.
*/
#include "prefix.h"
/*
* Author: Committee
*
*
* ROUTINE: $$remU
*
* Single precision divide for remainder with unsigned binary integers.
*
* The remainder must be dividend-(dividend/divisor)*divisor.
* Divide by zero is trapped.
*
* INPUT REGISTERS:
* arg0 == dividend
* arg1 == divisor
* r31 == return pc
* sr0 == return space when called externally
*
* OUTPUT REGISTERS:
* arg0 = undefined
* arg1 = undefined
* ret1 = remainder
*
* OTHER REGISTERS AFFECTED:
* r1 = undefined
*
* SIDE EFFECTS:
* Causes a trap under the following conditions: DIVIDE BY ZERO
* Changes memory at the following places: NONE
*
* PERMISSIBLE CONTEXT:
* Unwindable.
* Does not create a stack frame.
* Suitable for internal or external millicode.
* Assumes the special millicode register conventions.
*
* DISCUSSION:
* Calls other millicode routines using r31: NONE
* Calls other millicode routines: NONE
*/
DEFINE(temp,r1)
DEFINE(rmndr,ret1) ; r29
.subspa $MILLICODE$
.export $$remU,millicode
.proc
.callinfo millicode
.entry
$$remU
comib,>=,n 0,arg1,special_case
sub r0,arg1,rmndr ; clear carry, negate the divisor
ds r0,rmndr,r0 ; set V-bit to 1
add arg0,arg0,temp ; shift msb bit into carry
ds r0,arg1,rmndr ; 1st divide step, if no carry
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 2nd divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 3rd divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 4th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 5th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 6th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 7th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 8th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 9th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 10th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 11th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 12th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 13th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 14th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 15th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 16th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 17th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 18th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 19th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 20th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 21st divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 22nd divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 23rd divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 24th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 25th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 26th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 27th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 28th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 29th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 30th divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 31st divide step
addc temp,temp,temp ; shift temp with/into carry
ds rmndr,arg1,rmndr ; 32nd divide step,
comiclr,<= 0,rmndr,r0
add rmndr,arg1,rmndr ; correction
MILLIRETN
nop
; Putting >= on the last DS and deleting COMICLR does not work!
special_case
addit,= 0,arg1,r0 ; trap on div by zero
sub,>>= arg0,arg1,rmndr
copy arg0,rmndr
.exit
MILLIRETN
nop
.procend
.end
|