diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-07-10 08:15:06 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-07-10 08:15:06 -0400 |
commit | dd1eab0a024b5777a1f05e8321047f7034228a18 (patch) | |
tree | 304bc4f7271b01aa3dc11a058b411e3147577ff7 /gcc | |
parent | e74a2201543b8a835687acc396b169c5eda62fa6 (diff) | |
download | gcc-dd1eab0a024b5777a1f05e8321047f7034228a18.zip gcc-dd1eab0a024b5777a1f05e8321047f7034228a18.tar.gz gcc-dd1eab0a024b5777a1f05e8321047f7034228a18.tar.bz2 |
eliminate_regs_in_insn): Handle special case of assignment from hard frame...
eliminate_regs_in_insn): Handle special case of assignment from hard
frame pointer to frame pointer (for nonlocal goto).
From-SVN: r7696
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/reload1.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 360dc89..e46d764 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -3144,6 +3144,50 @@ eliminate_regs_in_insn (insn, replace) for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate) { +#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM + /* If this is setting the frame pointer register to the + hardware frame pointer register and this is an elimination + that will be done (tested above), this insn is really + adjusting the frame pointer downward to compensate for + the adjustment done before a nonlocal goto. */ + if (ep->from == FRAME_POINTER_REGNUM + && ep->to == HARD_FRAME_POINTER_REGNUM) + { + rtx src = SET_SRC (old_set); + int offset, ok = 0; + + if (src == ep->to_rtx) + offset = 0, ok = 1; + else if (GET_CODE (src) == PLUS + && GET_CODE (XEXP (src, 0)) == CONST_INT) + offset = INTVAL (XEXP (src, 0)), ok = 1; + + if (ok) + { + if (replace) + { + rtx src + = plus_constant (ep->to_rtx, offset - ep->offset); + + /* First see if this insn remains valid when we + make the change. If not, keep the INSN_CODE + the same and let reload fit it up. */ + validate_change (insn, &SET_SRC (old_set), src, 1); + validate_change (insn, &SET_DEST (old_set), + ep->to_rtx, 1); + if (! apply_change_group ()) + { + SET_SRC (old_set) = src; + SET_DEST (old_set) = ep->to_rtx; + } + } + + val = 1; + goto done; + } + } +#endif + /* In this case this insn isn't serving a useful purpose. We will delete it in reload_as_needed once we know that this elimination is, in fact, being done. |