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.parvathan...@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.parvathan...@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" } } */

Reply via email to