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