summaryrefslogtreecommitdiffstats
path: root/gcc/integrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r--gcc/integrate.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c
index ed6540e4bfd..327e8fa5f25 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -1895,23 +1895,33 @@ copy_rtx_and_substitute (orig, map, for_lhs)
copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs);
/* SUBREG is ordinary, but don't make nested SUBREGs. */
if (GET_CODE (copy) == SUBREG)
- return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
- SUBREG_WORD (orig) + SUBREG_WORD (copy));
+ {
+ int final_offset = SUBREG_BYTE (orig) + SUBREG_BYTE (copy);
+
+ /* When working with SUBREGs the rule is that the byte
+ offset must be a multiple of the SUBREG's mode. */
+ final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
+ final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
+ return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
+ final_offset);
+ }
else if (GET_CODE (copy) == CONCAT)
{
rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1);
+ int final_offset;
if (GET_MODE (retval) == GET_MODE (orig))
return retval;
- else
- return gen_rtx_SUBREG (GET_MODE (orig), retval,
- (SUBREG_WORD (orig) %
- (GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)))
- / (unsigned) UNITS_PER_WORD)));
+
+ final_offset = SUBREG_BYTE (orig) %
+ GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)));
+ final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
+ final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
+ return gen_rtx_SUBREG (GET_MODE (orig), retval, final_offset);
}
else
return gen_rtx_SUBREG (GET_MODE (orig), copy,
- SUBREG_WORD (orig));
+ SUBREG_BYTE (orig));
case ADDRESSOF:
copy = gen_rtx_ADDRESSOF (mode,
@@ -2397,8 +2407,8 @@ subst_constants (loc, insn, map, memonly)
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
&& GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD
&& GET_MODE (SUBREG_REG (x)) != VOIDmode)
- new = operand_subword (inner, SUBREG_WORD (x), 0,
- GET_MODE (SUBREG_REG (x)));
+ new = operand_subword (inner, SUBREG_BYTE (x) / UNITS_PER_WORD,
+ 0, GET_MODE (SUBREG_REG (x)));
cancel_changes (num_changes);
if (new == 0 && subreg_lowpart_p (x))
@@ -2675,7 +2685,12 @@ mark_stores (dest, x, data)
regno = REGNO (dest), mode = GET_MODE (dest);
else if (GET_CODE (dest) == SUBREG && GET_CODE (SUBREG_REG (dest)) == REG)
{
- regno = REGNO (SUBREG_REG (dest)) + SUBREG_WORD (dest);
+ regno = REGNO (SUBREG_REG (dest));
+ if (regno < FIRST_PSEUDO_REGISTER)
+ regno += subreg_regno_offset (REGNO (SUBREG_REG (dest)),
+ GET_MODE (SUBREG_REG (dest)),
+ SUBREG_BYTE (dest),
+ GET_MODE (dest));
mode = GET_MODE (SUBREG_REG (dest));
}
OpenPOWER on IntegriCloud