[AArch64] Properly handle mvn-register and add EON+shift pattern and cost appropriately
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Thu, 30 Apr 2015 16:59:50 +0000 (16:59 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Thu, 30 Apr 2015 16:59:50 +0000 (16:59 +0000)
* config/aarch64/aarch64.md
(*eor_one_cmpl_<SHIFT:optab><mode>3_alt): New pattern.
(*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze): Likewise.
* config/aarch64/aarch64.c (aarch64_rtx_costs): Handle MVN-shift
appropriately.  Handle alternative EON form.

From-SVN: r222637

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md

index 40d71fcbd12d8ae1e8f0a66d9e5099385503ff2a..a4569bbc075f4fe98ecc86c503ef3b9316e50117 100644 (file)
@@ -1,3 +1,11 @@
+2015-04-30  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md
+       (*eor_one_cmpl_<SHIFT:optab><mode>3_alt): New pattern.
+       (*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze): Likewise.
+       * config/aarch64/aarch64.c (aarch64_rtx_costs): Handle MVN-shift
+       appropriately.  Handle alternative EON form.
+
 2015-04-30  Renlin Li  <renlin.li@arm.com>
 
        * config/aarch64/aarch64-simd.md (vec_shr): Defined as an unspec.
index 7d7f8908a056b1a8f700fb12a03d53c5e0cfb652..7579f5b2519eb6d279f2c76bcfe13d9ea709809a 100644 (file)
@@ -6049,13 +6049,45 @@ cost_plus:
       return false;
 
     case NOT:
+      x = XEXP (x, 0);
+      op0 = aarch64_strip_shift (x);
+
+      /* MVN-shifted-reg.  */
+      if (op0 != x)
+        {
+          *cost += rtx_cost (op0, (enum rtx_code) code, 0, speed);
+
+          if (speed)
+            *cost += extra_cost->alu.log_shift;
+
+          return true;
+        }
+      /* EON can have two forms: (xor (not a) b) but also (not (xor a b)).
+         Handle the second form here taking care that 'a' in the above can
+         be a shift.  */
+      else if (GET_CODE (op0) == XOR)
+        {
+          rtx newop0 = XEXP (op0, 0);
+          rtx newop1 = XEXP (op0, 1);
+          rtx op0_stripped = aarch64_strip_shift (newop0);
+
+          *cost += rtx_cost (newop1, (enum rtx_code) code, 1, speed)
+                   + rtx_cost (op0_stripped, XOR, 0, speed);
+
+          if (speed)
+            {
+              if (op0_stripped != newop0)
+                *cost += extra_cost->alu.log_shift;
+              else
+                *cost += extra_cost->alu.logical;
+            }
+
+          return true;
+        }
       /* MVN.  */
       if (speed)
        *cost += extra_cost->alu.logical;
 
-      /* The logical instruction could have the shifted register form,
-         but the cost is the same if the shift is processed as a separate
-         instruction, so we don't bother with it here.  */
       return false;
 
     case ZERO_EXTEND:
index 429c5bac00078b1b3d751518f0f4b0e488a9d338..194bfd3d2bdd4bda69402d28a8af4b641b4fa9f2 100644 (file)
   [(set_attr "type" "logics_shift_imm")]
 )
 
+(define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+       (not:GPI (xor:GPI
+                     (SHIFT:GPI
+                      (match_operand:GPI 1 "register_operand" "r")
+                      (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
+                    (match_operand:GPI 3 "register_operand" "r"))))]
+  ""
+  "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
+  [(set_attr "type" "logic_shift_imm")]
+)
+
+;; Zero-extend version of the above.
+(define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (zero_extend:DI
+         (not:SI (xor:SI
+                   (SHIFT:SI
+                     (match_operand:SI 1 "register_operand" "r")
+                     (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
+                   (match_operand:SI 3 "register_operand" "r")))))]
+  ""
+  "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
+  [(set_attr "type" "logic_shift_imm")]
+)
+
 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ