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<P:mode>. From-SVN: r175297
This commit is contained in:
parent
8288cc7387
commit
78a8eb4edc
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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))]
|
||||
;; 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<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))]
|
||||
(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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue