[AArch64] Accept more addressing modes for PRFM
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Thu, 4 May 2017 16:14:37 +0000 (16:14 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Thu, 4 May 2017 16:14:37 +0000 (16:14 +0000)
* config/aarch64/aarch64.md (prefetch); Adjust predicate and
constraint on operand 0 to allow more general addressing modes.
Adjust output template.
* config/aarch64/aarch64.c (aarch64_address_valid_for_prefetch_p):
New function.
* config/aarch64/aarch64-protos.h
(aarch64_address_valid_for_prefetch_p): Declare prototype.
* config/aarch64/constraints.md (Dp): New address constraint.
* config/aarch64/predicates.md (aarch64_prefetch_operand): New
predicate.

* gcc.target/aarch64/prfm_imm_offset_1.c: New test.

From-SVN: r247603

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/constraints.md
gcc/config/aarch64/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c [new file with mode: 0644]

index c9e34c017b9232b56a48fad9bb94d49e75c7395f..34a56ab17c626a7fc4d99edec0dc6ca4c99c467a 100644 (file)
@@ -1,3 +1,16 @@
+2016-05-04  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md (prefetch); Adjust predicate and
+       constraint on operand 0 to allow more general addressing modes.
+       Adjust output template.
+       * config/aarch64/aarch64.c (aarch64_address_valid_for_prefetch_p):
+       New function.
+       * config/aarch64/aarch64-protos.h
+       (aarch64_address_valid_for_prefetch_p): Declare prototype.
+       * config/aarch64/constraints.md (Dp): New address constraint.
+       * config/aarch64/predicates.md (aarch64_prefetch_operand): New
+       predicate.
+
 2017-05-04  Jan Hubicka  <hubicka@ucw.cz>
 
        * ipa-cp.c (perform_estimation_of_a_value): Drop base_time parameter;
index 9543f8c9f2974ad7f8612aa007f975dd6eeec2bc..2895a2a97b5a9c63327cf1dc1ef74b8382c69ad1 100644 (file)
@@ -301,6 +301,7 @@ extern struct tune_params aarch64_tune_params;
 
 HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
 int aarch64_get_condition_code (rtx);
+bool aarch64_address_valid_for_prefetch_p (rtx, bool);
 bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
 unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in);
 unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
index b760905ce3bb374d49153a68dff7948213d853e0..43fc928b4602d9181bfedf99ca2edd3e241f007d 100644 (file)
@@ -4549,6 +4549,24 @@ aarch64_classify_address (struct aarch64_address_info *info,
     }
 }
 
+/* Return true if the address X is valid for a PRFM instruction.
+   STRICT_P is true if we should do strict checking with
+   aarch64_classify_address.  */
+
+bool
+aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p)
+{
+  struct aarch64_address_info addr;
+
+  /* PRFM accepts the same addresses as DImode...  */
+  bool res = aarch64_classify_address (&addr, x, DImode, MEM, strict_p);
+  if (!res)
+    return false;
+
+  /* ... except writeback forms.  */
+  return addr.type != ADDRESS_REG_WB;
+}
+
 bool
 aarch64_symbolic_address_p (rtx x)
 {
index 51368e29f2d1fd12f48a972bd81a08589a720e07..d39b8507c7570b4490ede20c523ffcf6bd533a36 100644 (file)
 )
 
 (define_insn "prefetch"
-  [(prefetch (match_operand:DI 0 "register_operand" "r")
+  [(prefetch (match_operand:DI 0 "aarch64_prefetch_operand" "Dp")
             (match_operand:QI 1 "const_int_operand" "")
             (match_operand:QI 2 "const_int_operand" ""))]
   ""
   {
-    const char * pftype[2][4] = 
+    const char * pftype[2][4] =
     {
-      {"prfm\\tPLDL1STRM, %a0",
-       "prfm\\tPLDL3KEEP, %a0",
-       "prfm\\tPLDL2KEEP, %a0",
-       "prfm\\tPLDL1KEEP, %a0"},
-      {"prfm\\tPSTL1STRM, %a0",
-       "prfm\\tPSTL3KEEP, %a0",
-       "prfm\\tPSTL2KEEP, %a0",
-       "prfm\\tPSTL1KEEP, %a0"},
+      {"prfm\\tPLDL1STRM, %0",
+       "prfm\\tPLDL3KEEP, %0",
+       "prfm\\tPLDL2KEEP, %0",
+       "prfm\\tPLDL1KEEP, %0"},
+      {"prfm\\tPSTL1STRM, %0",
+       "prfm\\tPSTL3KEEP, %0",
+       "prfm\\tPSTL2KEEP, %0",
+       "prfm\\tPSTL1KEEP, %0"},
     };
 
     int locality = INTVAL (operands[2]);
 
     gcc_assert (IN_RANGE (locality, 0, 3));
 
+    /* PRFM accepts the same addresses as a 64-bit LDR so wrap
+       the address into a DImode MEM so that aarch64_print_operand knows
+       how to print it.  */
+    operands[0] = gen_rtx_MEM (DImode, operands[0]);
     return pftype[INTVAL(operands[1])][locality];
   }
   [(set_attr "type" "load1")]
index 5a252c07afa6bda32af5d53bbff44958ce84108a..b8293376fde7e03c4cfc2a6ad6268201f487eb92 100644 (file)
  A constraint that matches an immediate operand valid for AdvSIMD scalar."
  (and (match_code "const_int")
       (match_test "aarch64_simd_imm_scalar_p (op, GET_MODE (op))")))
+
+(define_address_constraint "Dp"
+  "@internal
+ An address valid for a prefetch instruction."
+ (match_test "aarch64_address_valid_for_prefetch_p (op, true)"))
index e83d45b394518f106303a47df2069e498faa73cc..8e3ea9b469659410fe3d6ff52d9d590a711a46fa 100644 (file)
        (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,
                                               0)")))
 
+(define_predicate "aarch64_prefetch_operand"
+  (match_test "aarch64_address_valid_for_prefetch_p (op, false)"))
+
 (define_predicate "aarch64_valid_symref"
   (match_code "const, symbol_ref, label_ref")
 {
index 00f1cf245b989a220d38f06371e474dabd5a8ca6..b8d1e2f3cb3aaf41db59f8a48e31f2e4fc083235 100644 (file)
@@ -1,3 +1,7 @@
+2016-05-04  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/prfm_imm_offset_1.c: New test.
+
 2017-05-04  Jan Hubicka  <hubicka@ucw.cz>
 
        * gcc.dg/ipa/ipcp-2.c: Decrease ipcp threshold
diff --git a/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c b/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c
new file mode 100644 (file)
index 0000000..26ab913
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+/* Check that we can generate the immediate-offset addressing
+   mode for PRFM.  */
+
+#define ARRSIZE 65
+int *bad_addr[ARRSIZE];
+
+void
+prefetch_for_read (void)
+{
+  int i;
+  for (i = 0; i < ARRSIZE; i++)
+    __builtin_prefetch (bad_addr[i] + 2, 0, 0);
+}
+
+/* { dg-final { scan-assembler-times "prfm.*\\\[x\[0-9\]+, 8\\\]" 1 } } */