arit.c revision 1.1.1.8 1 1.1 mrg /* Signed and unsigned multiplication and division and modulus for CRIS.
2 1.1 mrg Contributed by Axis Communications.
3 1.1 mrg Written by Hans-Peter Nilsson <hp (at) axis.se>, c:a 1992.
4 1.1 mrg
5 1.1.1.8 mrg Copyright (C) 1998-2019 Free Software Foundation, Inc.
6 1.1 mrg
7 1.1 mrg This file is part of GCC.
8 1.1 mrg
9 1.1 mrg GCC is free software; you can redistribute it and/or modify it
10 1.1 mrg under the terms of the GNU General Public License as published by the
11 1.1 mrg Free Software Foundation; either version 3, or (at your option) any
12 1.1 mrg later version.
13 1.1 mrg
14 1.1 mrg This file is distributed in the hope that it will be useful, but
15 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of
16 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 1.1 mrg General Public License for more details.
18 1.1 mrg
19 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
20 1.1 mrg permissions described in the GCC Runtime Library Exception, version
21 1.1 mrg 3.1, as published by the Free Software Foundation.
22 1.1 mrg
23 1.1 mrg You should have received a copy of the GNU General Public License and
24 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
25 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 1.1 mrg <http://www.gnu.org/licenses/>. */
27 1.1 mrg
28 1.1 mrg
29 1.1 mrg /* Note that we provide prototypes for all "const" functions, to attach
30 1.1 mrg the const attribute. This is necessary in 2.7.2 - adding the
31 1.1 mrg attribute to the function *definition* is a syntax error.
32 1.1 mrg This did not work with e.g. 2.1; back then, the return type had to
33 1.1 mrg be "const". */
34 1.1 mrg
35 1.1 mrg #include "config.h"
36 1.1 mrg
37 1.1 mrg #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 3
38 1.1 mrg #define LZ(v) __builtin_clz (v)
39 1.1 mrg #endif
40 1.1 mrg
41 1.1.1.2 mrg /* In (at least) the 4.7 series, GCC doesn't automatically choose the
42 1.1.1.2 mrg most optimal strategy, possibly related to insufficient modelling of
43 1.1.1.2 mrg delay-slot costs. */
44 1.1.1.2 mrg #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
45 1.1.1.2 mrg #define SIGNMULT(s, a) ((s) * (a)) /* Cheap multiplication, better than branch. */
46 1.1.1.2 mrg #else
47 1.1.1.2 mrg #define SIGNMULT(s, a) ((s) < 0 ? -(a) : (a)) /* Branches are still better. */
48 1.1.1.2 mrg #endif
49 1.1 mrg
50 1.1 mrg #if defined (L_udivsi3) || defined (L_divsi3) || defined (L_umodsi3) \
51 1.1 mrg || defined (L_modsi3)
52 1.1 mrg /* Result type of divmod worker function. */
53 1.1 mrg struct quot_rem
54 1.1 mrg {
55 1.1 mrg long quot;
56 1.1 mrg long rem;
57 1.1 mrg };
58 1.1 mrg
59 1.1 mrg /* This is the worker function for div and mod. It is inlined into the
60 1.1 mrg respective library function. Parameter A must have bit 31 == 0. */
61 1.1 mrg
62 1.1 mrg static __inline__ struct quot_rem
63 1.1 mrg do_31div (unsigned long a, unsigned long b)
64 1.1 mrg __attribute__ ((__const__, __always_inline__));
65 1.1 mrg
66 1.1 mrg static __inline__ struct quot_rem
67 1.1 mrg do_31div (unsigned long a, unsigned long b)
68 1.1 mrg {
69 1.1 mrg /* Adjust operands and result if a is 31 bits. */
70 1.1 mrg long extra = 0;
71 1.1 mrg int quot_digits = 0;
72 1.1 mrg
73 1.1 mrg if (b == 0)
74 1.1 mrg {
75 1.1 mrg struct quot_rem ret;
76 1.1 mrg ret.quot = 0xffffffff;
77 1.1 mrg ret.rem = 0xffffffff;
78 1.1 mrg return ret;
79 1.1 mrg }
80 1.1 mrg
81 1.1 mrg if (a < b)
82 1.1 mrg return (struct quot_rem) { 0, a };
83 1.1 mrg
84 1.1 mrg #ifdef LZ
85 1.1 mrg if (b <= a)
86 1.1 mrg {
87 1.1 mrg quot_digits = LZ (b) - LZ (a);
88 1.1 mrg quot_digits += (a >= (b << quot_digits));
89 1.1 mrg b <<= quot_digits;
90 1.1 mrg }
91 1.1 mrg #else
92 1.1 mrg while (b <= a)
93 1.1 mrg {
94 1.1 mrg b <<= 1;
95 1.1 mrg quot_digits++;
96 1.1 mrg }
97 1.1 mrg #endif
98 1.1 mrg
99 1.1 mrg /* Is a 31 bits? Note that bit 31 is handled by the caller. */
100 1.1 mrg if (a & 0x40000000)
101 1.1 mrg {
102 1.1 mrg /* Then make b:s highest bit max 0x40000000, because it must have
103 1.1 mrg been 0x80000000 to be 1 bit higher than a. */
104 1.1 mrg b >>= 1;
105 1.1 mrg
106 1.1 mrg /* Adjust a to be maximum 0x3fffffff, i.e. two upper bits zero. */
107 1.1 mrg if (a >= b)
108 1.1 mrg {
109 1.1 mrg a -= b;
110 1.1 mrg extra = 1 << (quot_digits - 1);
111 1.1 mrg }
112 1.1 mrg else
113 1.1 mrg {
114 1.1 mrg a -= b >> 1;
115 1.1 mrg
116 1.1 mrg /* Remember that we adjusted a by subtracting b * 2 ** Something. */
117 1.1 mrg extra = 1 << quot_digits;
118 1.1 mrg }
119 1.1 mrg
120 1.1 mrg /* The number of quotient digits will be one less, because
121 1.1 mrg we just adjusted b. */
122 1.1 mrg quot_digits--;
123 1.1 mrg }
124 1.1 mrg
125 1.1 mrg /* Now do the division part. */
126 1.1 mrg
127 1.1 mrg /* Subtract b and add ones to the right when a >= b
128 1.1 mrg i.e. "a - (b - 1) == (a - b) + 1". */
129 1.1 mrg b--;
130 1.1 mrg
131 1.1 mrg #define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b))
132 1.1 mrg
133 1.1 mrg switch (quot_digits)
134 1.1 mrg {
135 1.1 mrg case 32: DS; case 31: DS; case 30: DS; case 29: DS;
136 1.1 mrg case 28: DS; case 27: DS; case 26: DS; case 25: DS;
137 1.1 mrg case 24: DS; case 23: DS; case 22: DS; case 21: DS;
138 1.1 mrg case 20: DS; case 19: DS; case 18: DS; case 17: DS;
139 1.1 mrg case 16: DS; case 15: DS; case 14: DS; case 13: DS;
140 1.1 mrg case 12: DS; case 11: DS; case 10: DS; case 9: DS;
141 1.1 mrg case 8: DS; case 7: DS; case 6: DS; case 5: DS;
142 1.1 mrg case 4: DS; case 3: DS; case 2: DS; case 1: DS;
143 1.1 mrg case 0:;
144 1.1 mrg }
145 1.1 mrg
146 1.1 mrg {
147 1.1 mrg struct quot_rem ret;
148 1.1 mrg ret.quot = (a & ((1 << quot_digits) - 1)) + extra;
149 1.1 mrg ret.rem = a >> quot_digits;
150 1.1 mrg return ret;
151 1.1 mrg }
152 1.1 mrg }
153 1.1 mrg
154 1.1 mrg #ifdef L_udivsi3
155 1.1 mrg unsigned long
156 1.1 mrg __Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__));
157 1.1 mrg
158 1.1 mrg unsigned long
159 1.1 mrg __Udiv (unsigned long a, unsigned long b)
160 1.1 mrg {
161 1.1 mrg long extra = 0;
162 1.1 mrg
163 1.1 mrg /* Adjust operands and result, if a and/or b is 32 bits. */
164 1.1 mrg /* Effectively: b & 0x80000000. */
165 1.1 mrg if ((long) b < 0)
166 1.1 mrg return a >= b;
167 1.1 mrg
168 1.1 mrg /* Effectively: a & 0x80000000. */
169 1.1 mrg if ((long) a < 0)
170 1.1 mrg {
171 1.1 mrg int tmp = 0;
172 1.1 mrg
173 1.1 mrg if (b == 0)
174 1.1 mrg return 0xffffffff;
175 1.1 mrg #ifdef LZ
176 1.1 mrg tmp = LZ (b);
177 1.1 mrg #else
178 1.1 mrg for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
179 1.1 mrg ;
180 1.1 mrg
181 1.1 mrg tmp = 31 - tmp;
182 1.1 mrg #endif
183 1.1 mrg
184 1.1 mrg if ((b << tmp) > a)
185 1.1 mrg {
186 1.1 mrg extra = 1 << (tmp-1);
187 1.1 mrg a -= b << (tmp - 1);
188 1.1 mrg }
189 1.1 mrg else
190 1.1 mrg {
191 1.1 mrg extra = 1 << tmp;
192 1.1 mrg a -= b << tmp;
193 1.1 mrg }
194 1.1 mrg }
195 1.1 mrg
196 1.1 mrg return do_31div (a, b).quot+extra;
197 1.1 mrg }
198 1.1 mrg #endif /* L_udivsi3 */
199 1.1 mrg
200 1.1 mrg #ifdef L_divsi3
201 1.1 mrg long
202 1.1 mrg __Div (long a, long b) __attribute__ ((__const__));
203 1.1 mrg
204 1.1 mrg long
205 1.1 mrg __Div (long a, long b)
206 1.1 mrg {
207 1.1 mrg long extra = 0;
208 1.1 mrg long sign = (b < 0) ? -1 : 1;
209 1.1.1.2 mrg long res;
210 1.1 mrg
211 1.1 mrg /* We need to handle a == -2147483648 as expected and must while
212 1.1 mrg doing that avoid producing a sequence like "abs (a) < 0" as GCC
213 1.1 mrg may optimize out the test. That sequence may not be obvious as
214 1.1 mrg we call inline functions. Testing for a being negative and
215 1.1 mrg handling (presumably much rarer than positive) enables us to get
216 1.1 mrg a bit of optimization for an (accumulated) reduction of the
217 1.1 mrg penalty of the 0x80000000 special-case. */
218 1.1 mrg if (a < 0)
219 1.1 mrg {
220 1.1 mrg sign = -sign;
221 1.1 mrg
222 1.1 mrg if ((a & 0x7fffffff) == 0)
223 1.1 mrg {
224 1.1 mrg /* We're at 0x80000000. Tread carefully. */
225 1.1.1.2 mrg a -= SIGNMULT (sign, b);
226 1.1 mrg extra = sign;
227 1.1 mrg }
228 1.1 mrg a = -a;
229 1.1 mrg }
230 1.1 mrg
231 1.1.1.2 mrg res = do_31div (a, __builtin_labs (b)).quot;
232 1.1.1.2 mrg return SIGNMULT (sign, res) + extra;
233 1.1 mrg }
234 1.1 mrg #endif /* L_divsi3 */
235 1.1 mrg
236 1.1 mrg
237 1.1 mrg #ifdef L_umodsi3
238 1.1 mrg unsigned long
239 1.1 mrg __Umod (unsigned long a, unsigned long b) __attribute__ ((__const__));
240 1.1 mrg
241 1.1 mrg unsigned long
242 1.1 mrg __Umod (unsigned long a, unsigned long b)
243 1.1 mrg {
244 1.1 mrg /* Adjust operands and result if a and/or b is 32 bits. */
245 1.1 mrg if ((long) b < 0)
246 1.1 mrg return a >= b ? a - b : a;
247 1.1 mrg
248 1.1 mrg if ((long) a < 0)
249 1.1 mrg {
250 1.1 mrg int tmp = 0;
251 1.1 mrg
252 1.1 mrg if (b == 0)
253 1.1 mrg return a;
254 1.1 mrg #ifdef LZ
255 1.1 mrg tmp = LZ (b);
256 1.1 mrg #else
257 1.1 mrg for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
258 1.1 mrg ;
259 1.1 mrg tmp = 31 - tmp;
260 1.1 mrg #endif
261 1.1 mrg
262 1.1 mrg if ((b << tmp) > a)
263 1.1 mrg {
264 1.1 mrg a -= b << (tmp - 1);
265 1.1 mrg }
266 1.1 mrg else
267 1.1 mrg {
268 1.1 mrg a -= b << tmp;
269 1.1 mrg }
270 1.1 mrg }
271 1.1 mrg
272 1.1 mrg return do_31div (a, b).rem;
273 1.1 mrg }
274 1.1 mrg #endif /* L_umodsi3 */
275 1.1 mrg
276 1.1 mrg #ifdef L_modsi3
277 1.1 mrg long
278 1.1 mrg __Mod (long a, long b) __attribute__ ((__const__));
279 1.1 mrg
280 1.1 mrg long
281 1.1 mrg __Mod (long a, long b)
282 1.1 mrg {
283 1.1 mrg long sign = 1;
284 1.1.1.2 mrg long res;
285 1.1 mrg
286 1.1 mrg /* We need to handle a == -2147483648 as expected and must while
287 1.1 mrg doing that avoid producing a sequence like "abs (a) < 0" as GCC
288 1.1 mrg may optimize out the test. That sequence may not be obvious as
289 1.1 mrg we call inline functions. Testing for a being negative and
290 1.1 mrg handling (presumably much rarer than positive) enables us to get
291 1.1 mrg a bit of optimization for an (accumulated) reduction of the
292 1.1 mrg penalty of the 0x80000000 special-case. */
293 1.1 mrg if (a < 0)
294 1.1 mrg {
295 1.1 mrg sign = -1;
296 1.1 mrg if ((a & 0x7fffffff) == 0)
297 1.1 mrg /* We're at 0x80000000. Tread carefully. */
298 1.1 mrg a += __builtin_labs (b);
299 1.1 mrg a = -a;
300 1.1 mrg }
301 1.1 mrg
302 1.1.1.2 mrg res = do_31div (a, __builtin_labs (b)).rem;
303 1.1.1.2 mrg return SIGNMULT (sign, res);
304 1.1 mrg }
305 1.1 mrg #endif /* L_modsi3 */
306 1.1 mrg #endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */
307 1.1 mrg
308 1.1 mrg /*
309 1.1 mrg * Local variables:
310 1.1 mrg * eval: (c-set-style "gnu")
311 1.1 mrg * indent-tabs-mode: t
312 1.1 mrg * End:
313 1.1 mrg */
314