invoke.texi (SPARC options): Add -mflat.

gcc/
	* doc/invoke.texi (SPARC options): Add -mflat.
	* config/sparc/sparc.opt: Likewise.
	* config/sparc/sparc-protos.h (sparc_expand_epilogue): Add parameter.
	(sparc_flat_expand_prologue): Declare.
	(sparc_flat_expand_epilogue): Likewise.
	* config/sparc/sparc.h (CPP_CPU_SPEC): Do not handle -msoft-float.
	(CPP_ENDIAN_SPEC): Replace with...
	(CPP_OTHER_SPEC): ...this.  Also handle -mflat and -msoft-float.
	(CPP_SPEC): Adjust to above change.
	(EXTRA_SPECS): Likewise.
	(SPARC_INCOMING_INT_ARG_FIRST): Add TARGET_FLAT handling.
	(INCOMING_REGNO): Likewise.
	(OUTGOING_REGNO): Likewise.
	(LOCAL_REGNO): Likewise.
	(SETUP_FRAME_ADDRESSES): Likewise.
	(FIXED_REGISTERS): Set 0 for %fp.
	(CALL_USED_REGISTERS): Likewise.
	(INITIAL_ELIMINATION_OFFSET): Pass current_function_is_leaf.
	(EXIT_IGNORE_STACK): Define to 1 unconditionally.
	(RETURN_ADDR_REGNUM): Define.
	(RETURN_ADDR_RTX): Use it.
	(INCOMING_RETURN_ADDR_REGNUM): Define.
	(INCOMING_RETURN_ADDR_RTX): Use it.
	(DWARF_FRAME_RETURN_COLUMN): Likewise.
	(EH_RETURN_REGNUM): Define.
	(EH_RETURN_STACKADJ_RTX): Use it.
	(EH_RETURN_HANDLER_RTX): Delete.
	(EPILOGUE_USES): Use them and add TARGET_FLAT handling.
	* config/sparc/sparc.c (apparent_fsize, actual_fsize, num_gfregs):
	Delete.
	(struct machine_function): Add frame_size, apparent_frame_size,
	frame_base_reg, frame_base_offset, n_global_fp_regs and
	save_local_in_regs_p fields.
	(sparc_frame_size, sparc_apparent_frame_size, sparc_frame_base_reg,
	sparc_frame_base_offset, sparc_n_global_fp_regs,
	sparc_save_local_in_regs_p): New macros.
	(sparc_option_override): Error out if -fcall-saved-REG is specified
	for Out registers.
	(eligible_for_restore_insn): Fix formatting.
	(eligible_for_return_delay): Likewise.  Add TARGET_FLAT handling.
	(eligible_for_sibcall_delay): Likewise.
	(RTX_OK_FOR_OFFSET_P, RTX_OK_FOR_OLO10_P): Add MODE parameter.
	(sparc_legitimate_address_p): Adjust to above change.
	(save_global_or_fp_reg_p): New predicate.
	(return_addr_reg_needed_p): Likewise.
	(save_local_or_in_reg_p): Likewise.
	(sparc_compute_frame_size): Use them.  Add TARGET_FLAT handling.
	(SORR_SAVE, SORR_RESTORE): Delete.
	(sorr_pred_t): New typedef.
	(sorr_act_t): New enum.
	(save_or_restore_regs): Rename to...
	(emit_save_or_restore_regs): ...this.  Change type of LOW and HIGH
	parameters, remove ACTION parameter, add LEAF_FUNCTION_P, SAVE_P,
	ACTION_TRUE and ACTION_FALSE parameters.  Implement more general
	mechanism.  Add CFI information for double-word saves in 32-bit mode.
	(emit_adjust_base_to_offset): New function extracted from...
	(emit_save_or_restore_regs): ...this.  Rename the rest to...
	(emit_save_or_restore_regs_global_fp_regs): ...this.
	(emit_save_or_restore_regs_local_in_regs): New function.
	(gen_create_flat_frame_[123]): New functions.
	(sparc_expand_prologue): Use SIZE local variable.  Adjust.
	(sparc_flat_expand_prologue): New function.
	(sparc_asm_function_prologue): Add TARGET_FLAT handling.
	(sparc_expand_epilogue): Use SIZE local variable.  Adjust.
	(sparc_flat_expand_epilogue): New function.
	(sparc_can_use_return_insn_p): Add TARGET_FLAT handling.
	(output_return): Likewise.
	(output_sibcall): Likewise.
	(sparc_output_mi_thunk): Likewise.
	(sparc_frame_pointer_required): Likewise.
	(sparc_conditional_register_usage): If TARGET_FLAT, disable the leaf
	function optimization.
	* config/sparc/sparc.md (flat): New attribute.
	(prologue): Add TARGET_FLAT handling.
	(save_register_window): Disable if TARGET_FLAT.
	(create_flat_frame_[123]): New patterns.
	(epilogue): Add TARGET_FLAT handling.
	(sibcall_epilogue): Likewise.
	(eh_return): New expander.
	(eh_return_internal): New insn and splitter.
	(return_internal): Add TARGET_FLAT handling.
	(untyped_return): Remove bogus test and use RETURN_ADDR_REGNUM.
	(save_stack_nonlocal): Use RETURN_ADDR_REGNUM.
	(nonlocal_goto): Add TARGET_FLAT handling.
	* config/sparc/t-elf: Add -mflat multilib.
	* config/sparc/t-leon: Likewise.
libgcc/
	* config/sparc/linux-unwind.h (STACK_BIAS): Define.
	(sparc64_fallback_frame_state): Use it.
	(sparc64_frob_update_context): Further adjust context.
	* config/sparc/sol2-unwind.h (sparc64_frob_update_context): Likewise.
	* config/sparc/sol2-ci.S: Add TARGET_FLAT handling.
	* config/sparc/sol2-cn.S: Likewise.

Co-Authored-By: Laurent Rougé <laurent.rouge@menta.fr>

From-SVN: r174897
This commit is contained in:
Eric Botcazou 2011-06-10 10:50:20 +00:00 committed by Eric Botcazou
parent f5c01f5bde
commit b11b09048d
17 changed files with 979 additions and 277 deletions

View file

@ -1,3 +1,93 @@
2011-06-10 Eric Botcazou <ebotcazou@adacore.com>
Laurent Rougé <laurent.rouge@menta.fr>
* doc/invoke.texi (SPARC options): Add -mflat.
* config/sparc/sparc.opt: Likewise.
* config/sparc/sparc-protos.h (sparc_expand_epilogue): Add parameter.
(sparc_flat_expand_prologue): Declare.
(sparc_flat_expand_epilogue): Likewise.
* config/sparc/sparc.h (CPP_CPU_SPEC): Do not handle -msoft-float.
(CPP_ENDIAN_SPEC): Replace with...
(CPP_OTHER_SPEC): ...this. Also handle -mflat and -msoft-float.
(CPP_SPEC): Adjust to above change.
(EXTRA_SPECS): Likewise.
(SPARC_INCOMING_INT_ARG_FIRST): Add TARGET_FLAT handling.
(INCOMING_REGNO): Likewise.
(OUTGOING_REGNO): Likewise.
(LOCAL_REGNO): Likewise.
(SETUP_FRAME_ADDRESSES): Likewise.
(FIXED_REGISTERS): Set 0 for %fp.
(CALL_USED_REGISTERS): Likewise.
(INITIAL_ELIMINATION_OFFSET): Pass current_function_is_leaf.
(EXIT_IGNORE_STACK): Define to 1 unconditionally.
(RETURN_ADDR_REGNUM): Define.
(RETURN_ADDR_RTX): Use it.
(INCOMING_RETURN_ADDR_REGNUM): Define.
(INCOMING_RETURN_ADDR_RTX): Use it.
(DWARF_FRAME_RETURN_COLUMN): Likewise.
(EH_RETURN_REGNUM): Define.
(EH_RETURN_STACKADJ_RTX): Use it.
(EH_RETURN_HANDLER_RTX): Delete.
(EPILOGUE_USES): Use them and add TARGET_FLAT handling.
* config/sparc/sparc.c (apparent_fsize, actual_fsize, num_gfregs):
Delete.
(struct machine_function): Add frame_size, apparent_frame_size,
frame_base_reg, frame_base_offset, n_global_fp_regs and
save_local_in_regs_p fields.
(sparc_frame_size, sparc_apparent_frame_size, sparc_frame_base_reg,
sparc_frame_base_offset, sparc_n_global_fp_regs,
sparc_save_local_in_regs_p): New macros.
(sparc_option_override): Error out if -fcall-saved-REG is specified
for Out registers.
(eligible_for_restore_insn): Fix formatting.
(eligible_for_return_delay): Likewise. Add TARGET_FLAT handling.
(eligible_for_sibcall_delay): Likewise.
(RTX_OK_FOR_OFFSET_P, RTX_OK_FOR_OLO10_P): Add MODE parameter.
(sparc_legitimate_address_p): Adjust to above change.
(save_global_or_fp_reg_p): New predicate.
(return_addr_reg_needed_p): Likewise.
(save_local_or_in_reg_p): Likewise.
(sparc_compute_frame_size): Use them. Add TARGET_FLAT handling.
(SORR_SAVE, SORR_RESTORE): Delete.
(sorr_pred_t): New typedef.
(sorr_act_t): New enum.
(save_or_restore_regs): Rename to...
(emit_save_or_restore_regs): ...this. Change type of LOW and HIGH
parameters, remove ACTION parameter, add LEAF_FUNCTION_P, SAVE_P,
ACTION_TRUE and ACTION_FALSE parameters. Implement more general
mechanism. Add CFI information for double-word saves in 32-bit mode.
(emit_adjust_base_to_offset): New function extracted from...
(emit_save_or_restore_regs): ...this. Rename the rest to...
(emit_save_or_restore_regs_global_fp_regs): ...this.
(emit_save_or_restore_regs_local_in_regs): New function.
(gen_create_flat_frame_[123]): New functions.
(sparc_expand_prologue): Use SIZE local variable. Adjust.
(sparc_flat_expand_prologue): New function.
(sparc_asm_function_prologue): Add TARGET_FLAT handling.
(sparc_expand_epilogue): Use SIZE local variable. Adjust.
(sparc_flat_expand_epilogue): New function.
(sparc_can_use_return_insn_p): Add TARGET_FLAT handling.
(output_return): Likewise.
(output_sibcall): Likewise.
(sparc_output_mi_thunk): Likewise.
(sparc_frame_pointer_required): Likewise.
(sparc_conditional_register_usage): If TARGET_FLAT, disable the leaf
function optimization.
* config/sparc/sparc.md (flat): New attribute.
(prologue): Add TARGET_FLAT handling.
(save_register_window): Disable if TARGET_FLAT.
(create_flat_frame_[123]): New patterns.
(epilogue): Add TARGET_FLAT handling.
(sibcall_epilogue): Likewise.
(eh_return): New expander.
(eh_return_internal): New insn and splitter.
(return_internal): Add TARGET_FLAT handling.
(untyped_return): Remove bogus test and use RETURN_ADDR_REGNUM.
(save_stack_nonlocal): Use RETURN_ADDR_REGNUM.
(nonlocal_goto): Add TARGET_FLAT handling.
* config/sparc/t-elf: Add -mflat multilib.
* config/sparc/t-leon: Likewise.
2011-06-10 Jan Hubicka <jh@suse.cz>
* ipa-utils.c (searchc): Use cgraph_function_or_thunk_node.

View file

@ -38,7 +38,9 @@ extern enum direction function_arg_padding (enum machine_mode, const_tree);
extern void order_regs_for_local_alloc (void);
extern HOST_WIDE_INT sparc_compute_frame_size (HOST_WIDE_INT, int);
extern void sparc_expand_prologue (void);
extern void sparc_expand_epilogue (void);
extern void sparc_flat_expand_prologue (void);
extern void sparc_expand_epilogue (bool);
extern void sparc_flat_expand_epilogue (bool);
extern bool sparc_can_use_return_insn_p (void);
extern int check_pic (int);
extern int short_branch (int, int);

File diff suppressed because it is too large Load diff

View file

@ -360,7 +360,6 @@ extern enum cmodel sparc_cmodel;
/* Common CPP definitions used by CPP_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#define CPP_CPU_SPEC "\
%{msoft-float:-D_SOFT_FLOAT} \
%{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \
%{mcpu=sparclite:-D__sparclite__} \
%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \
@ -388,14 +387,18 @@ extern enum cmodel sparc_cmodel;
%{!m32:%{!m64:%(cpp_arch_default)}} \
"
/* Macro to distinguish endianness. */
#define CPP_ENDIAN_SPEC "\
%{mlittle-endian:-D__LITTLE_ENDIAN__}"
/* Macros to distinguish the endianness, window model and FP support. */
#define CPP_OTHER_SPEC "\
%{mlittle-endian:-D__LITTLE_ENDIAN__} \
%{mflat:-D_FLAT} \
%{msoft-float:-D_SOFT_FLOAT} \
"
/* Macros to distinguish the particular subtarget. */
#define CPP_SUBTARGET_SPEC ""
#define CPP_SPEC "%(cpp_cpu) %(cpp_arch) %(cpp_endian) %(cpp_subtarget)"
#define CPP_SPEC \
"%(cpp_cpu) %(cpp_arch) %(cpp_endian) %(cpp_other) %(cpp_subtarget)"
/* This used to translate -dalign to -malign, but that is no good
because it can't turn off the usual meaning of making debugging dumps. */
@ -464,7 +467,7 @@ extern enum cmodel sparc_cmodel;
{ "cpp_arch64", CPP_ARCH64_SPEC }, \
{ "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC },\
{ "cpp_arch", CPP_ARCH_SPEC }, \
{ "cpp_endian", CPP_ENDIAN_SPEC }, \
{ "cpp_other", CPP_OTHER_SPEC }, \
{ "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
@ -687,7 +690,7 @@ extern enum cmodel sparc_cmodel;
/* Argument passing regs. */
#define SPARC_OUTGOING_INT_ARG_FIRST 8
#define SPARC_INCOMING_INT_ARG_FIRST 24
#define SPARC_INCOMING_INT_ARG_FIRST (TARGET_FLAT ? 8 : 24)
#define SPARC_FP_ARG_FIRST 32
/* 1 for registers that have pervasive standard uses
@ -721,7 +724,7 @@ extern enum cmodel sparc_cmodel;
{1, 0, 2, 2, 2, 2, 1, 1, \
0, 0, 0, 0, 0, 0, 1, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 1, \
\
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
@ -746,7 +749,7 @@ extern enum cmodel sparc_cmodel;
{1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 1, \
\
1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
@ -1223,13 +1226,11 @@ extern char leaf_reg_remap[];
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
/* We always pretend that this is a leaf function because if it's not,
there's no point in trying to eliminate the frame pointer. If it
is a leaf function, we guessed right! */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \
if ((TO) == STACK_POINTER_REGNUM) \
(OFFSET) = sparc_compute_frame_size (get_frame_size (), 1); \
(OFFSET) = sparc_compute_frame_size (get_frame_size (), \
current_function_is_leaf); \
else \
(OFFSET) = 0; \
(OFFSET) += SPARC_STACK_BIAS; \
@ -1247,7 +1248,7 @@ extern char leaf_reg_remap[];
Return OUT if register number OUT is not an outbound register. */
#define INCOMING_REGNO(OUT) \
(((OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16)
((TARGET_FLAT || (OUT) < 8 || (OUT) > 15) ? (OUT) : (OUT) + 16)
/* Define this macro if the target machine has "register windows". This
C expression returns the register number as seen by the calling function
@ -1255,14 +1256,14 @@ extern char leaf_reg_remap[];
Return IN if register number IN is not an inbound register. */
#define OUTGOING_REGNO(IN) \
(((IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)
((TARGET_FLAT || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)
/* Define this macro if the target machine has register windows. This
C expression returns true if the register is call-saved but is in the
register window. */
#define LOCAL_REGNO(REGNO) \
((REGNO) >= 16 && (REGNO) <= 31)
(!TARGET_FLAT && (REGNO) >= 16 && (REGNO) <= 31)
/* Define the size of space to allocate for the return value of an
untyped_call. */
@ -1373,35 +1374,27 @@ do { \
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers.
No definition is equivalent to always zero. */
functions that have frame pointers. */
#define EXIT_IGNORE_STACK 1
#define EXIT_IGNORE_STACK \
(get_frame_size () != 0 \
|| cfun->calls_alloca || crtl->outgoing_args_size)
/* Define registers used by the epilogue and return instruction. */
#define EPILOGUE_USES(REGNO) ((REGNO) == 31 \
|| (crtl->calls_eh_return && (REGNO) == 1))
/* We need 2 words, so we can save the stack pointer and the return register
of the function containing a non-local goto target. */
#define STACK_SAVEAREA_MODE(LEVEL) \
((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode)
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
/* Alignment required for trampolines, in bits. */
#define TRAMPOLINE_ALIGNMENT 128
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
#define SETUP_FRAME_ADDRESSES() \
emit_insn (gen_flush_register_windows ())
#define SETUP_FRAME_ADDRESSES() \
do { \
if (!TARGET_FLAT) \
emit_insn (gen_flush_register_windows ());\
} while (0)
/* Given an rtx for the address of a frame,
return an rtx for the address of the word in the frame
@ -1428,9 +1421,10 @@ do { \
farther back is in the register window save area at [%fp+60]. */
/* ??? This ignores the fact that the actual return address is +8 for normal
returns, and +12 for structure returns. */
#define RETURN_ADDR_REGNUM 31
#define RETURN_ADDR_RTX(count, frame) \
((count == -1) \
? gen_rtx_REG (Pmode, 31) \
? gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM) \
: gen_rtx_MEM (Pmode, \
memory_address (Pmode, plus_constant (frame, \
15 * UNITS_PER_WORD \
@ -1440,9 +1434,11 @@ do { \
+12, but always using +8 is close enough for frame unwind purposes.
Actually, just using %o7 is close enough for unwinding, but %o7+8
is something you can return to. */
#define INCOMING_RETURN_ADDR_REGNUM 15
#define INCOMING_RETURN_ADDR_RTX \
plus_constant (gen_rtx_REG (word_mode, 15), 8)
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (15)
plus_constant (gen_rtx_REG (word_mode, INCOMING_RETURN_ADDR_REGNUM), 8)
#define DWARF_FRAME_RETURN_COLUMN \
DWARF_FRAME_REGNUM (INCOMING_RETURN_ADDR_REGNUM)
/* The offset from the incoming value of %sp to the top of the stack frame
for the current function. On sparc64, we have to account for the stack
@ -1450,9 +1446,17 @@ do { \
#define INCOMING_FRAME_SP_OFFSET SPARC_STACK_BIAS
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_REGNUM 1
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 1) /* %g1 */
#define EH_RETURN_HANDLER_RTX gen_rtx_REG (Pmode, 31) /* %i7 */
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_REGNUM)
/* Define registers used by the epilogue and return instruction. */
#define EPILOGUE_USES(REGNO) \
((REGNO) == RETURN_ADDR_REGNUM \
|| (TARGET_FLAT \
&& epilogue_completed \
&& (REGNO) == INCOMING_RETURN_ADDR_REGNUM) \
|| (crtl->calls_eh_return && (REGNO) == EH_RETURN_REGNUM))
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is

View file

@ -164,7 +164,7 @@
(define_attr "calls_eh_return" "false,true"
(symbol_ref "(crtl->calls_eh_return != 0
? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
(define_attr "leaf_function" "false,true"
(symbol_ref "(current_function_uses_only_leaf_regs != 0
? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
@ -173,6 +173,10 @@
(symbol_ref "(flag_delayed_branch != 0
? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
(define_attr "flat" "false,true"
(symbol_ref "(TARGET_FLAT != 0
? FLAT_TRUE : FLAT_FALSE)"))
;; Length (in # of insns).
;; Beware that setting a length greater or equal to 3 for conditional branches
;; has a side-effect (see output_cbranch and output_v9branch).
@ -6265,7 +6269,10 @@
[(const_int 0)]
""
{
sparc_expand_prologue ();
if (TARGET_FLAT)
sparc_flat_expand_prologue ();
else
sparc_expand_prologue ();
DONE;
})
@ -6282,25 +6289,87 @@
(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))]
""
"!TARGET_FLAT"
"save\t%%sp, %0, %%sp"
[(set_attr "type" "savew")])
;; Likewise 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.
(define_insn "create_flat_frame_1<P:mode>"
[(set (reg:P 30) (reg:P 14))
(set (reg:P 14) (plus:P (reg:P 14)
(match_operand:P 0 "arith_operand" "rI")))
(set (reg:P 31) (reg:P 15))]
"TARGET_FLAT"
"add\t%%sp, %0, %%sp\n\tsub\t%%sp, %0, %%fp\n\tmov\t%%o7, %%i7"
[(set_attr "type" "multi")
(set_attr "length" "3")])
(define_insn "create_flat_frame_2<P:mode>"
[(set (reg:P 30) (reg:P 14))
(set (reg:P 14) (plus:P (reg:P 14)
(match_operand:P 0 "arith_operand" "rI")))]
"TARGET_FLAT"
"add\t%%sp, %0, %%sp\n\tsub\t%%sp, %0, %%fp"
[(set_attr "type" "multi")
(set_attr "length" "2")])
(define_insn "create_flat_frame_3<P:mode>"
[(set (reg:P 14) (plus:P (reg:P 14)
(match_operand:P 0 "arith_operand" "rI")))
(set (reg:P 31) (reg:P 15))]
"TARGET_FLAT"
"add\t%%sp, %0, %%sp\n\tmov\t%%o7, %%i7"
[(set_attr "type" "multi")
(set_attr "length" "2")])
(define_expand "epilogue"
[(return)]
""
{
sparc_expand_epilogue ();
if (TARGET_FLAT)
sparc_flat_expand_epilogue (false);
else
sparc_expand_epilogue (false);
})
(define_expand "sibcall_epilogue"
[(return)]
""
{
sparc_expand_epilogue ();
if (TARGET_FLAT)
sparc_flat_expand_epilogue (false);
else
sparc_expand_epilogue (false);
DONE;
})
(define_expand "eh_return"
[(use (match_operand 0 "general_operand" ""))]
""
{
emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
emit_jump_insn (gen_eh_return_internal ());
emit_barrier ();
DONE;
})
(define_insn_and_split "eh_return_internal"
[(eh_return)]
""
"#"
"epilogue_completed"
[(return)]
{
if (TARGET_FLAT)
sparc_flat_expand_epilogue (true);
else
sparc_expand_epilogue (true);
})
(define_expand "return"
[(return)]
"sparc_can_use_return_insn_p ()"
@ -6312,16 +6381,19 @@
"* return output_return (insn);"
[(set_attr "type" "return")
(set (attr "length")
(cond [(eq_attr "leaf_function" "true")
(cond [(eq_attr "calls_eh_return" "true")
(if_then_else (eq_attr "delayed_branch" "true")
(if_then_else (ior (eq_attr "isa" "v9")
(eq_attr "flat" "true"))
(const_int 2)
(const_int 3))
(if_then_else (eq_attr "flat" "true")
(const_int 3)
(const_int 4)))
(ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
(if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2)
(const_int 1))
(eq_attr "calls_eh_return" "true")
(if_then_else (eq_attr "delayed_branch" "true")
(if_then_else (eq_attr "isa" "v9")
(const_int 2)
(const_int 3))
(const_int 4))
(eq_attr "empty_delay_slot" "true")
(if_then_else (eq_attr "delayed_branch" "true")
(const_int 2)
@ -6367,8 +6439,7 @@
if (! TARGET_ARCH64)
{
rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
? 15 : 31));
rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
rtx value = gen_reg_rtx (SImode);
/* Fetch the instruction where we will return to and see if it's an unimp
@ -6449,7 +6520,7 @@
{
operands[0] = adjust_address_nv (operands[0], Pmode, 0);
operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
operands[3] = gen_rtx_REG (Pmode, 31); /* %i7 */
operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
})
(define_expand "restore_stack_nonlocal"
@ -6474,7 +6545,8 @@
/* We need to flush all the register windows so that their contents will
be re-synchronized by the restore insn of the target function. */
emit_insn (gen_flush_register_windows ());
if (!TARGET_FLAT)
emit_insn (gen_flush_register_windows ());
emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));

View file

@ -33,6 +33,10 @@ msoft-float
Target RejectNegative InverseMask(FPU)
Do not use hardware FP
mflat
Target Report Mask(FLAT)
Use flat register window model
munaligned-doubles
Target Report Mask(UNALIGNED_DOUBLES)
Assume possible double misalignment

View file

@ -32,8 +32,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
MULTILIB_OPTIONS = msoft-float mcpu=v8
MULTILIB_DIRNAMES = soft v8
MULTILIB_OPTIONS = msoft-float mcpu=v8 mflat
MULTILIB_DIRNAMES = soft v8 flat
MULTILIB_MATCHES = msoft-float=mno-fpu
LIBGCC = stmp-multilib

View file

@ -34,8 +34,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
# Multilibs for LEON
# LEON is a SPARC-V8, but the AT697 implementation has a bug in the
# V8-specific instructions.
MULTILIB_OPTIONS = mcpu=v7 msoft-float
MULTILIB_DIRNAMES = v7 soft
MULTILIB_OPTIONS = mcpu=v7 msoft-float mflat
MULTILIB_DIRNAMES = v7 soft flat
MULTILIB_MATCHES = mcpu?v7=mv7 msoft-float=mno-fpu
LIBGCC = stmp-multilib

View file

@ -863,7 +863,7 @@ See RS/6000 and PowerPC Options.
-mtune=@var{cpu-type} @gol
-mcmodel=@var{code-model} @gol
-m32 -m64 -mapp-regs -mno-app-regs @gol
-mfaster-structs -mno-faster-structs @gol
-mfaster-structs -mno-faster-structs -mflat -mno-flat @gol
-mfpu -mno-fpu -mhard-float -msoft-float @gol
-mhard-quad-float -msoft-quad-float @gol
-mlittle-endian @gol
@ -17043,6 +17043,19 @@ To be fully SVR4 ABI compliant at the cost of some performance loss,
specify @option{-mno-app-regs}. You should compile libraries and system
software with this option.
@item -mflat
@itemx -mno-flat
@opindex mflat
@opindex mno-flat
With @option{-mflat}, the compiler does not generate save/restore instructions
and uses a ``flat'' or single register window model. This model is compatible
with the regular register window model. The local registers and the input
registers (0--5) are still treated as ``call-saved'' registers and will be
saved on the stack as needed.
With @option{-mno-flat} (the default), the compiler generates save/restore
instructions (except for leaf functions). This is the normal operating mode.
@item -mfpu
@itemx -mhard-float
@opindex mfpu

View file

@ -1,3 +1,9 @@
2011-06-10 Eric Botcazou <ebotcazou@adacore.com>
Laurent Rougé <laurent.rouge@menta.fr>
* gcc.dg/20020503-1.c: Add back -mflat option on the SPARC.
* gcc.target/sparc/sparc-ret.c: Skip if -mflat is passed.
2011-06-10 Daniel Carrera <dcarrera@gmail.com>
* gfortran.dg/coarray/sync_1.f90: New test for

View file

@ -4,7 +4,7 @@
for leaf functions, the function was still leaf, but LEAF_REG_REMAP
returned -1 for some registers (like %o0). */
/* { dg-do compile } */
/* { dg-options "-O2 -g" } */
/* { dg-options "-O2 -g -mflat" { target sparc*-*-* } } */
void foo (char *a, char *b, char *c, char *d)
{

View file

@ -1,4 +1,5 @@
/* { dg-do compile } */
/* { dg-skip-if "no register windows" { *-*-* } { "-mflat" } { "" } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mcpu=ultrasparc -O" } */
@ -11,7 +12,7 @@ int bar (int a, int b, int c, int d, int e, int f, int g, int h)
toto (&res);
return h;
}
/* { dg-final { global compiler_flags; if ![string match "*-m64 *" $compiler_flags] { scan-assembler "return\[ \t\]*%i7\\+8\n\[^\n\]*ld\[ \t\]*\\\[%sp\\+96\\\]" } } } */
/* { dg-final { scan-assembler "return\[ \t\]*%i7\\+8\n\[^\n\]*ld\[ \t\]*\\\[%sp\\+96\\\]" } } */
int bar2 ()
{
@ -20,4 +21,4 @@ int bar2 ()
toto (&res);
return res;
}
/* { dg-final { global compiler_flags; if ![string match "*-m64 *" $compiler_flags] { scan-assembler "return\[ \t\]*%i7\\+8\n\[^\n\]*nop" } } } */
/* { dg-final { scan-assembler "return\[ \t\]*%i7\\+8\n\[^\n\]*nop" } } */

View file

@ -1,3 +1,12 @@
2011-06-10 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/linux-unwind.h (STACK_BIAS): Define.
(sparc64_fallback_frame_state): Use it.
(sparc64_frob_update_context): Further adjust context.
* config/sparc/sol2-unwind.h (sparc64_frob_update_context): Likewise.
* config/sparc/sol2-ci.S: Add TARGET_FLAT handling.
* config/sparc/sol2-cn.S: Likewise.
2011-06-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* enable-execute-stack-empty.c: New file.

View file

@ -27,6 +27,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(__arch64__)
#undef STACK_BIAS
#define STACK_BIAS 2047
/* 64-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
@ -49,7 +52,8 @@ sparc64_fallback_frame_state (struct _Unwind_Context *context,
fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
new_cfa = *(long *)(this_cfa + regs_off + (14 * 8));
new_cfa += 2047; /* Stack bias */
/* The frame address is %sp + STACK_BIAS in 64-bit mode. */
new_cfa += STACK_BIAS;
fpu_save = *(long *)(this_cfa + fpu_save_off);
fs->regs.cfa_how = CFA_REG_OFFSET;
fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
@ -112,7 +116,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
&& fs->regs.cfa_how == CFA_REG_OFFSET
&& fs->regs.cfa_offset != 0
&& !fs->signal_frame)
context->cfa -= 2047;
{
long i;
context->cfa -= STACK_BIAS;
for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
if (fs->regs.reg[i].how == REG_SAVED_OFFSET)
_Unwind_SetGRPtr (context, i,
_Unwind_GetGRPtr (context, i) - STACK_BIAS);
}
}
#else

View file

@ -1,6 +1,6 @@
! crti.s for solaris 2.0.
! Copyright (C) 1992, 2008, 2009 Free Software Foundation, Inc.
! Copyright (C) 1992, 2008, 2009, 2011 Free Software Foundation, Inc.
! Written By David Vinayak Henkel-Wallace, June 1992
!
! This file is free software; you can redistribute it and/or modify it
@ -35,11 +35,22 @@
.type _init,#function
.align 4
_init:
#ifdef _FLAT
#ifdef __sparcv9
stx %i7, [%sp+2167]
add %sp, -176, %sp
#else
st %i7, [%sp+60]
add %sp, -96, %sp
#endif
mov %o7, %i7
#else
#ifdef __sparcv9
save %sp, -176, %sp
#else
save %sp, -96, %sp
#endif
#endif
.section ".fini"
@ -48,8 +59,19 @@ _init:
.type _fini,#function
.align 4
_fini:
#ifdef _FLAT
#ifdef __sparcv9
stx %i7, [%sp+2167]
add %sp, -176, %sp
#else
st %i7, [%sp+60]
add %sp, -96, %sp
#endif
mov %o7, %i7
#else
#ifdef __sparcv9
save %sp, -176, %sp
#else
save %sp, -96, %sp
#endif
#endif

View file

@ -1,6 +1,6 @@
! crtn.s for solaris 2.0.
! Copyright (C) 1992, 2008, 2009 Free Software Foundation, Inc.
! Copyright (C) 1992, 2008, 2009, 2011 Free Software Foundation, Inc.
! Written By David Vinayak Henkel-Wallace, June 1992
!
! This file is free software; you can redistribute it and/or modify it
@ -28,14 +28,36 @@
.section ".init"
.align 4
ret
#ifdef _FLAT
mov %i7, %o7
#ifdef __sparcv9
ldx [%sp+2343], %i7
sub %sp, -176, %sp
#else
ld [%sp+156], %i7
sub %sp, -96, %sp
#endif
#else
restore
#endif
jmp %o7+8
nop
.section ".fini"
.align 4
ret
#ifdef _FLAT
mov %i7, %o7
#ifdef __sparcv9
ldx [%sp+2343], %i7
sub %sp, -176, %sp
#else
ld [%sp+156], %i7
sub %sp, -96, %sp
#endif
#else
restore
#endif
jmp %o7+8
nop
! Th-th-th-that is all folks!

View file

@ -164,7 +164,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
&& fs->regs.cfa_how == CFA_REG_OFFSET
&& fs->regs.cfa_offset != 0
&& !fs->signal_frame)
context->cfa -= STACK_BIAS;
{
long i;
context->cfa -= STACK_BIAS;
for (i = 0; i < DWARF_FRAME_REGISTERS + 1; ++i)
if (fs->regs.reg[i].how == REG_SAVED_OFFSET)
_Unwind_SetGRPtr (context, i,
_Unwind_GetGRPtr (context, i) - STACK_BIAS);
}
}
#else