Implement x86 pause intrinsic.
authorH.J. Lu <hongjiu.lu@intel.com>
Wed, 25 May 2011 13:42:58 +0000 (13:42 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Wed, 25 May 2011 13:42:58 +0000 (06:42 -0700)
gcc/

2011-05-25  H.J. Lu  <hongjiu.lu@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-25  H.J. Lu  <hongjiu.lu@intel.com>

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

From-SVN: r174197

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/ia32intrin.h
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pause-1.c [new file with mode: 0644]

index 1fc7adb540fdbe9aaefb244a6a235451b6f43312..873de19283131ec5632eb49e53b69621f7ad88af 100644 (file)
@@ -1,3 +1,16 @@
+2011-05-25  H.J. Lu  <hongjiu.lu@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.
+
 2011-05-25  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        PR tree-optimization/46728
index 4b5bc96c49293e42ab886aaf48a8f96ff45d1e43..c7da6d3f26e84ea1c9e5ac0c54ce0acf354948c4 100644 (file)
@@ -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 },
index 49f1ee747fc11d2020d22c6debac208476fb7dee..801573c1e980801b634cb31e2f8b13bfc5e453bc 100644 (file)
   UNSPEC_TRUNC_NOOP
   UNSPEC_DIV_ALREADY_SPLIT
   UNSPEC_CALL_NEEDS_VZEROUPPER
+  UNSPEC_PAUSE
 
   ;; For SSE/MMX support:
   UNSPEC_FIX_NOTRUNC
   [(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")
index 76c20a69a90269e127c91c9aae17cb28467992e3..42ebd17cdbb2525f77d9368df5233b9b965d00b3 100644 (file)
@@ -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
index b5702dbf7d8c061cc24cf71086699d25f3692878..bd2f08023ea1d725f95c6d068ff7d591c6d8e979 100644 (file)
@@ -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.
 
index 7e1878504f7f9aa09999f9f1ba5b8892377bb75c..4258b91106cd389d30b01041da0826265b0da000 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+        * gcc.target/i386/pause-1.c: New.
+
 2011-05-25  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc.dg/stack-usage-1.c: Adjust comment.
diff --git a/gcc/testsuite/gcc.target/i386/pause-1.c b/gcc/testsuite/gcc.target/i386/pause-1.c
new file mode 100644 (file)
index 0000000..50eb8e7
--- /dev/null
@@ -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();
+}