Commit c6036a37 by Jan Hubicka Committed by Jan Hubicka

i386.c (x86_accumulate_outgoing_args, [...]): New global variables.


	* i386.c (x86_accumulate_outgoing_args, x86_prologue_using_move,
	x86_epilogue_using_move): New global variables.
	(override_options): Enable ACCUMULATE_OUTGOING_ARGS if preferred.
	(ix86_emit_save_regs_using_mov): New static function.
	(ix86_expand_prologue, ix86_expand_epilogue): Use moves if preferred.
	* i386.h (MASK_MMX, MASK_SSE, MASK_SSE2, MASK_128BIT_LONG_DOUBLE,
	MASK_MIX_SSE_I387): Renumber.
	(MASK_NO_ACCUMULATE_OUTGOING_ARGS): New.
	(x86_accumulate_outgoing_args, x86_prologue_using_move,
	x86_epilogue_using_move): Declare.
	(TARGET_PROLOGUE_USING_MOVE, TARGET_EPILOGUE_USING_MOVE): New.

From-SVN: r43366
parent 1de9b822
Thu Jun 14 12:44:15 CEST 2001 Jan Hubicka <jh@suse.cz>
* i386.c (x86_accumulate_outgoing_args, x86_prologue_using_move,
x86_epilogue_using_move): New global variables.
(override_options): Enable ACCUMULATE_OUTGOING_ARGS if preferred.
(ix86_emit_save_regs_using_mov): New static function.
(ix86_expand_prologue, ix86_expand_epilogue): Use moves if preferred.
* i386.h (MASK_MMX, MASK_SSE, MASK_SSE2, MASK_128BIT_LONG_DOUBLE,
MASK_MIX_SSE_I387): Renumber.
(MASK_NO_ACCUMULATE_OUTGOING_ARGS): New.
(x86_accumulate_outgoing_args, x86_prologue_using_move,
x86_epilogue_using_move): Declare.
(TARGET_PROLOGUE_USING_MOVE, TARGET_EPILOGUE_USING_MOVE): New.
2001-06-13 John David Anglin <dave@hiauly1.hia.nrc.ca> 2001-06-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
* inclhack.def (hpux10_cpp_pow_inline): New hack. * inclhack.def (hpux10_cpp_pow_inline): New hack.
......
...@@ -313,6 +313,9 @@ const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4; ...@@ -313,6 +313,9 @@ const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4); const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4);
const int x86_partial_reg_dependency = m_ATHLON | m_PENT4; const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4; const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
#define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx)) #define AT_BP(mode) (gen_rtx_MEM ((mode), hard_frame_pointer_rtx))
...@@ -560,6 +563,7 @@ static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode)); ...@@ -560,6 +563,7 @@ static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
static int ix86_safe_length_prefix PARAMS ((rtx)); static int ix86_safe_length_prefix PARAMS ((rtx));
static int ix86_nsaved_regs PARAMS((void)); static int ix86_nsaved_regs PARAMS((void));
static void ix86_emit_save_regs PARAMS((void)); static void ix86_emit_save_regs PARAMS((void));
static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int)); static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx)); static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *)); static void ix86_sched_reorder_pentium PARAMS((rtx *, rtx *));
...@@ -835,6 +839,11 @@ override_options () ...@@ -835,6 +839,11 @@ override_options ()
on by -msse. */ on by -msse. */
if (TARGET_SSE) if (TARGET_SSE)
target_flags |= MASK_MMX; target_flags |= MASK_MMX;
if ((x86_accumulate_outgoing_args & CPUMASK)
&& !(target_flags & MASK_NO_ACCUMULATE_OUTGOING_ARGS)
&& !optimize_size)
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
} }
void void
...@@ -2465,6 +2474,28 @@ ix86_emit_save_regs () ...@@ -2465,6 +2474,28 @@ ix86_emit_save_regs ()
} }
} }
/* Emit code to save registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
ix86_emit_save_regs_using_mov (pointer, offset)
rtx pointer;
HOST_WIDE_INT offset;
{
int regno;
rtx insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, true))
{
insn = emit_move_insn (adj_offsettable_operand (gen_rtx_MEM (Pmode,
pointer),
offset),
gen_rtx_REG (Pmode, regno));
RTX_FRAME_RELATED_P (insn) = 1;
offset += UNITS_PER_WORD;
}
}
/* Expand the prologue into a bunch of separate insns. */ /* Expand the prologue into a bunch of separate insns. */
void void
...@@ -2475,6 +2506,8 @@ ix86_expand_prologue () ...@@ -2475,6 +2506,8 @@ ix86_expand_prologue ()
|| current_function_uses_const_pool) || current_function_uses_const_pool)
&& !TARGET_64BIT); && !TARGET_64BIT);
struct ix86_frame frame; struct ix86_frame frame;
int use_mov = (TARGET_PROLOGUE_USING_MOVE && !optimize_size);
HOST_WIDE_INT allocate;
ix86_compute_frame_layout (&frame); ix86_compute_frame_layout (&frame);
...@@ -2490,9 +2523,18 @@ ix86_expand_prologue () ...@@ -2490,9 +2523,18 @@ ix86_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
ix86_emit_save_regs (); allocate = frame.to_allocate;
/* In case we are dealing only with single register and empty frame,
push is equivalent of the mov+add sequence. */
if (allocate == 0 && frame.nregs <= 1)
use_mov = 0;
if (frame.to_allocate == 0) if (!use_mov)
ix86_emit_save_regs ();
else
allocate += frame.nregs * UNITS_PER_WORD;
if (allocate == 0)
; ;
else if (! TARGET_STACK_PROBE || frame.to_allocate < CHECK_STACK_LIMIT) else if (! TARGET_STACK_PROBE || frame.to_allocate < CHECK_STACK_LIMIT)
{ {
...@@ -2511,7 +2553,7 @@ ix86_expand_prologue () ...@@ -2511,7 +2553,7 @@ ix86_expand_prologue ()
abort(); abort();
arg0 = gen_rtx_REG (SImode, 0); arg0 = gen_rtx_REG (SImode, 0);
emit_move_insn (arg0, GEN_INT (frame.to_allocate)); emit_move_insn (arg0, GEN_INT (allocate));
sym = gen_rtx_MEM (FUNCTION_MODE, sym = gen_rtx_MEM (FUNCTION_MODE,
gen_rtx_SYMBOL_REF (Pmode, "_alloca")); gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
...@@ -2521,6 +2563,14 @@ ix86_expand_prologue () ...@@ -2521,6 +2563,14 @@ ix86_expand_prologue ()
= gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0), = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
CALL_INSN_FUNCTION_USAGE (insn)); CALL_INSN_FUNCTION_USAGE (insn));
} }
if (use_mov)
{
if (!frame_pointer_needed || !frame.to_allocate)
ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
else
ix86_emit_save_regs_using_mov (hard_frame_pointer_rtx,
-frame.nregs * UNITS_PER_WORD);
}
#ifdef SUBTARGET_PROLOGUE #ifdef SUBTARGET_PROLOGUE
SUBTARGET_PROLOGUE; SUBTARGET_PROLOGUE;
...@@ -2536,7 +2586,6 @@ ix86_expand_prologue () ...@@ -2536,7 +2586,6 @@ ix86_expand_prologue ()
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
} }
/* Emit code to restore saved registers using MOV insns. First register /* Emit code to restore saved registers using MOV insns. First register
is restored from POINTER + OFFSET. */ is restored from POINTER + OFFSET. */
static void static void
...@@ -2598,6 +2647,8 @@ ix86_expand_epilogue (style) ...@@ -2598,6 +2647,8 @@ ix86_expand_epilogue (style)
and there is exactly one register to pop. This heruistic may need some and there is exactly one register to pop. This heruistic may need some
tuning in future. */ tuning in future. */
if ((!sp_valid && frame.nregs <= 1) if ((!sp_valid && frame.nregs <= 1)
|| (TARGET_EPILOGUE_USING_MOVE && !optimize_size
&& (frame.nregs > 1 || frame.to_allocate))
|| (frame_pointer_needed && !frame.nregs && frame.to_allocate) || (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|| (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size || (frame_pointer_needed && TARGET_USE_LEAVE && !optimize_size
&& frame.nregs == 1) && frame.nregs == 1)
......
...@@ -114,13 +114,14 @@ extern int target_flags; ...@@ -114,13 +114,14 @@ extern int target_flags;
#define MASK_INLINE_ALL_STROPS 0x00002000 /* Inline stringops in all cases */ #define MASK_INLINE_ALL_STROPS 0x00002000 /* Inline stringops in all cases */
#define MASK_NO_PUSH_ARGS 0x00004000 /* Use push instructions */ #define MASK_NO_PUSH_ARGS 0x00004000 /* Use push instructions */
#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */ #define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
#define MASK_MMX 0x00010000 /* Support MMX regs/builtins */ #define MASK_NO_ACCUMULATE_OUTGOING_ARGS 0x00010000
#define MASK_SSE 0x00020000 /* Support SSE regs/builtins */ #define MASK_MMX 0x00020000 /* Support MMX regs/builtins */
#define MASK_SSE2 0x00040000 /* Support SSE2 regs/builtins */ #define MASK_SSE 0x00040000 /* Support SSE regs/builtins */
#define MASK_128BIT_LONG_DOUBLE 0x00080000 /* long double size is 128bit */ #define MASK_SSE2 0x00080000 /* Support SSE2 regs/builtins */
#define MASK_MIX_SSE_I387 0x00100000 /* Mix SSE and i387 instructions */ #define MASK_128BIT_LONG_DOUBLE 0x00100000 /* long double size is 128bit */
#define MASK_64BIT 0x00200000 /* Produce 64bit code */ #define MASK_MIX_SSE_I387 0x00200000 /* Mix SSE and i387 instructions */
#define MASK_NO_RED_ZONE 0x00400000 /* Do not use red zone */ #define MASK_64BIT 0x00400000 /* Produce 64bit code */
#define MASK_NO_RED_ZONE 0x00800000 /* Do not use red zone */
/* Temporary codegen switches */ /* Temporary codegen switches */
#define MASK_INTEL_SYNTAX 0x00000200 #define MASK_INTEL_SYNTAX 0x00000200
...@@ -212,6 +213,8 @@ extern const int x86_himode_math, x86_qimode_math, x86_promote_qi_regs; ...@@ -212,6 +213,8 @@ extern const int x86_himode_math, x86_qimode_math, x86_promote_qi_regs;
extern const int x86_promote_hi_regs, x86_integer_DFmode_moves; extern const int x86_promote_hi_regs, x86_integer_DFmode_moves;
extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8; extern const int x86_add_esp_4, x86_add_esp_8, x86_sub_esp_4, x86_sub_esp_8;
extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall; extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
extern const int x86_accumulate_outgoing_args, x86_prologue_using_move;
extern const int x86_epilogue_using_move;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK) #define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK) #define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
...@@ -247,6 +250,8 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall; ...@@ -247,6 +250,8 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
#define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & CPUMASK) #define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & CPUMASK)
#define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & CPUMASK) #define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & CPUMASK)
#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK) #define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK)
#define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & CPUMASK)
#define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & CPUMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE) #define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
......
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