i386.c (ix86_expand_ashl_const): Rewrite using indirect functions.
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 20 Sep 2010 19:04:02 +0000 (21:04 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 20 Sep 2010 19:04:02 +0000 (21:04 +0200)
* 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

gcc/ChangeLog
gcc/config/i386/i386.c

index b30d355961db68c7761be4f7e53b0888b5c0428b..88f350e1269215376092c67b1d04441655cc4e9c 100644 (file)
@@ -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.
index 9644a64f865fe57500498e466d279c28e485180a..33dbbe9ca2aba37e184f107073e089a3f88f4402 100644 (file)
@@ -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.  */