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