aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2014-03-12 12:31:19 +0100
committerChristian Bruel <chrbr@gcc.gnu.org>2014-03-12 12:31:19 +0100
commit7d55b94832e4c81e06cbc5007aa77ee31a8875a6 (patch)
tree3d4d6c6741e175091e2ab39cf8f7e13a1892746b /gcc/config
parentc3da584c59f134a74dbedf66a4a26774567af95d (diff)
downloadgcc-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.c33
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. */