summaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/gcc/final.c b/gcc/final.c
index bffc1a9c460..ceb688e5e31 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2560,7 +2560,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
{
rtx src1, src2;
if (GET_CODE (SET_SRC (set)) == SUBREG)
- SET_SRC (set) = alter_subreg (&SET_SRC (set));
+ SET_SRC (set) = alter_subreg (&SET_SRC (set), true);
src1 = SET_SRC (set);
src2 = NULL_RTX;
@@ -2568,10 +2568,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
{
if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG)
XEXP (SET_SRC (set), 0)
- = alter_subreg (&XEXP (SET_SRC (set), 0));
+ = alter_subreg (&XEXP (SET_SRC (set), 0), true);
if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG)
XEXP (SET_SRC (set), 1)
- = alter_subreg (&XEXP (SET_SRC (set), 1));
+ = alter_subreg (&XEXP (SET_SRC (set), 1), true);
if (XEXP (SET_SRC (set), 1)
== CONST0_RTX (GET_MODE (XEXP (SET_SRC (set), 0))))
src2 = XEXP (SET_SRC (set), 0);
@@ -2974,7 +2974,7 @@ cleanup_subreg_operands (rtx insn)
expression directly. */
if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
{
- recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
+ recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true);
changed = true;
}
else if (GET_CODE (recog_data.operand[i]) == PLUS
@@ -2987,7 +2987,7 @@ cleanup_subreg_operands (rtx insn)
{
if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
{
- *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
+ *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true);
changed = true;
}
else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
@@ -2999,11 +2999,11 @@ cleanup_subreg_operands (rtx insn)
df_insn_rescan (insn);
}
-/* If X is a SUBREG, replace it with a REG or a MEM,
- based on the thing it is a subreg of. */
+/* If X is a SUBREG, try to replace it with a REG or a MEM, based on
+ the thing it is a subreg of. Do it anyway if FINAL_P. */
rtx
-alter_subreg (rtx *xp)
+alter_subreg (rtx *xp, bool final_p)
{
rtx x = *xp;
rtx y = SUBREG_REG (x);
@@ -3027,16 +3027,19 @@ alter_subreg (rtx *xp)
offset += difference % UNITS_PER_WORD;
}
- *xp = adjust_address (y, GET_MODE (x), offset);
+ if (final_p)
+ *xp = adjust_address (y, GET_MODE (x), offset);
+ else
+ *xp = adjust_address_nv (y, GET_MODE (x), offset);
}
else
{
rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
- SUBREG_BYTE (x));
+ SUBREG_BYTE (x));
if (new_rtx != 0)
*xp = new_rtx;
- else if (REG_P (y))
+ else if (final_p && REG_P (y))
{
/* Simplify_subreg can't handle some REG cases, but we have to. */
unsigned int regno;
@@ -3076,7 +3079,7 @@ walk_alter_subreg (rtx *xp, bool *changed)
case SUBREG:
*changed = true;
- return alter_subreg (xp);
+ return alter_subreg (xp, true);
default:
break;
@@ -3682,7 +3685,7 @@ void
output_operand (rtx x, int code ATTRIBUTE_UNUSED)
{
if (x && GET_CODE (x) == SUBREG)
- x = alter_subreg (&x);
+ x = alter_subreg (&x, true);
/* X must not be a pseudo reg. */
gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);