[AArch64][3/5] Implement fusion of MOVK+MOVK
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Mon, 24 Nov 2014 11:26:04 +0000 (11:26 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Mon, 24 Nov 2014 11:26:04 +0000 (11:26 +0000)
* config/aarch64/aarch64.c (AARCH64_FUSE_MOVK_MOVK): Define.
(cortexa53_tunings): Specify AARCH64_FUSE_MOVK_MOVK in fuseable_ops.
(cortexa57_tunings): Likewise.
(aarch_macro_fusion_pair_p): Handle AARCH64_FUSE_MOVK_MOVK.

From-SVN: r218013

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

index 0db7927f2a2d12d3ada55569103de4f0ff35926d..d58c8c3593b288d86932cd197dab4c468d4281ea 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.c (AARCH64_FUSE_MOVK_MOVK): Define.
+       (cortexa53_tunings): Specify AARCH64_FUSE_MOVK_MOVK in fuseable_ops.
+       (cortexa57_tunings): Likewise.
+       (aarch_macro_fusion_pair_p): Handle AARCH64_FUSE_MOVK_MOVK.
+
 2014-11-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * sched-deps.c (sched_macro_fuse_insns): Do not check modified_in_p
index 0388e42278fcda5fb8f5044b49087166fe129c5a..5598b5b253edaeca100c98948a36068a5c66bf9a 100644 (file)
@@ -308,6 +308,7 @@ static const struct cpu_vector_cost cortexa57_vector_cost =
 #define AARCH64_FUSE_NOTHING   (0)
 #define AARCH64_FUSE_MOV_MOVK  (1 << 0)
 #define AARCH64_FUSE_ADRP_ADD  (1 << 1)
+#define AARCH64_FUSE_MOVK_MOVK (1 << 2)
 
 #if HAVE_DESIGNATED_INITIALIZERS && GCC_VERSION >= 2007
 __extension__
@@ -331,7 +332,7 @@ static const struct tune_params cortexa53_tunings =
   &generic_vector_cost,
   NAMED_PARAM (memmov_cost, 4),
   NAMED_PARAM (issue_rate, 2),
-  NAMED_PARAM (fuseable_ops, (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD))
+  NAMED_PARAM (fuseable_ops, (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_MOVK_MOVK))
 };
 
 static const struct tune_params cortexa57_tunings =
@@ -342,7 +343,7 @@ static const struct tune_params cortexa57_tunings =
   &cortexa57_vector_cost,
   NAMED_PARAM (memmov_cost, 4),
   NAMED_PARAM (issue_rate, 3),
-  NAMED_PARAM (fuseable_ops, (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD))
+  NAMED_PARAM (fuseable_ops, (AARCH64_FUSE_MOV_MOVK | AARCH64_FUSE_ADRP_ADD | AARCH64_FUSE_MOVK_MOVK))
 };
 
 static const struct tune_params thunderx_tunings =
@@ -10455,6 +10456,36 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
         }
     }
 
+  if (simple_sets_p
+      && (aarch64_tune_params->fuseable_ops & AARCH64_FUSE_MOVK_MOVK))
+    {
+
+      /* We're trying to match:
+         prev (movk) == (set (zero_extract (reg r0)
+                                           (const_int 16)
+                                           (const_int 32))
+                             (const_int imm16_1))
+         curr (movk) == (set (zero_extract (reg r0)
+                                           (const_int 16)
+                                           (const_int 48))
+                             (const_int imm16_2))  */
+
+      if (GET_CODE (SET_DEST (prev_set)) == ZERO_EXTRACT
+          && GET_CODE (SET_DEST (curr_set)) == ZERO_EXTRACT
+          && REG_P (XEXP (SET_DEST (prev_set), 0))
+          && REG_P (XEXP (SET_DEST (curr_set), 0))
+          && REGNO (XEXP (SET_DEST (prev_set), 0))
+             == REGNO (XEXP (SET_DEST (curr_set), 0))
+          && CONST_INT_P (XEXP (SET_DEST (prev_set), 2))
+          && CONST_INT_P (XEXP (SET_DEST (curr_set), 2))
+          && INTVAL (XEXP (SET_DEST (prev_set), 2)) == 32
+          && INTVAL (XEXP (SET_DEST (curr_set), 2)) == 48
+          && CONST_INT_P (SET_SRC (prev_set))
+          && CONST_INT_P (SET_SRC (curr_set)))
+        return true;
+
+    }
+
   return false;
 }