diff options
author | Jason Merrill <jason@casey.cygnus.com> | 2000-03-23 00:29:55 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2000-03-22 19:29:55 -0500 |
commit | 2c84914526bd6e657d8e55291fe7ce3f1395c766 (patch) | |
tree | b3b34069ee82d4ab6af7bad503c9132d5330f934 /gcc/libgcc2.c | |
parent | cb1072f45021824406e8ac504a111d6bbccb5b81 (diff) | |
download | gcc-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.c | 16 |
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 |