diff options
Diffstat (limited to 'gcc/final.c')
-rw-r--r-- | gcc/final.c | 29 |
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); |