This patch adds support for ACLE system hint intrinsics
__yield(), __wfe(), __wfi(), __sev() and __sevl() and their
corresponding AArch64 builtins. The ACLE specification is
available at [1].
Regression tested on aarch64-none-linux-gnu with no regressions.
Ok for trunk?
Thanks,
Srinath
gcc/ChangeLog:
* config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add
AARCH64_BUILTIN_YIELD, AARCH64_BUILTIN_WFE, AARCH64_BUILTIN_WFI,
AARCH64_BUILTIN_SEV and AARCH64_BUILTIN_SEVL.
(aarch64_init_syshintop_builtins): New function.
(aarch64_general_init_builtins): Call aarch64_init_syshintop_builtins.
(aarch64_general_expand_builtin): Expand the system hint builtins.
* config/aarch64/aarch64.md (unspecv): Add UNSPECV_YIELD, UNSPECV_WFE,
UNSPECV_WFI, UNSPECV_SEV and UNSPECV_SEVL.
(yield): New insn pattern.
(wfe): Likewise.
(wfi): Likewise.
(sev): Likewise.
(sevl): Likewise.
* config/aarch64/arm_acle.h (__yield): Define hint intrinsics.
(__wfe): Likewise.
(__wfi): Likewise.
(__sev): Likewise.
(__sevl): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/acle/hint-1.c: New test.
* gcc.target/aarch64/acle/hint-2.c: Likewise.
[1] https://github.com/ARM-software/acle/blob/main/main/acle.md#hints
---
gcc/config/aarch64/aarch64-builtins.cc | 51 ++++++++++++
gcc/config/aarch64/aarch64.md | 45 +++++++++++
gcc/config/aarch64/arm_acle.h | 16 ++++
.../gcc.target/aarch64/acle/hint-1.c | 26 +++++++
.../gcc.target/aarch64/acle/hint-2.c | 77 +++++++++++++++++++
5 files changed, 215 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
index 8cd1bc4b1a2..5cc5d1491e5 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -751,6 +751,12 @@ enum aarch64_builtins
AARCH64_BUILTIN_STSHH_SF,
AARCH64_BUILTIN_STSHH_DF,
AARCH64_BUILTIN_STSHH_PTR,
+ /* System Hint Operation builtins. */
+ AARCH64_BUILTIN_YIELD,
+ AARCH64_BUILTIN_WFE,
+ AARCH64_BUILTIN_WFI,
+ AARCH64_BUILTIN_SEV,
+ AARCH64_BUILTIN_SEVL,
AARCH64_BUILTIN_MAX
};
@@ -1261,6 +1267,30 @@ aarch64_get_attributes (unsigned int f, machine_mode mode)
return aarch64_add_attribute ("leaf", attrs);
}
+/* System Hint Operation builtins. */
+void
+aarch64_init_syshintop_builtins (void)
+{
+ tree vtype_node
+ = build_function_type_list (void_type_node, NULL);
+
+ aarch64_builtin_decls[AARCH64_BUILTIN_YIELD]
+ = aarch64_general_add_builtin ("__builtin_aarch64_yield",
+ vtype_node, AARCH64_BUILTIN_YIELD);
+ aarch64_builtin_decls[AARCH64_BUILTIN_WFE]
+ = aarch64_general_add_builtin ("__builtin_aarch64_wfe",
+ vtype_node, AARCH64_BUILTIN_WFE);
+ aarch64_builtin_decls[AARCH64_BUILTIN_WFI]
+ = aarch64_general_add_builtin ("__builtin_aarch64_wfi",
+ vtype_node, AARCH64_BUILTIN_WFI);
+ aarch64_builtin_decls[AARCH64_BUILTIN_SEV]
+ = aarch64_general_add_builtin ("__builtin_aarch64_sev",
+ vtype_node, AARCH64_BUILTIN_SEV);
+ aarch64_builtin_decls[AARCH64_BUILTIN_SEVL]
+ = aarch64_general_add_builtin ("__builtin_aarch64_sevl",
+ vtype_node, AARCH64_BUILTIN_SEVL);
+}
+
/* Due to the architecture not providing lane variant of the lane instructions
for fcmla we can't use the standard simd builtin expansion code, but we
still want the majority of the validation that would normally be done. */
@@ -2377,6 +2407,7 @@ aarch64_general_init_builtins (void)
aarch64_init_gcs_builtins ();
aarch64_init_pcdphint_builtins ();
+ aarch64_init_syshintop_builtins ();
if (in_lto_p)
handle_arm_acle_h ();
@@ -4354,6 +4385,26 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
return ops[0].value;
}
+ case AARCH64_BUILTIN_YIELD:
+ emit_insn (GEN_FCN (CODE_FOR_yield) ());
+ return NULL_RTX;
+
+ case AARCH64_BUILTIN_WFE:
+ emit_insn (GEN_FCN (CODE_FOR_wfe) ());
+ return NULL_RTX;
+
+ case AARCH64_BUILTIN_WFI:
+ emit_insn (GEN_FCN (CODE_FOR_wfi) ());
+ return NULL_RTX;
+
+ case AARCH64_BUILTIN_SEV:
+ emit_insn (GEN_FCN (CODE_FOR_sev) ());
+ return NULL_RTX;
+
+ case AARCH64_BUILTIN_SEVL:
+ emit_insn (GEN_FCN (CODE_FOR_sevl) ());
+ return NULL_RTX;
+
case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V2SF:
case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V2SF:
case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V2SF:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9cb55602c36..60dd72e4935 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -425,6 +425,11 @@ (define_c_enum "unspecv" [
UNSPECV_BLOCKAGE ; Represent a blockage
UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier.
+ UNSPECV_YIELD ; Represent yield instruction.
+ UNSPECV_WFE ; Represent wfe instruction.
+ UNSPECV_WFI ; Represent wfi instruction.
+ UNSPECV_SEV ; Represent sev instruction.
+ UNSPECV_SEVL ; Represent sevl instruction.
UNSPECV_BTI_NOARG ; Represent BTI.
UNSPECV_BTI_C ; Represent BTI c.
UNSPECV_BTI_J ; Represent BTI j.
@@ -1334,6 +1339,46 @@ (define_insn "nop"
[(set_attr "type" "no_insn")]
)
+(define_insn "yield"
+ [(unspec_volatile [(const_int 0)] UNSPECV_YIELD)
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "yield"
+ [(set_attr "type" "nop")]
+)
+
+(define_insn "wfe"
+ [(unspec_volatile [(const_int 0)] UNSPECV_WFE)
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "wfe"
+ [(set_attr "type" "nop")]
+)
+
+(define_insn "wfi"
+ [(unspec_volatile [(const_int 0)] UNSPECV_WFI)
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "wfi"
+ [(set_attr "type" "nop")]
+)
+
+(define_insn "sev"
+ [(unspec_volatile [(const_int 0)] UNSPECV_SEV)
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "sev"
+ [(set_attr "type" "nop")]
+)
+
+(define_insn "sevl"
+ [(unspec_volatile [(const_int 0)] UNSPECV_SEVL)
+ (clobber (mem:BLK (scratch)))]
+ ""
+ "sevl"
+ [(set_attr "type" "nop")]
+)
+
(define_insn "prefetch"
[(prefetch (match_operand:DI 0 "aarch64_prefetch_operand" "Dp")
(match_operand:QI 1 "const_int_operand" "")
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index b31e23e6cba..be3b2dc0552 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -353,6 +353,22 @@ __rndrrs (uint64_t *__res)
#pragma GCC pop_options
+/* Sytem hint operations. */
+#define __yield() \
+ __builtin_aarch64_yield ()
+
+#define __wfe() \
+ __builtin_aarch64_wfe ()
+
+#define __wfi() \
+ __builtin_aarch64_wfi ()
+
+#define __sev() \
+ __builtin_aarch64_sev ()
+
+#define __sevl() \
+ __builtin_aarch64_sevl ()
+
#ifdef __cplusplus
}
#endif
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c b/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
new file mode 100644
index 00000000000..17372a09617
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
@@ -0,0 +1,26 @@
+/* Test the ACLE hint intrinsics. */
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_acle.h>
+
+/*
+** test_hint:
+** ...
+** yield
+** wfe
+** sev
+** sevl
+** wfi
+**...
+** ret
+*/
+void
+test_hint ()
+{
+ __yield ();
+ __wfe ();
+ __sev ();
+ __sevl ();
+ __wfi ();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c b/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
new file mode 100644
index 00000000000..151fd690fa2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
@@ -0,0 +1,77 @@
+ /* Test the ACLE hint intrinsics effect on memory. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_acle.h>
+
+/*
+** foo:
+** ...
+** mov w[0-9]+, 5
+** str w[0-9]+, \[x0\]
+** yield
+** mov w[0-9]+, 4
+** str w[0-9]+, \[x0\]
+** wfe
+** mov w[0-9]+, 3
+** str w[0-9]+, \[x0\]
+** sev
+** str w[0-9]+, \[x0\]
+** sevl
+** mov w[0-9]+, 9
+** str w[0-9]+, \[x0\]
+** wfi
+** mov w0, 0
+** ret
+*/
+int foo (int* counter)
+{
+ *counter = 5;
+ __yield();
+ *counter = 4;
+ __wfe();
+ *counter = 3;
+ __sev();
+ *counter = 4;
+ __sevl();
+ *counter = 9;
+ __wfi();
+ return 0;
+}
+
+/*
+** foo1:
+** ...
+** mov w[0-9]+, 5
+** str w[0-9]+, \[x0\]
+** yield
+** mov w[0-9]+, 4
+** str w[0-9]+, \[x0\]
+** yield
+** mov w[0-9]+, 3
+** str w[0-9]+, \[x0\]
+** yield
+** mov w[0-9]+, 6
+** str w[0-9]+, \[x0\]
+** yield
+** mov w[0-9]+, 9
+** str w[0-9]+, \[x0\]
+** yield
+** mov w0, 0
+** ret
+*/
+int foo1 (int* counter)
+{
+ *counter = 5;
+ __yield();
+ *counter = 4;
+ __yield();
+ *counter = 3;
+ __yield();
+ *counter = 6;
+ __yield();
+ *counter = 9;
+ __yield();
+ return 0;
+}