summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 22:27:44 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2001-01-30 22:27:44 +0000
commitdea958cbe7a29e6028732d405aa1c139bce5a464 (patch)
tree983c1a7912b85c8b1399ed734fd64afee06afddc /gcc/combine.c
parent767b093ff5f16ea04d12d99eb5a7f2a3ef6540d1 (diff)
downloadgcc-dea958cbe7a29e6028732d405aa1c139bce5a464.tar.gz
* combine.c (try_combine): Fix SUBREG setting for
HOST_BITS_PER_WIDE_INT >= 2 * BITS_PER_WORD. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39355 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 9b721af4df4..74b02b55a47 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1661,9 +1661,32 @@ try_combine (i3, i2, i1, new_direct_jump_p)
}
if (subreg_lowpart_p (SET_DEST (PATTERN (i3))))
- lo = INTVAL (SET_SRC (PATTERN (i3)));
- else
+ {
+ /* We don't handle the case of the target word being wider
+ than a host wide int. */
+ if (HOST_BITS_PER_WIDE_INT < BITS_PER_WORD)
+ abort ();
+
+ lo &= ~(((unsigned HOST_WIDE_INT)1 << BITS_PER_WORD) - 1);
+ lo |= INTVAL (SET_SRC (PATTERN (i3)));
+ }
+ else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
hi = INTVAL (SET_SRC (PATTERN (i3)));
+ else if (HOST_BITS_PER_WIDE_INT >= 2 * BITS_PER_WORD)
+ {
+ int sign = -(int) ((unsigned HOST_WIDE_INT) lo
+ >> (HOST_BITS_PER_WIDE_INT - 1));
+
+ lo &= ~((((unsigned HOST_WIDE_INT)1 << BITS_PER_WORD) - 1)
+ << BITS_PER_WORD);
+ lo |= INTVAL (SET_SRC (PATTERN (i3))) << BITS_PER_WORD;
+ if (hi == sign)
+ hi = lo < 0 ? -1 : 0;
+ }
+ else
+ /* We don't handle the case of the higher word not fitting
+ entirely in either hi or lo. */
+ abort ();
combine_merges++;
subst_insn = i3;