diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-10-27 15:08:26 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-10-27 15:08:26 -0400 |
commit | b69960ac72922e24256e50e02320f56626097113 (patch) | |
tree | 119e038ed62856bfc42ceb44b8f6ff3720aee098 /gcc | |
parent | bcbed709847b6a0461ff70a574c14681af66844c (diff) | |
download | gcc-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.c | 26 |
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) |