This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2][GCC][ARM] Implement hint intrinsics for ARM


Hi All,

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

The intrinsics specification will be published on the Arm website [1].

[1] 
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf

Bootstrapped on arm-none-linux-gnueabihf, regression tested on 
arm-none-eabi with no regressions and
ran the added tests for arm, thumb-1 and thumb-2 modes.

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/arm/arm-builtins.c (NOP_QUALIFIERS): New qualifier.
	(arm_expand_builtin_args): New case.
	* config/arm/arm.md (yield): New pattern name.
	(wfe): Likewise.
	(wfi): Likewise.
	(sev): Likewise.
	(sevl): Likewise.
	* config/arm/arm_acle.h (__nop ): New inline function.
	(__yield): Likewise.
	(__sev): Likewise.
	(__sevl): Likewise.
	(__wfi): Likewise.
	(__wfe): Likewise.
	* config/arm/arm_acle_builtins.def (VAR1):
	(nop): New builtin definitions.
	(yield): Likewise.
	(sev): Likewise.
	(sevl): Likewise.
	(wfi): Likewise.
	(wfe): Likewise.
	* config/arm/unspecs.md (unspecv):
	(VUNSPEC_YIELD): New volatile unspec.
	(VUNSPEC_SEV): Likewise.
	(VUNSPEC_SEVL): Likewise.
	(VUNSPEC_WFI): Likewise.

gcc/testsuite/ChangeLog:

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

	* gcc.target/arm/acle/nop.c: New test.
	* gcc.target/arm/acle/sev-1.c: Likewise.
	* gcc.target/arm/acle/sev-2.c: Likewise.
	* gcc.target/arm/acle/sev-3.c: Likewise.
	* gcc.target/arm/acle/sevl-1.c: Likewise.
	* gcc.target/arm/acle/sevl-2.c: Likewise.
	* gcc.target/arm/acle/sevl-3.c: Likewise.
	* gcc.target/arm/acle/wfe-1.c: Likewise.
	* gcc.target/arm/acle/wfe-2.c: Likewise.
	* gcc.target/arm/acle/wfe-3.c: Likewise.
	* gcc.target/arm/acle/wfi-1.c: Likewise.
	* gcc.target/arm/acle/wfi-2.c: Likewise.
	* gcc.target/arm/acle/wfi-3.c: Likewise.
	* gcc.target/arm/acle/yield-1.c: Likewise.
	* gcc.target/arm/acle/yield-2.c: Likewise.
	* gcc.target/arm/acle/yield-3.c: Likewise.




diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 563ca51dcd0d63046d2bf577ca86d5f70a466bcf..2afa9649813c0f37a803db5add1139067d83a343 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -85,6 +85,12 @@ enum arm_type_qualifiers
   qualifier_const_void_pointer = 0x802
 };
 
+/* The qualifier allows generation of builtins with no operands.  */
+static enum arm_type_qualifiers
+arm_nop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
+  = { qualifier_void };
+#define NOP_QUALIFIERS (arm_nop_qualifiers)
+
 /*  The qualifier_internal allows generation of a unary builtin from
     a pattern with a third pseudo-operand such as a match_scratch.
     T (T).  */
@@ -2343,6 +2349,10 @@ constant_arg:
   else
     switch (argc)
       {
+      case 0:
+        pat = GEN_FCN (icode) ();
+        break;
+
       case 1:
 	pat = GEN_FCN (icode) (op[0]);
 	break;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index f6196e9316898e3258e08d8f2ece8fe9640676ca..36b24cfdfa6c61d952a5c704f54d37f2b0fdd34e 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8906,6 +8906,76 @@
    (set_attr "type" "mov_reg")]
 )
 
+(define_insn "yield"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_YIELD)]
+  ""
+{
+  if (TARGET_ARM)
+    return ".inst\t0xe320f001\t//yield";
+  else if(TARGET_THUMB2)
+    return ".inst\t0xf3af8001\t//yield";
+  else /* TARGET_THUMB1 */
+    return ".inst\t0xbf10\t//yield";
+}
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "wfe"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_WFE)]
+  ""
+{
+  if (TARGET_ARM)
+    return ".inst\t0xe320f002\t//wfe";
+  else if(TARGET_THUMB2)
+    return ".inst\t0xf3af8002\t//wfe";
+  else /* TARGET_THUMB1 */
+    return ".inst\t0xbf20\t//wfe";
+}
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "wfi"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_WFI)]
+  ""
+{
+  if (TARGET_ARM)
+    return ".inst\t0xe320f003\t//wfi";
+  else if(TARGET_THUMB2)
+    return ".inst\t0xf3af8003\t//wfi";
+  else /* TARGET_THUMB1 */
+    return ".inst\t0xbf30\t//wfi";
+}
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "sev"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_SEV)]
+  ""
+{
+  if (TARGET_ARM)
+    return ".inst\t0xe320f004\t//sev";
+  else if(TARGET_THUMB2)
+    return ".inst\t0xf3af8004\t//sev";
+  else /* TARGET_THUMB1 */
+    return ".inst\t0xbf40\t//sev";
+}
+  [(set_attr "type" "coproc")]
+)
+
+(define_insn "sevl"
+  [(unspec_volatile [(const_int 0)] VUNSPEC_SEVL)]
+  ""
+{
+  if (TARGET_ARM)
+    return ".inst\t0xe320f005\t//sevl";
+  else if(TARGET_THUMB2)
+    return ".inst\t0xf3af8005\t//sevl";
+  else /* TARGET_THUMB1 */
+    return ".inst\t0xbf50\t//sevl";
+}
+  [(set_attr "type" "coproc")]
+)
+
 (define_insn "trap"
   [(trap_if (const_int 1) (const_int 0))]
   ""
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
index c0f6ea2d1567bbbe25045c02191a11427f250ec3..1ea1d7ecf0972c0aa796bf9b6280b6a97ec9e3c7 100644
--- a/gcc/config/arm/arm_acle.h
+++ b/gcc/config/arm/arm_acle.h
@@ -241,5 +241,39 @@ __crc32cd (uint32_t __a, uint64_t __b)
 #ifdef __cplusplus
 }
 #endif
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__nop (void)
+{
+  __builtin_arm_nop ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__yield (void)
+{
+  __builtin_arm_yield ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__sev (void)
+{
+  __builtin_arm_sev ();
+}
 
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__sevl (void)
+{
+  __builtin_arm_sevl ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__wfi (void)
+{
+  __builtin_arm_wfi ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__wfe (void)
+{
+  __builtin_arm_wfe ();
+}
 #endif
diff --git a/gcc/config/arm/arm_acle_builtins.def b/gcc/config/arm/arm_acle_builtins.def
index 47370ecc5ef6b606988a5e423d6d306b038d8d60..0958dbd0adac15104ed5955f828de97a6cadabc6 100644
--- a/gcc/config/arm/arm_acle_builtins.def
+++ b/gcc/config/arm/arm_acle_builtins.def
@@ -42,3 +42,9 @@ VAR1 (MCRR, mcrr, void)
 VAR1 (MCRR, mcrr2, void)
 VAR1 (MRRC, mrrc, di)
 VAR1 (MRRC, mrrc2, di)
+VAR1 (NOP, nop, void)
+VAR1 (NOP, yield, void)
+VAR1 (NOP, wfi, void)
+VAR1 (NOP, wfe, void)
+VAR1 (NOP, sev, void)
+VAR1 (NOP, sevl, void)
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 8f9dbcb08dc2547375e2d5195fe5dbb4098aa29a..b1b99c863684a87134c44ce18bb33cd51ed32cfb 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -172,6 +172,11 @@
   VUNSPEC_MRRC		; Represent the coprocessor mrrc instruction.
   VUNSPEC_MRRC2		; Represent the coprocessor mrrc2 instruction.
   VUNSPEC_SPECULATION_BARRIER ; Represents an unconditional speculation barrier.
+  VUNSPEC_YIELD	; Used by the intrinsic form of the YIELD instruction.
+  VUNSPEC_SEV		; Used by the intrinsic form of the SEV instruction.
+  VUNSPEC_SEVL		; Used by the intrinsic form of the SEVL instruction.
+  VUNSPEC_WFI		; Used by the intrinsic form of the WFI instruction.
+  VUNSPEC_WFE		; Used by the intrinsic form of the WFE instruction.
 ])
 
 ;; Enumerators for NEON unspecs.
diff --git a/gcc/testsuite/gcc.target/arm/acle/nop.c b/gcc/testsuite/gcc.target/arm/acle/nop.c
new file mode 100644
index 0000000000000000000000000000000000000000..ce555bf56cc6d26511bbcce14ad21b24c1d37f50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/nop.c
@@ -0,0 +1,13 @@
+/* Test the nop ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-additional-options "-O0" } */
+
+#include "arm_acle.h"
+
+void
+test_hint (void)
+{
+ __nop ();
+}
+
+/* { dg-final {scan-assembler-times "\tnop" 3 } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sev-1.c b/gcc/testsuite/gcc.target/arm/acle/sev-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..02780caf0bde37995f0dfb1dad58929276df4cd4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sev-1.c
@@ -0,0 +1,14 @@
+/* Test the sev ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-marm" } */
+
+#include "arm_acle.h"
+
+void
+test_sev (void)
+{
+ __sev ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xe320f004\t\/\/sev" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sev-2.c b/gcc/testsuite/gcc.target/arm/acle/sev-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..63ee21c305dd7f58dc63ab03c715ddbd4a63da1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sev-2.c
@@ -0,0 +1,14 @@
+/* Test the sev ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_sev (void)
+{
+ __sev ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xbf40\t\/\/sev" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sev-3.c b/gcc/testsuite/gcc.target/arm/acle/sev-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..85382fda0800b507526d7d47ae2508bbde99222e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sev-3.c
@@ -0,0 +1,14 @@
+/* Test the sev ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_sev (void)
+{
+ __sev ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xf3af8004\t\/\/sev" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sevl-1.c b/gcc/testsuite/gcc.target/arm/acle/sevl-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..75e176001f8cd6f9baa2fce764cc54c3d118c9d3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sevl-1.c
@@ -0,0 +1,14 @@
+/* Test the sevl ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-marm" } */
+
+#include "arm_acle.h"
+
+void
+test_sevl (void)
+{
+ __sevl ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xe320f005\t\/\/sevl" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sevl-2.c b/gcc/testsuite/gcc.target/arm/acle/sevl-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..acd3c96f5a28241fe322f132b910fa4043c93771
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sevl-2.c
@@ -0,0 +1,14 @@
+/* Test the sevl ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_sevl (void)
+{
+ __sevl ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xbf50\t\/\/sevl" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/sevl-3.c b/gcc/testsuite/gcc.target/arm/acle/sevl-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc86213313a1140f870041862ea6d0a7f5b6be51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/sevl-3.c
@@ -0,0 +1,14 @@
+/* Test the sevl ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_sevl (void)
+{
+ __sevl ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xf3af8005\t\/\/sevl" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfe-1.c b/gcc/testsuite/gcc.target/arm/acle/wfe-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..e806ed553e51d76aa1f42ec1aead4a05b1c46b8d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfe-1.c
@@ -0,0 +1,14 @@
+/* Test the wfe ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-marm" } */
+
+#include "arm_acle.h"
+
+void
+test_wfe (void)
+{
+ __wfe ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xe320f002\t\/\/wfe" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfe-2.c b/gcc/testsuite/gcc.target/arm/acle/wfe-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..7ebf5c2b9076bed5ab9b8a4252bc1634028248ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfe-2.c
@@ -0,0 +1,14 @@
+/* Test the wfe ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_wfe (void)
+{
+ __wfe ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xbf20\t\/\/wfe" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfe-3.c b/gcc/testsuite/gcc.target/arm/acle/wfe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..248fac29885a866ee809c44a362e0ced3f9a73ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfe-3.c
@@ -0,0 +1,14 @@
+/* Test the wfe ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_wfe (void)
+{
+ __wfe ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xf3af8002\t\/\/wfe" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfi-1.c b/gcc/testsuite/gcc.target/arm/acle/wfi-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..cfaabed6dbbd00d212f66c7934ab1ab7734a7e92
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfi-1.c
@@ -0,0 +1,14 @@
+/* Test the wfi ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-marm" } */
+
+#include "arm_acle.h"
+
+void
+test_wfi (void)
+{
+ __wfi ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xe320f003\t\/\/wfi" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfi-2.c b/gcc/testsuite/gcc.target/arm/acle/wfi-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..a66a11ada9240a162a974542a53ec7b22c01c297
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfi-2.c
@@ -0,0 +1,14 @@
+/* Test the wfi ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_wfi (void)
+{
+ __wfi ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xbf30\t\/\/wfi" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/wfi-3.c b/gcc/testsuite/gcc.target/arm/acle/wfi-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..40adfc4b0c30015ce8caaab31c3e743b883a3aa2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/wfi-3.c
@@ -0,0 +1,14 @@
+/* Test the wfi ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_wfi (void)
+{
+ __wfi ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xf3af8003\t\/\/wfi" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/yield-1.c b/gcc/testsuite/gcc.target/arm/acle/yield-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..e46a35b0e2123d9d86130f639ab56d73256d6c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/yield-1.c
@@ -0,0 +1,14 @@
+/* Test the yield ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-marm" } */
+
+#include "arm_acle.h"
+
+void
+test_yield (void)
+{
+ __yield ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xe320f001\t\/\/yield" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/yield-2.c b/gcc/testsuite/gcc.target/arm/acle/yield-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..5ef53d6ed8687e8e15cff505c96de2fbdacc3005
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/yield-2.c
@@ -0,0 +1,14 @@
+/* Test the yield ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_yield (void)
+{
+ __yield ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xbf10\t\/\/yield" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/yield-3.c b/gcc/testsuite/gcc.target/arm/acle/yield-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d8a2cca097f647be7263af2613b0e507fbd84cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/yield-3.c
@@ -0,0 +1,14 @@
+/* Test the yield ACLE hint intrinsic */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-additional-options "-mthumb" } */
+
+#include "arm_acle.h"
+
+void
+test_yield (void)
+{
+ __yield ();
+}
+
+/* { dg-final {scan-assembler ".inst\t0xf3af8001\t\/\/yield" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]