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> 2010-09-20 Nicola Pero <nicola.pero@meta-innovation.com>
* c-family/c-common.h (constant_string_class): Documented with * c-family/c-common.h (constant_string_class): Documented with
......
...@@ -18057,32 +18057,29 @@ ix86_split_long_move (rtx operands[]) ...@@ -18057,32 +18057,29 @@ ix86_split_long_move (rtx operands[])
static void static void
ix86_expand_ashl_const (rtx operand, int count, enum machine_mode mode) 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 insn = mode == DImode ? gen_addsi3 : gen_adddi3;
? gen_addsi3 while (count-- > 0)
: gen_adddi3) (operand, operand, operand)); emit_insn (insn (operand, operand, operand));
} }
else if (!optimize_insn_for_size_p () else
&& count * ix86_cost->add <= ix86_cost->shift_const)
{
int i;
for (i=0; i<count; i++)
{ {
emit_insn ((mode == DImode insn = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
? gen_addsi3 emit_insn (insn (operand, operand, GEN_INT (count)));
: gen_adddi3) (operand, operand, operand));
}
} }
else
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (operand, operand, GEN_INT (count)));
} }
void void
ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) 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]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64; const int single_width = mode == DImode ? 32 : 64;
...@@ -18102,11 +18099,12 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -18102,11 +18099,12 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
} }
else else
{ {
gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shld emit_insn (gen_shld (high[0], low[0], GEN_INT (count)));
: gen_x86_64_shld) (high[0], low[0], GEN_INT (count)));
ix86_expand_ashl_const (low[0], count, mode); ix86_expand_ashl_const (low[0], count, mode);
} }
return; return;
...@@ -18114,6 +18112,8 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -18114,6 +18112,8 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
split_double_mode (mode, operands, 1, low, high); split_double_mode (mode, operands, 1, low, high);
gen_ashl3 = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
if (operands[1] == const1_rtx) if (operands[1] == const1_rtx)
{ {
/* Assuming we've chosen a QImode capable registers, then 1 << N /* 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) ...@@ -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. */ pentium4 a bit; no one else seems to care much either way. */
else 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; 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 ()) 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 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 (gen_rtx_SET (VOIDmode, high[0], x));
emit_insn ((mode == DImode emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (bits)));
? gen_lshrsi3 emit_insn (gen_and3 (high[0], high[0], const1_rtx));
: 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_move_insn (low[0], high[0]); emit_move_insn (low[0], high[0]);
emit_insn ((mode == DImode emit_insn (gen_xor3 (low[0], low[0], const1_rtx));
? gen_xorsi3
: gen_xordi3) (low[0], low[0], const1_rtx));
} }
emit_insn ((mode == DImode emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
? gen_ashlsi3 emit_insn (gen_ashl3 (high[0], high[0], operands[2]));
: gen_ashldi3) (low[0], low[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashlsi3
: gen_ashldi3) (high[0], high[0], operands[2]));
return; return;
} }
...@@ -18186,36 +18197,41 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -18186,36 +18197,41 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
} }
else else
{ {
gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high); split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode emit_insn (gen_shld (high[0], low[0], operands[2]));
? gen_x86_shld
: gen_x86_64_shld) (high[0], low[0], operands[2]));
} }
emit_insn ((mode == DImode emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
? gen_ashlsi3
: gen_ashldi3) (low[0], low[0], operands[2]));
if (TARGET_CMOVE && scratch) 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); ix86_expand_clear (scratch);
emit_insn ((mode == DImode emit_insn (gen_x86_shift_adj_1 (high[0], low[0], operands[2], scratch));
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (high[0], low[0], operands[2],
scratch));
} }
else else
emit_insn ((mode == DImode {
? gen_x86_shiftsi_adj_2 rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
: gen_x86_shiftdi_adj_2) (high[0], low[0], operands[2])); = 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 void
ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode) 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]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64; const int single_width = mode == DImode ? 32 : 64;
...@@ -18228,9 +18244,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -18228,9 +18244,7 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
if (count == single_width * 2 - 1) if (count == single_width * 2 - 1)
{ {
emit_move_insn (high[0], high[1]); emit_move_insn (high[0], high[1]);
emit_insn ((mode == DImode emit_insn (gen_ashr3 (high[0], high[0],
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1))); GEN_INT (single_width - 1)));
emit_move_insn (low[0], high[0]); emit_move_insn (low[0], high[0]);
...@@ -18239,64 +18253,64 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -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 (low[0], high[1]);
emit_move_insn (high[0], low[0]); emit_move_insn (high[0], low[0]);
emit_insn ((mode == DImode emit_insn (gen_ashr3 (high[0], high[0],
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0],
GEN_INT (single_width - 1))); GEN_INT (single_width - 1)));
if (count > single_width) if (count > single_width)
emit_insn ((mode == DImode emit_insn (gen_ashr3 (low[0], low[0],
? gen_ashrsi3
: gen_ashrdi3) (low[0], low[0],
GEN_INT (count - single_width))); GEN_INT (count - single_width)));
} }
else else
{ {
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shrd emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count))); emit_insn (gen_ashr3 (high[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], GEN_INT (count)));
} }
} }
else else
{ {
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high); split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode emit_insn (gen_shrd (low[0], high[0], operands[2]));
? gen_x86_shrd emit_insn (gen_ashr3 (high[0], high[0], operands[2]));
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_ashrsi3
: gen_ashrdi3) (high[0], high[0], operands[2]));
if (TARGET_CMOVE && scratch) 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_move_insn (scratch, high[0]);
emit_insn ((mode == DImode emit_insn (gen_ashr3 (scratch, scratch,
? gen_ashrsi3
: gen_ashrdi3) (scratch, scratch,
GEN_INT (single_width - 1))); GEN_INT (single_width - 1)));
emit_insn ((mode == DImode emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch)); scratch));
} }
else else
emit_insn ((mode == DImode {
? gen_x86_shiftsi_adj_3 rtx (*gen_x86_shift_adj_3)(rtx, rtx, rtx)
: gen_x86_shiftdi_adj_3) (low[0], high[0], operands[2])); = 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 void
ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode) 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]; rtx low[2], high[2];
int count; int count;
const int single_width = mode == DImode ? 32 : 64; const int single_width = mode == DImode ? 32 : 64;
...@@ -18312,50 +18326,48 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode) ...@@ -18312,50 +18326,48 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
ix86_expand_clear (high[0]); ix86_expand_clear (high[0]);
if (count > single_width) if (count > single_width)
emit_insn ((mode == DImode emit_insn (gen_lshr3 (low[0], low[0],
? gen_lshrsi3
: gen_lshrdi3) (low[0], low[0],
GEN_INT (count - single_width))); GEN_INT (count - single_width)));
} }
else else
{ {
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
emit_insn ((mode == DImode
? gen_x86_shrd emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
: gen_x86_64_shrd) (low[0], high[0], GEN_INT (count))); emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (count)));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], GEN_INT (count)));
} }
} }
else else
{ {
gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
if (!rtx_equal_p (operands[0], operands[1])) if (!rtx_equal_p (operands[0], operands[1]))
emit_move_insn (operands[0], operands[1]); emit_move_insn (operands[0], operands[1]);
split_double_mode (mode, operands, 1, low, high); split_double_mode (mode, operands, 1, low, high);
emit_insn ((mode == DImode emit_insn (gen_shrd (low[0], high[0], operands[2]));
? gen_x86_shrd emit_insn (gen_lshr3 (high[0], high[0], operands[2]));
: gen_x86_64_shrd) (low[0], high[0], operands[2]));
emit_insn ((mode == DImode
? gen_lshrsi3
: gen_lshrdi3) (high[0], high[0], operands[2]));
/* Heh. By reversing the arguments, we can reuse this pattern. */
if (TARGET_CMOVE && scratch) 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); ix86_expand_clear (scratch);
emit_insn ((mode == DImode emit_insn (gen_x86_shift_adj_1 (low[0], high[0], operands[2],
? gen_x86_shiftsi_adj_1
: gen_x86_shiftdi_adj_1) (low[0], high[0], operands[2],
scratch)); scratch));
} }
else else
emit_insn ((mode == DImode {
? gen_x86_shiftsi_adj_2 rtx (*gen_x86_shift_adj_2)(rtx, rtx, rtx)
: gen_x86_shiftdi_adj_2) (low[0], high[0], operands[2])); = 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) ...@@ -18392,10 +18404,10 @@ ix86_expand_aligntest (rtx variable, int value, bool epilogue)
static void static void
ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value) ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
{ {
if (GET_MODE (countreg) == DImode) rtx (*gen_add)(rtx, rtx, rtx)
emit_insn (gen_adddi3 (countreg, countreg, GEN_INT (-value))); = GET_MODE (countreg) == DImode ? gen_adddi3 : gen_addsi3;
else
emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-value))); emit_insn (gen_add (countreg, countreg, GEN_INT (-value)));
} }
/* Zero extend possibly SImode EXP to Pmode register. */ /* 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