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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [cris/] [arit.c] - Blame information for rev 820

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

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

powered by: WebSVN 2.1.0

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