aboutsummaryrefslogtreecommitdiff
path: root/gcc/libgcc2.c
diff options
context:
space:
mode:
authorJason Merrill <jason@casey.cygnus.com>2000-03-23 00:29:55 +0000
committerJason Merrill <jason@gcc.gnu.org>2000-03-22 19:29:55 -0500
commit2c84914526bd6e657d8e55291fe7ce3f1395c766 (patch)
treeb3b34069ee82d4ab6af7bad503c9132d5330f934 /gcc/libgcc2.c
parentcb1072f45021824406e8ac504a111d6bbccb5b81 (diff)
downloadgcc-2c84914526bd6e657d8e55291fe7ce3f1395c766.zip
gcc-2c84914526bd6e657d8e55291fe7ce3f1395c766.tar.gz
gcc-2c84914526bd6e657d8e55291fe7ce3f1395c766.tar.bz2
Implement dwarf2 exception handling for the ARM.
* config/arm/arm.h (INCOMING_RETURN_ADDR_RTX): Define. (DWARF_FRAME_RETURN_COLUMN): Define. * config/arm/arm.c (emit_multi_reg_push): Return rtx. Attach REG_FRAME_RELATED_EXPR note. (emit_sfm): Likewise. (arm_expand_prologue): Set RTX_FRAME_RELATED_P on everything. * dwarf2out.c (reg_save): Handle saving a register to itself. (dwarf2out_frame_debug_expr): Handle an intermediate cfa reg. * except.c (eh_regs): Don't use the static chain reg if it's callee-saved. * frame.h (frame_state): Add cfa_saved field. * frame.c (execute_cfa_insn): Set it. * libgcc2.c (throw_helper): Don't adjust sp if it's restored in the epilogue. * function.c (ARG_POINTER_CFA_OFFSET): Default to FIRST_PARM_OFFSET. Now takes a parm. (instantiate_virtual_regs): Adjust. * tm.texi: Adjust. * config/m68k/m68k.h (ARG_POINTER_CFA_OFFSET): Don't define. * config/ns32k/ns32k.h (ARG_POINTER_CFA_OFFSET): Don't define. * config/sparc/sparc.h (ARG_POINTER_CFA_OFFSET): Take a parm. * dwarf2out.c (reg_number): Refer to FIRST_PSEUDO_REGISTER. (initial_return_save): Use DWARF_FRAME_REGNUM, not reg_number. From-SVN: r32696
Diffstat (limited to 'gcc/libgcc2.c')
-rw-r--r--gcc/libgcc2.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index e2a852c..aafbe75 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -3679,6 +3679,7 @@ throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
void *handler;
void *handler_p = 0;
void *pc_p = 0;
+ void *restored_cfa = 0;
frame_state saved_ustruct;
int new_eh_model;
int cleanup = 0;
@@ -3788,6 +3789,11 @@ throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
pc = saved_pc;
memcpy (udata, my_udata, sizeof (*udata));
+ if (udata->cfa_saved)
+ /* We saved the CFA register into the stack in this frame, so we
+ will restore it in the __throw epilogue. Remember the value. */
+ restored_cfa = udata->cfa;
+
while (pc != handler_pc)
{
frame_state *p = udata;
@@ -3808,6 +3814,9 @@ throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
copy_reg (i, udata, my_udata);
}
+ if (udata->cfa_saved)
+ restored_cfa = udata->cfa;
+
pc = get_return_addr (udata, sub_udata) - 1;
}
@@ -3823,6 +3832,13 @@ throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
}
/* udata now refers to the frame called by the handler frame. */
+ if (my_udata->cfa_saved)
+ /* If we saved the CFA register into the stack (after it became the
+ CFA register), we'll restore that value into SP in the epilogue,
+ as on the ARM. So calculate the adjustment based on the value that
+ will be restored. */
+ my_udata->cfa = restored_cfa;
+
/* We adjust SP by the difference between __throw's CFA and the CFA for
the frame called by the handler frame, because those CFAs correspond
to the SP values at the two call sites. We need to further adjust by