This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch for ia64 epilogue
- To: gcc-patches at gcc dot gnu dot org
- Subject: patch for ia64 epilogue
- From: Andrew Macleod <amacleod at cygnus dot com>
- Date: Tue, 22 May 2001 13:06:23 -0700
If we have swapped the names of r2 and HARD_FRAME_POINTER_REGNUM in the
prologue code, we don't change it back until ia64_function_epilogue ().
When expand_epilogue is called, and if the sibcall_p flag is set, we
issue an alloc insn. This alloc insn uses GR_REG(2), which
may turn out to be loc79 if the register names have been swapped...
Oh, and we also want to avoid issuing it if its parameters are all 0 too....
The executable chokes on an invalid insn if we do that.
This allows the memcheck* family of testcases in torture to compile
and execute.
Checked into mainline and 3.0 branch. Verified on ia64 and approved by rth.
Andrew
* config/ia64/ia64.c (ia64_expand_epilogue): Make sure we are issuing
"r2" to the assembly file. Only issue allocs with non-zero parameters.
Index: ia64.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/ia64/ia64.c,v
retrieving revision 1.95
diff -c -p -r1.95 ia64.c
*** ia64.c 2001/05/14 17:57:41 1.95
--- ia64.c 2001/05/18 19:14:06
*************** ia64_expand_epilogue (sibcall_p)
*** 2400,2416 ****
if (! sibcall_p)
emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
else
! /* We must emit an alloc to force the input registers to become output
! registers. Otherwise, if the callee tries to pass its parameters
! through to another call without an intervening alloc, then these
! values get lost. */
! /* ??? We don't need to preserve all input registers. We only need to
! preserve those input registers used as arguments to the sibling call.
! It is unclear how to compute that number here. */
! emit_insn (gen_alloc (gen_rtx_REG (DImode, GR_REG (2)),
! GEN_INT (0), GEN_INT (0),
! GEN_INT (current_frame_info.n_input_regs),
! GEN_INT (0)));
}
/* Return 1 if br.ret can do all the work required to return from a
--- 2400,2428 ----
if (! sibcall_p)
emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
else
! {
! int fp = GR_REG (2);
! /* We need a throw away register here, r0 and r1 are reserved, so r2 is the
! first available call clobbered register. If there was a frame_pointer
! register, we may have swapped the names of r2 and HARD_FRAME_POINTER_REGNUM,
! so we have to make sure we're using the string "r2" when emitting
! the register name for the assmbler. */
! if (current_frame_info.reg_fp && current_frame_info.reg_fp == GR_REG (2))
! fp = HARD_FRAME_POINTER_REGNUM;
!
! /* We must emit an alloc to force the input registers to become output
! registers. Otherwise, if the callee tries to pass its parameters
! through to another call without an intervening alloc, then these
! values get lost. */
! /* ??? We don't need to preserve all input registers. We only need to
! preserve those input registers used as arguments to the sibling call.
! It is unclear how to compute that number here. */
! if (current_frame_info.n_input_regs != 0)
! emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
! GEN_INT (0), GEN_INT (0),
! GEN_INT (current_frame_info.n_input_regs),
! GEN_INT (0)));
! }
}
/* Return 1 if br.ret can do all the work required to return from a