From: Tsukasa OI <research_tra...@irq.a4lg.com>

The "pause" RISC-V hint instruction requires the 'Zihintpause' extension
(in the assembler).  However, GCC emits "pause" unconditionally, making
an assembler error while compiling code with __builtin_riscv_pause while
the 'Zihintpause' extension disabled.

Despite that the "pause" instruction code (0x0100000f) is a HINT and
emitting its instruction code is safe in any environment, enabling the
built-in only for certain environment is not a good idea.

This commit implements handling for the 'Zihintpause' extension and makes
__built_riscv_pause built-in 'Zihintpause'-only.

gcc/ChangeLog:

        * common/config/riscv/riscv-common.cc
        (riscv_ext_version_table): Implement the 'Zihintpause' extension,
        version 2.0.  (riscv_ext_flag_table) Add 'Zihintpause' handling.
        * config/riscv/riscv-builtins.cc: Remove availability predicate
        "always" and add "hint_pause", corresponding the existence of the
        'Zihintpause' extension.
        (riscv_builtins) Change che "riscv_pause" requirements.
        * config/riscv/riscv-opts.h
        (MASK_ZIHINTPAUSE, TARGET_ZIHINTPAUSE): New.
        * config/riscv/riscv.md (riscv_pause): Make it only available when
        the 'Zihintpause' extension is enabled.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/builtin_pause.c: Removed.
        * gcc.target/riscv/zihintpause-1.c:
        New test when the 'Zihintpause' extension is enabled.
        * gcc.target/riscv/zihintpause-2.c: Likewise.
---
 gcc/common/config/riscv/riscv-common.cc        |  2 ++
 gcc/config/riscv/riscv-builtins.cc             |  4 ++--
 gcc/config/riscv/riscv-opts.h                  |  2 ++
 gcc/config/riscv/riscv.md                      |  2 +-
 gcc/testsuite/gcc.target/riscv/builtin_pause.c | 10 ----------
 gcc/testsuite/gcc.target/riscv/zihintpause-1.c | 11 +++++++++++
 gcc/testsuite/gcc.target/riscv/zihintpause-2.c | 11 +++++++++++
 7 files changed, 29 insertions(+), 13 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/riscv/builtin_pause.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zihintpause-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/zihintpause-2.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index f25131eab28b..b77fdb909567 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -209,6 +209,7 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zkt",   ISA_SPEC_CLASS_NONE, 1, 0},
 
   {"zihintntl", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zihintpause", ISA_SPEC_CLASS_NONE, 2, 0},
 
   {"zicboz",ISA_SPEC_CLASS_NONE, 1, 0},
   {"zicbom",ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1343,6 +1344,7 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zkt",    &gcc_options::x_riscv_zk_subext, MASK_ZKT},
 
   {"zihintntl", &gcc_options::x_riscv_zi_subext, MASK_ZIHINTNTL},
+  {"zihintpause", &gcc_options::x_riscv_zi_subext, MASK_ZIHINTPAUSE},
 
   {"zicboz", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOZ},
   {"zicbom", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOM},
diff --git a/gcc/config/riscv/riscv-builtins.cc 
b/gcc/config/riscv/riscv-builtins.cc
index 79681d759628..73e1512a5992 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -122,7 +122,7 @@ AVAIL (clmul_zbkc32_or_zbc32, (TARGET_ZBKC || TARGET_ZBC) 
&& !TARGET_64BIT)
 AVAIL (clmul_zbkc64_or_zbc64, (TARGET_ZBKC || TARGET_ZBC) && TARGET_64BIT)
 AVAIL (clmulr_zbc32, TARGET_ZBC && !TARGET_64BIT)
 AVAIL (clmulr_zbc64, TARGET_ZBC && TARGET_64BIT)
-AVAIL (always,     (!0))
+AVAIL (hint_pause, TARGET_ZIHINTPAUSE)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -179,7 +179,7 @@ static const struct riscv_builtin_description 
riscv_builtins[] = {
 
   DIRECT_BUILTIN (frflags, RISCV_USI_FTYPE, hard_float),
   DIRECT_NO_TARGET_BUILTIN (fsflags, RISCV_VOID_FTYPE_USI, hard_float),
-  DIRECT_NO_TARGET_BUILTIN (pause, RISCV_VOID_FTYPE, always),
+  DIRECT_NO_TARGET_BUILTIN (pause, RISCV_VOID_FTYPE, hint_pause),
 };
 
 /* Index I is the function declaration for riscv_builtins[I], or null if the
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 28d9b81bd800..a6c3e0c9098f 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -102,10 +102,12 @@ enum riscv_entity
 #define MASK_ZICSR    (1 << 0)
 #define MASK_ZIFENCEI (1 << 1)
 #define MASK_ZIHINTNTL (1 << 2)
+#define MASK_ZIHINTPAUSE (1 << 3)
 
 #define TARGET_ZICSR    ((riscv_zi_subext & MASK_ZICSR) != 0)
 #define TARGET_ZIFENCEI ((riscv_zi_subext & MASK_ZIFENCEI) != 0)
 #define TARGET_ZIHINTNTL ((riscv_zi_subext & MASK_ZIHINTNTL) != 0)
+#define TARGET_ZIHINTPAUSE ((riscv_zi_subext & MASK_ZIHINTPAUSE) != 0)
 
 #define MASK_ZAWRS   (1 << 0)
 #define TARGET_ZAWRS ((riscv_za_subext & MASK_ZAWRS) != 0)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 688fd697255b..44ea1c54b96b 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -2192,7 +2192,7 @@
 
 (define_insn "riscv_pause"
   [(unspec_volatile [(const_int 0)] UNSPECV_PAUSE)]
-  ""
+  "TARGET_ZIHINTPAUSE"
   "pause")
 
 ;;
diff --git a/gcc/testsuite/gcc.target/riscv/builtin_pause.c 
b/gcc/testsuite/gcc.target/riscv/builtin_pause.c
deleted file mode 100644
index 9250937cabb9..000000000000
--- a/gcc/testsuite/gcc.target/riscv/builtin_pause.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2" }  */
-
-void test_pause()
-{
-  __builtin_riscv_pause ();
-}
-
-/* { dg-final { scan-assembler "pause" } } */
-
diff --git a/gcc/testsuite/gcc.target/riscv/zihintpause-1.c 
b/gcc/testsuite/gcc.target/riscv/zihintpause-1.c
new file mode 100644
index 000000000000..fc86efe55902
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zihintpause-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_zihintpause -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+
+void
+test ()
+{
+  __builtin_riscv_pause ();
+}
+
+/* { dg-final { scan-assembler-times "\tpause" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/zihintpause-2.c 
b/gcc/testsuite/gcc.target/riscv/zihintpause-2.c
new file mode 100644
index 000000000000..4eaca95e9f02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zihintpause-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zihintpause -mabi=ilp32" } */
+/* { dg-skip-if "" { *-*-* } { "-g" "-flto"} } */
+
+void
+test ()
+{
+  __builtin_riscv_pause ();
+}
+
+/* { dg-final { scan-assembler-times "\tpause" 1 } } */
-- 
2.41.0

Reply via email to