* expmed.c (expand_shift_1): Canonicalize rotates by
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 May 2013 08:55:34 +0000 (08:55 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 May 2013 08:55:34 +0000 (08:55 +0000)
constant bitsize / 2 to bitsize - 1.
* simplify-rt.x (simplify_binary_operation_1) <case ROTATE,
case ROTATERT>: Likewise.

Revert:
2013-05-10  Jakub Jelinek  <jakub@redhat.com>

* config/i386/i386.md (rotateinv): New code attr.
(*<rotate_insn><mode>3_1, *<rotate_insn>si3_1_zext,
*<rotate_insn>qi3_1_slp): Emit rorl %eax instead of
roll $31, %eax, etc.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@198864 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/expmed.c
gcc/simplify-rtx.c

index f225d80..a751b29 100644 (file)
@@ -1,3 +1,18 @@
+2013-05-14  Jakub Jelinek  <jakub@redhat.com>
+
+       * expmed.c (expand_shift_1): Canonicalize rotates by
+       constant bitsize / 2 to bitsize - 1.
+       * simplify-rt.x (simplify_binary_operation_1) <case ROTATE,
+       case ROTATERT>: Likewise.
+
+       Revert:
+       2013-05-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/i386/i386.md (rotateinv): New code attr.
+       (*<rotate_insn><mode>3_1, *<rotate_insn>si3_1_zext,
+       *<rotate_insn>qi3_1_slp): Emit rorl %eax instead of
+       roll $31, %eax, etc.
+
 2013-05-14  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/57235
index fe86fb9..417d784 100644 (file)
 ;; Base name for insn mnemonic.
 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
 
-;; Base name for insn mnemonic of rotation in the other direction.
-(define_code_attr rotateinv [(rotate "ror") (rotatert "rol")])
-
 ;; Mapping of abs neg operators
 (define_code_iterator absneg [abs neg])
 
       return "#";
 
     default:
-      if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-       {
-         if (operands[2] == const1_rtx)
-           return "<rotate>{<imodesuffix>}\t%0";
-         if (CONST_INT_P (operands[2])
-             && INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode) - 1)
-           return "<rotateinv>{<imodesuffix>}\t%0";
-       }
-      return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+      if (operands[2] == const1_rtx
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+       return "<rotate>{<imodesuffix>}\t%0";
+      else
+       return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
     }
 }
   [(set_attr "isa" "*,bmi2")
       return "#";
 
     default:
-      if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-       {
-         if (operands[2] == const1_rtx)
-           return "<rotate>{l}\t%k0";
-         if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 31)
-           return "<rotateinv>{l}\t%k0";
-       }
-      return "<rotate>{l}\t{%2, %k0|%k0, %2}";
+      if (operands[2] == const1_rtx
+         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+       return "<rotate>{l}\t%k0";
+      else
+       return "<rotate>{l}\t{%2, %k0|%k0, %2}";
     }
 }
   [(set_attr "isa" "*,bmi2")
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
 {
-  if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-    {
-      if (operands[2] == const1_rtx)
-       return "<rotate>{<imodesuffix>}\t%0";
-      if (CONST_INT_P (operands[2])
-         && INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode) - 1)
-       return "<rotateinv>{<imodesuffix>}\t%0";
-    }
-  return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
+  if (operands[2] == const1_rtx
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "<rotate>{<imodesuffix>}\t%0";
+  else
+    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
 }
   [(set_attr "type" "rotate")
    (set (attr "length_immediate")
     || (operands[1] == const1_rtx
        && TARGET_SHIFT1))"
 {
-  if (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
-    {
-      if (operands[2] == const1_rtx)
-       return "<rotate>{b}\t%0";
-      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 7)
-       return "<rotateinv>{b}\t%0";
-    }
-  return "<rotate>{b}\t{%1, %0|%0, %1}";
+  if (operands[1] == const1_rtx
+      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
+    return "<rotate>{b}\t%0";
+  else
+    return "<rotate>{b}\t{%1, %0|%0, %1}";
 }
   [(set_attr "type" "rotate1")
    (set (attr "length_immediate")
index 6e61e9a..c85e68c 100644 (file)
@@ -2122,6 +2122,20 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted,
        op1 = SUBREG_REG (op1);
     }
 
+  /* Canonicalize rotates by constant amount.  If op1 is bitsize / 2,
+     prefer left rotation, if op1 is from bitsize / 2 + 1 to
+     bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
+     amount instead.  */
+  if (rotate
+      && CONST_INT_P (op1)
+      && IN_RANGE (INTVAL (op1), GET_MODE_BITSIZE (mode) / 2 + left,
+                  GET_MODE_BITSIZE (mode) - 1))
+    {
+      op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
+      left = !left;
+      code = left ? LROTATE_EXPR : RROTATE_EXPR;
+    }
+
   if (op1 == const0_rtx)
     return shifted;
 
index 791f91a..865d37d 100644 (file)
@@ -3250,6 +3250,18 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
 
     case ROTATERT:
     case ROTATE:
+      /* Canonicalize rotates by constant amount.  If op1 is bitsize / 2,
+        prefer left rotation, if op1 is from bitsize / 2 + 1 to
+        bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
+        amount instead.  */
+      if (CONST_INT_P (trueop1)
+         && IN_RANGE (INTVAL (trueop1),
+                      GET_MODE_BITSIZE (mode) / 2 + (code == ROTATE),
+                      GET_MODE_BITSIZE (mode) - 1))
+       return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
+                                   mode, op0, GEN_INT (GET_MODE_BITSIZE (mode)
+                                                       - INTVAL (trueop1)));
+      /* FALLTHRU */
     case ASHIFTRT:
       if (trueop1 == CONST0_RTX (mode))
        return op0;