Commit 382eb33c by Uros Bizjak

i386.c (ix86_expand_ashl_const): Rewrite using indirect functions.

	* config/i386/i386.c (ix86_expand_ashl_const): Rewrite using
	indirect functions.
	(ix86_split_ashl): Ditto.
	(ix86_split_ashr): Ditto.
	(ix86_split_lshr): Ditto.
	(ix86_adjust_counter): Ditto.

From-SVN: r164449
parent 15c2ef5a
2010-09-20 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (ix86_expand_ashl_const): Rewrite using
indirect functions.
(ix86_split_ashl): Ditto.
(ix86_split_ashr): Ditto.
(ix86_split_lshr): Ditto.
(ix86_adjust_counter): Ditto.
2010-09-20 Nicola Pero <nicola.pero@meta-innovation.com>
* c-family/c-common.h (constant_string_class): Documented with
......@@ -17,7 +26,7 @@
(gen_inheritance_die): Assume DW_ACCESS_public as the default
for dwarf_version > 2 and parent other than DW_TAG_class_type.
2010-09-20 Rafael Carre <rafael.carre@gmail.com>
2010-09-20 Rafael Carre <rafael.carre@gmail.com>
PR target/45726
* arm.md (arm_movt): Only enable on machines with MOVT.
......@@ -59,7 +68,7 @@
too and work for automatic vars.
(varpool_finalize_decl): Use const_value_known_p.
2010-09-20 Rafael Carre <rafael.carre@gmail.com>
2010-09-20 Rafael Carre <rafael.carre@gmail.com>
PR target/45726
* arm.md (arm_movtas_ze): Only enable on machine with MOVT.
......
......@@ -18057,32 +18057,29 @@ ix86_split_long_move (rtx operands[])
static void
ix86_expand_ashl_const (rtx operand, int count, enum machine_mode mode)
{
if (count == 1)
rtx (*insn)(rtx, rtx, rtx);
if (count == 1
|| (count * ix86_cost->add <= ix86_cost->shift_const
&& !optimize_insn_for_size_p ()))
{
emit_insn ((mode == DImode
? gen_addsi3
: gen_adddi3) (operand, operand, operand));
insn = mode == DImode ? gen_addsi3 : gen_adddi3;
while (count-- > 0)
emit_insn (insn (operand, operand, operand));
}
else if (!optimize_insn_for_size_p ()
&& count * ix86_cost->add <= ix86_cost->shift_const)
else
{
int i;
for (i=0; i<count; i++)
{
emit_insn ((mode == DImode
? gen_addsi3
: gen_adddi3) (operand, operand, operand));
}
insn = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
emit_insn (insn (operand, operand, GEN_INT (count)));
}
else
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (operand, operand, GEN_INT (count)));
}
void
ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
{
rtx (*gen_ashl3)(rtx, rtx, rtx);
rtx (*gen_shld)(rtx, rtx, rtx);
rtx low[2], high[2];
int count;
const int single_width = mode == DImode ? 32 : 64;
......@@ -18102,11 +18099,12 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
}
else
{
gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shld
: gen_x86_64_shld) (high[0], low[0], GEN_INT (count)));
emit_insn (gen_shld (high[0], low[0], GEN_INT (count)));
ix86_expand_ashl_const (low[0], count, mode);
}
return;
......@@ -18114,6 +18112,8 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
split_double_mode (mode, operands, 1, low, high);
gen_ashl3 = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
if (operands[1] == const1_rtx)
{
/* Assuming we've chosen a QImode capable registers, then 1 << N
......@@ -18144,33 +18144,44 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
pentium4 a bit; no one else seems to care much either way. */
else
{
enum machine_mode half_mode;
rtx (*gen_lshr3)(rtx, rtx, rtx);
rtx (*gen_and3)(rtx, rtx, rtx);
rtx (*gen_xor3)(rtx, rtx, rtx);
HOST_WIDE_INT bits;
rtx x;
if (mode == DImode)
{
half_mode = SImode;
gen_lshr3 = gen_lshrsi3;
gen_and3 = gen_andsi3;
gen_xor3 = gen_xorsi3;
bits = 5;
}
else
{
half_mode = DImode;
gen_lshr3 = gen_lshrdi3;
gen_and3 = gen_anddi3;
gen_xor3 = gen_xordi3;
bits = 6;
}
if (TARGET_PARTIAL_REG_STALL && !optimize_insn_for_size_p ())
x = gen_rtx_ZERO_EXTEND (mode == DImode ? SImode : DImode, operands[2]);
x = gen_rtx_ZERO_EXTEND (half_mode, operands[2]);
else
x = gen_lowpart (mode == DImode ? SImode : DImode, operands[2]);
x = gen_lowpart (half_mode, operands[2]);
emit_insn (gen_rtx_SET (VOIDmode, high[0], x));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0],
GEN_INT (mode == DImode ? 5 : 6)));
emit_insn ((mode == DImode
? gen_andsi3
: gen_anddi3) (high[0], high[0], const1_rtx));
emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (bits)));
emit_insn (gen_and3 (high[0], high[0], const1_rtx));
emit_move_insn (low[0], high[0]);
emit_insn ((mode == DImode
? gen_xorsi3
: gen_xordi3) (low[0], low[0], const1_rtx));
emit_insn (gen_xor3 (low[0], low[0], const1_rtx));
}
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (low[0], low[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (high[0], high[0], operands[2]));
emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
emit_insn (gen_ashl3 (high[0], high[0], operands[2]));
return;
}
......@@ -18186,36 +18197,41 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
}
else
{
gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shld
: gen_x86_64_shld) (high[0], low[0], operands[2]));
emit_insn (gen_shld (high[0], low[0], operands[2]));
}
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (low[0], low[0], operands[2]));
emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
if (TARGET_CMOVE && scratch)
{
rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (high[0], low[0], operands[2],
scratch));
emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2], scratch));
}
else
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_2
: gen_x86_shiftdi_adj_2) (high[0], low[0], operands[2]));
{
rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_2 : gen_x86_shiftdi_adj_2;
emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
}
}
void
ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
{
rtx (*gen_ashr3)(rtx, rtx, rtx)
= mode == DImode ? gen_ashrsi3 : gen_ashrdi3;
rtx (*gen_shrd)(rtx, rtx, rtx);
rtx low[2], high[2];
int count;
const int single_width = mode == DImode ? 32 : 64;
......@@ -18228,10 +18244,8 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
if (count == single_width * 2 - 1)
{
emit_move_insn (high[0], high[1]);
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1)));
emit_insn (gen_ashr3 (high[0], high[0],
GEN_INT (single_width - 1)));
emit_move_insn (low[0], high[0]);
}
......@@ -18239,64 +18253,64 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
{
emit_move_insn (low[0], high[1]);
emit_move_insn (high[0], low[0]);
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1)));
emit_insn (gen_ashr3 (high[0], high[0],
GEN_INT (single_width - 1)));
if (count > single_width)
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (low[0], low[0],
GEN_INT (count - single_width)));
emit_insn (gen_ashr3 (low[0], low[0],
GEN_INT (count - single_width)));
}
else
{
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shrd
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], GEN_INT (count)));
emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
emit_insn (gen_ashr3 (high[0], high[0], GEN_INT (count)));
}
}
else
{
if (!rtx_equal_p (operands[0], operands[1]))
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shrd
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], operands[2]));
emit_insn (gen_shrd (low[0], high[0], operands[2]));
emit_insn (gen_ashr3 (high[0], high[0], operands[2]));
if (TARGET_CMOVE && scratch)
{
rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
emit_move_insn (scratch, high[0]);
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (scratch, scratch,
GEN_INT (single_width - 1)));
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch));
emit_insn (gen_ashr3 (scratch, scratch,
GEN_INT (single_width - 1)));
emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
scratch));
}
else
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_3
: gen_x86_shiftdi_adj_3) (low[0], high[0], operands[2]));
{
rtx (*gen_x86_shift_adj_3)(rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_3 : gen_x86_shiftdi_adj_3;
emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
}
}
}
void
ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
{
rtx (*gen_lshr3)(rtx, rtx, rtx)
= mode == DImode ? gen_lshrsi3 : gen_lshrdi3;
rtx (*gen_shrd)(rtx, rtx, rtx);
rtx low[2], high[2];
int count;
const int single_width = mode == DImode ? 32 : 64;
......@@ -18312,50 +18326,48 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
ix86_expand_clear (high[0]);
if (count > single_width)
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (low[0], low[0],
GEN_INT (count - single_width)));
emit_insn (gen_lshr3 (low[0], low[0],
GEN_INT (count - single_width)));
}
else
{
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shrd
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], GEN_INT (count)));
emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (count)));
}
}
else
{
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode
? gen_x86_shrd
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], operands[2]));
emit_insn (gen_shrd (low[0], high[0], operands[2]));
emit_insn (gen_lshr3 (high[0], high[0], operands[2]));
/* Heh. By reversing the arguments, we can reuse this pattern. */
if (TARGET_CMOVE && scratch)
{
rtx (*gen_x86_shift_adj_1)(rtx, rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_1 : gen_x86_shiftdi_adj_1;
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch));
emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
scratch));
}
else
emit_insn ((mode == DImode
? gen_x86_shiftsi_adj_2
: gen_x86_shiftdi_adj_2) (low[0], high[0], operands[2]));
{
rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
= mode == DImode ? gen_x86_shiftsi_adj_2 : gen_x86_shiftdi_adj_2;
emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
}
}
}
......@@ -18392,10 +18404,10 @@ ix86_expand_aligntest (rtx variable, int value, bool epilogue)
static void
ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
{
if (GET_MODE (countreg) == DImode)
emit_insn (gen_adddi3 (countreg, countreg, GEN_INT (-value)));
else
emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-value)));
rtx (*gen_add)(rtx, rtx, rtx)
= GET_MODE (countreg) == DImode ? gen_adddi3 : gen_addsi3;
emit_insn (gen_add (countreg, countreg, GEN_INT (-value)));
}
/* Zero extend possibly SImode EXP to Pmode register. */
......
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