Hi,

This patch implements pause intrinsic suggested by Andi.  OK
for trunk?

Thanks.


-- 
H.J.
---
gcc/

2011-05-24  H.J. Lu  <hongjiu...@intel.com>

        * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE.
        (bdesc_special_args): Add pause intrinsic.

        * config/i386/i386.md (UNSPEC_PAUSE): New.
        (pause): Likewise.
        (*pause): Likewise.
        * config/i386/ia32intrin.h (__pause): Likewise.

        * doc/extend.texi (X86 Built-in Functions): Add documentation for
        pause intrinsic.

gcc/testsuite/

2011-05-24  H.J. Lu  <hongjiu...@intel.com>

         * gcc.target/i386/pause-1.c: New.
gcc/

2011-05-24  H.J. Lu  <hongjiu...@intel.com>

	* config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_PAUSE.
	(bdesc_special_args): Add pause intrinsic.

	* config/i386/i386.md (UNSPEC_PAUSE): New.
	(pause): Likewise.
	(*pause): Likewise.
	* config/i386/ia32intrin.h (__pause): Likewise.

	* doc/extend.texi (X86 Built-in Functions): Add documentation for
	pause intrinsic.

gcc/testsuite/

2011-05-24  H.J. Lu  <hongjiu...@intel.com>

	 * gcc.target/i386/pause-1.c: New.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 854e376..174caa0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -23912,6 +23912,7 @@ enum ix86_builtins
   IX86_BUILTIN_CLFLUSH,
   IX86_BUILTIN_MFENCE,
   IX86_BUILTIN_LFENCE,
+  IX86_BUILTIN_PAUSE,
 
   IX86_BUILTIN_BSRSI,
   IX86_BUILTIN_BSRDI,
@@ -24664,6 +24665,7 @@ static const struct builtin_description bdesc_special_args[] =
 {
   { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtsc, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID },
   { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtscp, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED },
+  { ~OPTION_MASK_ISA_64BIT, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID },
 
   /* MMX */
   { OPTION_MASK_ISA_MMX, CODE_FOR_mmx_emms, "__builtin_ia32_emms", IX86_BUILTIN_EMMS, UNKNOWN, (int) VOID_FTYPE_VOID },
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 49f1ee7..801573c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -108,6 +108,7 @@
   UNSPEC_TRUNC_NOOP
   UNSPEC_DIV_ALREADY_SPLIT
   UNSPEC_CALL_NEEDS_VZEROUPPER
+  UNSPEC_PAUSE
 
   ;; For SSE/MMX support:
   UNSPEC_FIX_NOTRUNC
@@ -17716,6 +17717,25 @@
   [(set_attr "type" "other")
    (set_attr "prefix_extra" "1")])
 
+(define_expand "pause"
+  [(set (match_dup 0)
+	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
+  ""
+{
+  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+  MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+;; Use "rep; nop", instead of "pause", to support older assemblers.
+;; They have the same encoding.
+(define_insn "*pause"
+  [(set (match_operand:BLK 0 "" "")
+	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
+  ""
+  "rep; nop"
+  [(set_attr "length" "2")
+   (set_attr "memory" "unknown")])
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")
diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
index 76c20a6..42ebd17 100644
--- a/gcc/config/i386/ia32intrin.h
+++ b/gcc/config/i386/ia32intrin.h
@@ -153,6 +153,14 @@ __rord (unsigned int __X, int __C)
   return (__X >> __C) | (__X << (32 - __C));
 }
 
+/* Pause */
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__pause (void)
+{
+  __builtin_ia32_pause ();
+}
+
 #ifdef __x86_64__
 /* 64bit bsf */
 extern __inline int
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b5702db..bd2f080 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8695,6 +8695,13 @@ __float128 __builtin_fabsq (__float128)
 __float128 __builtin_copysignq (__float128, __float128)
 @end smallexample
 
+The following built-in function is always available.
+
+@table @code
+@item void __builtin_ia32_pause (void)
+Generates the @code{pause} machine instruction with full memory barrier.
+@end table
+
 The following floating point built-in functions are made available in the
 64-bit mode.
 
diff --git a/gcc/testsuite/gcc.target/i386/pause-1.c b/gcc/testsuite/gcc.target/i386/pause-1.c
new file mode 100644
index 0000000..50eb8e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pause-1.c
@@ -0,0 +1,11 @@
+/* Test that we generate pause instruction.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -dp" } */
+/* { dg-final { scan-assembler-times "\\*pause" 1 } } */
+
+#include <x86intrin.h>
+
+void foo(void)
+{
+  __pause();
+}

Reply via email to