Frame-related delay slot insns
Richard Sandiford
rsandifo@redhat.com
Tue May 6 12:06:00 GMT 2003
In the thread started by:
http://gcc.gnu.org/ml/gcc-patches/2001-11/msg00037.html
it was suggested that the frame effects of delay-slot insns be
described before the call. And execute_cfa_program says:
/* The comparison with the return address uses < rather than <= because
we are only interested in the effects of code before the call; for a
noreturn function, the return address may point to unrelated code with
a different stack configuration that we are not interested in. We
assume that the call itself is unwind info-neutral; if not, or if
there are delay instructions that adjust the stack, these must be
reflected at the point immediately before the call insn. */
while (insn_ptr < insn_end && fs->pc < context->ra)
{
As far as I can tell, the delay-slot aspect of this isn't implemented.
dwarf2out_frame_debug() is applied to delay slot insns after the insns
themselves have been written out. This is causing g++/eh/registers1.C
to fail on some mips targets.
The (somewhat ugly) patch below was tested on mips-elf, mips64-elf,
mips-sgi-irix6.5, mips64vrel-elf & mipsel-linux-gnu. OK to install?
Richard
* final.c (final_scan_insn): Apply the effects of frame-related
delay slot insns before emitting a delayed branch.
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.275
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.275 final.c
*** final.c 25 Jan 2003 23:32:20 -0000 1.275
--- final.c 5 May 2003 12:48:31 -0000
*************** final_scan_insn (insn, file, optimize, p
*** 2160,2165 ****
--- 2160,2175 ----
break;
final_sequence = body;
+ /* When a call's delay slots include frame-related insns,
+ their effect must be described before the call. See
+ execute_cfa_program(). */
+ #if defined (DWARF2_UNWIND_INFO)
+ if (dwarf2out_do_frame ())
+ for (i = 1; i < XVECLEN (body, 0); i++)
+ if (GET_CODE (XVECEXP (body, 0, i)) == INSN)
+ dwarf2out_frame_debug (XVECEXP (body, 0, i));
+ #endif
+
/* The first insn in this SEQUENCE might be a JUMP_INSN that will
force the restoration of a comparison that was previously
thought unnecessary. If that happens, cancel this sequence
*************** final_scan_insn (insn, file, optimize, p
*** 2514,2525 ****
output_asm_insn (template, recog_data.operand);
#if defined (DWARF2_UNWIND_INFO)
#if defined (HAVE_prologue)
! if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#else
if (!ACCUMULATE_OUTGOING_ARGS
&& GET_CODE (insn) == INSN
&& dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
--- 2524,2540 ----
output_asm_insn (template, recog_data.operand);
+ /* The frame information for calls and delay slot insns was
+ added above. */
#if defined (DWARF2_UNWIND_INFO)
#if defined (HAVE_prologue)
! if (final_sequence == 0
! && GET_CODE (insn) == INSN
! && dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#else
if (!ACCUMULATE_OUTGOING_ARGS
+ && final_sequence == 0
&& GET_CODE (insn) == INSN
&& dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
More information about the Gcc-patches
mailing list