Home | History | Annotate | Line # | Download | only in cris
arit.c revision 1.1.1.8
      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.8  mrg    Copyright (C) 1998-2019 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  mrg #define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b))
    132      1.1  mrg 
    133      1.1  mrg   switch (quot_digits)
    134      1.1  mrg     {
    135      1.1  mrg     case 32: DS; case 31: DS; case 30: DS; case 29: DS;
    136      1.1  mrg     case 28: DS; case 27: DS; case 26: DS; case 25: DS;
    137      1.1  mrg     case 24: DS; case 23: DS; case 22: DS; case 21: DS;
    138      1.1  mrg     case 20: DS; case 19: DS; case 18: DS; case 17: DS;
    139      1.1  mrg     case 16: DS; case 15: DS; case 14: DS; case 13: DS;
    140      1.1  mrg     case 12: DS; case 11: DS; case 10: DS; case 9: DS;
    141      1.1  mrg     case 8: DS; case 7: DS; case 6: DS; case 5: DS;
    142      1.1  mrg     case 4: DS; case 3: DS; case 2: DS; case 1: DS;
    143      1.1  mrg     case 0:;
    144      1.1  mrg     }
    145      1.1  mrg 
    146      1.1  mrg   {
    147      1.1  mrg     struct quot_rem ret;
    148      1.1  mrg     ret.quot = (a & ((1 << quot_digits) - 1)) + extra;
    149      1.1  mrg     ret.rem = a >> quot_digits;
    150      1.1  mrg     return ret;
    151      1.1  mrg   }
    152      1.1  mrg }
    153      1.1  mrg 
    154      1.1  mrg #ifdef L_udivsi3
    155      1.1  mrg unsigned long
    156      1.1  mrg __Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__));
    157      1.1  mrg 
    158      1.1  mrg unsigned long
    159      1.1  mrg __Udiv (unsigned long a, unsigned long b)
    160      1.1  mrg {
    161      1.1  mrg   long extra = 0;
    162      1.1  mrg 
    163      1.1  mrg   /* Adjust operands and result, if a and/or b is 32 bits.  */
    164      1.1  mrg   /* Effectively: b & 0x80000000.  */
    165      1.1  mrg   if ((long) b < 0)
    166      1.1  mrg     return a >= b;
    167      1.1  mrg 
    168      1.1  mrg   /* Effectively: a & 0x80000000.  */
    169      1.1  mrg   if ((long) a < 0)
    170      1.1  mrg     {
    171      1.1  mrg       int tmp = 0;
    172      1.1  mrg 
    173      1.1  mrg       if (b == 0)
    174      1.1  mrg 	return 0xffffffff;
    175      1.1  mrg #ifdef LZ
    176      1.1  mrg       tmp = LZ (b);
    177      1.1  mrg #else
    178      1.1  mrg       for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
    179      1.1  mrg 	;
    180      1.1  mrg 
    181      1.1  mrg       tmp = 31 - tmp;
    182      1.1  mrg #endif
    183      1.1  mrg 
    184      1.1  mrg       if ((b << tmp) > a)
    185      1.1  mrg 	{
    186      1.1  mrg 	  extra = 1 << (tmp-1);
    187      1.1  mrg 	  a -= b << (tmp - 1);
    188      1.1  mrg 	}
    189      1.1  mrg       else
    190      1.1  mrg 	{
    191      1.1  mrg 	  extra = 1 << tmp;
    192      1.1  mrg 	  a -= b << tmp;
    193      1.1  mrg 	}
    194      1.1  mrg     }
    195      1.1  mrg 
    196      1.1  mrg   return do_31div (a, b).quot+extra;
    197      1.1  mrg }
    198      1.1  mrg #endif /* L_udivsi3 */
    199      1.1  mrg 
    200      1.1  mrg #ifdef L_divsi3
    201      1.1  mrg long
    202      1.1  mrg __Div (long a, long b) __attribute__ ((__const__));
    203      1.1  mrg 
    204      1.1  mrg long
    205      1.1  mrg __Div (long a, long b)
    206      1.1  mrg {
    207      1.1  mrg   long extra = 0;
    208      1.1  mrg   long sign = (b < 0) ? -1 : 1;
    209  1.1.1.2  mrg   long res;
    210      1.1  mrg 
    211      1.1  mrg   /* We need to handle a == -2147483648 as expected and must while
    212      1.1  mrg      doing that avoid producing a sequence like "abs (a) < 0" as GCC
    213      1.1  mrg      may optimize out the test.  That sequence may not be obvious as
    214      1.1  mrg      we call inline functions.  Testing for a being negative and
    215      1.1  mrg      handling (presumably much rarer than positive) enables us to get
    216      1.1  mrg      a bit of optimization for an (accumulated) reduction of the
    217      1.1  mrg      penalty of the 0x80000000 special-case.  */
    218      1.1  mrg   if (a < 0)
    219      1.1  mrg     {
    220      1.1  mrg       sign = -sign;
    221      1.1  mrg 
    222      1.1  mrg       if ((a & 0x7fffffff) == 0)
    223      1.1  mrg 	{
    224      1.1  mrg 	  /* We're at 0x80000000.  Tread carefully.  */
    225  1.1.1.2  mrg 	  a -= SIGNMULT (sign, b);
    226      1.1  mrg 	  extra = sign;
    227      1.1  mrg 	}
    228      1.1  mrg       a = -a;
    229      1.1  mrg     }
    230      1.1  mrg 
    231  1.1.1.2  mrg   res = do_31div (a, __builtin_labs (b)).quot;
    232  1.1.1.2  mrg   return SIGNMULT (sign, res) + extra;
    233      1.1  mrg }
    234      1.1  mrg #endif /* L_divsi3 */
    235      1.1  mrg 
    236      1.1  mrg 
    237      1.1  mrg #ifdef L_umodsi3
    238      1.1  mrg unsigned long
    239      1.1  mrg __Umod (unsigned long a, unsigned long b) __attribute__ ((__const__));
    240      1.1  mrg 
    241      1.1  mrg unsigned long
    242      1.1  mrg __Umod (unsigned long a, unsigned long b)
    243      1.1  mrg {
    244      1.1  mrg   /* Adjust operands and result if a and/or b is 32 bits.  */
    245      1.1  mrg   if ((long) b < 0)
    246      1.1  mrg     return a >= b ? a - b : a;
    247      1.1  mrg 
    248      1.1  mrg   if ((long) a < 0)
    249      1.1  mrg     {
    250      1.1  mrg       int tmp = 0;
    251      1.1  mrg 
    252      1.1  mrg       if (b == 0)
    253      1.1  mrg 	return a;
    254      1.1  mrg #ifdef LZ
    255      1.1  mrg       tmp = LZ (b);
    256      1.1  mrg #else
    257      1.1  mrg       for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--)
    258      1.1  mrg 	;
    259      1.1  mrg       tmp = 31 - tmp;
    260      1.1  mrg #endif
    261      1.1  mrg 
    262      1.1  mrg       if ((b << tmp) > a)
    263      1.1  mrg 	{
    264      1.1  mrg 	  a -= b << (tmp - 1);
    265      1.1  mrg 	}
    266      1.1  mrg       else
    267      1.1  mrg 	{
    268      1.1  mrg 	  a -= b << tmp;
    269      1.1  mrg 	}
    270      1.1  mrg     }
    271      1.1  mrg 
    272      1.1  mrg   return do_31div (a, b).rem;
    273      1.1  mrg }
    274      1.1  mrg #endif /* L_umodsi3 */
    275      1.1  mrg 
    276      1.1  mrg #ifdef L_modsi3
    277      1.1  mrg long
    278      1.1  mrg __Mod (long a, long b) __attribute__ ((__const__));
    279      1.1  mrg 
    280      1.1  mrg long
    281      1.1  mrg __Mod (long a, long b)
    282      1.1  mrg {
    283      1.1  mrg   long sign = 1;
    284  1.1.1.2  mrg   long res;
    285      1.1  mrg 
    286      1.1  mrg   /* We need to handle a == -2147483648 as expected and must while
    287      1.1  mrg      doing that avoid producing a sequence like "abs (a) < 0" as GCC
    288      1.1  mrg      may optimize out the test.  That sequence may not be obvious as
    289      1.1  mrg      we call inline functions.  Testing for a being negative and
    290      1.1  mrg      handling (presumably much rarer than positive) enables us to get
    291      1.1  mrg      a bit of optimization for an (accumulated) reduction of the
    292      1.1  mrg      penalty of the 0x80000000 special-case.  */
    293      1.1  mrg   if (a < 0)
    294      1.1  mrg     {
    295      1.1  mrg       sign = -1;
    296      1.1  mrg       if ((a & 0x7fffffff) == 0)
    297      1.1  mrg 	/* We're at 0x80000000.  Tread carefully.  */
    298      1.1  mrg 	a += __builtin_labs (b);
    299      1.1  mrg       a = -a;
    300      1.1  mrg     }
    301      1.1  mrg 
    302  1.1.1.2  mrg   res = do_31div (a, __builtin_labs (b)).rem;
    303  1.1.1.2  mrg   return SIGNMULT (sign, res);
    304      1.1  mrg }
    305      1.1  mrg #endif /* L_modsi3 */
    306      1.1  mrg #endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */
    307      1.1  mrg 
    308      1.1  mrg /*
    309      1.1  mrg  * Local variables:
    310      1.1  mrg  * eval: (c-set-style "gnu")
    311      1.1  mrg  * indent-tabs-mode: t
    312      1.1  mrg  * End:
    313      1.1  mrg  */
    314