Patch to make nested functions and non-local gotos work.

* i960/i960.c (i960_function_prologue): Don't save static chain
	pointer.
	* i960/i960.h (STACK_CHAIN_REGNUM): Change from r3 to g12.
	(TRAMPOLINE_TEMPLATE): Likewise.
	(FRAME_POINTER_REQUIRED): Check current_function_has_nonlocal_goto.
	* i960/i960.md (nonlocal_goto): Rewrite.

From-SVN: r26282
This commit is contained in:
Jim Wilson 1999-04-07 23:03:01 +00:00 committed by Jim Wilson
parent 9a566c0926
commit a45f333130
4 changed files with 44 additions and 39 deletions

View File

@ -1,3 +1,12 @@
Wed Apr 7 22:40:19 1999 Jim Wilson <wilson@cygnus.com>
* i960/i960.c (i960_function_prologue): Don't save static chain
pointer.
* i960/i960.h (STACK_CHAIN_REGNUM): Change from r3 to g12.
(TRAMPOLINE_TEMPLATE): Likewise.
(FRAME_POINTER_REQUIRED): Check current_function_has_nonlocal_goto.
* i960/i960.md (nonlocal_goto): Rewrite.
Tue Apr 6 17:49:49 1999 Philip Blundell <pb@nexus.co.uk>
* config/arm/lib1funcs.asm: Test for __ELF__ not __elf__.

View File

@ -1349,7 +1349,9 @@ i960_function_prologue (file, size)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_ever_live[i]
&& ((! call_used_regs[i]) || (i > 7 && i < 12)))
&& ((! call_used_regs[i]) || (i > 7 && i < 12))
/* No need to save the static chain pointer. */
&& ! (i == STATIC_CHAIN_REGNUM && current_function_needs_context))
{
regs[i] = -1;
/* Count global registers that need saving. */

View File

@ -528,7 +528,7 @@ extern int target_flags;
g0..g3 are used for return values,
g0..g7 may always be used for parameters,
g8..g11 may be used for parameters, but are preserved if they aren't,
g12 is always preserved, but otherwise unused,
g12 is the static chain if needed, otherwise is preserved
g13 is the struct return ptr if used, or temp, but may be trashed,
g14 is the leaf return ptr or the arg block ptr otherwise zero,
must be reset to zero before returning if it was used,
@ -606,7 +606,12 @@ extern int hard_regno_mode_ok ();
/* ??? It isn't clear to me why this is here. Perhaps because of a bug (since
fixed) in the definition of INITIAL_FRAME_POINTER_OFFSET which would have
caused this to fail. */
#define FRAME_POINTER_REQUIRED (! leaf_function_p ())
/* ??? Must check current_function_has_nonlocal_goto, otherwise frame pointer
elimination messes up nonlocal goto sequences. I think this works for other
targets because they use indirect jumps for the return which disables fp
elimination. */
#define FRAME_POINTER_REQUIRED \
(! leaf_function_p () || current_function_has_nonlocal_goto)
/* C statement to store the difference between the frame pointer
and the stack pointer values immediately after the function prologue.
@ -622,8 +627,9 @@ extern int hard_regno_mode_ok ();
#define ARG_POINTER_REGNUM 14
/* Register in which static-chain is passed to a function.
On i960, we use r3. */
#define STATIC_CHAIN_REGNUM 19
On i960, we use g12. We can't use any local register, because we need
a register that can be set before a call or before a jump. */
#define STATIC_CHAIN_REGNUM 12
/* Functions which return large structures get the address
to place the wanted value at in g13. */
@ -1543,14 +1549,14 @@ extern struct rtx_def *gen_compare_reg ();
/* On the i960, the trampoline contains three instructions:
ldconst _function, r4
ldconst static addr, r3
ldconst static addr, g12
jump (r4) */
#define TRAMPOLINE_TEMPLATE(FILE) \
{ \
ASM_OUTPUT_INT (FILE, GEN_INT (0x8C203000)); \
ASM_OUTPUT_INT (FILE, GEN_INT (0x00000000)); \
ASM_OUTPUT_INT (FILE, GEN_INT (0x8C183000)); \
ASM_OUTPUT_INT (FILE, GEN_INT (0x8CE03000)); \
ASM_OUTPUT_INT (FILE, GEN_INT (0x00000000)); \
ASM_OUTPUT_INT (FILE, GEN_INT (0x84212000)); \
}

View File

@ -2308,57 +2308,45 @@
""
"
{
rtx fp = operands[1];
rtx new_pc = operands[3];
rtx chain = operands[0];
rtx handler = operands[1];
rtx stack = operands[2];
rtx val = operands[0];
/* This code isn't sufficient to make nonlocal_gotos for nested
functions to work fully. Here we assume that the passed frame
pointer is a real hard frame pointer, not a
virtual_stack_vars_rtx type of frame. */
rtx label = operands[3];
/* We must restore the stack pointer, frame pointer, previous frame
pointer and the return instruction pointer. Since the ret
instruction does all this for us with one instruction, we arrange
everything so that ret will do everything we need done. */
if (GET_CODE (fp) != REG)
fp = force_reg (Pmode, fp);
if (GET_CODE (val) != REG)
val = force_reg (Pmode, val);
if (GET_CODE (new_pc) != REG)
new_pc = force_reg (Pmode, new_pc);
/* First, we must flush the register windows, so that we can modify
the saved local registers on the stack directly and because we
are going to change the previous frame pointer. */
emit_insn (gen_flush_register_windows ());
/* Load the static chain value for the containing fn into fp. This is needed
because STACK refers to fp. */
emit_move_insn (hard_frame_pointer_rtx, chain);
/* Now move the adjusted value into the pfp register for the following return
instruction. */
emit_move_insn (gen_rtx (REG, SImode, 16),
plus_constant (hard_frame_pointer_rtx, -64));
/* Next, we put the address that we want to transfer to, into the
saved $rip value on the stack. Once we ret below, that value
saved $rip value in the frame. Once we ret below, that value
will be loaded into the pc (IP). */
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (fp, 8)),
new_pc);
plus_constant (hard_frame_pointer_rtx, -56)),
replace_rtx (copy_rtx (handler), virtual_stack_vars_rtx,
hard_frame_pointer_rtx));
#if 0
/* Next, we put the value into the static chain register's save
area on the stack. After the ret below, this will be loaded into
r3 (the static chain). */
/* Next, we put stack into the saved $sp value in the frame. */
emit_move_insn (gen_rtx (MEM, SImode,
plus_constant (fp, 12)),
val);
#endif
/* We now load pfp (the previous frame pointer) with the value that
we want fp to be. */
emit_move_insn (gen_rtx (REG, SImode, 16), fp);
plus_constant (hard_frame_pointer_rtx, -60)),
replace_rtx (copy_rtx (stack), virtual_stack_vars_rtx,
hard_frame_pointer_rtx));
/* And finally, we can now just ret to get all the values saved
above into all the right registers, and also, all the local