summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-20 19:04:02 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-20 19:04:02 +0000
commitac3c47f139e899414007abef1edb27aeea6e3291 (patch)
tree37ec8305435c061f2ba3420a08d30ea73db7e6ba /gcc
parent4721b582c8436d1664bcfb422d9731baf034eb2d (diff)
downloadgcc-ac3c47f139e899414007abef1edb27aeea6e3291.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164449 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c242
2 files changed, 138 insertions, 117 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b30d355961d..88f350e1269 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9644a64f865..33dbbe9ca2a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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. */