reg-notes.def (REG_CFA_WINDOW_SAVE): New.
authorRichard Henderson <rth@redhat.com>
Wed, 22 Jun 2011 16:26:52 +0000 (09:26 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 22 Jun 2011 16:26:52 +0000 (09:26 -0700)
* reg-notes.def (REG_CFA_WINDOW_SAVE): New.
* dwarf2out.c (dwarf2out_frame_debug): Handle it.
(dwarf2out_frame_debug_cfa_window_save): Rename from
dwarf2out_window_save; make static.
* tree.h (dwarf2out_window_save): Don't declare.

* config/sparc/sparc.c (sparc_dwarf_handle_frame_unspec): Remove.
(TARGET_DWARF_HANDLE_FRAME_UNSPEC): Remove.
(emit_save_register_window): Rename from gen_save_register_window;
emit the insn and add REG_CFA_* notes.
(sparc_expand_prologue): Update to match.
* config/sparc/sparc.md (save_register_window_1): Simplify from
save_register_window<P:mode>.

From-SVN: r175297

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/dwarf2out.c
gcc/reg-notes.def
gcc/tree.h

index b643f7cc1590493cfc963628791e1bc91536d174..f487bd2ff312274dff4bc1ad367135dbdbd96378 100644 (file)
@@ -1,3 +1,19 @@
+2011-06-22  Richard Henderson  <rth@redhat.com>
+
+       * reg-notes.def (REG_CFA_WINDOW_SAVE): New.
+       * dwarf2out.c (dwarf2out_frame_debug): Handle it.
+       (dwarf2out_frame_debug_cfa_window_save): Rename from
+       dwarf2out_window_save; make static.
+       * tree.h (dwarf2out_window_save): Don't declare.
+
+       * config/sparc/sparc.c (sparc_dwarf_handle_frame_unspec): Remove.
+       (TARGET_DWARF_HANDLE_FRAME_UNSPEC): Remove.
+       (emit_save_register_window): Rename from gen_save_register_window;
+       emit the insn and add REG_CFA_* notes.
+       (sparc_expand_prologue): Update to match.
+       * config/sparc/sparc.md (save_register_window_1): Simplify from
+       save_register_window<P:mode>.
+
 2011-06-22  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/49497
index fe28d55ee432026c3e02598f35c65742d07c6d53..e50d2f14dffc82966546a205969fcc4dec4a3869 100644 (file)
@@ -460,7 +460,6 @@ static unsigned int sparc_function_arg_boundary (enum machine_mode,
                                                 const_tree);
 static int sparc_arg_partial_bytes (cumulative_args_t,
                                    enum machine_mode, tree, bool);
-static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int);
 static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
 static void sparc_file_end (void);
 static bool sparc_frame_pointer_required (void);
@@ -611,9 +610,6 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE sparc_preferred_simd_mode
 
-#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
-#define TARGET_DWARF_HANDLE_FRAME_UNSPEC sparc_dwarf_handle_frame_unspec
-
 #ifdef SUBTARGET_INSERT_ATTRIBUTES
 #undef TARGET_INSERT_ATTRIBUTES
 #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
@@ -4597,12 +4593,28 @@ emit_save_or_restore_local_in_regs (rtx base, int offset, sorr_act_t action)
 /* Generate a save_register_window insn.  */
 
 static rtx
-gen_save_register_window (rtx increment)
+emit_save_register_window (rtx increment)
 {
-  if (TARGET_ARCH64)
-    return gen_save_register_windowdi (increment);
-  else
-    return gen_save_register_windowsi (increment);
+  rtx insn;
+
+  insn = emit_insn (gen_save_register_window_1 (increment));
+  RTX_FRAME_RELATED_P (insn) = 1;
+
+  /* The return address (%i7) is saved in %o7.  */
+  add_reg_note (insn, REG_CFA_REGISTER,
+               gen_rtx_SET (VOIDmode,
+                            gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
+                            gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM)));
+
+  /* The window save event.  */
+  add_reg_note (insn, REG_CFA_WINDOW_SAVE, const0_rtx);
+
+  /* The CFA is %fp, the hard frame pointer.  */
+  add_reg_note (insn, REG_CFA_DEF_CFA,
+               plus_constant (hard_frame_pointer_rtx,
+                              INCOMING_FRAME_SP_OFFSET));
+
+  return insn;
 }
 
 /* Generate a create_flat_frame_1 insn.  */
@@ -4671,7 +4683,6 @@ sparc_expand_prologue (void)
 {
   HOST_WIDE_INT size;
   rtx insn;
-  int i;
 
   /* Compute a snapshot of current_function_uses_only_leaf_regs.  Relying
      on the final value of the flag means deferring the prologue/epilogue
@@ -4733,10 +4744,10 @@ sparc_expand_prologue (void)
   else
     {
       if (size <= 4096)
-       insn = emit_insn (gen_save_register_window (GEN_INT (-size)));
+       emit_save_register_window (GEN_INT (-size));
       else if (size <= 8192)
        {
-         insn = emit_insn (gen_save_register_window (GEN_INT (-4096)));
+         emit_save_register_window (GEN_INT (-4096));
          /* %sp is not the CFA register anymore.  */
          emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
        }
@@ -4744,12 +4755,8 @@ sparc_expand_prologue (void)
        {
          rtx reg = gen_rtx_REG (Pmode, 1);
          emit_move_insn (reg, GEN_INT (-size));
-         insn = emit_insn (gen_save_register_window (reg));
+         emit_save_register_window (reg);
        }
-
-      RTX_FRAME_RELATED_P (insn) = 1;
-      for (i=0; i < XVECLEN (PATTERN (insn), 0); i++)
-        RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
     }
 
   if (sparc_leaf_function_p)
@@ -10000,20 +10007,6 @@ get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
   return 0;
 }
 
-/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
-
-   This is called from dwarf2out.c to emit call frame instructions
-   for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs.  */
-
-static void
-sparc_dwarf_handle_frame_unspec (const char *label,
-                                rtx pattern ATTRIBUTE_UNUSED,
-                                int index ATTRIBUTE_UNUSED)
-{
-  gcc_assert (index == UNSPECV_SAVEW);
-  dwarf2out_window_save (label);
-}
-
 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
    We need to emit DTP-relative relocations.  */
 
index acf317d46bd512aea86f08decbf49d8af5b45799..017b689d47572db1164d06f04f8b131ff8ba7051 100644 (file)
   DONE;
 })
 
-;; The "save register window" insn is modelled as follows so that the DWARF-2
-;; backend automatically emits the required call frame debugging information
-;; while it is parsing it.  Therefore, the pattern should not be modified
-;; without first studying the impact of the changes on the debug info.
-;; [(set (%fp) (%sp))
-;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
-;;  (set (%i7) (%o7))]
-
-(define_insn "save_register_window<P:mode>"
-  [(set (reg:P 30) (reg:P 14))
-   (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
-                                      (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
-   (set (reg:P 31) (reg:P 15))]
+;; The "save register window" insn is modelled as follows.  The dwarf2
+;; information is manually added in emit_save_register_window in sparc.c.
+
+(define_insn "save_register_window_1"
+  [(unspec_volatile
+       [(match_operand 0 "arith_operand" "rI")]
+       UNSPECV_SAVEW)]
   "!TARGET_FLAT"
   "save\t%%sp, %0, %%sp"
   [(set_attr "type" "savew")])
 
-;; Likewise for the "create flat frame" insns.  We need to use special insns
+;; For the "create flat frame" insns, we need to use special insns
 ;; because %fp cannot be clobbered until after the frame is established (so
 ;; that it contains the live register window save area) and %i7 changed with
 ;; a simple move as it is a fixed register and the move would be eliminated.
index 492de62b58418b686e2ca9119f226eabd0a68b98..6d58a00dd634d98453e2f899368a4feb1afbcb1a 100644 (file)
@@ -1232,22 +1232,6 @@ reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT
   add_fde_cfi (label, cfi);
 }
 
-/* Add the CFI for saving a register window.  LABEL is passed to reg_save.
-   This CFI tells the unwinder that it needs to restore the window registers
-   from the previous frame's window save area.
-
-   ??? Perhaps we should note in the CIE where windows are saved (instead of
-   assuming 0(cfa)) and what registers are in the window.  */
-
-void
-dwarf2out_window_save (const char *label)
-{
-  dw_cfi_ref cfi = new_cfi ();
-
-  cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
-  add_fde_cfi (label, cfi);
-}
-
 /* Entry point for saving a register to the stack.  REG is the GCC register
    number.  LABEL and OFFSET are passed to reg_save.  */
 
@@ -2104,6 +2088,19 @@ dwarf2out_frame_debug_cfa_restore (rtx reg, const char *label)
   add_fde_cfi (label, cfi);
 }
 
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.
+   ??? Perhaps we should note in the CIE where windows are saved (instead of
+   assuming 0(cfa)) and what registers are in the window.  */
+
+static void
+dwarf2out_frame_debug_cfa_window_save (const char *label)
+{
+  dw_cfi_ref cfi = new_cfi ();
+
+  cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
+  add_fde_cfi (label, cfi);
+}
+
 /* Record call frame debugging information for an expression EXPR,
    which either sets SP or FP (adjusting how we calculate the frame
    address) or saves a register to the stack or another register.
@@ -2900,6 +2897,11 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
        handled_one = true;
        break;
 
+      case REG_CFA_WINDOW_SAVE:
+       dwarf2out_frame_debug_cfa_window_save (label);
+       handled_one = true;
+       break;
+
       default:
        break;
       }
index 329cd6799d58c67aaf64b47302119199a7453ec0..9924355f7721534b0364391c45f7ddc9673de06d 100644 (file)
@@ -160,6 +160,11 @@ REG_NOTE (CFA_RESTORE)
    to the argument, if it is a MEM, it is ignored.  */
 REG_NOTE (CFA_SET_VDRAP)
 
+/* Attached to insn that are RTX_FRAME_RELATED_P, indicating a window
+   save operation, i.e. will result in a DW_CFA_GNU_window_save.
+   The argument is ignored.  */
+REG_NOTE (CFA_WINDOW_SAVE)
+
 /* Indicates that REG holds the exception context for the function.
    This context is shared by inline functions, so the code to acquire
    the real exception context is delayed until after inlining.  */
index 1d1bb31f579507c64422577fcfe1c248e5f9b8a0..20ba295a219ad52fecf2c0ee94621d54dc7ede63 100644 (file)
@@ -5607,10 +5607,6 @@ extern char *dwarf2out_cfi_label (bool);
 
 extern void dwarf2out_def_cfa (const char *, unsigned, HOST_WIDE_INT);
 
-/* Add the CFI for saving a register window.  */
-
-extern void dwarf2out_window_save (const char *);
-
 /* Entry point for saving a register to the stack.  */
 
 extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);