comparison gcc/config/cris/arit.c @ 0:a06113de4d67

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