From: Richard Ball <[email protected]>

This patch adds support for the __pldir intrinsic.
This is a new prefetch intrinsic which declares an
intent to read from an address.
This intrinsic is part of FEAT_PCDPHINT.

gcc/ChangeLog:

        * config/aarch64/aarch64-builtins.cc
        (enum aarch64_builtins): New builtin flag.
        (aarch64_init_pcdphint_builtins): New builtin function.
        (aarch64_expand_pldir_builtin): Expander for new intrinsic.
        (aarch64_general_expand_builtin): Call new expander.
        * config/aarch64/aarch64.md
        (aarch64_pldir): New pattern for instrinsic.
        * config/aarch64/arm_acle.h
        (__attribute__): New call to builtin.
        (__pldir): Likewise.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/pldir.c: New test.
---
 gcc/config/aarch64/aarch64-builtins.cc   | 25 ++++++++++++++++++++++++
 gcc/config/aarch64/aarch64.md            | 12 ++++++++++++
 gcc/config/aarch64/arm_acle.h            |  8 ++++++++
 gcc/testsuite/gcc.target/aarch64/pldir.c | 12 ++++++++++++
 4 files changed, 57 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pldir.c

diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
b/gcc/config/aarch64/aarch64-builtins.cc
index 1e682c00302..61126593e49 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -909,6 +909,7 @@ enum aarch64_builtins
   AARCH64_BUILTIN_STSHH_PTR,
   AARCH64_BUILTIN_STSHH_SF,
   AARCH64_BUILTIN_STSHH_DF,
+  AARCH64_BUILTIN_PLDIR,
   AARCH64_BUILTIN_MAX
 };
 
@@ -2536,6 +2537,15 @@ aarch64_init_pcdphint_builtins (void)
   aarch64_builtin_decls[AARCH64_BUILTIN_STSHH_DF]
     = aarch64_general_add_builtin ("__builtin_aarch64_stshh_df", ftype,
                                   AARCH64_BUILTIN_STSHH_DF);
+
+  tree cv_argtype = build_qualified_type (void_type_node, TYPE_QUAL_CONST
+                                         | TYPE_QUAL_VOLATILE);
+  cv_argtype = build_pointer_type (cv_argtype);
+
+  ftype = build_function_type_list (void_type_node, cv_argtype, NULL_TREE);
+  aarch64_builtin_decls[AARCH64_BUILTIN_PLDIR]
+    = aarch64_general_add_builtin ("__builtin_aarch64_pldir", ftype,
+                                  AARCH64_BUILTIN_PLDIR);
 }
 
 /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group.  */
@@ -4054,6 +4064,15 @@ aarch64_expand_stshh_builtin (tree exp, int fcode)
   expand_insn (icode, 4, ops);
 }
 
+void
+aarch64_expand_pldir_builtin (tree exp)
+{
+  expand_operand ops[1];
+  rtx addr = expand_normal (CALL_EXPR_ARG (exp, 0));
+  create_input_operand (&ops[0], addr, Pmode);
+  expand_insn (CODE_FOR_aarch64_pldir, 1, ops);
+}
+
 /* Expand CALL_EXPR EXP, given that it is a call to the function described
    by BUILTIN_DATA, and return the function's return value.  Put the result
    in TARGET if convenient.  */
@@ -4554,6 +4573,12 @@ aarch64_general_expand_builtin (unsigned int fcode, tree 
exp, rtx target,
     case AARCH64_BUILTIN_STSHH_DF:
       aarch64_expand_stshh_builtin (exp, fcode);
       return target;
+
+    case AARCH64_BUILTIN_PLDIR:
+      {
+       aarch64_expand_pldir_builtin (exp);
+       return target;
+      }
     }
 
   if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 98c65a74c8e..6075efe6e17 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -371,6 +371,7 @@
     UNSPEC_SYSREG_WDI
     UNSPEC_SYSREG_WTI
     UNSPEC_PLDX
+    UNSPEC_PLDIR
     ;; Represents an SVE-style lane index, in which the indexing applies
     ;; within the containing 128-bit block.
     UNSPEC_SVE_LANE_SELECT
@@ -1332,6 +1333,17 @@
   [(set_attr "type" "load_4")]
 )
 
+(define_insn "aarch64_pldir"
+  [(unspec [(match_operand:DI 0 "aarch64_prefetch_operand" "Dp")]
+            UNSPEC_PLDIR)]
+  ""
+  {
+    operands[0] = gen_rtx_MEM (DImode, operands[0]);
+    return "prfm\\tir, %0";
+  }
+  [(set_attr "type" "load_4")]
+)
+
 (define_insn "aarch64_pldx"
   [(unspec [(match_operand 0 "" "")
            (match_operand:DI 1 "aarch64_prefetch_operand" "Dp")] UNSPEC_PLDX)]
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index d2a5be0e8f7..890dea5fa42 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -108,6 +108,14 @@ __pldx (unsigned int __access, unsigned int __cache, 
unsigned int __rettn,
   return __builtin_aarch64_pldx (__access, __cache, __rettn, __addr);
 }
 
+__extension__ extern __inline void
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__pldir (void const volatile *__addr)
+{
+  return __builtin_aarch64_pldir (__addr);
+}
+
+
 __extension__ extern __inline unsigned long
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 __revl (unsigned long __value)
diff --git a/gcc/testsuite/gcc.target/aarch64/pldir.c 
b/gcc/testsuite/gcc.target/aarch64/pldir.c
new file mode 100644
index 00000000000..f395d02b0ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pldir.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a -O2" } */
+
+#include <arm_acle.h>
+
+void
+prefetch_intent_to_read (void *addr)
+{
+  __pldir (addr);
+}
+
+/* { dg-final { scan-assembler "prfm\tir, \[x\[0-9\]+\]" } } */
-- 
2.34.1

Reply via email to