diff options
author | Christian Bruel <christian.bruel@st.com> | 2014-03-12 12:31:19 +0100 |
---|---|---|
committer | Christian Bruel <chrbr@gcc.gnu.org> | 2014-03-12 12:31:19 +0100 |
commit | 7d55b94832e4c81e06cbc5007aa77ee31a8875a6 (patch) | |
tree | 3d4d6c6741e175091e2ab39cf8f7e13a1892746b /gcc/config | |
parent | c3da584c59f134a74dbedf66a4a26774567af95d (diff) | |
download | gcc-7d55b94832e4c81e06cbc5007aa77ee31a8875a6.zip gcc-7d55b94832e4c81e06cbc5007aa77ee31a8875a6.tar.gz gcc-7d55b94832e4c81e06cbc5007aa77ee31a8875a6.tar.bz2 |
re PR target/60264 (ARM ICE in dwarf2out_frame_debug_adjust_cfa, at dwarf2cfi.c:1090)
2014-03-12 Christian Bruel <christian.bruel@st.com>
PR target/60264
* config/arm/arm.c (arm_emit_vfp_multi_reg_pop): Emit a REG_CFA_DEF_CFA
note.
(arm_expand_epilogue_apcs_frame): call arm_add_cfa_adjust_cfa_note.
(arm_unwind_emit): Allow REG_CFA_DEF_CFA.
From-SVN: r208511
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/arm/arm.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index af5666b..a68ed8d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -19914,8 +19914,15 @@ arm_emit_vfp_multi_reg_pop (int first_reg, int num_regs, rtx base_reg) par = emit_insn (par); REG_NOTES (par) = dwarf; - arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, - base_reg, base_reg); + /* Make sure cfa doesn't leave with IP_REGNUM to allow unwinding fron FP. */ + if (TARGET_VFP && REGNO (base_reg) == IP_REGNUM) + { + RTX_FRAME_RELATED_P (par) = 1; + add_reg_note (par, REG_CFA_DEF_CFA, hard_frame_pointer_rtx); + } + else + arm_add_cfa_adjust_cfa_note (par, 2 * UNITS_PER_WORD * num_regs, + base_reg, base_reg); } /* Generate and emit a pattern that will be recognized as LDRD pattern. If even @@ -27108,15 +27115,19 @@ arm_expand_epilogue_apcs_frame (bool really_return) if (TARGET_HARD_FLOAT && TARGET_VFP) { int start_reg; + rtx ip_rtx = gen_rtx_REG (SImode, IP_REGNUM); /* The offset is from IP_REGNUM. */ int saved_size = arm_get_vfp_saved_size (); if (saved_size > 0) { + rtx insn; floats_from_frame += saved_size; - emit_insn (gen_addsi3 (gen_rtx_REG (SImode, IP_REGNUM), - hard_frame_pointer_rtx, - GEN_INT (-floats_from_frame))); + insn = emit_insn (gen_addsi3 (ip_rtx, + hard_frame_pointer_rtx, + GEN_INT (-floats_from_frame))); + arm_add_cfa_adjust_cfa_note (insn, -floats_from_frame, + ip_rtx, hard_frame_pointer_rtx); } /* Generate VFP register multi-pop. */ @@ -27189,11 +27200,15 @@ arm_expand_epilogue_apcs_frame (bool really_return) num_regs = bit_count (saved_regs_mask); if ((offsets->outgoing_args != (1 + num_regs)) || cfun->calls_alloca) { + rtx insn; emit_insn (gen_blockage ()); /* Unwind the stack to just below the saved registers. */ - emit_insn (gen_addsi3 (stack_pointer_rtx, - hard_frame_pointer_rtx, - GEN_INT (- 4 * num_regs))); + insn = emit_insn (gen_addsi3 (stack_pointer_rtx, + hard_frame_pointer_rtx, + GEN_INT (- 4 * num_regs))); + + arm_add_cfa_adjust_cfa_note (insn, - 4 * num_regs, + stack_pointer_rtx, hard_frame_pointer_rtx); } arm_emit_multi_reg_pop (saved_regs_mask); @@ -28985,11 +29000,11 @@ arm_unwind_emit (FILE * asm_out_file, rtx insn) emit unwind information for it because these are used either for pretend arguments or notes to adjust sp and restore registers from stack. */ + case REG_CFA_DEF_CFA: case REG_CFA_ADJUST_CFA: case REG_CFA_RESTORE: return; - case REG_CFA_DEF_CFA: case REG_CFA_EXPRESSION: case REG_CFA_OFFSET: /* ??? Only handling here what we actually emit. */ |