if (ep->from == FRAME_POINTER_REGNUM
&& ep->to == HARD_FRAME_POINTER_REGNUM)
{
- rtx src = SET_SRC (old_set);
- int offset = 0, ok = 0;
- rtx prev_insn, prev_set;
-
- if (src == ep->to_rtx)
- offset = 0, ok = 1;
- else if (GET_CODE (src) == PLUS
- && GET_CODE (XEXP (src, 0)) == CONST_INT
- && XEXP (src, 1) == ep->to_rtx)
- offset = INTVAL (XEXP (src, 0)), ok = 1;
- else if (GET_CODE (src) == PLUS
- && GET_CODE (XEXP (src, 1)) == CONST_INT
- && XEXP (src, 0) == ep->to_rtx)
- offset = INTVAL (XEXP (src, 1)), ok = 1;
- else if ((prev_insn = prev_nonnote_insn (insn)) != 0
- && (prev_set = single_set (prev_insn)) != 0
- && rtx_equal_p (SET_DEST (prev_set), src))
+ rtx base = SET_SRC (old_set);
+ rtx base_insn = insn;
+ int offset = 0;
+
+ while (base != ep->to_rtx)
{
- src = SET_SRC (prev_set);
- if (src == ep->to_rtx)
- offset = 0, ok = 1;
- else if (GET_CODE (src) == PLUS
- && GET_CODE (XEXP (src, 0)) == CONST_INT
- && XEXP (src, 1) == ep->to_rtx)
- offset = INTVAL (XEXP (src, 0)), ok = 1;
- else if (GET_CODE (src) == PLUS
- && GET_CODE (XEXP (src, 1)) == CONST_INT
- && XEXP (src, 0) == ep->to_rtx)
- offset = INTVAL (XEXP (src, 1)), ok = 1;
+ rtx prev_insn, prev_set;
+
+ if (GET_CODE (base) == PLUS
+ && GET_CODE (XEXP (base, 1)) == CONST_INT)
+ {
+ offset += INTVAL (XEXP (base, 1));
+ base = XEXP (base, 0);
+ }
+ else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
+ && (prev_set = single_set (prev_insn)) != 0
+ && rtx_equal_p (SET_DEST (prev_set), base))
+ {
+ base = SET_SRC (prev_set);
+ base_insn = prev_insn;
+ }
+ else
+ break;
}
- if (ok)
+ if (base == ep->to_rtx)
{
rtx src
= plus_constant (ep->to_rtx, offset - ep->offset);