aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/lib/milli/divU.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/lib/milli/divU.S')
-rw-r--r--arch/parisc/lib/milli/divU.S235
1 files changed, 235 insertions, 0 deletions
diff --git a/arch/parisc/lib/milli/divU.S b/arch/parisc/lib/milli/divU.S
new file mode 100644
index 000000000000..9287fe2546fa
--- /dev/null
+++ b/arch/parisc/lib/milli/divU.S
@@ -0,0 +1,235 @@
1/* 32 and 64-bit millicode, original author Hewlett-Packard
2 adapted for gcc by Paul Bame <bame@debian.org>
3 and Alan Modra <alan@linuxcare.com.au>.
4
5 Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
6
7 This file is part of GCC and is released under the terms of
8 of the GNU General Public License as published by the Free Software
9 Foundation; either version 2, or (at your option) any later version.
10 See the file COPYING in the top-level GCC source directory for a copy
11 of the license. */
12
13#include "milli.h"
14
15#ifdef L_divU
16/* ROUTINE: $$divU
17 .
18 . Single precision divide for unsigned integers.
19 .
20 . Quotient is truncated towards zero.
21 . Traps on divide by zero.
22
23 INPUT REGISTERS:
24 . arg0 == dividend
25 . arg1 == divisor
26 . mrp == return pc
27 . sr0 == return space when called externally
28
29 OUTPUT REGISTERS:
30 . arg0 = undefined
31 . arg1 = undefined
32 . ret1 = quotient
33
34 OTHER REGISTERS AFFECTED:
35 . r1 = undefined
36
37 SIDE EFFECTS:
38 . Causes a trap under the following conditions:
39 . divisor is zero
40 . Changes memory at the following places:
41 . NONE
42
43 PERMISSIBLE CONTEXT:
44 . Unwindable.
45 . Does not create a stack frame.
46 . Suitable for internal or external millicode.
47 . Assumes the special millicode register conventions.
48
49 DISCUSSION:
50 . Branchs to other millicode routines using BE:
51 . $$divU_# for 3,5,6,7,9,10,12,14,15
52 .
53 . For selected small divisors calls the special divide by constant
54 . routines written by Karl Pettis. These are: 3,5,6,7,9,10,12,14,15. */
55
56RDEFINE(temp,r1)
57RDEFINE(retreg,ret1) /* r29 */
58RDEFINE(temp1,arg0)
59 SUBSPA_MILLI_DIV
60 ATTR_MILLI
61 .export $$divU,millicode
62 .import $$divU_3,millicode
63 .import $$divU_5,millicode
64 .import $$divU_6,millicode
65 .import $$divU_7,millicode
66 .import $$divU_9,millicode
67 .import $$divU_10,millicode
68 .import $$divU_12,millicode
69 .import $$divU_14,millicode
70 .import $$divU_15,millicode
71 .proc
72 .callinfo millicode
73 .entry
74GSYM($$divU)
75/* The subtract is not nullified since it does no harm and can be used
76 by the two cases that branch back to "normal". */
77 ldo -1(arg1),temp /* is there at most one bit set ? */
78 and,= arg1,temp,r0 /* if so, denominator is power of 2 */
79 b LREF(regular_seq)
80 addit,= 0,arg1,0 /* trap for zero dvr */
81 copy arg0,retreg
82 extru,= arg1,15,16,temp /* test denominator with 0xffff0000 */
83 extru retreg,15,16,retreg /* retreg = retreg >> 16 */
84 or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 16) */
85 ldi 0xcc,temp1 /* setup 0xcc in temp1 */
86 extru,= arg1,23,8,temp /* test denominator with 0xff00 */
87 extru retreg,23,24,retreg /* retreg = retreg >> 8 */
88 or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 8) */
89 ldi 0xaa,temp /* setup 0xaa in temp */
90 extru,= arg1,27,4,r0 /* test denominator with 0xf0 */
91 extru retreg,27,28,retreg /* retreg = retreg >> 4 */
92 and,= arg1,temp1,r0 /* test denominator with 0xcc */
93 extru retreg,29,30,retreg /* retreg = retreg >> 2 */
94 and,= arg1,temp,r0 /* test denominator with 0xaa */
95 extru retreg,30,31,retreg /* retreg = retreg >> 1 */
96 MILLIRETN
97 nop
98LSYM(regular_seq)
99 comib,>= 15,arg1,LREF(special_divisor)
100 subi 0,arg1,temp /* clear carry, negate the divisor */
101 ds r0,temp,r0 /* set V-bit to 1 */
102LSYM(normal)
103 add arg0,arg0,retreg /* shift msb bit into carry */
104 ds r0,arg1,temp /* 1st divide step, if no carry */
105 addc retreg,retreg,retreg /* shift retreg with/into carry */
106 ds temp,arg1,temp /* 2nd divide step */
107 addc retreg,retreg,retreg /* shift retreg with/into carry */
108 ds temp,arg1,temp /* 3rd divide step */
109 addc retreg,retreg,retreg /* shift retreg with/into carry */
110 ds temp,arg1,temp /* 4th divide step */
111 addc retreg,retreg,retreg /* shift retreg with/into carry */
112 ds temp,arg1,temp /* 5th divide step */
113 addc retreg,retreg,retreg /* shift retreg with/into carry */
114 ds temp,arg1,temp /* 6th divide step */
115 addc retreg,retreg,retreg /* shift retreg with/into carry */
116 ds temp,arg1,temp /* 7th divide step */
117 addc retreg,retreg,retreg /* shift retreg with/into carry */
118 ds temp,arg1,temp /* 8th divide step */
119 addc retreg,retreg,retreg /* shift retreg with/into carry */
120 ds temp,arg1,temp /* 9th divide step */
121 addc retreg,retreg,retreg /* shift retreg with/into carry */
122 ds temp,arg1,temp /* 10th divide step */
123 addc retreg,retreg,retreg /* shift retreg with/into carry */
124 ds temp,arg1,temp /* 11th divide step */
125 addc retreg,retreg,retreg /* shift retreg with/into carry */
126 ds temp,arg1,temp /* 12th divide step */
127 addc retreg,retreg,retreg /* shift retreg with/into carry */
128 ds temp,arg1,temp /* 13th divide step */
129 addc retreg,retreg,retreg /* shift retreg with/into carry */
130 ds temp,arg1,temp /* 14th divide step */
131 addc retreg,retreg,retreg /* shift retreg with/into carry */
132 ds temp,arg1,temp /* 15th divide step */
133 addc retreg,retreg,retreg /* shift retreg with/into carry */
134 ds temp,arg1,temp /* 16th divide step */
135 addc retreg,retreg,retreg /* shift retreg with/into carry */
136 ds temp,arg1,temp /* 17th divide step */
137 addc retreg,retreg,retreg /* shift retreg with/into carry */
138 ds temp,arg1,temp /* 18th divide step */
139 addc retreg,retreg,retreg /* shift retreg with/into carry */
140 ds temp,arg1,temp /* 19th divide step */
141 addc retreg,retreg,retreg /* shift retreg with/into carry */
142 ds temp,arg1,temp /* 20th divide step */
143 addc retreg,retreg,retreg /* shift retreg with/into carry */
144 ds temp,arg1,temp /* 21st divide step */
145 addc retreg,retreg,retreg /* shift retreg with/into carry */
146 ds temp,arg1,temp /* 22nd divide step */
147 addc retreg,retreg,retreg /* shift retreg with/into carry */
148 ds temp,arg1,temp /* 23rd divide step */
149 addc retreg,retreg,retreg /* shift retreg with/into carry */
150 ds temp,arg1,temp /* 24th divide step */
151 addc retreg,retreg,retreg /* shift retreg with/into carry */
152 ds temp,arg1,temp /* 25th divide step */
153 addc retreg,retreg,retreg /* shift retreg with/into carry */
154 ds temp,arg1,temp /* 26th divide step */
155 addc retreg,retreg,retreg /* shift retreg with/into carry */
156 ds temp,arg1,temp /* 27th divide step */
157 addc retreg,retreg,retreg /* shift retreg with/into carry */
158 ds temp,arg1,temp /* 28th divide step */
159 addc retreg,retreg,retreg /* shift retreg with/into carry */
160 ds temp,arg1,temp /* 29th divide step */
161 addc retreg,retreg,retreg /* shift retreg with/into carry */
162 ds temp,arg1,temp /* 30th divide step */
163 addc retreg,retreg,retreg /* shift retreg with/into carry */
164 ds temp,arg1,temp /* 31st divide step */
165 addc retreg,retreg,retreg /* shift retreg with/into carry */
166 ds temp,arg1,temp /* 32nd divide step, */
167 MILLIRET
168 addc retreg,retreg,retreg /* shift last retreg bit into retreg */
169
170/* Handle the cases where divisor is a small constant or has high bit on. */
171LSYM(special_divisor)
172/* blr arg1,r0 */
173/* comib,>,n 0,arg1,LREF(big_divisor) ; nullify previous instruction */
174
175/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
176 generating such a blr, comib sequence. A problem in nullification. So I
177 rewrote this code. */
178
179#if defined(CONFIG_64BIT)
180/* Clear the upper 32 bits of the arg1 register. We are working with
181 small divisors (and 32-bit unsigned integers) We must not be mislead
182 by "1" bits left in the upper 32 bits. */
183 depd %r0,31,32,%r25
184#endif
185 comib,> 0,arg1,LREF(big_divisor)
186 nop
187 blr arg1,r0
188 nop
189
190LSYM(zero_divisor) /* this label is here to provide external visibility */
191 addit,= 0,arg1,0 /* trap for zero dvr */
192 nop
193 MILLIRET /* divisor == 1 */
194 copy arg0,retreg
195 MILLIRET /* divisor == 2 */
196 extru arg0,30,31,retreg
197 MILLI_BEN($$divU_3) /* divisor == 3 */
198 nop
199 MILLIRET /* divisor == 4 */
200 extru arg0,29,30,retreg
201 MILLI_BEN($$divU_5) /* divisor == 5 */
202 nop
203 MILLI_BEN($$divU_6) /* divisor == 6 */
204 nop
205 MILLI_BEN($$divU_7) /* divisor == 7 */
206 nop
207 MILLIRET /* divisor == 8 */
208 extru arg0,28,29,retreg
209 MILLI_BEN($$divU_9) /* divisor == 9 */
210 nop
211 MILLI_BEN($$divU_10) /* divisor == 10 */
212 nop
213 b LREF(normal) /* divisor == 11 */
214 ds r0,temp,r0 /* set V-bit to 1 */
215 MILLI_BEN($$divU_12) /* divisor == 12 */
216 nop
217 b LREF(normal) /* divisor == 13 */
218 ds r0,temp,r0 /* set V-bit to 1 */
219 MILLI_BEN($$divU_14) /* divisor == 14 */
220 nop
221 MILLI_BEN($$divU_15) /* divisor == 15 */
222 nop
223
224/* Handle the case where the high bit is on in the divisor.
225 Compute: if( dividend>=divisor) quotient=1; else quotient=0;
226 Note: dividend>==divisor iff dividend-divisor does not borrow
227 and not borrow iff carry. */
228LSYM(big_divisor)
229 sub arg0,arg1,r0
230 MILLIRET
231 addc r0,r0,retreg
232 .exit
233 .procend
234 .end
235#endif