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