The patch add the Zihintntl instructions in the prefetch pattern.
Zicbop has prefetch instructions. Zihintntl has NTL instructions.
Insert NTL instructions before prefetch instruction, if target
has Zihintntl extension.

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_print_operand): Add 'L' letter
          to print zihintntl instructions string.
        * config/riscv/riscv.md (prefetch): Add zihintntl instructions.

    gcc/testsuite/ChangeLog:

        * gcc.target/riscv/prefetch-zicbop.c: New test.
        * gcc.target/riscv/prefetch-zihintntl.c: New test.
---
 gcc/config/riscv/riscv.cc                     | 22 +++++++++++++++++++
 gcc/config/riscv/riscv.md                     | 10 ++++++---
 .../gcc.target/riscv/prefetch-zicbop.c        | 20 +++++++++++++++++
 .../gcc.target/riscv/prefetch-zihintntl.c     | 20 +++++++++++++++++
 4 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d50ac611e1a..34c672cb8e2 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6485,6 +6485,7 @@ riscv_asm_output_opcode (FILE *asm_out_file, const char 
*p)
    'A' Print the atomic operation suffix for memory model OP.
    'I' Print the LR suffix for memory model OP.
    'J' Print the SC suffix for memory model OP.
+   'L' Print a non-temporal locality hints instruction.
    'z' Print x0 if OP is zero, otherwise print OP normally.
    'i' Print i if the operand is not a register.
    'S' Print shift-index of single-bit mask OP.
@@ -6679,6 +6680,27 @@ riscv_print_operand (FILE *file, rtx op, int letter)
       break;
     }
 
+    case 'L':
+      {
+       const char *ntl_hint = NULL;
+       switch (INTVAL (op))
+         {
+         case 0:
+           ntl_hint = "ntl.all";
+           break;
+         case 1:
+           ntl_hint = "ntl.pall";
+           break;
+         case 2:
+           ntl_hint = "ntl.p1";
+           break;
+         }
+
+      if (ntl_hint)
+       asm_fprintf (file, "%s\n\t", ntl_hint);
+      break;
+      }
+
     case 'i':
       if (code != REG)
         fputs ("i", file);
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 2e2379dfca4..4a3bac26ecd 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4093,12 +4093,16 @@
 {
   switch (INTVAL (operands[1]))
   {
-    case 0: return "prefetch.r\t%a0";
-    case 1: return "prefetch.w\t%a0";
+    case 0: return TARGET_ZIHINTNTL ? "%L2prefetch.r\t%a0" : "prefetch.r\t%a0";
+    case 1: return TARGET_ZIHINTNTL ? "%L2prefetch.w\t%a0" : "prefetch.w\t%a0";
     default: gcc_unreachable ();
   }
 }
-  [(set_attr "type" "store")])
+  [(set_attr "type" "store")
+   (set (attr "length") (if_then_else (and (match_test "TARGET_ZIHINTNTL")
+                                          (match_test "IN_RANGE (INTVAL 
(operands[2]), 0, 2)"))
+                                     (const_string "8")
+                                     (const_string "4")))])
 
 (define_insn "riscv_prefetchi_<mode>"
   [(unspec_volatile:X [(match_operand:X 0 "address_operand" "r")
diff --git a/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c 
b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c
new file mode 100644
index 00000000000..0faa120f1f7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/prefetch-zicbop.c
@@ -0,0 +1,20 @@
+/* { dg-do compile target { { rv64-*-*}}} */
+/* { dg-options "-march=rv64gc_zicbop -mabi=lp64" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+/* { dg-final { scan-assembler-not "ntl.all\t" } } */
+/* { dg-final { scan-assembler-not "ntl.pall\t" } } */
+/* { dg-final { scan-assembler-not "ntl.p1\t" } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c 
b/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c
new file mode 100644
index 00000000000..78a3afe6833
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/prefetch-zihintntl.c
@@ -0,0 +1,20 @@
+/* { dg-do compile target { { rv64-*-*}}} */
+/* { dg-options "-march=rv64gc_zicbop_zihintntl -mabi=lp64" } */
+
+void foo (char *p)
+{
+  __builtin_prefetch (p, 0, 0);
+  __builtin_prefetch (p, 0, 1);
+  __builtin_prefetch (p, 0, 2);
+  __builtin_prefetch (p, 0, 3);
+  __builtin_prefetch (p, 1, 0);
+  __builtin_prefetch (p, 1, 1);
+  __builtin_prefetch (p, 1, 2);
+  __builtin_prefetch (p, 1, 3);
+}
+
+/* { dg-final { scan-assembler-times "ntl.all" 2 } } */
+/* { dg-final { scan-assembler-times "ntl.pall" 2 } } */
+/* { dg-final { scan-assembler-times "ntl.p1" 2 } } */
+/* { dg-final { scan-assembler-times "prefetch.r" 4 } } */
+/* { dg-final { scan-assembler-times "prefetch.w" 4 } } */
-- 
2.40.1

Reply via email to