builtins.c (expand_builtin_longjmp): A longjmp can be a call too.

2001-05-22  Andrew MacLeod  <amacleod@redhat.com>

	* builtins.c (expand_builtin_longjmp): A longjmp can be a call too.
	* config/ia64/ia64.md (nonlocal_goto): Reverse label and frame pointer
	parameters to __ia64_nonlocal_goto. Flag as NO_RETURN.
	* config/ia64/ia64.c (ia64_expand_epilogue): Make sure we are issuing
	"r2" to the assembly file. Only issue allocs with non-zero parameters.

From-SVN: r42467
This commit is contained in:
Andrew MacLeod 2001-05-22 20:04:58 +00:00 committed by Andrew Macleod
parent 0401d4997a
commit 8206fc899c
4 changed files with 45 additions and 20 deletions

View File

@ -1,3 +1,11 @@
2001-05-22 Andrew MacLeod <amacleod@redhat.com>
* builtins.c (expand_builtin_longjmp): A longjmp can be a call too.
* config/ia64/ia64.md (nonlocal_goto): Reverse label and frame pointer
parameters to __ia64_nonlocal_goto. Flag as NO_RETURN.
* config/ia64/ia64.c (ia64_expand_epilogue): Make sure we are issuing
"r2" to the assembly file. Only issue allocs with non-zero parameters.
2001-05-22 Loren J. Rittle <ljrittle@acm.org>
David O'Brien <obrien@freebsd.org>

View File

@ -718,12 +718,17 @@ expand_builtin_longjmp (buf_addr, value)
__builtin_setjmp target in the same function. However, we've
already cautioned the user that these functions are for
internal exception handling use only. */
for (insn = get_last_insn ();
GET_CODE (insn) != JUMP_INSN;
insn = PREV_INSN (insn))
continue;
REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
REG_NOTES (insn));
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
{
if (GET_CODE (insn) == JUMP_INSN)
{
REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
REG_NOTES (insn));
break;
}
else if (GET_CODE (insn) == CALL_INSN)
break;
}
}
/* Get a MEM rtx for expression EXP which is the address of an operand

View File

@ -2400,17 +2400,29 @@ ia64_expand_epilogue (sibcall_p)
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)));
{
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

View File

@ -4971,10 +4971,10 @@
"
{
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
0, VOIDmode, 3,
operands[1], Pmode,
LCT_NORETURN, VOIDmode, 3,
operands[3], Pmode,
copy_to_reg (XEXP (operands[2], 0)), Pmode,
operands[3], Pmode);
operands[1], Pmode);
emit_barrier ();
DONE;
}")