diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-20 19:04:02 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-20 19:04:02 +0000 |
commit | ac3c47f139e899414007abef1edb27aeea6e3291 (patch) | |
tree | 37ec8305435c061f2ba3420a08d30ea73db7e6ba /gcc | |
parent | 4721b582c8436d1664bcfb422d9731baf034eb2d (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 242 |
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. */ |