aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-10-07 08:14:16 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1993-10-07 08:14:16 -0400
commitceb7983c7c9d08b444761ebbb375e12ca78a5852 (patch)
treeb1b45fc0fabfddb319f16ec433176ea615e075fd
parent7be2640ddbc65bfc504351af589d0ba84e50d4f4 (diff)
downloadgcc-ceb7983c7c9d08b444761ebbb375e12ca78a5852.zip
gcc-ceb7983c7c9d08b444761ebbb375e12ca78a5852.tar.gz
gcc-ceb7983c7c9d08b444761ebbb375e12ca78a5852.tar.bz2
(force_to_mode): Sign-extend constant being truncated.
From-SVN: r5654
-rw-r--r--gcc/combine.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 8f9efb8..abc224c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5614,7 +5614,18 @@ force_to_mode (x, mode, mask, reg)
/* If X is a CONST_INT, return a new one. Do this here since the
test below will fail. */
if (GET_CODE (x) == CONST_INT)
- return GEN_INT (INTVAL (x) & mask);
+ {
+ HOST_WIDE_INT cval = INTVAL (x) & mask;
+ int width = GET_MODE_BITSIZE (mode);
+
+ /* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
+ number, sign extend it. */
+ if (width > 0 && width < HOST_BITS_PER_WIDE_INT
+ && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
+ cval |= (HOST_WIDE_INT) -1 << width;
+
+ return GEN_INT (cval);
+ }
/* If X is narrower than MODE, just get X in the proper mode. */
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))