[1/2,AArch64] Implement hint intrinsics for AArch64

Message ID 3b938af0-7978-2646-80d9-b39ed2d04ba1@arm.com
State New
Headers show
Series
  • [1/2,AArch64] Implement hint intrinsics for AArch64
Related show

Commit Message

Srinath Parvathaneni Jan. 10, 2019, 7:20 p.m.
Hi All,

This patch implements the ACLE hint intrinsics (nop, yield, wfe, wfi, 
sev and sevl), for AArch64.

The instructions are documented in the ArmARM[1] and the intrinsics 
specification will be
published on the Arm website [2].

[1] 
https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
[2] 
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf

Bootstrapped on aarch64-none-linux-gnu and regression tested on 
aarch64-none-elf with no regressions.

Ok for trunk? If ok, could someone commit the patch on my behalf, I 
don't have commit rights.

Thanks,
Srinath

gcc/ChangeLog:

2019-01-10  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* config/aarch64/aarch64.md (yield): New pattern name.
	(wfe): Likewise.
	(wfi): Likewise.
	(sev): Likewise.
	(sevl): Likewise.
	(UNSPECV_YIELD): New volatile unspec.
	(UNSPECV_WFE): Likewise.
	(UNSPECV_WFI): Likewise.
	(UNSPECV_SEV): Likewise.
	(UNSPECV_SEVL): Likewise.
	* config/aarch64/aarch64-builtins.c (aarch64_builtins):
	AARCH64_SYSHINTOP_BUILTIN_NOP: New builtin.
	AARCH64_SYSHINTOP_BUILTIN_YIELD: Likewise.
	AARCH64_SYSHINTOP_BUILTIN_WFE: Likewise.
	AARCH64_SYSHINTOP_BUILTIN_WFI: Likewise.
	AARCH64_SYSHINTOP_BUILTIN_SEV: Likewise.
	AARCH64_SYSHINTOP_BUILTIN_SEVL: Likewise.
	(aarch64_init_syshintop_builtins): New function.
	(aarch64_init_builtins): New call statement.
	(aarch64_expand_builtin): New case.
	* config/aarch64/arm_acle.h (__nop ): New inline function.
	(__yield): Likewise.
	(__sev): Likewise.
	(__sevl): Likewise.
	(__wfi): Likewise.
	(__wfe): Likewise.

gcc/testsuite/ChangeLog:

2019-01-10  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* gcc.target/aarch64/acle/hint-1.c: New test.
	* gcc.target/aarch64/acle/hint-2.c: Likewise.

Comments

Sudakshina Das Jan. 11, 2019, 6:22 p.m. | #1
Hi Srinath

On 10/01/19 19:20, Srinath Parvathaneni wrote:
> Hi All,

> 

> This patch implements the ACLE hint intrinsics (nop, yield, wfe, wfi,

> sev and sevl), for AArch64.

> 

> The instructions are documented in the ArmARM[1] and the intrinsics

> specification will be

> published on the Arm website [2].

> 

> [1]

> https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile

> [2]

> http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf

> 

> Bootstrapped on aarch64-none-linux-gnu and regression tested on

> aarch64-none-elf with no regressions.

> 

> Ok for trunk? If ok, could someone commit the patch on my behalf, I

> don't have commit rights.

> 

> Thanks,

> Srinath

> 

> gcc/ChangeLog:

> 

> 2019-01-10  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

> 

> 	* config/aarch64/aarch64.md (yield): New pattern name.

> 	(wfe): Likewise.

> 	(wfi): Likewise.

> 	(sev): Likewise.

> 	(sevl): Likewise.

> 	(UNSPECV_YIELD): New volatile unspec.

> 	(UNSPECV_WFE): Likewise.

> 	(UNSPECV_WFI): Likewise.

> 	(UNSPECV_SEV): Likewise.

> 	(UNSPECV_SEVL): Likewise.

> 	* config/aarch64/aarch64-builtins.c (aarch64_builtins):

> 	AARCH64_SYSHINTOP_BUILTIN_NOP: New builtin.

> 	AARCH64_SYSHINTOP_BUILTIN_YIELD: Likewise.

> 	AARCH64_SYSHINTOP_BUILTIN_WFE: Likewise.

> 	AARCH64_SYSHINTOP_BUILTIN_WFI: Likewise.

> 	AARCH64_SYSHINTOP_BUILTIN_SEV: Likewise.

> 	AARCH64_SYSHINTOP_BUILTIN_SEVL: Likewise.

> 	(aarch64_init_syshintop_builtins): New function.

> 	(aarch64_init_builtins): New call statement.

> 	(aarch64_expand_builtin): New case.

> 	* config/aarch64/arm_acle.h (__nop ): New inline function.

> 	(__yield): Likewise.

> 	(__sev): Likewise.

> 	(__sevl): Likewise.

> 	(__wfi): Likewise.

> 	(__wfe): Likewise.

> 

> gcc/testsuite/ChangeLog:

> 

> 2019-01-10  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

> 

> 	* gcc.target/aarch64/acle/hint-1.c: New test.

> 	* gcc.target/aarch64/acle/hint-2.c: Likewise.

> 

> 


Thank you for doing this and I am not a maintainer. I have some comments 
bellow:

diff --git a/gcc/config/aarch64/aarch64-builtins.c 
b/gcc/config/aarch64/aarch64-builtins.c
index 
8cced94567008e28b1761ec8771589a3925f2904..d5424f98df1f5c8f206cbded097bdd2dfcd1ca8e 
100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -399,6 +399,13 @@ enum aarch64_builtins
    AARCH64_PAUTH_BUILTIN_AUTIA1716,
    AARCH64_PAUTH_BUILTIN_PACIA1716,
    AARCH64_PAUTH_BUILTIN_XPACLRI,
+  /* System Hint Operation Builtins for AArch64.  */
+  AARCH64_SYSHINTOP_BUILTIN_NOP,
+  AARCH64_SYSHINTOP_BUILTIN_YIELD,
+  AARCH64_SYSHINTOP_BUILTIN_WFE,
+  AARCH64_SYSHINTOP_BUILTIN_WFI,
+  AARCH64_SYSHINTOP_BUILTIN_SEV,
+  AARCH64_SYSHINTOP_BUILTIN_SEVL,
    AARCH64_BUILTIN_MAX
  };

Is there any reason for the naming? They don't seem to be part of any 
extensions? IMHO AARCH64_BUILTIN_NOP, etc looks cleaner and follows 
other builtins which are not part of any extensions.

...
@@ -1395,6 +1436,29 @@ aarch64_expand_builtin (tree exp,
  	}

        return target;
+    case AARCH64_SYSHINTOP_BUILTIN_NOP:
+      emit_insn (GEN_FCN (CODE_FOR_nop) ());
+      return gen_reg_rtx (VOIDmode);
+

Needs a newline before the new case.

...
+(define_insn "yield"
+  [(unspec_volatile [(const_int 0)] UNSPECV_YIELD)]
+  ""
+  "yield"
+  [(set_attr "type" "coproc")]
+)

I don't believe setting the type to coproc in AArch64 is correct. 
Likewise for the other instructions.

...
+/* Test the nop ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-additional-options "-O0" } */
+/* { dg-options "-march=armv8-a" } */
+
+#include "arm_acle.h"
+
+void
+test_hint (void)
+{
+ __nop ();
+}
+
+/* { dg-final { scan-assembler-times "\tnop" 3 } } */

Just curious, why are there 3 nops here?

Thanks
Sudi

> 

> 

> 

>

Patch

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 8cced94567008e28b1761ec8771589a3925f2904..d5424f98df1f5c8f206cbded097bdd2dfcd1ca8e 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -399,6 +399,13 @@  enum aarch64_builtins
   AARCH64_PAUTH_BUILTIN_AUTIA1716,
   AARCH64_PAUTH_BUILTIN_PACIA1716,
   AARCH64_PAUTH_BUILTIN_XPACLRI,
+  /* System Hint Operation Builtins for AArch64.  */
+  AARCH64_SYSHINTOP_BUILTIN_NOP,
+  AARCH64_SYSHINTOP_BUILTIN_YIELD,
+  AARCH64_SYSHINTOP_BUILTIN_WFE,
+  AARCH64_SYSHINTOP_BUILTIN_WFI,
+  AARCH64_SYSHINTOP_BUILTIN_SEV,
+  AARCH64_SYSHINTOP_BUILTIN_SEVL,
   AARCH64_BUILTIN_MAX
 };
 
@@ -977,6 +984,39 @@  aarch64_init_pauth_hint_builtins (void)
 			    NULL_TREE);
 }
 
+/* System Hint Operation builtins for AArch64.  */
+void
+aarch64_init_syshintop_builtins (void)
+{
+  tree vtype_node
+    = build_function_type_list (void_type_node, NULL);
+
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_NOP]
+    = add_builtin_function ("__builtin_aarch64_nop", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_NOP, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_YIELD]
+    = add_builtin_function ("__builtin_aarch64_yield", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_YIELD, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_WFE]
+    = add_builtin_function ("__builtin_aarch64_wfe", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_WFE, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_WFI]
+    = add_builtin_function ("__builtin_aarch64_wfi", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_WFI, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_SEV]
+    = add_builtin_function ("__builtin_aarch64_sev", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_SEV, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+  aarch64_builtin_decls[AARCH64_SYSHINTOP_BUILTIN_SEVL]
+    = add_builtin_function ("__builtin_aarch64_sevl", vtype_node,
+                            AARCH64_SYSHINTOP_BUILTIN_SEVL, BUILT_IN_MD, NULL,
+                            NULL_TREE);
+}
+
 void
 aarch64_init_builtins (void)
 {
@@ -1014,6 +1054,7 @@  aarch64_init_builtins (void)
      register them.  */
   if (!TARGET_ILP32)
     aarch64_init_pauth_hint_builtins ();
+  aarch64_init_syshintop_builtins ();
 }
 
 tree
@@ -1395,6 +1436,29 @@  aarch64_expand_builtin (tree exp,
 	}
 
       return target;
+    case AARCH64_SYSHINTOP_BUILTIN_NOP:
+      emit_insn (GEN_FCN (CODE_FOR_nop) ());
+      return gen_reg_rtx (VOIDmode);
+
+    case AARCH64_SYSHINTOP_BUILTIN_YIELD:
+      emit_insn (GEN_FCN (CODE_FOR_yield) ());
+      return gen_reg_rtx (VOIDmode);
+
+    case AARCH64_SYSHINTOP_BUILTIN_WFE:
+      emit_insn (GEN_FCN (CODE_FOR_wfe) ());
+      return gen_reg_rtx (VOIDmode);
+
+    case AARCH64_SYSHINTOP_BUILTIN_WFI:
+      emit_insn (GEN_FCN (CODE_FOR_wfi) ());
+      return gen_reg_rtx (VOIDmode);
+
+    case AARCH64_SYSHINTOP_BUILTIN_SEV:
+      emit_insn (GEN_FCN (CODE_FOR_sev) ());
+      return gen_reg_rtx (VOIDmode);
+
+    case AARCH64_SYSHINTOP_BUILTIN_SEVL:
+      emit_insn (GEN_FCN (CODE_FOR_sevl) ());
+      return gen_reg_rtx (VOIDmode);
     }
 
   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 82af4d47f78c65880f5eec78add5a69110db7711..9b9819f9877303db7d21bcb840ab583abef14c28 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -233,6 +233,11 @@ 
     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
   ]
 )
 
@@ -634,12 +639,47 @@ 
 )
 
 (define_insn "nop"
-  [(unspec[(const_int 0)] UNSPEC_NOP)]
+  [(unspec [(const_int 0)] UNSPEC_NOP)]
   ""
   "nop"
   [(set_attr "type" "no_insn")]
 )
 
+(define_insn "yield"
+  [(unspec_volatile [(const_int 0)] UNSPECV_YIELD)]
+  ""
+  "yield"
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "wfe"
+  [(unspec_volatile [(const_int 0)] UNSPECV_WFE)]
+  ""
+  "wfe"
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "wfi"
+  [(unspec_volatile [(const_int 0)] UNSPECV_WFI)]
+  ""
+  "wfi"
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "sev"
+  [(unspec_volatile [(const_int 0)] UNSPECV_SEV)]
+  ""
+  "sev"
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "sevl"
+  [(unspec_volatile [(const_int 0)] UNSPECV_SEVL)]
+  ""
+  "sevl"
+  [(set_attr "type" "coproc")]
+)
+
 (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 8504c3f1d7647e9217751a5bf354a884224bc1f1..326f33dfb342657156a962f502355c77714e2b5e 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -90,5 +90,40 @@  __crc32d (uint32_t __a, uint64_t __b)
 #endif
 
 #pragma GCC pop_options
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__nop (void)
+{
+  __builtin_aarch64_nop ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__yield (void)
+{
+  __builtin_aarch64_yield ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__sev (void)
+{
+  __builtin_aarch64_sev ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__sevl (void)
+{
+  __builtin_aarch64_sevl ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__wfi (void)
+{
+  __builtin_aarch64_wfi ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__wfe (void)
+{
+  __builtin_aarch64_wfe ();
+}
 
 #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 0000000000000000000000000000000000000000..8930f1dbe5afb74036ecf34b182338ed81e5323c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
@@ -0,0 +1,14 @@ 
+/* Test the nop ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-additional-options "-O0" } */
+/* { dg-options "-march=armv8-a" } */
+
+#include "arm_acle.h"
+
+void
+test_hint (void)
+{
+ __nop ();
+}
+
+/* { dg-final { scan-assembler-times "\tnop" 3 } } */
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 0000000000000000000000000000000000000000..5b5449ee16ee121ac1799503610c57ab931d42a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
@@ -0,0 +1,53 @@ 
+/* Test the yield ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a" } */
+
+#include "arm_acle.h"
+
+void
+test_hint1 (void)
+{
+ __yield ();
+}
+
+/* { dg-final {scan-assembler "yield" } } */
+
+/* Test the yield ACLE hint intrinsic */
+
+void
+test_hint2 (void)
+{
+ __wfe ();
+}
+
+/* { dg-final {scan-assembler "wfe" } } */
+
+/* Test the wfi ACLE hint intrinsic */
+
+void
+test_hint3 (void)
+{
+__wfi ();
+}
+
+/* { dg-final {scan-assembler "wfi" } } */
+
+/* Test the sev ACLE hint intrinsic */
+
+void
+test_hint4 (void)
+{
+__sev ();
+}
+
+/* { dg-final {scan-assembler "sev" } } */
+
+/* Test the sevl ACLE hint intrinsic */
+
+void
+test_hint5 (void)
+{
+__sevl ();
+}
+
+/* { dg-final {scan-assembler "sevl" } } */