ia64.c patch for sibcall unwinding issue

James E Wilson wilson@specifixinc.com
Thu Oct 28 00:24:00 GMT 2004


This fixes PR 13158.

We were emitting incorrect unwind info for sibcall sequences.  The IA-64
sequence requires an alloc instruction to manipulate the register
windows before a sibcall.  We need unwind info for this alloc
instruction, but we were not emitting any.

This has been tested with an ia64-linux bootstrap and make check.  There
were no regressions.  Also, the libunwind author confirms that it works
correctly according to the libunwind testsuite.

I have checked in the patch.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

-------------- next part --------------
2004-10-27  David Mosberger  <davidm@hpl.hp.com>
	    James E Wilson  <wilson@specifixinc.com>

	PR target/13158
	* config/ia64/ia64.c (ia64_expand_epilogue): Set RTX_FRAME_RELATED_P on
	sibcall alloc instruction.
	(process_set): Handle sibcall alloc instruction.

Index: ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.328
diff -p -r1.328 ia64.c
*** ia64.c	7 Oct 2004 13:18:34 -0000	1.328
--- ia64.c	27 Oct 2004 22:31:04 -0000
*************** ia64_expand_epilogue (int sibcall_p)
*** 2604,2613 ****
  	 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),
! 			      const0_rtx, const0_rtx,
! 			      GEN_INT (current_frame_info.n_input_regs),
! 			      const0_rtx));
      }
  }
  
--- 2604,2616 ----
  	 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)
! 	{
! 	  rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
! 	  insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
! 				const0_rtx, const0_rtx,
! 				n_inputs, const0_rtx));
! 	  RTX_FRAME_RELATED_P (insn) = 1;
! 	}
      }
  }
  
*************** process_set (FILE *asm_out_file, rtx pat
*** 7290,7302 ****
      {
        dest_regno = REGNO (dest);
  
!       /* If this isn't the final destination for ar.pfs, the alloc
! 	 shouldn't have been marked frame related.  */
!       if (dest_regno != current_frame_info.reg_save_ar_pfs)
! 	abort ();
! 
!       fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
! 	       ia64_dbx_register_number (dest_regno));
        return 1;
      }
  
--- 7293,7316 ----
      {
        dest_regno = REGNO (dest);
  
!       /* If this is the final destination for ar.pfs, then this must
! 	 be the alloc in the prologue.  */
!       if (dest_regno == current_frame_info.reg_save_ar_pfs)
! 	fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
! 		 ia64_dbx_register_number (dest_regno));
!       else
! 	{
! 	  /* This must be an alloc before a sibcall.  We must drop the
! 	     old frame info.  The easiest way to drop the old frame
! 	     info is to ensure we had a ".restore sp" directive
! 	     followed by a new prologue.  If the procedure doesn't
! 	     have a memory-stack frame, we'll issue a dummy ".restore
! 	     sp" now.  */
! 	  if (current_frame_info.total_size == 0)
! 	    /* if haven't done process_epilogue() yet, do it now */
! 	    process_epilogue ();
! 	  fprintf (asm_out_file, "\t.prologue\n");
! 	}
        return 1;
      }
  


More information about the Gcc-patches mailing list