diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-26 19:21:16 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-26 19:21:16 +0000 |
commit | d15ee1a58e26a69d4a56e58f6930e13e686a6c8a (patch) | |
tree | c465f270ce510064453ef668b699763e5cde22f5 /gcc/config/sparc | |
parent | 99a104182e185e02aa1104076ed836fe54db3efc (diff) | |
download | gcc-d15ee1a58e26a69d4a56e58f6930e13e686a6c8a.tar.gz |
* target.h (struct gcc_target): New field 'dwarf_handle_frame_unspec'.
* target_def.h (TARGET_DWARF_HANDLE_FRAME_UNSPEC): Define to 0.
(TARGET_INITIALIZER): Add TARGET_DWARF_HANDLE_FRAME_UNSPEC.
* dwarf2out.c (dwarf2out_frame_debug_expr): Allow REG->REG move
to a fixed reg if the source is the Return Address register.
Implement new Rule 15.
* doc/tm.texi (Frame Layout): Document TARGET_DWARF_HANDLE_FRAME_UNSPEC.
* config/sparc/sparc.c (TARGET_DWARF_HANDLE_FRAME_UNSPEC): Define to
sparc_dwarf_handle_frame_unspec.
(gen_save_register_window): New function.
(emit_stack_pointer_increment): Rename into gen_stack_pointer_inc.
(emit_stack_pointer_decrement): Rename into gen_stack_pointer_dec.
(expand_prologue): Adjust calls to emit_stack_pointer_{in,de}crement.
Set RTX_FRAME_RELATED_P on the appropriate insns and members of insns.
(sparc_asm_function_prologue): Do not emit call frame debugging info.
(emit_and_preserve): Adjust calls to emit_stack_pointer_{in,de}crement.
(sparc_expand_epilogue): Likewise.
(sparc_dwarf_handle_frame_unspec): New function.
* config/sparc/sparc.md (save_register_window): Remove.
(save_register_windowdi): Rewrite modelled on the callframe debug info.
(save_register_windowsi): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91346 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r-- | gcc/config/sparc/sparc.c | 118 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 52 |
2 files changed, 91 insertions, 79 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 4ab98d85bde..b13f820b0a1 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -356,6 +356,7 @@ static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *); static bool sparc_vector_mode_supported_p (enum machine_mode); static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); +static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int); #ifdef SUBTARGET_ATTRIBUTE_TABLE const struct attribute_spec sparc_attribute_table[]; #endif @@ -480,6 +481,9 @@ enum processor_type sparc_cpu; #undef TARGET_VECTOR_MODE_SUPPORTED_P #define TARGET_VECTOR_MODE_SUPPORTED_P sparc_vector_mode_supported_p +#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 @@ -4478,26 +4482,37 @@ emit_restore_regs (void) save_or_restore_regs (32, TARGET_V9 ? 96 : 64, base, offset, SORR_RESTORE); } -/* Emit an increment for the stack pointer. */ +/* Generate a save_register_window insn. */ -static void -emit_stack_pointer_increment (rtx increment) +static rtx +gen_save_register_window (rtx increment) { if (TARGET_ARCH64) - emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, increment)); + return gen_save_register_windowdi (increment); else - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, increment)); + return gen_save_register_windowsi (increment); } -/* Emit a decrement for the stack pointer. */ +/* Generate an increment for the stack pointer. */ -static void -emit_stack_pointer_decrement (rtx decrement) +static rtx +gen_stack_pointer_inc (rtx increment) { if (TARGET_ARCH64) - emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, decrement)); + return gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, increment); else - emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, decrement)); + return gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, increment); +} + +/* Generate a decrement for the stack pointer. */ + +static rtx +gen_stack_pointer_dec (rtx decrement) +{ + if (TARGET_ARCH64) + return gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, decrement); + else + return gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, decrement); } /* Expand the function prologue. The prologue is responsible for reserving @@ -4507,6 +4522,9 @@ emit_stack_pointer_decrement (rtx decrement) void sparc_expand_prologue (void) { + 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 expansion until just before the second scheduling pass, which is too @@ -4556,34 +4574,48 @@ sparc_expand_prologue (void) else if (sparc_leaf_function_p) { if (actual_fsize <= 4096) - emit_stack_pointer_increment (GEN_INT (- actual_fsize)); + insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-actual_fsize))); else if (actual_fsize <= 8192) { - emit_stack_pointer_increment (GEN_INT (-4096)); - emit_stack_pointer_increment (GEN_INT (4096 - actual_fsize)); + insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096))); + /* %sp is still the CFA register. */ + RTX_FRAME_RELATED_P (insn) = 1; + insn + = emit_insn (gen_stack_pointer_inc (GEN_INT (4096-actual_fsize))); } else { rtx reg = gen_rtx_REG (Pmode, 1); emit_move_insn (reg, GEN_INT (-actual_fsize)); - emit_stack_pointer_increment (reg); + insn = emit_insn (gen_stack_pointer_inc (reg)); + REG_NOTES (insn) = + gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + PATTERN (gen_stack_pointer_inc (GEN_INT (-actual_fsize))), + REG_NOTES (insn)); } + + RTX_FRAME_RELATED_P (insn) = 1; } else { if (actual_fsize <= 4096) - emit_insn (gen_save_register_window (GEN_INT (-actual_fsize))); + insn = emit_insn (gen_save_register_window (GEN_INT (-actual_fsize))); else if (actual_fsize <= 8192) { - emit_insn (gen_save_register_window (GEN_INT (-4096))); - emit_stack_pointer_increment (GEN_INT (4096 - actual_fsize)); + insn = emit_insn (gen_save_register_window (GEN_INT (-4096))); + /* %sp is not the CFA register anymore. */ + emit_insn (gen_stack_pointer_inc (GEN_INT (4096-actual_fsize))); } else { rtx reg = gen_rtx_REG (Pmode, 1); emit_move_insn (reg, GEN_INT (-actual_fsize)); - emit_insn (gen_save_register_window (reg)); + insn = emit_insn (gen_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; } /* Call-saved registers are saved just above the outgoing argument area. */ @@ -4596,8 +4628,7 @@ sparc_expand_prologue (void) } /* This function generates the assembly code for function entry, which boils - down to emitting the necessary .register directives. It also informs the - DWARF-2 back-end on the layout of the frame. + down to emitting the necessary .register directives. ??? Historical cruft: "On SPARC, move-double insns between fpu and cpu need an 8-byte block of memory. If any fpu reg is used in the function, we @@ -4612,29 +4643,6 @@ sparc_asm_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED) abort(); sparc_output_scratch_registers (file); - - if (dwarf2out_do_frame () && actual_fsize) - { - char *label = dwarf2out_cfi_label (); - - /* The canonical frame address refers to the top of the frame. */ - dwarf2out_def_cfa (label, - sparc_leaf_function_p - ? STACK_POINTER_REGNUM - : HARD_FRAME_POINTER_REGNUM, - frame_base_offset); - - if (! sparc_leaf_function_p) - { - /* Note the register window save. This tells the unwinder that - it needs to restore the window registers from the previous - frame's window save area at 0(cfa). */ - dwarf2out_window_save (label); - - /* The return address (-8) is now in %i7. */ - dwarf2out_return_reg (label, 31); - } - } } /* Expand the function epilogue, either normal or part of a sibcall. @@ -4651,17 +4659,17 @@ sparc_expand_epilogue (void) else if (sparc_leaf_function_p) { if (actual_fsize <= 4096) - emit_stack_pointer_decrement (GEN_INT (- actual_fsize)); + emit_insn (gen_stack_pointer_dec (GEN_INT (- actual_fsize))); else if (actual_fsize <= 8192) { - emit_stack_pointer_decrement (GEN_INT (-4096)); - emit_stack_pointer_decrement (GEN_INT (4096 - actual_fsize)); + emit_insn (gen_stack_pointer_dec (GEN_INT (-4096))); + emit_insn (gen_stack_pointer_dec (GEN_INT (4096 - actual_fsize))); } else { rtx reg = gen_rtx_REG (Pmode, 1); emit_move_insn (reg, GEN_INT (-actual_fsize)); - emit_stack_pointer_decrement (reg); + emit_insn (gen_stack_pointer_dec (reg)); } } } @@ -8886,11 +8894,11 @@ emit_and_preserve (rtx seq, rtx reg) rtx slot = gen_rtx_MEM (word_mode, plus_constant (stack_pointer_rtx, SPARC_STACK_BIAS)); - emit_stack_pointer_decrement (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)); + emit_insn (gen_stack_pointer_dec (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT))); emit_insn (gen_rtx_SET (VOIDmode, slot, reg)); emit_insn (seq); emit_insn (gen_rtx_SET (VOIDmode, reg, slot)); - emit_stack_pointer_increment (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)); + emit_insn (gen_stack_pointer_inc (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT))); } /* Output the assembler code for a thunk function. THUNK_DECL is the @@ -9153,6 +9161,18 @@ 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 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 5e5e1f654fb..44879c03024 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -7713,39 +7713,31 @@ DONE; }) -(define_expand "save_register_window" - [(use (match_operand 0 "arith_operand" ""))] - "" -{ - rtvec vec; - - vec = gen_rtvec (2, - gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - gen_rtx_PLUS (Pmode, - hard_frame_pointer_rtx, - operands[0])), - gen_rtx_UNSPEC_VOLATILE (VOIDmode, - gen_rtvec (1, const0_rtx), - UNSPECV_SAVEW)); - - emit_insn (gen_rtx_PARALLEL (VOIDmode, vec)); - DONE; -}) - -(define_insn "*save_register_windowsi" - [(set (reg:SI 14) (plus:SI (reg:SI 30) - (match_operand:SI 0 "arith_operand" "rI"))) - (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)] - "! TARGET_ARCH64" +;; 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_windowdi" + [(set (reg:DI 30) (reg:DI 14)) + (set (reg:DI 14) (unspec_volatile [(reg:DI 14) + (match_operand:DI 0 "arith_operand" "rI")] + UNSPECV_SAVEW)) + (set (reg:DI 31) (reg:DI 15))] + "TARGET_ARCH64" "save\t%%sp, %0, %%sp" [(set_attr "type" "savew")]) -(define_insn "*save_register_windowdi" - [(set (reg:DI 14) (plus:DI (reg:DI 30) - (match_operand:DI 0 "arith_operand" "rI"))) - (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)] - "TARGET_ARCH64" +(define_insn "save_register_windowsi" + [(set (reg:SI 30) (reg:SI 14)) + (set (reg:SI 14) (unspec_volatile [(reg:SI 14) + (match_operand:SI 0 "arith_operand" "rI")] + UNSPECV_SAVEW)) + (set (reg:SI 31) (reg:SI 15))] + "!TARGET_ARCH64" "save\t%%sp, %0, %%sp" [(set_attr "type" "savew")]) |