From 78a8eb4edcc2352b7af778d2a3563825d8d72b36 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 22 Jun 2011 09:26:52 -0700 Subject: [PATCH] reg-notes.def (REG_CFA_WINDOW_SAVE): New. * 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. From-SVN: r175297 --- gcc/ChangeLog | 16 ++++++++++++ gcc/config/sparc/sparc.c | 55 +++++++++++++++++---------------------- gcc/config/sparc/sparc.md | 22 ++++++---------- gcc/dwarf2out.c | 34 ++++++++++++------------ gcc/reg-notes.def | 5 ++++ gcc/tree.h | 4 --- 6 files changed, 71 insertions(+), 65 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b643f7cc159..f487bd2ff31 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-06-22 Richard Henderson + + * 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. + 2011-06-22 H.J. Lu PR target/49497 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index fe28d55ee43..e50d2f14dff 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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. */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index acf317d46bd..017b689d475 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -6276,24 +6276,18 @@ 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" - [(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. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 492de62b584..6d58a00dd63 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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; } diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def index 329cd6799d5..9924355f772 100644 --- a/gcc/reg-notes.def +++ b/gcc/reg-notes.def @@ -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. */ diff --git a/gcc/tree.h b/gcc/tree.h index 1d1bb31f579..20ba295a219 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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); -- 2.30.2