OSDN Git Service

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