RISC-V: Fix epilogue unwind info with fp and single sp adjust.
authorJim Wilson <jimw@sifive.com>
Sat, 17 Nov 2018 23:31:01 +0000 (23:31 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Sat, 17 Nov 2018 23:31:01 +0000 (15:31 -0800)
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

gcc/ChangeLog
gcc/config/riscv/riscv.c

index dd790a26acb6d7c92a5ca2ca1cf4478f3d26adef..45dd8d62cc76a19a4259f0e4866b7b1b87463e96 100644 (file)
@@ -1,3 +1,11 @@
+2018-11-17  Jim Wilson  <jimw@sifive.com>
+
+       * 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.
+
 2018-11-17  Sandra Loosemore  <sandra@codesourcery.com>
 
        PR c++/4225
index 381a203da9be390d25ef8738f556903d05251caa..47d0b6e849e25d51b9f5a728a4bf51dd1d79935e 100644 (file)
@@ -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.  */