aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-11-17 23:31:01 +0000
committerJim Wilson <wilson@gcc.gnu.org>2018-11-17 15:31:01 -0800
commitb579523b7bcd02739e6f06fe21a7ac6eb24dd6ec (patch)
tree42b0503525877eab5d73704ad1d0d31fb7beda2a /gcc/config/riscv
parent9472dfbf21e34bbca599c15fd31c7341af3fda29 (diff)
downloadgcc-b579523b7bcd02739e6f06fe21a7ac6eb24dd6ec.zip
gcc-b579523b7bcd02739e6f06fe21a7ac6eb24dd6ec.tar.gz
gcc-b579523b7bcd02739e6f06fe21a7ac6eb24dd6ec.tar.bz2
RISC-V: Fix epilogue unwind info with fp and single sp adjust.
gcc/ * config/riscv/riscv.c (epilogue_cfa_sp_offset): New. (riscv_restore_reg): If restoring HARD_FRAME_POINTER_REGNUM, and epilogue_cfa_sp_offset set, then add REG_CFA_DEF_CFA regnote. (riscv_expand_epilogue): Initialize epilogue_cfa_sp_offset. Set it to step2 if frame_pointer_needed and step1 is 0. From-SVN: r266241
Diffstat (limited to 'gcc/config/riscv')
-rw-r--r--gcc/config/riscv/riscv.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 381a203..47d0b6e 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -237,6 +237,11 @@ bool riscv_slow_unaligned_access_p;
/* Stack alignment to assume/maintain. */
unsigned riscv_stack_boundary;
+/* If non-zero, this is an offset to be added to SP to redefine the CFA
+ when restoring the FP register from the stack. Only valid when generating
+ the epilogue. */
+static int epilogue_cfa_sp_offset;
+
/* Which tuning parameters to use. */
static const struct riscv_tune_info *tune_info;
@@ -3627,8 +3632,15 @@ riscv_restore_reg (rtx reg, rtx mem)
rtx insn = riscv_emit_move (reg, mem);
rtx dwarf = NULL_RTX;
dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
- REG_NOTES (insn) = dwarf;
+ if (epilogue_cfa_sp_offset && REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
+ {
+ rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (epilogue_cfa_sp_offset));
+ dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
+ }
+
+ REG_NOTES (insn) = dwarf;
RTX_FRAME_RELATED_P (insn) = 1;
}
@@ -3877,6 +3889,9 @@ riscv_expand_epilogue (int style)
return;
}
+ /* Reset the epilogue cfa info before starting to emit the epilogue. */
+ epilogue_cfa_sp_offset = 0;
+
/* Move past any dynamic stack allocations. */
if (cfun->calls_alloca)
{
@@ -3941,6 +3956,12 @@ riscv_expand_epilogue (int style)
REG_NOTES (insn) = dwarf;
}
+ else if (frame_pointer_needed)
+ {
+ /* Tell riscv_restore_reg to emit dwarf to redefine CFA when restoring
+ old value of FP. */
+ epilogue_cfa_sp_offset = step2;
+ }
if (use_restore_libcall)
frame->mask = 0; /* Temporarily fib that we need not save GPRs. */