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:
parent
f5c01f5bde
commit
b11b09048d
17 changed files with 979 additions and 277 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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" } } */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue