i386-common.c (OPTION_MASK_ISA_WAITPKG_SET, [...]): New defines.
authorSebastian Peryt <sebastian.peryt@intel.com>
Fri, 11 May 2018 13:17:42 +0000 (15:17 +0200)
committerSebastian Peryt <speryt@gcc.gnu.org>
Fri, 11 May 2018 13:17:42 +0000 (15:17 +0200)
2018-05-11  Sebastian Peryt  <sebastian.peryt@intel.com>

gcc/

        * common/config/i386/i386-common.c (OPTION_MASK_ISA_WAITPKG_SET,
        OPTION_MASK_ISA_WAITPKG_UNSET): New defines.
        (ix86_handle_option): Handle -mwaitpkg.
        * config.gcc: New header.
        * config/i386/cpuid.h (bit_WAITPKG): New bit.
        * config/i386/driver-i386.c (host_detect_local_cpu): Detect -mwaitpkg.
        * config/i386/i386-builtin-types.def ((UINT8, UNSIGNED, UINT64)): New
        function type.
        * config/i386/i386-c.c (ix86_target_macros_internal): Handle
        OPTION_MASK_ISA_WAITPKG.
        * config/i386/i386.c (ix86_target_string): Add -mwaitpkg.
        (ix86_option_override_internal): Add PTA_WAITPKG.
        (ix86_valid_target_attribute_inner_p): Add -mwaitpkg.
        (enum ix86_builtins): Add IX86_BUILTIN_UMONITOR, IX86_BUILTIN_UMWAIT,
        IX86_BUILTIN_TPAUSE.
        (ix86_init_mmx_sse_builtins): Define __builtin_ia32_umonitor,
        __builtin_ia32_umwait and __builtin_ia32_tpause.
        (ix86_expand_builtin): Expand IX86_BUILTIN_UMONITOR,
        IX86_BUILTIN_UMWAIT, IX86_BUILTIN_TPAUSE.
        * config/i386/i386.h (TARGET_WAITPKG, TARGET_WAITPKG_P): New.
        * config/i386/i386.md (UNSPECV_UMWAIT, UNSPECV_UMONITOR,
        UNSPECV_TPAUSE): New.
        (umwait, umwait_rex64, umonitor_<mode>, tpause, tpause_rex64): New.
        * config/i386/i386.opt: Add -mwaitpkg.
        * config/i386/waitpkgintrin.h: New file.
        * config/i386/x86intrin.h: New header.
        * doc/invoke.texi: Add -mwaitpkg.

gcc/testsuite/

        * gcc.target/i386/tpause-1.c: New test.
        * gcc.target/i386/umonitor-1.c: New test.

From-SVN: r260161

17 files changed:
gcc/ChangeLog
gcc/common/config/i386/i386-common.c
gcc/config.gcc
gcc/config/i386/cpuid.h
gcc/config/i386/driver-i386.c
gcc/config/i386/i386-builtin-types.def
gcc/config/i386/i386-c.c
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/i386.opt
gcc/config/i386/waitpkgintrin.h [new file with mode: 0644]
gcc/config/i386/x86intrin.h
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/tpause-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/umonitor-1.c [new file with mode: 0644]

index 434d443130386e030bf0ea8e34180ee553eb2bb5..aa93ad8f9633ac165b5887987f83c344de293f13 100644 (file)
@@ -1,3 +1,33 @@
+2018-05-11  Sebastian Peryt  <sebastian.peryt@intel.com>
+
+       * common/config/i386/i386-common.c (OPTION_MASK_ISA_WAITPKG_SET,
+       OPTION_MASK_ISA_WAITPKG_UNSET): New defines.
+       (ix86_handle_option): Handle -mwaitpkg.
+       * config.gcc: New header.
+       * config/i386/cpuid.h (bit_WAITPKG): New bit.
+       * config/i386/driver-i386.c (host_detect_local_cpu): Detect -mwaitpkg.
+       * config/i386/i386-builtin-types.def ((UINT8, UNSIGNED, UINT64)): New
+       function type.
+       * config/i386/i386-c.c (ix86_target_macros_internal): Handle
+       OPTION_MASK_ISA_WAITPKG.
+       * config/i386/i386.c (ix86_target_string): Add -mwaitpkg.
+       (ix86_option_override_internal): Add PTA_WAITPKG.
+       (ix86_valid_target_attribute_inner_p): Add -mwaitpkg.
+       (enum ix86_builtins): Add IX86_BUILTIN_UMONITOR, IX86_BUILTIN_UMWAIT,
+       IX86_BUILTIN_TPAUSE.
+       (ix86_init_mmx_sse_builtins): Define __builtin_ia32_umonitor,
+       __builtin_ia32_umwait and __builtin_ia32_tpause.
+       (ix86_expand_builtin): Expand IX86_BUILTIN_UMONITOR,
+       IX86_BUILTIN_UMWAIT, IX86_BUILTIN_TPAUSE.
+       * config/i386/i386.h (TARGET_WAITPKG, TARGET_WAITPKG_P): New.
+       * config/i386/i386.md (UNSPECV_UMWAIT, UNSPECV_UMONITOR,
+       UNSPECV_TPAUSE): New.
+       (umwait, umwait_rex64, umonitor_<mode>, tpause, tpause_rex64): New.
+       * config/i386/i386.opt: Add -mwaitpkg.
+       * config/i386/waitpkgintrin.h: New file.
+       * config/i386/x86intrin.h: New header.
+       * doc/invoke.texi: Add -mwaitpkg.
+
 2018-05-11  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/85606
index 2629ae62a2804805f20bf37f4cb64524fab3518a..b17646c165ad4150acf51b343abfb62ff0446e8f 100644 (file)
@@ -152,6 +152,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_VPCLMULQDQ_SET OPTION_MASK_ISA_VPCLMULQDQ
 #define OPTION_MASK_ISA_MOVDIRI_SET OPTION_MASK_ISA_MOVDIRI
 #define OPTION_MASK_ISA_MOVDIR64B_SET OPTION_MASK_ISA_MOVDIR64B
+#define OPTION_MASK_ISA_WAITPKG_SET OPTION_MASK_ISA_WAITPKG
 
 /* Define a set of ISAs which aren't available when a given ISA is
    disabled.  MMX and SSE ISAs are handled separately.  */
@@ -228,6 +229,7 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_VPCLMULQDQ_UNSET OPTION_MASK_ISA_VPCLMULQDQ
 #define OPTION_MASK_ISA_MOVDIRI_UNSET OPTION_MASK_ISA_MOVDIRI
 #define OPTION_MASK_ISA_MOVDIR64B_UNSET OPTION_MASK_ISA_MOVDIR64B
+#define OPTION_MASK_ISA_WAITPKG_UNSET OPTION_MASK_ISA_WAITPKG
 
 /* SSE4 includes both SSE4.1 and SSE4.2.  -mno-sse4 should the same
    as -mno-sse4.1. */
@@ -608,6 +610,19 @@ ix86_handle_option (struct gcc_options *opts,
        }
       return true;
 
+    case OPT_mwaitpkg:
+      if (value)
+       {
+         opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA_WAITPKG_SET;
+         opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_WAITPKG_SET;
+       }
+      else
+       {
+         opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA_WAITPKG_UNSET;
+         opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_WAITPKG_UNSET;
+       }
+      return true;
+
     case OPT_mavx5124fmaps:
       if (value)
        {
index 96bdd5c542779f84f131299922b985a8246299b5..9c4a84931083bf0c16673477d0fd7e27e1226171 100644 (file)
@@ -384,7 +384,8 @@ i[34567]86-*-*)
                       avx512vbmi2vlintrin.h avx512vnniintrin.h
                       avx512vnnivlintrin.h vaesintrin.h vpclmulqdqintrin.h
                       avx512vpopcntdqvlintrin.h avx512bitalgintrin.h
-                      pconfigintrin.h wbnoinvdintrin.h movdirintrin.h"
+                      pconfigintrin.h wbnoinvdintrin.h movdirintrin.h
+                      waitpkgintrin.h"
        ;;
 x86_64-*-*)
        cpu_type=i386
@@ -413,7 +414,8 @@ x86_64-*-*)
                       avx512vbmi2vlintrin.h avx512vnniintrin.h
                       avx512vnnivlintrin.h vaesintrin.h vpclmulqdqintrin.h
                       avx512vpopcntdqvlintrin.h avx512bitalgintrin.h
-                      pconfigintrin.h wbnoinvdintrin.h movdirintrin.h"
+                      pconfigintrin.h wbnoinvdintrin.h movdirintrin.h
+                      waitpkgintrin.h"
        ;;
 ia64-*-*)
        extra_headers=ia64intrin.h
index a26c5e4979509d199dcb256129d86873254432c4..0672cf54a9b4fbca861f00aedf1e040451004972 100644 (file)
@@ -98,6 +98,7 @@
 #define bit_AVX512VBMI (1 << 1)
 #define bit_PKU        (1 << 3)
 #define bit_OSPKE      (1 << 4)
+#define bit_WAITPKG    (1 << 5)
 #define bit_AVX512VBMI2        (1 << 6)
 #define bit_SHSTK      (1 << 7)
 #define bit_GFNI       (1 << 8)
index 88cf6eaf7255893c3df369507fd6edd31625f456..52891f9ecf062e9ebbd047a926454b9e1514796e 100644 (file)
@@ -424,6 +424,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
   unsigned int has_avx512vnni = 0, has_vaes = 0;
   unsigned int has_vpclmulqdq = 0;
   unsigned int has_movdiri = 0, has_movdir64b = 0;
+  unsigned int has_waitpkg = 0;
 
   bool arch;
 
@@ -527,6 +528,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
 
       has_shstk = ecx & bit_SHSTK;
       has_pconfig = edx & bit_PCONFIG;
+      has_waitpkg = ecx & bit_WAITPKG;
     }
 
   if (max_level >= 13)
@@ -1108,6 +1110,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
       const char *avx512bitalg = has_avx512bitalg ? " -mavx512bitalg" : " -mno-avx512bitalg";
       const char *movdiri = has_movdiri ? " -mmovdiri" : " -mno-movdiri";
       const char *movdir64b = has_movdir64b ? " -mmovdir64b" : " -mno-movdir64b";
+      const char *waitpkg = has_waitpkg ? " -mwaitpkg" : " -mno-waitpkg";
       options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
                        sse4a, cx16, sahf, movbe, aes, sha, pclmul,
                        popcnt, abm, lwp, fma, fma4, xop, bmi, sgx, bmi2,
@@ -1120,7 +1123,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
                        avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw,
                        clwb, mwaitx, clzero, pku, rdpid, gfni, shstk,
                        avx512vbmi2, avx512vnni, vaes, vpclmulqdq,
-                       avx512bitalg, movdiri, movdir64b, NULL);
+                       avx512bitalg, movdiri, movdir64b, waitpkg, NULL);
     }
 
 done:
index eec01a2b6b9904607201a1d41ab8a795e688f043..6a75415d1fd0301dff3b694c69dd2b9e55e4d1f9 100644 (file)
@@ -290,6 +290,7 @@ DEF_FUNCTION_TYPE (VOID, UINT64)
 DEF_FUNCTION_TYPE (VOID, UINT64, PVOID)
 DEF_FUNCTION_TYPE (VOID, UNSIGNED)
 DEF_FUNCTION_TYPE (VOID, UNSIGNED, PVOID)
+DEF_FUNCTION_TYPE (UINT8, UNSIGNED, UINT64)
 DEF_FUNCTION_TYPE (INT, PUSHORT)
 DEF_FUNCTION_TYPE (INT, PUNSIGNED)
 DEF_FUNCTION_TYPE (INT, PULONGLONG)
index 3df599cdc8b98720307a60eed1b23e5dab7b547b..93766be7230674903385e4c7aadb428dee82aa40 100644 (file)
@@ -516,6 +516,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__MOVDIRI__");
   if (isa_flag2 & OPTION_MASK_ISA_MOVDIR64B)
     def_or_undef (parse_in, "__MOVDIR64B__");
+  if (isa_flag2 & OPTION_MASK_ISA_WAITPKG)
+    def_or_undef (parse_in, "__WAITPKG__");
   if (TARGET_IAMCU)
     {
       def_or_undef (parse_in, "__iamcu");
index 526e7d162c6e93732e7414ac282f7fbfbdc64638..ffb1386e80f370a8ca2f255acd9de40d0b44aa5e 100644 (file)
@@ -2772,7 +2772,8 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
     { "-mmovbe",       OPTION_MASK_ISA_MOVBE },
     { "-mclzero",      OPTION_MASK_ISA_CLZERO },
     { "-mmwaitx",      OPTION_MASK_ISA_MWAITX },
-    { "-mmovdir64b",   OPTION_MASK_ISA_MOVDIR64B }
+    { "-mmovdir64b",   OPTION_MASK_ISA_MOVDIR64B },
+    { "-mwaitpkg",     OPTION_MASK_ISA_WAITPKG }
   };
   static struct ix86_target_opts isa_opts[] =
   {
@@ -3455,6 +3456,7 @@ ix86_option_override_internal (bool main_args_p,
   const wide_int_bitmask PTA_RDPID (0, HOST_WIDE_INT_1U << 6);
   const wide_int_bitmask PTA_PCONFIG (0, HOST_WIDE_INT_1U << 7);
   const wide_int_bitmask PTA_WBNOINVD (0, HOST_WIDE_INT_1U << 8);
+  const wide_int_bitmask PTA_WAITPKG (0, HOST_WIDE_INT_1U << 9);
 
   const wide_int_bitmask PTA_CORE2 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2
     | PTA_SSE3 | PTA_SSSE3 | PTA_CX16 | PTA_FXSR;
@@ -5387,6 +5389,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
     IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),
     IX86_ATTR_ISA ("movdiri", OPT_mmovdiri),
     IX86_ATTR_ISA ("movdir64b", OPT_mmovdir64b),
+    IX86_ATTR_ISA ("waitpkg", OPT_mwaitpkg),
 
     /* enum options */
     IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -30642,6 +30645,9 @@ enum ix86_builtins
   IX86_BUILTIN_CLFLUSH,
   IX86_BUILTIN_MONITOR,
   IX86_BUILTIN_MWAIT,
+  IX86_BUILTIN_UMONITOR,
+  IX86_BUILTIN_UMWAIT,
+  IX86_BUILTIN_TPAUSE,
   IX86_BUILTIN_CLZERO,
   IX86_BUILTIN_VEC_INIT_V2SI,
   IX86_BUILTIN_VEC_INIT_V4HI,
@@ -31973,6 +31979,14 @@ ix86_init_mmx_sse_builtins (void)
   def_builtin2 (OPTION_MASK_ISA_CLZERO, "__builtin_ia32_clzero",
                VOID_FTYPE_PCVOID, IX86_BUILTIN_CLZERO);
 
+  /* WAITPKG.  */
+  def_builtin2 (OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_umonitor",
+              VOID_FTYPE_PVOID, IX86_BUILTIN_UMONITOR);
+  def_builtin2 (OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_umwait",
+              UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_UMWAIT);
+  def_builtin2 (OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_tpause",
+              UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_TPAUSE);
+
   /* Add FMA4 multi-arg argument instructions */
   for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
     {
@@ -37048,6 +37062,82 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
       emit_insn (gen_mwaitx (op0, op1, op2));
       return 0;
 
+    case IX86_BUILTIN_UMONITOR:
+      arg0 = CALL_EXPR_ARG (exp, 0);
+      op0 = expand_normal (arg0);
+
+      op0 = ix86_zero_extend_to_Pmode (op0);
+
+      insn = (TARGET_64BIT
+             ? gen_umonitor_di (op0)
+             : gen_umonitor_si (op0));
+
+      emit_insn (insn);
+      return 0;
+
+    case IX86_BUILTIN_UMWAIT:
+    case IX86_BUILTIN_TPAUSE:
+      arg0 = CALL_EXPR_ARG (exp, 0);
+      arg1 = CALL_EXPR_ARG (exp, 1);
+      op0 = expand_normal (arg0);
+      op1 = expand_normal (arg1);
+
+      if (!REG_P (op0))
+       op0 = copy_to_mode_reg (SImode, op0);
+
+      op1 = force_reg (DImode, op1);
+
+      if (TARGET_64BIT)
+       {
+         op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32),
+                                    NULL, 1, OPTAB_DIRECT);
+         switch (fcode)
+           {
+           case IX86_BUILTIN_UMWAIT:
+             icode = CODE_FOR_umwait_rex64;
+             break;
+           case IX86_BUILTIN_TPAUSE:
+             icode = CODE_FOR_tpause_rex64;
+             break;
+           default:
+             gcc_unreachable ();
+           }
+
+         op2 = gen_lowpart (SImode, op2);
+         op1 = gen_lowpart (SImode, op1);
+         pat = GEN_FCN (icode) (op0, op1, op2);
+       }
+      else
+       {
+         switch (fcode)
+           {
+           case IX86_BUILTIN_UMWAIT:
+             icode = CODE_FOR_umwait;
+             break;
+           case IX86_BUILTIN_TPAUSE:
+             icode = CODE_FOR_tpause;
+             break;
+           default:
+             gcc_unreachable ();
+           }
+         pat = GEN_FCN (icode) (op0, op1);
+       }
+
+      if (!pat)
+       return 0;
+
+      emit_insn (pat);
+
+      if (target == 0
+         || !register_operand (target, QImode))
+       target = gen_reg_rtx (QImode);
+
+      pat = gen_rtx_EQ (QImode, gen_rtx_REG (CCCmode, FLAGS_REG),
+                       const0_rtx);
+      emit_insn (gen_rtx_SET (target, pat));
+
+      return target;
+
     case IX86_BUILTIN_CLZERO:
       arg0 = CALL_EXPR_ARG (exp, 0);
       op0 = expand_normal (arg0);
index 787bf9fd39a3a8918ca8959a717fac58fc5f955c..8fc980f3ca373ad9d7b0c0c31efaab58bc15383f 100644 (file)
@@ -189,6 +189,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_MOVDIRI_P(x) TARGET_ISA_MOVDIRI_P(x)
 #define TARGET_MOVDIR64B       TARGET_ISA_MOVDIR64B
 #define TARGET_MOVDIR64B_P(x) TARGET_ISA_MOVDIR64B_P(x)
+#define TARGET_WAITPKG TARGET_ISA_WAITPKG
+#define TARGET_WAITPKG_P(x)    TARGET_ISA_WAITPKG_P(x)
 
 #define TARGET_LP64    TARGET_ABI_64
 #define TARGET_LP64_P(x)       TARGET_ABI_64_P(x)
index 97b1ca318006dc1baf3caa7ea719a8728dd3c84d..1ba352ac293734852867874ad59d6f38fb14afc9 100644 (file)
   UNSPECV_WRUSS
   UNSPECV_SETSSBSY
   UNSPECV_CLRSSBSY
+
+  ;; For MOVDIRI and MOVDIR64B support
   UNSPECV_MOVDIRI
   UNSPECV_MOVDIR64B
+
+  ;; For WAITPKG support
+  UNSPECV_UMWAIT
+  UNSPECV_UMONITOR
+  UNSPECV_TPAUSE
 ])
 
 ;; Constants to represent rounding modes in the ROUND instruction
   "wbnoinvd"
   [(set_attr "type" "other")])
 
+;; MOVDIRI and MOVDIR64B
+
 (define_insn "movdiri<mode>"
-  [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
-       (match_operand:SWI48 1 "register_operand" "r")]
-                  UNSPECV_MOVDIRI)]
+  [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
+                          (match_operand:SWI48 1 "register_operand" "r")]
+                         UNSPECV_MOVDIRI)]
   "TARGET_MOVDIRI"
   "movdiri\t{%1, %0|%0, %1}"
   [(set_attr "type" "other")])
 
 (define_insn "movdir64b_<mode>"
-  [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
-       (match_operand:XI 1 "memory_operand")]
-                UNSPECV_MOVDIR64B)]
+  [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
+                       (match_operand:XI 1 "memory_operand")]
+                      UNSPECV_MOVDIR64B)]
   "TARGET_MOVDIR64B"
   "movdir64b\t{%1, %0|%0, %1}"
   [(set_attr "type" "other")])
 
+;; WAITPKG
+
+(define_insn "umwait"
+  [(set (reg:CCC FLAGS_REG)
+       (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
+                             (match_operand:DI 1 "register_operand" "A")]
+                            UNSPECV_UMWAIT))]
+  "!TARGET_64BIT && TARGET_WAITPKG"
+  "umwait\t%0"
+  [(set_attr "length" "3")])
+
+(define_insn "umwait_rex64"
+  [(set (reg:CCC FLAGS_REG)
+       (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
+                             (match_operand:SI 1 "register_operand" "a")
+                             (match_operand:SI 2 "register_operand" "d")]
+                            UNSPECV_UMWAIT))]
+  "TARGET_64BIT && TARGET_WAITPKG"
+  "umwait\t%0"
+  [(set_attr "length" "3")])
+
+(define_insn "umonitor_<mode>"
+  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
+                   UNSPECV_UMONITOR)]
+  "TARGET_WAITPKG"
+  "umonitor\t%0"
+  [(set (attr "length")
+     (symbol_ref ("(Pmode != word_mode) + 3")))])
+
+(define_insn "tpause"
+  [(set (reg:CCC FLAGS_REG)
+       (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
+                             (match_operand:DI 1 "register_operand" "A")]
+                            UNSPECV_TPAUSE))]
+  "!TARGET_64BIT && TARGET_WAITPKG"
+  "tpause\t%0"
+  [(set_attr "length" "3")])
+
+(define_insn "tpause_rex64"
+  [(set (reg:CCC FLAGS_REG)
+       (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
+                             (match_operand:SI 1 "register_operand" "a")
+                             (match_operand:SI 2 "register_operand" "d")]
+                            UNSPECV_TPAUSE))]
+  "TARGET_64BIT && TARGET_WAITPKG"
+  "tpause\t%0"
+  [(set_attr "length" "3")])
+
 (include "mmx.md")
 (include "sse.md")
 (include "sync.md")
index d9bd909a8854f40dca3638ae8117e1d18f8cdd13..eec702623d2647e2da04908bae3b1def2f019a2b 100644 (file)
@@ -1055,3 +1055,7 @@ Support MOVDIRI built-in functions and code generation.
 mmovdir64b
 Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save
 Support MOVDIR64B built-in functions and code generation.
+
+mwaitpkg
+Target Report Mask(ISA_WAITPKG) Var(ix86_isa_flags2) Save
+Support WAITPKG built-in functions and code generation.
diff --git a/gcc/config/i386/waitpkgintrin.h b/gcc/config/i386/waitpkgintrin.h
new file mode 100644 (file)
index 0000000..8b68091
--- /dev/null
@@ -0,0 +1,63 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#if !defined _X86INTRIN_H_INCLUDED
+# error "Never use <waitpkgintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef _WAITPKG_H_INCLUDED
+#define _WAITPKG_H_INCLUDED
+
+#ifndef __WAITPKG__
+#pragma GCC push_options
+#pragma GCC target("waitpkg")
+#define __DISABLE_WAITPKG__
+#endif /* __WAITPKG__ */
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_umonitor (void *__A)
+{
+  __builtin_ia32_umonitor (__A);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_umwait (unsigned int __A, unsigned long long __B)
+{
+  return __builtin_ia32_umwait (__A, __B);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_tpause (unsigned int __A, unsigned long long __B)
+{
+  return __builtin_ia32_tpause (__A, __B);
+}
+
+#ifdef __DISABLE_WAITPKG__
+#undef __DISABLE_WAITPKG__
+#pragma GCC pop_options
+#endif /* __DISABLE_WAITPKG__ */
+
+#endif /* _WAITPKG_H_INCLUDED.  */
index b12aecc80b51a740b37a2b8924c0c747c5c0dae8..71a33feb7786c1f1c017c03979dab4b87dac5bdc 100644 (file)
 
 #include <pkuintrin.h>
 
+#include <waitpkgintrin.h>
+
 #endif /* __iamcu__ */
 
 #endif /* _X86INTRIN_H_INCLUDED */
index 6019e1f7ec835f333eae90565adb51746e1d86cb..8066fd3f5cc904f33fb8f820a834ef07564a6409 100644 (file)
@@ -1258,7 +1258,7 @@ See RS/6000 and PowerPC Options.
 -mprefetchwt1  -mclflushopt  -mxsavec  -mxsaves @gol
 -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -mfma4  -mxop @gol
 -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mlwp  -mmpx  @gol
--mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  @gol
+-mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  -mwaitpkg @gol
 -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
 -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
 -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol
@@ -27246,6 +27246,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
 @itemx -mvaes
 @opindex mvaes
 @need 200
+@itemx -mwaitpkg
+@opindex -mwaitpkg
+@need 200
 @itemx -mvpclmulqdq
 @opindex mvpclmulqdq
 @need 200
@@ -27263,7 +27266,7 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
 These switches enable the use of instructions in the MMX, SSE,
 SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD,
 SHA, AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM,
-AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, BMI, BMI2, VAES,
+AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, BMI, BMI2, VAES, WAITPKG,
 FXSR, XSAVE, XSAVEOPT, LZCNT, RTM, MPX, MWAITX, PKU, IBT, SHSTK, AVX512VBMI2,
 GFNI, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B,
 AVX512VPOPCNTDQ3DNow!@: or enhanced 3DNow!@: extended instruction sets.
index ca16f5cc5a16fae10aef1daf62f82e0cf71c85ec..bc367196b1074c118510b64f3fe325c943435682 100644 (file)
@@ -1,3 +1,8 @@
+2018-05-11  Sebastian Peryt  <sebastian.peryt@intel.com>
+
+       * gcc.target/i386/tpause-1.c: New test.
+       * gcc.target/i386/umonitor-1.c: New test.
+
 2018-05-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/85696
diff --git a/gcc/testsuite/gcc.target/i386/tpause-1.c b/gcc/testsuite/gcc.target/i386/tpause-1.c
new file mode 100644 (file)
index 0000000..6b0d393
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mwaitpkg" } */
+/* { dg-final { scan-assembler-times "tpause\[ \\t\]+\[^\{\n\]*%" 3 } } */
+/* { dg-final { scan-assembler-times "setc\[ \\t\]+\[^\{\n\]*%" 3 } } */
+
+#include <x86intrin.h>
+
+unsigned char
+foo (unsigned x, unsigned y)
+{
+   return _tpause (x, y);
+}
+
+unsigned char
+bar (unsigned x, unsigned long long y)
+{
+   return _tpause (x, y);
+}
+
+unsigned char
+foo1 (void)
+{
+   return _tpause (0, 0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/umonitor-1.c b/gcc/testsuite/gcc.target/i386/umonitor-1.c
new file mode 100644 (file)
index 0000000..d58e1e8
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mwaitpkg" } */
+/* { dg-final { scan-assembler-times "umonitor\[ \\t\]+\[^\{\n\]*%"  3 } } */
+/* { dg-final { scan-assembler-times "umwait"  3 } } */
+/* { dg-final { scan-assembler-times "setc\[ \\t\]+\[^\{\n\]*%" 3 } } */
+
+/* Verify that they work in both 32bit and 64bit.  */
+
+#include <x86intrin.h>
+
+unsigned char
+foo (void *p, unsigned x, unsigned y)
+{
+   _umonitor (p);
+   return _umwait (x, y);
+}
+
+unsigned char
+bar (void *p, unsigned x, unsigned long long y)
+{
+   _umonitor (p);
+   return _umwait (x, y);
+}
+
+unsigned char
+foo1 (char *p)
+{
+   _umonitor (p);
+   return _umwait (0, 0);
+}