Commit 566be57c by Joern Rennecke Committed by Joern Rennecke

epiphany.c (epiphany_init): Check size of NUM_MODES_FOR_MODE_SWITCHING.

	* config/epiphany/epiphany.c (epiphany_init): Check size of
	NUM_MODES_FOR_MODE_SWITCHING.
	(epiphany_expand_prologue):
	Remove CONFIG_REGNUM initial value handling code.
	(epiphany_optimize_mode_switching): Handle EPIPHANY_MSW_ENTITY_CONFIG.
	(epiphany_mode_needed, epiphany_mode_entry_exit): Likewise.
	(emit_set_fp_mode): Likewise.
	(epiphany_mode_needed) <Handle EPIPHANY_MSW_ENTITY_AND>:
	Don't return 1 for FP_MODE_NONE.
	* config/epiphany/epiphany.h (NUM_MODES_FOR_MODE_SWITCHING):
	Add value for EPIPHANY_MSW_ENTITY_CONFIG.
	(EPIPHANY_MSW_ENTITY_CONFIG, EPIPHANY_MSW_ENTITY_NUM): Define.
	* config/epiphany/epiphany.md (save_config): New pattern.

From-SVN: r198807
parent 0f2c2331
2013-05-12 Joern Rennecke <joern.rennecke@embecosm.com>
* config/epiphany/epiphany.c (epiphany_init): Check size of
NUM_MODES_FOR_MODE_SWITCHING.
(epiphany_expand_prologue):
Remove CONFIG_REGNUM initial value handling code.
(epiphany_optimize_mode_switching): Handle EPIPHANY_MSW_ENTITY_CONFIG.
(epiphany_mode_needed, epiphany_mode_entry_exit): Likewise.
(emit_set_fp_mode): Likewise.
(epiphany_mode_needed) <Handle EPIPHANY_MSW_ENTITY_AND>:
Don't return 1 for FP_MODE_NONE.
* config/epiphany/epiphany.h (NUM_MODES_FOR_MODE_SWITCHING):
Add value for EPIPHANY_MSW_ENTITY_CONFIG.
(EPIPHANY_MSW_ENTITY_CONFIG, EPIPHANY_MSW_ENTITY_NUM): Define.
* config/epiphany/epiphany.md (save_config): New pattern.
2013-05-12 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*zero_extendsidi2): Add *x->?r alternative.
......
......@@ -181,6 +181,8 @@ epiphany_init (void)
= { &pass_split_all_insns.pass, "mode_sw",
1, PASS_POS_INSERT_AFTER
};
static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
#define N_ENTITIES ARRAY_SIZE (num_modes)
epiphany_init_reg_tables ();
......@@ -196,6 +198,8 @@ epiphany_init (void)
register_pass (&mode_sw3_info);
register_pass (&insert_use_info);
register_pass (&mode_sw2_info);
/* Verify that NUM_MODES_FOR_MODE_SWITCHING has one value per entity. */
gcc_assert (N_ENTITIES == EPIPHANY_MSW_ENTITY_NUM);
#if 1 /* As long as peep2_rescan is not implemented,
(see http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html,)
......@@ -1773,44 +1777,6 @@ epiphany_expand_prologue (void)
}
frame_insn (gen_stack_adjust_add (off, mem));
}
/* Mode switching uses get_hard_reg_initial_val after
emit_initial_value_sets, so we have to fix this up now. */
save_config = has_hard_reg_initial_val (SImode, CONFIG_REGNUM);
if (save_config)
{
if (REG_P (save_config))
{
if (REGNO (save_config) >= FIRST_PSEUDO_REGISTER)
gcc_assert (!df_regs_ever_live_p (REGNO (save_config)));
else
frame_move_insn (save_config,
get_hard_reg_initial_reg (save_config));
}
else
{
rtx save_dst = save_config;
reg = gen_rtx_REG (SImode, GPR_IP);
gcc_assert (MEM_P (save_dst));
if (!memory_operand (save_dst, SImode))
{
rtx addr = XEXP (save_dst, 0);
rtx reg2 = gen_rtx_REG (SImode, GPR_16);
gcc_assert (GET_CODE (addr) == PLUS);
gcc_assert (XEXP (addr, 0) == hard_frame_pointer_rtx
|| XEXP (addr, 0) == stack_pointer_rtx);
emit_move_insn (reg2, XEXP (addr, 1));
save_dst
= replace_equiv_address (save_dst,
gen_rtx_PLUS (Pmode, XEXP (addr, 0),
reg2));
}
emit_move_insn (reg, get_hard_reg_initial_reg (save_config));
emit_move_insn (save_dst, reg);
}
}
}
void
......@@ -2271,6 +2237,7 @@ epiphany_optimize_mode_switching (int entity)
{
case EPIPHANY_MSW_ENTITY_AND:
case EPIPHANY_MSW_ENTITY_OR:
case EPIPHANY_MSW_ENTITY_CONFIG:
return true;
case EPIPHANY_MSW_ENTITY_NEAREST:
case EPIPHANY_MSW_ENTITY_TRUNC:
......@@ -2289,7 +2256,8 @@ epiphany_optimize_mode_switching (int entity)
int
epiphany_mode_priority_to_mode (int entity, unsigned priority)
{
if (entity == EPIPHANY_MSW_ENTITY_AND || entity == EPIPHANY_MSW_ENTITY_OR)
if (entity == EPIPHANY_MSW_ENTITY_AND || entity == EPIPHANY_MSW_ENTITY_OR
|| entity== EPIPHANY_MSW_ENTITY_CONFIG)
return priority;
if (priority > 3)
switch (priority)
......@@ -2341,7 +2309,8 @@ epiphany_mode_needed (int entity, rtx insn)
if (recog_memoized (insn) < 0)
{
if (entity == EPIPHANY_MSW_ENTITY_AND
|| entity == EPIPHANY_MSW_ENTITY_OR)
|| entity == EPIPHANY_MSW_ENTITY_OR
|| entity == EPIPHANY_MSW_ENTITY_CONFIG)
return 2;
return FP_MODE_NONE;
}
......@@ -2350,9 +2319,16 @@ epiphany_mode_needed (int entity, rtx insn)
switch (entity)
{
case EPIPHANY_MSW_ENTITY_AND:
return mode != FP_MODE_INT ? 1 : 2;
return mode != FP_MODE_NONE && mode != FP_MODE_INT ? 1 : 2;
case EPIPHANY_MSW_ENTITY_OR:
return mode == FP_MODE_INT ? 1 : 2;
case EPIPHANY_MSW_ENTITY_CONFIG:
/* We must know/save config before we set it to something else.
Where we need the original value, we are fine with having it
just unchanged from the function start.
Because of the nature of the mode switching optimization,
a restore will be dominated by a clobber. */
return mode != FP_MODE_NONE && mode != FP_MODE_CALLER ? 1 : 2;
case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn);
......@@ -2396,6 +2372,10 @@ epiphany_mode_entry_exit (int entity, bool exit)
if (exit)
return normal_mode == FP_MODE_INT ? 1 : 2;
return 0;
case EPIPHANY_MSW_ENTITY_CONFIG:
if (exit)
return 2;
return normal_mode == FP_MODE_CALLER ? 0 : 1;
case EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN:
if (normal_mode == FP_MODE_ROUND_NEAREST
|| normal_mode == FP_MODE_ROUND_TRUNC)
......@@ -2475,12 +2455,25 @@ emit_set_fp_mode (int entity, int mode, HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
emit_move_insn (MACHINE_FUNCTION (cfun)->or_mask, GEN_INT(0x00080000));
return;
}
else if (entity == EPIPHANY_MSW_ENTITY_CONFIG)
{
/* Mode switching optimization is done after emit_initial_value_sets,
so we have to take care of CONFIG_REGNUM here. */
gcc_assert (mode >= 0 && mode <= 2);
rtx save = get_hard_reg_initial_val (SImode, CONFIG_REGNUM);
if (mode == 1)
emit_insn (gen_save_config (save));
return;
}
fp_mode = (enum attr_fp_mode) mode;
src = NULL_RTX;
switch (fp_mode)
{
case FP_MODE_CALLER:
/* The EPIPHANY_MSW_ENTITY_CONFIG processing must come later
so that the config save gets inserted before the first use. */
gcc_assert (entity > EPIPHANY_MSW_ENTITY_CONFIG);
src = get_hard_reg_initial_val (SImode, CONFIG_REGNUM);
mask = MACHINE_FUNCTION (cfun)->and_mask;
break;
......
......@@ -896,7 +896,8 @@ enum epiphany_function_type
finally an entity that runs in a second mode switching pass to
resolve FP_MODE_ROUND_UNKNOWN. */
#define NUM_MODES_FOR_MODE_SWITCHING \
{ 2, 2, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE }
{ 2, 2, 2, \
FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE, FP_MODE_NONE }
#define MODE_NEEDED(ENTITY, INSN) epiphany_mode_needed((ENTITY), (INSN))
......@@ -918,11 +919,13 @@ enum
{
EPIPHANY_MSW_ENTITY_AND,
EPIPHANY_MSW_ENTITY_OR,
EPIPHANY_MSW_ENTITY_CONFIG, /* 1 means config is known or saved. */
EPIPHANY_MSW_ENTITY_NEAREST,
EPIPHANY_MSW_ENTITY_TRUNC,
EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN,
EPIPHANY_MSW_ENTITY_ROUND_KNOWN,
EPIPHANY_MSW_ENTITY_FPU_OMNIBUS
EPIPHANY_MSW_ENTITY_FPU_OMNIBUS,
EPIPHANY_MSW_ENTITY_NUM
};
extern int epiphany_normal_fp_rounding;
......
......@@ -1448,6 +1448,16 @@
[(set_attr "type" "flow")
(set_attr "length" "20,4")])
(define_insn_and_split "save_config"
[(set (match_operand:SI 0 "gpr_operand" "=r") (reg:SI CONFIG_REGNUM))
(use (reg:SI FP_NEAREST_REGNUM))
(use (reg:SI FP_TRUNCATE_REGNUM))
(use (reg:SI FP_ANYFP_REGNUM))]
""
"#"
"reload_completed"
[(set (match_dup 0) (reg:SI CONFIG_REGNUM))])
(define_insn_and_split "set_fp_mode"
[(set (reg:SI FP_NEAREST_REGNUM)
(match_operand:SI 0 "set_fp_mode_operand" "rCfm"))
......
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