aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-10-27 15:08:26 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-10-27 15:08:26 -0400
commitb69960ac72922e24256e50e02320f56626097113 (patch)
tree119e038ed62856bfc42ceb44b8f6ff3720aee098 /gcc
parentbcbed709847b6a0461ff70a574c14681af66844c (diff)
downloadgcc-b69960ac72922e24256e50e02320f56626097113.zip
gcc-b69960ac72922e24256e50e02320f56626097113.tar.gz
gcc-b69960ac72922e24256e50e02320f56626097113.tar.bz2
(force_to_mode, case ASHIFTRT): Properly handle mask wider than
HOST_WIDE_INT. From-SVN: r10534
Diffstat (limited to 'gcc')
-rw-r--r--gcc/combine.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 323db6b..e622b16 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6035,8 +6035,30 @@ force_to_mode (x, mode, mask, reg, just_select)
{
int i = -1;
- nonzero = GET_MODE_MASK (GET_MODE (x));
- nonzero >>= INTVAL (XEXP (x, 1));
+ /* If the considered data is wider then HOST_WIDE_INT, we can't
+ represent a mask for all its bits in a single scalar.
+ But we only care about the lower bits, so calculate these. */
+
+ if (GET_MODE_SIZE (GET_MODE (x)) > sizeof (HOST_WIDE_INT))
+ {
+ nonzero = ~(HOST_WIDE_INT)0;
+
+ /* GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
+ is the number of bits a full-width mask would have set.
+ We need only shift if these are fewer than nonzero can
+ hold. If not, we must keep all bits set in nonzero. */
+
+ if (GET_MODE_BITSIZE (GET_MODE (x)) - INTVAL (XEXP (x, 1))
+ < HOST_BITS_PER_WIDE_INT)
+ nonzero >>= INTVAL (XEXP (x, 1))
+ + HOST_BITS_PER_WIDE_INT
+ - GET_MODE_BITSIZE (GET_MODE (x)) ;
+ }
+ else
+ {
+ nonzero = GET_MODE_MASK (GET_MODE (x));
+ nonzero >>= INTVAL (XEXP (x, 1));
+ }
if ((mask & ~ nonzero) == 0
|| (i = exact_log2 (mask)) >= 0)