aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2005-12-23 03:02:30 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2005-12-23 03:02:30 +0000
commit01ad6816a1ebfcbccabd2aaecc22ffa8d047f0e6 (patch)
treea4d658b19495ecaf09986eadff5e37d6bebc513e /gcc
parent1c3a47459b84141aeba46bc1273fed8fb39c8d79 (diff)
downloadgcc-01ad6816a1ebfcbccabd2aaecc22ffa8d047f0e6.zip
gcc-01ad6816a1ebfcbccabd2aaecc22ffa8d047f0e6.tar.gz
gcc-01ad6816a1ebfcbccabd2aaecc22ffa8d047f0e6.tar.bz2
arit.c (do_31div): Clarify what "31" refers to.
* config/cris/arit.c (do_31div): Clarify what "31" refers to. [L_divsi3] (__Udiv): Don't use as inline function. [L_modsi3] (__Umod): Ditto. (__Div): Rearrange to call do_31div directly instead of __Udiv. (__Mod): Similarly regarding __Umod. From-SVN: r109007
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/cris/arit.c92
2 files changed, 58 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0906088..1b64d26 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2005-12-23 Hans-Peter Nilsson <hp@axis.com>
+ * config/cris/arit.c (do_31div): Clarify what "31" refers to.
+ [L_divsi3] (__Udiv): Don't use as inline function.
+ [L_modsi3] (__Umod): Ditto.
+ (__Div): Rearrange to call do_31div directly instead of __Udiv.
+ (__Mod): Similarly regarding __Umod.
+
PR target/24342
* config/cris/cris.c (cris_split_movdx): Add REG_INC notes for
emitted insns with post-increments.
diff --git a/gcc/config/cris/arit.c b/gcc/config/cris/arit.c
index 32632ab..e094ea7 100644
--- a/gcc/config/cris/arit.c
+++ b/gcc/config/cris/arit.c
@@ -2,7 +2,8 @@
Contributed by Axis Communications.
Written by Hans-Peter Nilsson <hp@axis.se>, c:a 1992.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -62,7 +63,8 @@ struct quot_rem
};
/* This is the worker function for div and mod. It is inlined into the
- respective library function. */
+ respective library function. Parameter A must have bit 31 == 0. */
+
static __inline__ struct quot_rem
do_31div (unsigned long a, unsigned long b)
__attribute__ ((__const__, __always_inline__));
@@ -155,19 +157,10 @@ do_31div (unsigned long a, unsigned long b)
}
}
-/* Note that unsigned and signed division both build when L_divsi3, but
- the unsigned variant is then inlined, as with do_31div above. */
-#if defined (L_udivsi3) || defined (L_divsi3)
-#ifndef L_udivsi3
-static __inline__
-#endif
+#ifdef L_udivsi3
unsigned long
-__Udiv (unsigned long a, unsigned long b)
- __attribute__ ((__const__, __always_inline__));
+__Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__));
-#ifndef L_udivsi3
-static __inline__
-#endif
unsigned long
__Udiv (unsigned long a, unsigned long b)
{
@@ -208,7 +201,7 @@ __Udiv (unsigned long a, unsigned long b)
return do_31div (a, b).quot+extra;
}
-
+#endif /* L_udivsi3 */
#ifdef L_divsi3
long
@@ -217,35 +210,40 @@ __Div (long a, long b) __attribute__ ((__const__));
long
__Div (long a, long b)
{
- long sign;
- long result;
-
- /* Do *not* call do_31div since abs (-2147483648) == 2147483648
- <=> abs (-0x80000000) == 0x80000000
- which is still 32 bits. */
+ long extra = 0;
+ long sign = (b < 0) ? -1 : 1;
+
+ /* We need to handle a == -2147483648 as expected and must while
+ doing that avoid producing a sequence like "abs (a) < 0" as GCC
+ may optimize out the test. That sequence may not be obvious as
+ we call inline functions. Testing for a being negative and
+ handling (presumably much rarer than positive) enables us to get
+ a bit of optimization for an (accumulated) reduction of the
+ penalty of the 0x80000000 special-case. */
+ if (a < 0)
+ {
+ sign = -sign;
- sign = a ^ b;
- result = __Udiv (__builtin_labs (a), __builtin_labs (b));
+ if ((a & 0x7fffffff) == 0)
+ {
+ /* We're at 0x80000000. Tread carefully. */
+ a -= b * sign;
+ extra = sign;
+ }
+ a = -a;
+ }
- return (sign < 0) ? -result : result;
+ /* We knowingly penalize pre-v10 models by multiplication with the
+ sign. */
+ return sign * do_31div (a, __builtin_labs (b)).quot + extra;
}
#endif /* L_divsi3 */
-#endif /* L_udivsi3 || L_divsi3 */
-/* Note that unsigned and signed modulus both build when L_modsi3, but
- then the unsigned variant is inlined, as with do_31div above. */
-#if defined (L_umodsi3) || defined (L_modsi3)
-#ifndef L_umodsi3
-static __inline__
-#endif
+#ifdef L_umodsi3
unsigned long
-__Umod (unsigned long a, unsigned long b)
- __attribute__ ((__const__, __always_inline__));
+__Umod (unsigned long a, unsigned long b) __attribute__ ((__const__));
-#ifndef L_umodsi3
-static __inline__
-#endif
unsigned long
__Umod (unsigned long a, unsigned long b)
{
@@ -279,6 +277,7 @@ __Umod (unsigned long a, unsigned long b)
return do_31div (a, b).rem;
}
+#endif /* L_umodsi3 */
#ifdef L_modsi3
long
@@ -287,14 +286,27 @@ __Mod (long a, long b) __attribute__ ((__const__));
long
__Mod (long a, long b)
{
- long result;
-
- result = __Umod (__builtin_labs (a), __builtin_labs (b));
+ long sign = 1;
+
+ /* We need to handle a == -2147483648 as expected and must while
+ doing that avoid producing a sequence like "abs (a) < 0" as GCC
+ may optimize out the test. That sequence may not be obvious as
+ we call inline functions. Testing for a being negative and
+ handling (presumably much rarer than positive) enables us to get
+ a bit of optimization for an (accumulated) reduction of the
+ penalty of the 0x80000000 special-case. */
+ if (a < 0)
+ {
+ sign = -1;
+ if ((a & 0x7fffffff) == 0)
+ /* We're at 0x80000000. Tread carefully. */
+ a += __builtin_labs (b);
+ a = -a;
+ }
- return (a < 0) ? -result : result;
+ return sign * do_31div (a, __builtin_labs (b)).rem;
}
#endif /* L_modsi3 */
-#endif /* L_umodsi3 || L_modsi3 */
#endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */
/*