From: Tsukasa OI <research_trasio@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
@@ -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},
@@ -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
@@ -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)
@@ -2192,7 +2192,7 @@
(define_insn "riscv_pause"
[(unspec_volatile [(const_int 0)] UNSPECV_PAUSE)]
- ""
+ "TARGET_ZIHINTPAUSE"
"pause")
;;
deleted file mode 100644
@@ -1,10 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2" } */
-
-void test_pause()
-{
- __builtin_riscv_pause ();
-}
-
-/* { dg-final { scan-assembler "pause" } } */
-
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */