OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [cris/] [arit.c] - Blame information for rev 758

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* 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
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.