Home | History | Annotate | Line # | Download | only in cris
arit.c revision 1.1
      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  mrg    Copyright (C) 1998-2013 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  mrg 
     42  1.1  mrg #if defined (L_udivsi3) || defined (L_divsi3) || defined (L_umodsi3) \
     43  1.1  mrg     || defined (L_modsi3)
     44  1.1  mrg /* Result type of divmod worker function.  */
     45  1.1  mrg struct quot_rem
     46  1.1  mrg  {
     47  1.1  mrg    long quot;
     48  1.1  mrg    long rem;
     49  1.1  mrg  };
     50  1.1  mrg 
     51  1.1  mrg /* This is the worker function for div and mod.  It is inlined into the
     52  1.1  mrg    respective library function.  Parameter A must have bit 31 == 0.  */
     53  1.1  mrg 
     54  1.1  mrg static __inline__ struct quot_rem
     55  1.1  mrg do_31div (unsigned long a, unsigned long b)
     56  1.1  mrg      __attribute__ ((__const__, __always_inline__));
     57  1.1  mrg 
     58  1.1  mrg static __inline__ struct quot_rem
     59  1.1  mrg do_31div (unsigned long a, unsigned long b)
     60  1.1  mrg {
     61  1.1  mrg   /* Adjust operands and result if a is 31 bits.  */
     62  1.1  mrg   long extra = 0;
     63  1.1  mrg   int quot_digits = 0;
     64  1.1  mrg 
     65  1.1  mrg   if (b == 0)
     66  1.1  mrg     {
     67  1.1  mrg       struct quot_rem ret;
     68  1.1  mrg       ret.quot = 0xffffffff;
     69  1.1  mrg       ret.rem = 0xffffffff;
     70  1.1  mrg       return ret;
     71  1.1  mrg     }
     72  1.1  mrg 
     73  1.1  mrg   if (a < b)
     74  1.1  mrg     return (struct quot_rem) { 0, a };
     75  1.1  mrg 
     76  1.1  mrg #ifdef LZ
     77  1.1  mrg   if (b <= a)
     78  1.1  mrg     {
     79  1.1  mrg       quot_digits = LZ (b) - LZ (a);
     80  1.1  mrg       quot_digits += (a >= (b << quot_digits));
     81  1.1  mrg       b <<= quot_digits;
     82  1.1  mrg     }
     83  1.1  mrg #else
     84  1.1  mrg   while (b <= a)
     85  1.1  mrg     {
     86  1.1  mrg       b <<= 1;
     87  1.1  mrg       quot_digits++;
     88  1.1  mrg     }
     89  1.1  mrg #endif
     90  1.1  mrg 
     91  1.1  mrg   /* Is a 31 bits?  Note that bit 31 is handled by the caller.  */
     92  1.1  mrg   if (a & 0x40000000)
     93  1.1  mrg     {
     94  1.1  mrg       /* Then make b:s highest bit max 0x40000000, because it must have
     95  1.1  mrg 	 been 0x80000000 to be 1 bit higher than a.  */
     96  1.1  mrg       b >>= 1;
     97  1.1  mrg 
     98  1.1  mrg       /* Adjust a to be maximum 0x3fffffff, i.e. two upper bits zero.  */
     99  1.1  mrg       if (a >= b)
    100  1.1  mrg 	{
    101  1.1  mrg 	  a -= b;
    102  1.1  mrg 	  extra = 1 << (quot_digits - 1);
    103  1.1  mrg 	}
    104  1.1  mrg       else
    105  1.1  mrg 	{
    106  1.1  mrg 	  a -= b >> 1;
    107  1.1  mrg 
    108  1.1  mrg 	  /* Remember that we adjusted a by subtracting b * 2 ** Something.  */
    109  1.1  mrg 	  extra = 1 << quot_digits;
    110  1.1  mrg 	}
    111  1.1  mrg 
    112  1.1  mrg       /* The number of quotient digits will be one less, because
    113  1.1  mrg 	 we just adjusted b.  */
    114  1.1  mrg       quot_digits--;
    115  1.1  mrg     }
    116  1.1  mrg 
    117  1.1  mrg   /* Now do the division part.  */
    118  1.1  mrg 
    119  1.1  mrg   /* Subtract b and add ones to the right when a >= b
    120  1.1  mrg      i.e. "a - (b - 1) == (a - b) + 1".  */
    121  1.1  mrg   b--;
    122  1.1  mrg 
    123  1.1  mrg #define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b))
    124  1.1  mrg 
    125  1.1  mrg   switch (quot_digits)
    126  1.1  mrg     {
    127  1.1  mrg     case 32: DS; case 31: DS; case 30: DS; case 29: DS;
    128  1.1  mrg     case 28: DS; case 27: DS; case 26: DS; case 25: DS;
    129  1.1  mrg     case 24: DS; case 23: DS; case 22: DS; case 21: DS;
    130  1.1  mrg     case 20: DS; case 19: DS; case 18: DS; case 17: DS;
    131  1.1  mrg     case 16: DS; case 15: DS; case 14: DS; case 13: DS;
    132  1.1  mrg     case 12: DS; case 11: DS; case 10: DS; case 9: DS;
    133  1.1  mrg     case 8: DS; case 7: DS; case 6: DS; case 5: DS;
    134  1.1  mrg     case 4: DS; case 3: DS; case 2: DS; case 1: DS;
    135  1.1  mrg     case 0:;
    136  1.1  mrg     }
    137  1.1  mrg 
    138  1.1  mrg   {
    139  1.1  mrg     struct quot_rem ret;
    140  1.1  mrg     ret.quot = (a & ((1 << quot_digits) - 1)) + extra;
    141  1.1  mrg     ret.rem = a >> quot_digits;
    142  1.1  mrg     return ret;
    143  1.1  mrg   }
    144  1.1  mrg }
    145  1.1  mrg 
    146  1.1  mrg #ifdef L_udivsi3
    147  1.1  mrg unsigned long
    148  1.1  mrg __Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__));
    149  1.1  mrg 
    150  1.1  mrg unsigned long
    151  1.1  mrg __Udiv (unsigned long a, unsigned long b)
    152  1.1  mrg {
    153  1.1  mrg   long extra = 0;
    154  1.1  mrg 
    155  1.1  mrg   /* Adjust operands and result, if a and/or b is 32 bits.  */
    156  1.1  mrg   /* Effectively: b & 0x80000000.  */
    157  1.1  mrg   if ((long) b < 0)
    158  1.1  mrg     return a >= b;
    159  1.1  mrg 
    160  1.1  mrg   /* Effectively: a & 0x80000000.  */
    161  1.1  mrg   if ((long) a < 0)
    162  1.1  mrg     {
    163  1.1  mrg       int tmp = 0;
    164  1.1  mrg 
    165  1.1  mrg       if (b == 0)
    166  1.1  mrg 	return 0xffffffff;
    167  1.1  mrg #ifdef LZ
    168  1.1  mrg       tmp = LZ (b);
    169  1.1  mrg #else
    170  1.1  mrg       for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
    171  1.1  mrg 	;
    172  1.1  mrg 
    173  1.1  mrg       tmp = 31 - tmp;
    174  1.1  mrg #endif
    175  1.1  mrg 
    176  1.1  mrg       if ((b << tmp) > a)
    177  1.1  mrg 	{
    178  1.1  mrg 	  extra = 1 << (tmp-1);
    179  1.1  mrg 	  a -= b << (tmp - 1);
    180  1.1  mrg 	}
    181  1.1  mrg       else
    182  1.1  mrg 	{
    183  1.1  mrg 	  extra = 1 << tmp;
    184  1.1  mrg 	  a -= b << tmp;
    185  1.1  mrg 	}
    186  1.1  mrg     }
    187  1.1  mrg 
    188  1.1  mrg   return do_31div (a, b).quot+extra;
    189  1.1  mrg }
    190  1.1  mrg #endif /* L_udivsi3 */
    191  1.1  mrg 
    192  1.1  mrg #ifdef L_divsi3
    193  1.1  mrg long
    194  1.1  mrg __Div (long a, long b) __attribute__ ((__const__));
    195  1.1  mrg 
    196  1.1  mrg long
    197  1.1  mrg __Div (long a, long b)
    198  1.1  mrg {
    199  1.1  mrg   long extra = 0;
    200  1.1  mrg   long sign = (b < 0) ? -1 : 1;
    201  1.1  mrg 
    202  1.1  mrg   /* We need to handle a == -2147483648 as expected and must while
    203  1.1  mrg      doing that avoid producing a sequence like "abs (a) < 0" as GCC
    204  1.1  mrg      may optimize out the test.  That sequence may not be obvious as
    205  1.1  mrg      we call inline functions.  Testing for a being negative and
    206  1.1  mrg      handling (presumably much rarer than positive) enables us to get
    207  1.1  mrg      a bit of optimization for an (accumulated) reduction of the
    208  1.1  mrg      penalty of the 0x80000000 special-case.  */
    209  1.1  mrg   if (a < 0)
    210  1.1  mrg     {
    211  1.1  mrg       sign = -sign;
    212  1.1  mrg 
    213  1.1  mrg       if ((a & 0x7fffffff) == 0)
    214  1.1  mrg 	{
    215  1.1  mrg 	  /* We're at 0x80000000.  Tread carefully.  */
    216  1.1  mrg 	  a -= b * sign;
    217  1.1  mrg 	  extra = sign;
    218  1.1  mrg 	}
    219  1.1  mrg       a = -a;
    220  1.1  mrg     }
    221  1.1  mrg 
    222  1.1  mrg   /* We knowingly penalize pre-v10 models by multiplication with the
    223  1.1  mrg      sign.  */
    224  1.1  mrg   return sign * do_31div (a, __builtin_labs (b)).quot + extra;
    225  1.1  mrg }
    226  1.1  mrg #endif /* L_divsi3 */
    227  1.1  mrg 
    228  1.1  mrg 
    229  1.1  mrg #ifdef L_umodsi3
    230  1.1  mrg unsigned long
    231  1.1  mrg __Umod (unsigned long a, unsigned long b) __attribute__ ((__const__));
    232  1.1  mrg 
    233  1.1  mrg unsigned long
    234  1.1  mrg __Umod (unsigned long a, unsigned long b)
    235  1.1  mrg {
    236  1.1  mrg   /* Adjust operands and result if a and/or b is 32 bits.  */
    237  1.1  mrg   if ((long) b < 0)
    238  1.1  mrg     return a >= b ? a - b : a;
    239  1.1  mrg 
    240  1.1  mrg   if ((long) a < 0)
    241  1.1  mrg     {
    242  1.1  mrg       int tmp = 0;
    243  1.1  mrg 
    244  1.1  mrg       if (b == 0)
    245  1.1  mrg 	return a;
    246  1.1  mrg #ifdef LZ
    247  1.1  mrg       tmp = LZ (b);
    248  1.1  mrg #else
    249  1.1  mrg       for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
    250  1.1  mrg 	;
    251  1.1  mrg       tmp = 31 - tmp;
    252  1.1  mrg #endif
    253  1.1  mrg 
    254  1.1  mrg       if ((b << tmp) > a)
    255  1.1  mrg 	{
    256  1.1  mrg 	  a -= b << (tmp - 1);
    257  1.1  mrg 	}
    258  1.1  mrg       else
    259  1.1  mrg 	{
    260  1.1  mrg 	  a -= b << tmp;
    261  1.1  mrg 	}
    262  1.1  mrg     }
    263  1.1  mrg 
    264  1.1  mrg   return do_31div (a, b).rem;
    265  1.1  mrg }
    266  1.1  mrg #endif /* L_umodsi3 */
    267  1.1  mrg 
    268  1.1  mrg #ifdef L_modsi3
    269  1.1  mrg long
    270  1.1  mrg __Mod (long a, long b) __attribute__ ((__const__));
    271  1.1  mrg 
    272  1.1  mrg long
    273  1.1  mrg __Mod (long a, long b)
    274  1.1  mrg {
    275  1.1  mrg   long sign = 1;
    276  1.1  mrg 
    277  1.1  mrg   /* We need to handle a == -2147483648 as expected and must while
    278  1.1  mrg      doing that avoid producing a sequence like "abs (a) < 0" as GCC
    279  1.1  mrg      may optimize out the test.  That sequence may not be obvious as
    280  1.1  mrg      we call inline functions.  Testing for a being negative and
    281  1.1  mrg      handling (presumably much rarer than positive) enables us to get
    282  1.1  mrg      a bit of optimization for an (accumulated) reduction of the
    283  1.1  mrg      penalty of the 0x80000000 special-case.  */
    284  1.1  mrg   if (a < 0)
    285  1.1  mrg     {
    286  1.1  mrg       sign = -1;
    287  1.1  mrg       if ((a & 0x7fffffff) == 0)
    288  1.1  mrg 	/* We're at 0x80000000.  Tread carefully.  */
    289  1.1  mrg 	a += __builtin_labs (b);
    290  1.1  mrg       a = -a;
    291  1.1  mrg     }
    292  1.1  mrg 
    293  1.1  mrg   return sign * do_31div (a, __builtin_labs (b)).rem;
    294  1.1  mrg }
    295  1.1  mrg #endif /* L_modsi3 */
    296  1.1  mrg #endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */
    297  1.1  mrg 
    298  1.1  mrg /*
    299  1.1  mrg  * Local variables:
    300  1.1  mrg  * eval: (c-set-style "gnu")
    301  1.1  mrg  * indent-tabs-mode: t
    302  1.1  mrg  * End:
    303  1.1  mrg  */
    304