aarch64.c (aarch64_expand_prologue): For the load-pair with writeback instruction...
authorYufeng Zhang <yufeng.zhang@arm.com>
Wed, 7 Nov 2012 11:01:46 +0000 (11:01 +0000)
committerYufeng Zhang <yufeng@gcc.gnu.org>
Wed, 7 Nov 2012 11:01:46 +0000 (11:01 +0000)
gcc/ChangeLog

2012-11-07  Yufeng Zhang  <yufeng.zhang@arm.com>

* config/aarch64/aarch64.c (aarch64_expand_prologue): For the
load-pair with writeback instruction, replace
aarch64_set_frame_expr with add_reg_note (REG_CFA_ADJUST_CFA);
add new local variable 'cfa_reg' and use it.

gcc/testsuite/ChangeLog

2012-11-07  Yufeng Zhang  <yufeng.zhang@arm.com>

* gcc.target/aarch64/dwarf-cfa-reg.c: New test.

From-SVN: r193291

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c [new file with mode: 0644]

index 9444adc..1f90132 100644 (file)
@@ -1,3 +1,10 @@
+2012-11-07  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_expand_prologue): For the
+       load-pair with writeback instruction, replace
+       aarch64_set_frame_expr with add_reg_note (REG_CFA_ADJUST_CFA);
+       add new local variable 'cfa_reg' and use it.
+
 2012-11-07  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR middle-end/49220
index aaebdf6..a33c73f 100644 (file)
@@ -1840,7 +1840,7 @@ aarch64_expand_prologue (void)
               - original_frame_size
               - cfun->machine->frame.saved_regs_size);
 
-  /* Store pairs and load pairs have a range only of +/- 512.  */
+  /* Store pairs and load pairs have a range only -512 to 504.  */
   if (offset >= 512)
     {
       /* When the frame has a large size, an initial decrease is done on
@@ -1988,6 +1988,7 @@ aarch64_expand_epilogue (bool for_sibcall)
   HOST_WIDE_INT original_frame_size, frame_size, offset;
   HOST_WIDE_INT fp_offset;
   rtx insn;
+  rtx cfa_reg;
 
   aarch64_layout_frame ();
   original_frame_size = get_frame_size () + cfun->machine->saved_varargs_size;
@@ -2000,7 +2001,9 @@ aarch64_expand_epilogue (bool for_sibcall)
               - original_frame_size
               - cfun->machine->frame.saved_regs_size);
 
-  /* Store pairs and load pairs have a range only of +/- 512.  */
+  cfa_reg = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
+
+  /* Store pairs and load pairs have a range only -512 to 504.  */
   if (offset >= 512)
     {
       offset = original_frame_size + cfun->machine->frame.saved_regs_size;
@@ -2031,6 +2034,10 @@ aarch64_expand_epilogue (bool for_sibcall)
                                       hard_frame_pointer_rtx,
                                       GEN_INT (- fp_offset)));
       RTX_FRAME_RELATED_P (insn) = 1;
+      /* As SP is set to (FP - fp_offset), according to the rules in
+        dwarf2cfi.c:dwarf2out_frame_debug_expr, CFA should be calculated
+        from the value of SP from now on.  */
+      cfa_reg = stack_pointer_rtx;
     }
 
   aarch64_save_or_restore_callee_save_registers
@@ -2070,11 +2077,9 @@ aarch64_expand_epilogue (bool for_sibcall)
                                 GEN_INT (offset),
                                 GEN_INT (GET_MODE_SIZE (DImode) + offset)));
              RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 2)) = 1;
-             aarch64_set_frame_expr (gen_rtx_SET
-                                     (Pmode,
-                                      stack_pointer_rtx,
-                                      gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-                                                    GEN_INT (offset))));
+             add_reg_note (insn, REG_CFA_ADJUST_CFA,
+                           (gen_rtx_SET (Pmode, stack_pointer_rtx,
+                                         plus_constant (cfa_reg, offset))));
            }
 
          /* The first part of a frame-related parallel insn
@@ -2094,7 +2099,6 @@ aarch64_expand_epilogue (bool for_sibcall)
              RTX_FRAME_RELATED_P (insn) = 1;
            }
        }
-
       else
        {
          insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
index 1ba75af..23f142a 100644 (file)
@@ -1,3 +1,7 @@
+2012-11-07  Yufeng Zhang  <yufeng.zhang@arm.com>
+
+       * gcc.target/aarch64/dwarf-cfa-reg.c: New test.
+
 2012-11-07  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        * gcc.c-torture/compile/pr49220.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c b/gcc/testsuite/gcc.target/aarch64/dwarf-cfa-reg.c
new file mode 100644 (file)
index 0000000..cce8815
--- /dev/null
@@ -0,0 +1,14 @@
+/* Verify that CFA register is restored to SP after FP is restored.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gdwarf-2" } */
+/* { dg-final { scan-assembler ".cfi_restore 30" } } */
+/* { dg-final { scan-assembler ".cfi_restore 29" } } */
+/* { dg-final { scan-assembler ".cfi_def_cfa 31, 0" } } */
+/* { dg-final { scan-assembler "ret" } } */
+
+int bar (unsigned int);
+
+int foo (void)
+{
+  return bar (0xcafe);
+}