Commit b11b0904 by Eric Botcazou Committed by Eric Botcazou

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
parent f5c01f5b
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> 2011-06-10 Jan Hubicka <jh@suse.cz>
* ipa-utils.c (searchc): Use cgraph_function_or_thunk_node. * 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); ...@@ -38,7 +38,9 @@ extern enum direction function_arg_padding (enum machine_mode, const_tree);
extern void order_regs_for_local_alloc (void); extern void order_regs_for_local_alloc (void);
extern HOST_WIDE_INT sparc_compute_frame_size (HOST_WIDE_INT, int); extern HOST_WIDE_INT sparc_compute_frame_size (HOST_WIDE_INT, int);
extern void sparc_expand_prologue (void); 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 bool sparc_can_use_return_insn_p (void);
extern int check_pic (int); extern int check_pic (int);
extern int short_branch (int, int); extern int short_branch (int, int);
......
...@@ -360,7 +360,6 @@ extern enum cmodel sparc_cmodel; ...@@ -360,7 +360,6 @@ extern enum cmodel sparc_cmodel;
/* Common CPP definitions used by CPP_SPEC amongst the various targets /* Common CPP definitions used by CPP_SPEC amongst the various targets
for handling -mcpu=xxx switches. */ for handling -mcpu=xxx switches. */
#define CPP_CPU_SPEC "\ #define CPP_CPU_SPEC "\
%{msoft-float:-D_SOFT_FLOAT} \
%{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \ %{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \
%{mcpu=sparclite:-D__sparclite__} \ %{mcpu=sparclite:-D__sparclite__} \
%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \ %{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \
...@@ -388,14 +387,18 @@ extern enum cmodel sparc_cmodel; ...@@ -388,14 +387,18 @@ extern enum cmodel sparc_cmodel;
%{!m32:%{!m64:%(cpp_arch_default)}} \ %{!m32:%{!m64:%(cpp_arch_default)}} \
" "
/* Macro to distinguish endianness. */ /* Macros to distinguish the endianness, window model and FP support. */
#define CPP_ENDIAN_SPEC "\ #define CPP_OTHER_SPEC "\
%{mlittle-endian:-D__LITTLE_ENDIAN__}" %{mlittle-endian:-D__LITTLE_ENDIAN__} \
%{mflat:-D_FLAT} \
%{msoft-float:-D_SOFT_FLOAT} \
"
/* Macros to distinguish the particular subtarget. */ /* Macros to distinguish the particular subtarget. */
#define CPP_SUBTARGET_SPEC "" #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 /* 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. */ because it can't turn off the usual meaning of making debugging dumps. */
...@@ -464,7 +467,7 @@ extern enum cmodel sparc_cmodel; ...@@ -464,7 +467,7 @@ extern enum cmodel sparc_cmodel;
{ "cpp_arch64", CPP_ARCH64_SPEC }, \ { "cpp_arch64", CPP_ARCH64_SPEC }, \
{ "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC },\ { "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC },\
{ "cpp_arch", CPP_ARCH_SPEC }, \ { "cpp_arch", CPP_ARCH_SPEC }, \
{ "cpp_endian", CPP_ENDIAN_SPEC }, \ { "cpp_other", CPP_OTHER_SPEC }, \
{ "cpp_subtarget", CPP_SUBTARGET_SPEC }, \ { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \ { "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \ { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
...@@ -687,7 +690,7 @@ extern enum cmodel sparc_cmodel; ...@@ -687,7 +690,7 @@ extern enum cmodel sparc_cmodel;
/* Argument passing regs. */ /* Argument passing regs. */
#define SPARC_OUTGOING_INT_ARG_FIRST 8 #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 #define SPARC_FP_ARG_FIRST 32
/* 1 for registers that have pervasive standard uses /* 1 for registers that have pervasive standard uses
...@@ -721,7 +724,7 @@ extern enum cmodel sparc_cmodel; ...@@ -721,7 +724,7 @@ extern enum cmodel sparc_cmodel;
{1, 0, 2, 2, 2, 2, 1, 1, \ {1, 0, 2, 2, 2, 2, 1, 1, \
0, 0, 0, 0, 0, 0, 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, 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, \
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; ...@@ -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, \
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, 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, \
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[]; ...@@ -1223,13 +1226,11 @@ extern char leaf_reg_remap[];
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_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) \ #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \ do { \
if ((TO) == STACK_POINTER_REGNUM) \ 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 \ else \
(OFFSET) = 0; \ (OFFSET) = 0; \
(OFFSET) += SPARC_STACK_BIAS; \ (OFFSET) += SPARC_STACK_BIAS; \
...@@ -1247,7 +1248,7 @@ extern char leaf_reg_remap[]; ...@@ -1247,7 +1248,7 @@ extern char leaf_reg_remap[];
Return OUT if register number OUT is not an outbound register. */ Return OUT if register number OUT is not an outbound register. */
#define INCOMING_REGNO(OUT) \ #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 /* Define this macro if the target machine has "register windows". This
C expression returns the register number as seen by the calling function C expression returns the register number as seen by the calling function
...@@ -1255,14 +1256,14 @@ extern char leaf_reg_remap[]; ...@@ -1255,14 +1256,14 @@ extern char leaf_reg_remap[];
Return IN if register number IN is not an inbound register. */ Return IN if register number IN is not an inbound register. */
#define OUTGOING_REGNO(IN) \ #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 /* 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 C expression returns true if the register is call-saved but is in the
register window. */ register window. */
#define LOCAL_REGNO(REGNO) \ #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 /* Define the size of space to allocate for the return value of an
untyped_call. */ untyped_call. */
...@@ -1373,35 +1374,27 @@ do { \ ...@@ -1373,35 +1374,27 @@ do { \
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in the stack pointer does not matter. The value is tested only in
functions that have frame pointers. functions that have frame pointers. */
No definition is equivalent to always zero. */ #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 /* We need 2 words, so we can save the stack pointer and the return register
of the function containing a non-local goto target. */ of the function containing a non-local goto target. */
#define STACK_SAVEAREA_MODE(LEVEL) \ #define STACK_SAVEAREA_MODE(LEVEL) \
((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode) ((LEVEL) == SAVE_NONLOCAL ? (TARGET_ARCH64 ? TImode : DImode) : Pmode)
/* Length in units of the trampoline for entering a nested function. */ /* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16) #define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
/* Alignment required for trampolines, in bits. */ /* Alignment required for trampolines, in bits. */
#define TRAMPOLINE_ALIGNMENT 128 #define TRAMPOLINE_ALIGNMENT 128
/* Generate RTL to flush the register windows so as to make arbitrary frames /* Generate RTL to flush the register windows so as to make arbitrary frames
available. */ available. */
#define SETUP_FRAME_ADDRESSES() \ #define SETUP_FRAME_ADDRESSES() \
emit_insn (gen_flush_register_windows ()) do { \
if (!TARGET_FLAT) \
emit_insn (gen_flush_register_windows ());\
} while (0)
/* Given an rtx for the address of a frame, /* Given an rtx for the address of a frame,
return an rtx for the address of the word in the frame return an rtx for the address of the word in the frame
...@@ -1428,9 +1421,10 @@ do { \ ...@@ -1428,9 +1421,10 @@ do { \
farther back is in the register window save area at [%fp+60]. */ 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 /* ??? This ignores the fact that the actual return address is +8 for normal
returns, and +12 for structure returns. */ returns, and +12 for structure returns. */
#define RETURN_ADDR_REGNUM 31
#define RETURN_ADDR_RTX(count, frame) \ #define RETURN_ADDR_RTX(count, frame) \
((count == -1) \ ((count == -1) \
? gen_rtx_REG (Pmode, 31) \ ? gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM) \
: gen_rtx_MEM (Pmode, \ : gen_rtx_MEM (Pmode, \
memory_address (Pmode, plus_constant (frame, \ memory_address (Pmode, plus_constant (frame, \
15 * UNITS_PER_WORD \ 15 * UNITS_PER_WORD \
...@@ -1440,9 +1434,11 @@ do { \ ...@@ -1440,9 +1434,11 @@ do { \
+12, but always using +8 is close enough for frame unwind purposes. +12, but always using +8 is close enough for frame unwind purposes.
Actually, just using %o7 is close enough for unwinding, but %o7+8 Actually, just using %o7 is close enough for unwinding, but %o7+8
is something you can return to. */ is something you can return to. */
#define INCOMING_RETURN_ADDR_REGNUM 15
#define INCOMING_RETURN_ADDR_RTX \ #define INCOMING_RETURN_ADDR_RTX \
plus_constant (gen_rtx_REG (word_mode, 15), 8) plus_constant (gen_rtx_REG (word_mode, INCOMING_RETURN_ADDR_REGNUM), 8)
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (15) #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 /* 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 for the current function. On sparc64, we have to account for the stack
...@@ -1450,9 +1446,17 @@ do { \ ...@@ -1450,9 +1446,17 @@ do { \
#define INCOMING_FRAME_SP_OFFSET SPARC_STACK_BIAS #define INCOMING_FRAME_SP_OFFSET SPARC_STACK_BIAS
/* Describe how we implement __builtin_eh_return. */ /* 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_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 1) /* %g1 */ #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, EH_RETURN_REGNUM)
#define EH_RETURN_HANDLER_RTX gen_rtx_REG (Pmode, 31) /* %i7 */
/* 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 /* 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 is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
......
...@@ -164,7 +164,7 @@ ...@@ -164,7 +164,7 @@
(define_attr "calls_eh_return" "false,true" (define_attr "calls_eh_return" "false,true"
(symbol_ref "(crtl->calls_eh_return != 0 (symbol_ref "(crtl->calls_eh_return != 0
? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
(define_attr "leaf_function" "false,true" (define_attr "leaf_function" "false,true"
(symbol_ref "(current_function_uses_only_leaf_regs != 0 (symbol_ref "(current_function_uses_only_leaf_regs != 0
? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
...@@ -173,6 +173,10 @@ ...@@ -173,6 +173,10 @@
(symbol_ref "(flag_delayed_branch != 0 (symbol_ref "(flag_delayed_branch != 0
? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
(define_attr "flat" "false,true"
(symbol_ref "(TARGET_FLAT != 0
? FLAT_TRUE : FLAT_FALSE)"))
;; Length (in # of insns). ;; Length (in # of insns).
;; Beware that setting a length greater or equal to 3 for conditional branches ;; Beware that setting a length greater or equal to 3 for conditional branches
;; has a side-effect (see output_cbranch and output_v9branch). ;; has a side-effect (see output_cbranch and output_v9branch).
...@@ -6265,7 +6269,10 @@ ...@@ -6265,7 +6269,10 @@
[(const_int 0)] [(const_int 0)]
"" ""
{ {
sparc_expand_prologue (); if (TARGET_FLAT)
sparc_flat_expand_prologue ();
else
sparc_expand_prologue ();
DONE; DONE;
}) })
...@@ -6282,25 +6289,87 @@ ...@@ -6282,25 +6289,87 @@
(set (reg:P 14) (unspec_volatile:P [(reg:P 14) (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
(match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW)) (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
(set (reg:P 31) (reg:P 15))] (set (reg:P 31) (reg:P 15))]
"" "!TARGET_FLAT"
"save\t%%sp, %0, %%sp" "save\t%%sp, %0, %%sp"
[(set_attr "type" "savew")]) [(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" (define_expand "epilogue"
[(return)] [(return)]
"" ""
{ {
sparc_expand_epilogue (); if (TARGET_FLAT)
sparc_flat_expand_epilogue (false);
else
sparc_expand_epilogue (false);
}) })
(define_expand "sibcall_epilogue" (define_expand "sibcall_epilogue"
[(return)] [(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; 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" (define_expand "return"
[(return)] [(return)]
"sparc_can_use_return_insn_p ()" "sparc_can_use_return_insn_p ()"
...@@ -6312,16 +6381,19 @@ ...@@ -6312,16 +6381,19 @@
"* return output_return (insn);" "* return output_return (insn);"
[(set_attr "type" "return") [(set_attr "type" "return")
(set (attr "length") (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") (if_then_else (eq_attr "empty_delay_slot" "true")
(const_int 2) (const_int 2)
(const_int 1)) (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") (eq_attr "empty_delay_slot" "true")
(if_then_else (eq_attr "delayed_branch" "true") (if_then_else (eq_attr "delayed_branch" "true")
(const_int 2) (const_int 2)
...@@ -6367,8 +6439,7 @@ ...@@ -6367,8 +6439,7 @@
if (! TARGET_ARCH64) if (! TARGET_ARCH64)
{ {
rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
? 15 : 31));
rtx value = gen_reg_rtx (SImode); rtx value = gen_reg_rtx (SImode);
/* Fetch the instruction where we will return to and see if it's an unimp /* Fetch the instruction where we will return to and see if it's an unimp
...@@ -6449,7 +6520,7 @@ ...@@ -6449,7 +6520,7 @@
{ {
operands[0] = adjust_address_nv (operands[0], Pmode, 0); operands[0] = adjust_address_nv (operands[0], Pmode, 0);
operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode)); 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" (define_expand "restore_stack_nonlocal"
...@@ -6474,7 +6545,8 @@ ...@@ -6474,7 +6545,8 @@
/* We need to flush all the register windows so that their contents will /* We need to flush all the register windows so that their contents will
be re-synchronized by the restore insn of the target function. */ 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, gen_rtx_SCRATCH (VOIDmode)));
emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
......
...@@ -33,6 +33,10 @@ msoft-float ...@@ -33,6 +33,10 @@ msoft-float
Target RejectNegative InverseMask(FPU) Target RejectNegative InverseMask(FPU)
Do not use hardware FP Do not use hardware FP
mflat
Target Report Mask(FLAT)
Use flat register window model
munaligned-doubles munaligned-doubles
Target Report Mask(UNALIGNED_DOUBLES) Target Report Mask(UNALIGNED_DOUBLES)
Assume possible double misalignment Assume possible double misalignment
......
...@@ -32,8 +32,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -32,8 +32,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c
MULTILIB_OPTIONS = msoft-float mcpu=v8 MULTILIB_OPTIONS = msoft-float mcpu=v8 mflat
MULTILIB_DIRNAMES = soft v8 MULTILIB_DIRNAMES = soft v8 flat
MULTILIB_MATCHES = msoft-float=mno-fpu MULTILIB_MATCHES = msoft-float=mno-fpu
LIBGCC = stmp-multilib LIBGCC = stmp-multilib
......
...@@ -34,8 +34,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -34,8 +34,8 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
# Multilibs for LEON # Multilibs for LEON
# LEON is a SPARC-V8, but the AT697 implementation has a bug in the # LEON is a SPARC-V8, but the AT697 implementation has a bug in the
# V8-specific instructions. # V8-specific instructions.
MULTILIB_OPTIONS = mcpu=v7 msoft-float MULTILIB_OPTIONS = mcpu=v7 msoft-float mflat
MULTILIB_DIRNAMES = v7 soft MULTILIB_DIRNAMES = v7 soft flat
MULTILIB_MATCHES = mcpu?v7=mv7 msoft-float=mno-fpu MULTILIB_MATCHES = mcpu?v7=mv7 msoft-float=mno-fpu
LIBGCC = stmp-multilib LIBGCC = stmp-multilib
......
...@@ -863,7 +863,7 @@ See RS/6000 and PowerPC Options. ...@@ -863,7 +863,7 @@ See RS/6000 and PowerPC Options.
-mtune=@var{cpu-type} @gol -mtune=@var{cpu-type} @gol
-mcmodel=@var{code-model} @gol -mcmodel=@var{code-model} @gol
-m32 -m64 -mapp-regs -mno-app-regs @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 -mfpu -mno-fpu -mhard-float -msoft-float @gol
-mhard-quad-float -msoft-quad-float @gol -mhard-quad-float -msoft-quad-float @gol
-mlittle-endian @gol -mlittle-endian @gol
...@@ -17043,6 +17043,19 @@ To be fully SVR4 ABI compliant at the cost of some performance loss, ...@@ -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 specify @option{-mno-app-regs}. You should compile libraries and system
software with this option. 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 @item -mfpu
@itemx -mhard-float @itemx -mhard-float
@opindex mfpu @opindex mfpu
......
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> 2011-06-10 Daniel Carrera <dcarrera@gmail.com>
* gfortran.dg/coarray/sync_1.f90: New test for * gfortran.dg/coarray/sync_1.f90: New test for
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
for leaf functions, the function was still leaf, but LEAF_REG_REMAP for leaf functions, the function was still leaf, but LEAF_REG_REMAP
returned -1 for some registers (like %o0). */ returned -1 for some registers (like %o0). */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -g" } */ /* { dg-options "-O2 -g -mflat" { target sparc*-*-* } } */
void foo (char *a, char *b, char *c, char *d) void foo (char *a, char *b, char *c, char *d)
{ {
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-skip-if "no register windows" { *-*-* } { "-mflat" } { "" } } */
/* { dg-require-effective-target ilp32 } */ /* { dg-require-effective-target ilp32 } */
/* { dg-options "-mcpu=ultrasparc -O" } */ /* { 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) ...@@ -11,7 +12,7 @@ int bar (int a, int b, int c, int d, int e, int f, int g, int h)
toto (&res); toto (&res);
return h; 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 () int bar2 ()
{ {
...@@ -20,4 +21,4 @@ int bar2 () ...@@ -20,4 +21,4 @@ int bar2 ()
toto (&res); toto (&res);
return 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" } } */
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> 2011-06-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* enable-execute-stack-empty.c: New file. * enable-execute-stack-empty.c: New file.
......
...@@ -27,6 +27,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -27,6 +27,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(__arch64__) #if defined(__arch64__)
#undef STACK_BIAS
#define STACK_BIAS 2047
/* 64-bit SPARC version */ /* 64-bit SPARC version */
#define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state #define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
...@@ -49,7 +52,8 @@ sparc64_fallback_frame_state (struct _Unwind_Context *context, ...@@ -49,7 +52,8 @@ sparc64_fallback_frame_state (struct _Unwind_Context *context,
fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4); fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
new_cfa = *(long *)(this_cfa + regs_off + (14 * 8)); 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); fpu_save = *(long *)(this_cfa + fpu_save_off);
fs->regs.cfa_how = CFA_REG_OFFSET; fs->regs.cfa_how = CFA_REG_OFFSET;
fs->regs.cfa_reg = __builtin_dwarf_sp_column (); fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
...@@ -112,7 +116,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context, ...@@ -112,7 +116,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
&& fs->regs.cfa_how == CFA_REG_OFFSET && fs->regs.cfa_how == CFA_REG_OFFSET
&& fs->regs.cfa_offset != 0 && fs->regs.cfa_offset != 0
&& !fs->signal_frame) && !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 #else
......
! crti.s for solaris 2.0. ! 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 ! Written By David Vinayak Henkel-Wallace, June 1992
! !
! This file is free software; you can redistribute it and/or modify it ! This file is free software; you can redistribute it and/or modify it
...@@ -35,11 +35,22 @@ ...@@ -35,11 +35,22 @@
.type _init,#function .type _init,#function
.align 4 .align 4
_init: _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 #ifdef __sparcv9
save %sp, -176, %sp save %sp, -176, %sp
#else #else
save %sp, -96, %sp save %sp, -96, %sp
#endif #endif
#endif
.section ".fini" .section ".fini"
...@@ -48,8 +59,19 @@ _init: ...@@ -48,8 +59,19 @@ _init:
.type _fini,#function .type _fini,#function
.align 4 .align 4
_fini: _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 #ifdef __sparcv9
save %sp, -176, %sp save %sp, -176, %sp
#else #else
save %sp, -96, %sp save %sp, -96, %sp
#endif #endif
#endif
! crtn.s for solaris 2.0. ! 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 ! Written By David Vinayak Henkel-Wallace, June 1992
! !
! This file is free software; you can redistribute it and/or modify it ! This file is free software; you can redistribute it and/or modify it
...@@ -28,14 +28,36 @@ ...@@ -28,14 +28,36 @@
.section ".init" .section ".init"
.align 4 .align 4
#ifdef _FLAT
ret 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 restore
#endif
jmp %o7+8
nop
.section ".fini" .section ".fini"
.align 4 .align 4
#ifdef _FLAT
ret 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 restore
#endif
jmp %o7+8
nop
! Th-th-th-that is all folks! ! Th-th-th-that is all folks!
...@@ -164,7 +164,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context, ...@@ -164,7 +164,16 @@ sparc64_frob_update_context (struct _Unwind_Context *context,
&& fs->regs.cfa_how == CFA_REG_OFFSET && fs->regs.cfa_how == CFA_REG_OFFSET
&& fs->regs.cfa_offset != 0 && fs->regs.cfa_offset != 0
&& !fs->signal_frame) && !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 #else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment