From 01ad6816a1ebfcbccabd2aaecc22ffa8d047f0e6 Mon Sep 17 00:00:00 2001 From: Hans-Peter Nilsson Date: Fri, 23 Dec 2005 03:02:30 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++ gcc/config/cris/arit.c | 92 ++++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0906088fb59..1b64d262c5e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2005-12-23 Hans-Peter Nilsson + * 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 32632ab5c18..e094ea76ec0 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 , 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 */ /* -- 2.30.2