aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorliuhongt <hongtao.liu@intel.com>2019-05-20 17:56:41 +0800
committerliuhongt <hongtao.liu@intel.com>2020-10-15 11:02:49 +0800
commit299a53d7979aaa639298b95bd46b69d3a8546f49 (patch)
tree38526ee4a057f3d8b01d302af56a847911809f03
parentb2698c21f2cdbe579bd0271cca8dc7fba7a3dc25 (diff)
downloadgcc-299a53d7979aaa639298b95bd46b69d3a8546f49.zip
gcc-299a53d7979aaa639298b95bd46b69d3a8546f49.tar.gz
gcc-299a53d7979aaa639298b95bd46b69d3a8546f49.tar.bz2
Enable gcc support for UINTR
2020-05-20 Hongtao Liu <hongtao.liu@intel.com> gcc/ * common/config/i386/cpuinfo.h (get_available_features): Detect UINTR. * common/config/i386/i386-common.c (OPTION_MASK_ISA2_UINTR_SET OPTION_MASK_ISA2_UINTR_UNSET): New. (ix86_handle_option): Handle -muintr. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_UINTR. * common/config/i386/i386-isas.h: Add ISA_NAMES_TABLE_ENTRY for uintr. * config.gcc: Add uintrintrin.h to extra_headers. * config/i386/uintrintrin.h: New. * config/i386/cpuid.h (bit_UINTR): New. * config/i386/i386-builtin-types.def: Add new types. * config/i386/i386-builtin.def: Add new builtins. * config/i386/i386-builtins.c (ix86_init_mmx_sse_builtins): Add __builtin_ia32_testui. * config/i386/i386-builtins.h (ix86_builtins): Add IX86_BUILTIN_TESTUI. * config/i386/i386-c.c (ix86_target_macros_internal): Define __UINTR__. * config/i386/i386-expand.c (ix86_expand_special_args_builtin): Handle UINT8_FTYPE_VOID. (ix86_expand_builtin): Handle IX86_BUILTIN_TESTUI. * config/i386/i386-options.c (isa2_opts): Add -muintr. (ix86_valid_target_attribute_inner_p): Handle UINTR. (ix86_option_override_internal): Add TARGET_64BIT check for UINTR. * config/i386/i386.h (TARGET_UINTR, TARGET_UINTR_P, PTA_UINTR): New. (PTA_SAPPHIRRAPIDS): Add PTA_UINTR. * config/i386/i386.opt: Add -muintr. * config/i386/i386.md (define_int_iterator UINTR_UNSPECV): New. (define_int_attr uintr_unspecv): New. (uintr_<uintr_unspecv>, uintr_senduipi, testui): New define_insn patterns. * config/i386/x86gprintrin.h: Include uintrintrin.h * doc/invoke.texi: Document -muintr. * doc/extend.texi: Document uintr. gcc/testsuite/ * gcc.target/i386/funcspec-56.inc: Add new target attribute. * gcc.target/i386/uintr-1.c: New test. * gcc.target/i386/uintr-2.c: Ditto. * gcc.target/i386/uintr-3.c: Ditto. * gcc.target/i386/uintr-4.c: Ditto. * gcc.target/i386/uintr-5.c: Ditto. * gcc.target/i386/x86gprintrin-1.c: Add -muintr for 64bit target. * gcc.target/i386/x86gprintrin-2.c: Ditto. * gcc.target/i386/x86gprintrin-3.c: Ditto. * gcc.target/i386/x86gprintrin-4.c: Add muintr for 64bit target. * gcc.target/i386/x86gprintrin-5.c: Ditto.
-rw-r--r--gcc/common/config/i386/cpuinfo.h2
-rw-r--r--gcc/common/config/i386/i386-common.c15
-rw-r--r--gcc/common/config/i386/i386-cpuinfo.h1
-rw-r--r--gcc/common/config/i386/i386-isas.h1
-rw-r--r--gcc/config.gcc4
-rw-r--r--gcc/config/i386/cpuid.h1
-rw-r--r--gcc/config/i386/i386-builtin-types.def1
-rw-r--r--gcc/config/i386/i386-builtin.def5
-rw-r--r--gcc/config/i386/i386-builtins.c5
-rw-r--r--gcc/config/i386/i386-builtins.h1
-rw-r--r--gcc/config/i386/i386-c.c2
-rw-r--r--gcc/config/i386/i386-expand.c14
-rw-r--r--gcc/config/i386/i386-options.c7
-rw-r--r--gcc/config/i386/i386.h6
-rw-r--r--gcc/config/i386/i386.md36
-rw-r--r--gcc/config/i386/i386.opt4
-rw-r--r--gcc/config/i386/uintrintrin.h87
-rw-r--r--gcc/config/i386/x86gprintrin.h2
-rw-r--r--gcc/doc/extend.texi5
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-56.inc2
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-1.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-3.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-4.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/uintr-5.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-4.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/x86gprintrin-5.c4
31 files changed, 278 insertions, 8 deletions
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index c96455c..0e63db2 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -701,6 +701,8 @@ get_available_features (struct __processor_model *cpu_model,
set_feature (FEATURE_AVX5124FMAPS);
if (edx & bit_AVX512VP2INTERSECT)
set_feature (FEATURE_AVX512VP2INTERSECT);
+ if (edx & bit_UINTR)
+ set_feature (FEATURE_UINTR);
__cpuid_count (7, 1, eax, ebx, ecx, edx);
if (eax & bit_AVX512BF16)
diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index 62a620b..6a06383 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -163,6 +163,7 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_ENQCMD_SET OPTION_MASK_ISA2_ENQCMD
#define OPTION_MASK_ISA2_SERIALIZE_SET OPTION_MASK_ISA2_SERIALIZE
#define OPTION_MASK_ISA2_TSXLDTRK_SET OPTION_MASK_ISA2_TSXLDTRK
+#define OPTION_MASK_ISA2_UINTR_SET OPTION_MASK_ISA2_UINTR
/* Define a set of ISAs which aren't available when a given ISA is
disabled. MMX and SSE ISAs are handled separately. */
@@ -254,6 +255,7 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA2_AMX_TILE_UNSET OPTION_MASK_ISA2_AMX_TILE
#define OPTION_MASK_ISA2_AMX_INT8_UNSET OPTION_MASK_ISA2_AMX_INT8
#define OPTION_MASK_ISA2_AMX_BF16_UNSET OPTION_MASK_ISA2_AMX_BF16
+#define OPTION_MASK_ISA2_UINTR_UNSET OPTION_MASK_ISA2_UINTR
/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same
as -mno-sse4.1. */
@@ -702,6 +704,19 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_muintr:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_UINTR_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_UINTR_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_UNSET;
+ }
+ return true;
+
case OPT_mavx5124fmaps:
if (value)
{
diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h
index 5b94b1f..3fc2af5 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -219,6 +219,7 @@ enum processor_features
FEATURE_AMX_TILE,
FEATURE_AMX_INT8,
FEATURE_AMX_BF16,
+ FEATURE_UINTR,
CPU_FEATURE_MAX
};
diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h
index 3c830ea..c2dc741 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -163,4 +163,5 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("amx-tile", FEATURE_AMX_TILE, P_NONE, "-mamx-tile")
ISA_NAMES_TABLE_ENTRY("amx-int8", FEATURE_AMX_INT8, P_NONE, "-mamx-int8")
ISA_NAMES_TABLE_ENTRY("amx-bf16", FEATURE_AMX_BF16, P_NONE, "-mamx-bf16")
+ ISA_NAMES_TABLE_ENTRY("uintr", FEATURE_UINTR, P_NONE, "-muintr")
ISA_NAMES_TABLE_END
diff --git a/gcc/config.gcc b/gcc/config.gcc
index d5634b0..c02bddda 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -413,7 +413,7 @@ i[34567]86-*-*)
avx512bf16intrin.h enqcmdintrin.h serializeintrin.h
avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h
tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h
- amxbf16intrin.h x86gprintrin.h"
+ amxbf16intrin.h x86gprintrin.h uintrintrin.h"
;;
x86_64-*-*)
cpu_type=i386
@@ -449,7 +449,7 @@ x86_64-*-*)
avx512bf16intrin.h enqcmdintrin.h serializeintrin.h
avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h
tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h
- amxbf16intrin.h x86gprintrin.h"
+ amxbf16intrin.h x86gprintrin.h uintrintrin.h"
;;
ia64-*-*)
extra_headers=ia64intrin.h
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 4598434..fbc8ca2 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -124,6 +124,7 @@
#define bit_AVX5124FMAPS (1 << 3)
#define bit_AVX512VP2INTERSECT (1 << 8)
#define bit_IBT (1 << 20)
+#define bit_UINTR (1 << 5)
#define bit_PCONFIG (1 << 18)
#define bit_SERIALIZE (1 << 14)
#define bit_TSXLDTRK (1 << 16)
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index ff2fa3f..964633d 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -194,6 +194,7 @@ DEF_FUNCTION_TYPE (UNSIGNED)
DEF_FUNCTION_TYPE (UINT)
DEF_FUNCTION_TYPE (USHORT)
DEF_FUNCTION_TYPE (INT)
+DEF_FUNCTION_TYPE (UINT8)
DEF_FUNCTION_TYPE (VOID)
DEF_FUNCTION_TYPE (PVOID)
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index e6deaa2..bc1b0c7 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -452,6 +452,11 @@ BDESC (0, OPTION_MASK_ISA2_SERIALIZE, CODE_FOR_serialize, "__builtin_ia32_serial
BDESC (0, OPTION_MASK_ISA2_TSXLDTRK, CODE_FOR_xsusldtrk, "__builtin_ia32_xsusldtrk", IX86_BUILTIN_XSUSLDTRK, UNKNOWN, (int) VOID_FTYPE_VOID)
BDESC (0, OPTION_MASK_ISA2_TSXLDTRK, CODE_FOR_xresldtrk, "__builtin_ia32_xresldtrk", IX86_BUILTIN_XRESLDTRK, UNKNOWN, (int) VOID_FTYPE_VOID)
+/* UINTR. */
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_clui, "__builtin_ia32_clui", IX86_BUILTIN_CLUI, UNKNOWN, (int) VOID_FTYPE_VOID)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_stui, "__builtin_ia32_stui", IX86_BUILTIN_STUI, UNKNOWN, (int) VOID_FTYPE_VOID)
+BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_senduipi, "__builtin_ia32_senduipi", IX86_BUILTIN_SENDUIPI, UNKNOWN, (int) VOID_FTYPE_UINT64)
+
BDESC_END (SPECIAL_ARGS, ARGS)
/* Builtins with variable number of arguments. */
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index ca7a870..504987a 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1194,6 +1194,11 @@ ix86_init_mmx_sse_builtins (void)
def_builtin (0, OPTION_MASK_ISA2_WAITPKG, "__builtin_ia32_tpause",
UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_TPAUSE);
+ /* UINTR. */
+ def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR,
+ "__builtin_ia32_testui",
+ UINT8_FTYPE_VOID, IX86_BUILTIN_TESTUI);
+
/* CLDEMOTE. */
def_builtin (0, OPTION_MASK_ISA2_CLDEMOTE, "__builtin_ia32_cldemote",
VOID_FTYPE_PCVOID, IX86_BUILTIN_CLDEMOTE);
diff --git a/gcc/config/i386/i386-builtins.h b/gcc/config/i386/i386-builtins.h
index cc6a8ce..a88cc0c 100644
--- a/gcc/config/i386/i386-builtins.h
+++ b/gcc/config/i386/i386-builtins.h
@@ -40,6 +40,7 @@ enum ix86_builtins
IX86_BUILTIN_UMONITOR,
IX86_BUILTIN_UMWAIT,
IX86_BUILTIN_TPAUSE,
+ IX86_BUILTIN_TESTUI,
IX86_BUILTIN_CLZERO,
IX86_BUILTIN_CLDEMOTE,
IX86_BUILTIN_VEC_INIT_V2SI,
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index e647fce..219e1be 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -598,6 +598,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__LAHF_SAHF__");
if (isa_flag2 & OPTION_MASK_ISA2_MOVBE)
def_or_undef (parse_in, "__MOVBE__");
+ if (isa_flag2 & OPTION_MASK_ISA2_UINTR)
+ def_or_undef (parse_in, "__UINTR__");
if (TARGET_IAMCU)
{
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index d35c654..e67c267 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -10417,6 +10417,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case USHORT_FTYPE_VOID:
case UINT64_FTYPE_VOID:
case UINT_FTYPE_VOID:
+ case UINT8_FTYPE_VOID:
case UNSIGNED_FTYPE_VOID:
nargs = 0;
klass = load;
@@ -11207,6 +11208,19 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
return target;
+ case IX86_BUILTIN_TESTUI:
+ emit_insn (gen_testui ());
+
+ if (target == 0
+ || !register_operand (target, QImode))
+ target = gen_reg_rtx (QImode);
+
+ pat = gen_rtx_LTU (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);
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index a59bd70..1edc1c8 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -212,7 +212,8 @@ static struct ix86_target_opts isa2_opts[] =
{ "-mtsxldtrk", OPTION_MASK_ISA2_TSXLDTRK },
{ "-mamx-tile", OPTION_MASK_ISA2_AMX_TILE },
{ "-mamx-int8", OPTION_MASK_ISA2_AMX_INT8 },
- { "-mamx-bf16", OPTION_MASK_ISA2_AMX_BF16 }
+ { "-mamx-bf16", OPTION_MASK_ISA2_AMX_BF16 },
+ { "-muintr", OPTION_MASK_ISA2_UINTR }
};
static struct ix86_target_opts isa_opts[] =
{
@@ -1031,6 +1032,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
IX86_ATTR_ISA ("movdir64b", OPT_mmovdir64b),
IX86_ATTR_ISA ("waitpkg", OPT_mwaitpkg),
IX86_ATTR_ISA ("cldemote", OPT_mcldemote),
+ IX86_ATTR_ISA ("uintr", OPT_muintr),
IX86_ATTR_ISA ("ptwrite", OPT_mptwrite),
IX86_ATTR_ISA ("avx512bf16", OPT_mavx512bf16),
IX86_ATTR_ISA ("enqcmd", OPT_menqcmd),
@@ -1899,6 +1901,9 @@ ix86_option_override_internal (bool main_args_p,
opts->x_ix86_stringop_alg = no_stringop;
}
+ if (TARGET_UINTR && !TARGET_64BIT)
+ error ("%<-muintr%> not supported for 32-bit code");
+
if (!opts->x_ix86_arch_string)
opts->x_ix86_arch_string
= TARGET_64BIT_P (opts->x_ix86_isa_flags)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9a5de6a..e933b35 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -209,6 +209,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_AMX_INT8_P(x) TARGET_ISA2_AMX_INT8(x)
#define TARGET_AMX_BF16 TARGET_ISA2_AMX_BF16
#define TARGET_AMX_BF16_P(x) TARGET_ISA2_AMX_BF16(x)
+#define TARGET_UINTR TARGET_ISA2_UINTR
+#define TARGET_UINTR_P(x) TARGET_ISA2_UINTR_P(x)
#define TARGET_LP64 TARGET_ABI_64
#define TARGET_LP64_P(x) TARGET_ABI_64_P(x)
@@ -2475,6 +2477,7 @@ const wide_int_bitmask PTA_TSXLDTRK (0, HOST_WIDE_INT_1U << 18);
const wide_int_bitmask PTA_AMX_TILE(0, HOST_WIDE_INT_1U << 19);
const wide_int_bitmask PTA_AMX_INT8(0, HOST_WIDE_INT_1U << 20);
const wide_int_bitmask PTA_AMX_BF16(0, HOST_WIDE_INT_1U << 21);
+const wide_int_bitmask PTA_UINTR (0, HOST_WIDE_INT_1U << 22);
const wide_int_bitmask PTA_X86_64_BASELINE = PTA_64BIT | PTA_MMX | PTA_SSE
| PTA_SSE2 | PTA_NO_SAHF | PTA_FXSR;
@@ -2485,6 +2488,7 @@ const wide_int_bitmask PTA_X86_64_V3 = PTA_X86_64_V2
| PTA_MOVBE | PTA_XSAVE;
const wide_int_bitmask PTA_X86_64_V4 = PTA_X86_64_V3
| PTA_AVX512F | PTA_AVX512BW | PTA_AVX512CD | PTA_AVX512DQ | PTA_AVX512VL;
+
const wide_int_bitmask PTA_CORE2 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2
| PTA_SSE3 | PTA_SSSE3 | PTA_CX16 | PTA_FXSR;
const wide_int_bitmask PTA_NEHALEM = PTA_CORE2 | PTA_SSE4_1 | PTA_SSE4_2
@@ -2518,7 +2522,7 @@ const wide_int_bitmask PTA_TIGERLAKE = PTA_ICELAKE_CLIENT | PTA_MOVDIRI
const wide_int_bitmask PTA_SAPPHIRERAPIDS = PTA_COOPERLAKE | PTA_MOVDIRI
| PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_ENQCMD | PTA_CLDEMOTE
| PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE | PTA_TSXLDTRK | PTA_AMX_TILE
- | PTA_AMX_INT8 | PTA_AMX_BF16;
+ | PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR;
const wide_int_bitmask PTA_ALDERLAKE = PTA_SKYLAKE | PTA_CLDEMOTE | PTA_PTWRITE
| PTA_WAITPKG | PTA_SERIALIZE;
const wide_int_bitmask PTA_KNL = PTA_BROADWELL | PTA_AVX512PF | PTA_AVX512ER
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d1350cf..d712a34 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -293,6 +293,12 @@
UNSPECV_UMONITOR
UNSPECV_TPAUSE
+ ;; For UINTR support
+ UNSPECV_CLUI
+ UNSPECV_STUI
+ UNSPECV_TESTUI
+ UNSPECV_SENDUIPI
+
;; For CLDEMOTE support
UNSPECV_CLDEMOTE
@@ -13680,7 +13686,7 @@
(unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
"reload_completed"
{
- return TARGET_64BIT ? "iretq" : "iret";
+ return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
})
;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
@@ -21585,6 +21591,34 @@
"enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
[(set_attr "type" "other")])
+;; UINTR
+(define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
+(define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
+
+(define_insn "<uintr>"
+ [(unspec_volatile [(const_int 0)] UINTR)]
+ "TARGET_UINTR && TARGET_64BIT"
+ "<uintr>"
+ [(set_attr "type" "other")
+ (set_attr "length" "4")])
+
+(define_insn "testui"
+ [(set (reg:CCC FLAGS_REG)
+ (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
+ "TARGET_UINTR && TARGET_64BIT"
+ "testui"
+ [(set_attr "type" "other")
+ (set_attr "length" "4")])
+
+(define_insn "senduipi"
+ [(unspec_volatile
+ [(match_operand:DI 0 "register_operand" "r")]
+ UNSPECV_SENDUIPI)]
+ "TARGET_UINTR && TARGET_64BIT"
+ "senduipi\t%0"
+ [(set_attr "type" "other")
+ (set_attr "length" "4")])
+
;; WAITPKG
(define_insn "umwait"
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 9389dc2..68f49f5 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -788,6 +788,10 @@ mptwrite
Target Report Mask(ISA2_PTWRITE) Var(ix86_isa_flags2) Save
Support PTWRITE built-in functions and code generation.
+muintr
+Target Report Mask(ISA2_UINTR) Var(ix86_isa_flags2) Save
+Support UINTR built-in functions and code generation.
+
msgx
Target Report Mask(ISA2_SGX) Var(ix86_isa_flags2) Save
Support SGX built-in functions and code generation.
diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
new file mode 100644
index 0000000..991f642
--- /dev/null
+++ b/gcc/config/i386/uintrintrin.h
@@ -0,0 +1,87 @@
+/* Copyright (C) 2020 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/>. */
+
+#ifndef _X86GPRINTRIN_H_INCLUDED
+# error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead."
+#endif
+
+#ifndef _UINTRNTRIN_H_INCLUDED
+#define _UINTRNTRIN_H_INCLUDED
+
+#ifdef __x86_64__
+
+#ifndef __UINTR__
+#pragma GCC push_options
+#pragma GCC target ("uintr")
+#define __DISABLE_UINTR__
+#endif /* __UINTR__ */
+
+struct __uintr_frame
+{
+ /* The position of the most significant bit set in user-interrupt
+ request register. */
+ unsigned long long uirrv;
+ /* RIP of the interrupted user process. */
+ unsigned long long rip;
+ /* RFLAGS of the interrupted user process. */
+ unsigned long long rflags;
+ /* RSP of the interrupted user process. */
+ unsigned long long rsp;
+};
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_clui (void)
+{
+ __builtin_ia32_clui ();
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_stui (void)
+{
+ __builtin_ia32_stui ();
+}
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_senduipi (unsigned long long __R)
+{
+ __builtin_ia32_senduipi (__R);
+}
+
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_testui (void)
+{
+ return __builtin_ia32_testui ();
+}
+
+#ifdef __DISABLE_UINTR__
+#undef __DISABLE_UINTR__
+#pragma GCC pop_options
+#endif /* __DISABLE_UINTR__ */
+
+#endif
+
+#endif /* _UINTRNTRIN_H_INCLUDED. */
diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h
index ecfb1c0..e35f4b6 100644
--- a/gcc/config/i386/x86gprintrin.h
+++ b/gcc/config/i386/x86gprintrin.h
@@ -76,6 +76,8 @@
#include <tsxldtrkintrin.h>
+#include <uintrintrin.h>
+
#include <waitpkgintrin.h>
#include <wbnoinvdintrin.h>
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index b9684dc..bd46ebc 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6638,6 +6638,11 @@ Enable/disable the generation of the AMX-INT8 instructions.
@cindex @code{target("amx-bf16")} function attribute, x86
Enable/disable the generation of the AMX-BF16 instructions.
+@item uintr
+@itemx no-uintr
+@cindex @code{target("uintr")} function attribute, x86
+Enable/disable the generation of the UINTR instructions.
+
@item cld
@itemx no-cld
@cindex @code{target("cld")} function attribute, x86
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 47aa695..0a5e1e8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1364,7 +1364,7 @@ See RS/6000 and PowerPC Options.
-mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
-mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol
-mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol
--mamx-tile -mamx-int8 -mamx-bf16@gol
+-mamx-tile -mamx-int8 -mamx-bf16 -muintr@gol
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} @gol
@@ -30259,6 +30259,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@need 200
@itemx -menqcmd
@opindex menqcmd
+@itemx -muintr
+@opindex muintr
@need 200
@itemx -mtsxldtrk
@opindex mtsxldtrk
@@ -30300,8 +30302,8 @@ WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP,
3DNow!@:, enhanced 3DNow!@:, POPCNT, ABM, ADX, BMI, BMI2, LZCNT, FXSR, XSAVE,
XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2,
GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16,
-ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE
-or CLDEMOTE extended instruction sets. Each has a corresponding
+ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE,
+UINTR or CLDEMOTE extended instruction sets. Each has a corresponding
@option{-mno-} option to disable use of these instructions.
These extensions are also available as built-in functions: see
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
index 8e669f1..d6a2e8d 100644
--- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc
+++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc
@@ -74,6 +74,7 @@ extern void test_avx512vp2intersect (void) __attribute__((__target__("avx512vp2i
extern void test_amx_tile (void) __attribute__((__target__("amx-tile")));
extern void test_amx_int8 (void) __attribute__((__target__("amx-int8")));
extern void test_amx_bf16 (void) __attribute__((__target__("amx-bf16")));
+extern void test_uintr (void) __attribute__((__target__("uintr")));
extern void test_no_sgx (void) __attribute__((__target__("no-sgx")));
extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps")));
@@ -149,6 +150,7 @@ extern void test_no_avx512vp2intersect (void) __attribute__((__target__("no-avx5
extern void test_no_amx_tile (void) __attribute__((__target__("no-amx-tile")));
extern void test_no_amx_int8 (void) __attribute__((__target__("no-amx-int8")));
extern void test_no_amx_bf16 (void) __attribute__((__target__("no-amx-bf16")));
+extern void test_no_uintr (void) __attribute__((__target__("no-uintr")));
extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona")));
extern void test_arch_core2 (void) __attribute__((__target__("arch=core2")));
diff --git a/gcc/testsuite/gcc.target/i386/uintr-1.c b/gcc/testsuite/gcc.target/i386/uintr-1.c
new file mode 100644
index 0000000..f30f755
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/uintr-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -muintr" } */
+/* { dg-final { scan-assembler-times "clui" "1" } } */
+/* { dg-final { scan-assembler-times "stui" "2" } } */
+/* { dg-final { scan-assembler-times "senduipi" "1" } } */
+/* { dg-final { scan-assembler-times "setc" "1" } } */
+/* { dg-final { scan-assembler-times "testui" "1" } } */
+
+#include <x86gprintrin.h>
+
+extern volatile unsigned char c;
+extern volatile unsigned long long l;
+
+void
+foo (void)
+{
+ _clui ();
+ _stui ();
+ _senduipi (l);
+ c = _testui ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c
new file mode 100644
index 0000000..e705732
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/uintr-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -muintr -mgeneral-regs-only" } */
+/* { dg-final { scan-assembler-times "uiret" "2" } } */
+
+#include <x86gprintrin.h>
+
+void
+__attribute__((interrupt))
+foo (void *frame)
+{
+}
+
+void
+__attribute__((interrupt))
+UINTR_hanlder (struct __uintr_frame *frame)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c
new file mode 100644
index 0000000..d284349
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/uintr-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -muintr" } */
+/* { dg-final { scan-assembler "uiret" } } */
+#include <x86gprintrin.h>
+
+void __attribute__ ((target("general-regs-only"), interrupt))
+UINTR_handler (struct __uintr_frame *p)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c
new file mode 100644
index 0000000..f3b371b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/uintr-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -muintr" } */
+
+#include <x86gprintrin.h>
+
+void __attribute__ ((interrupt))
+UINTR_handler (struct __uintr_frame *p)
+{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c
new file mode 100644
index 0000000..ac44be0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/uintr-5.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -muintr" } */
+/* { dg-error "'-muintr' not supported for 32-bit code" "" { target ia32 } 0 } */
+
+#include <x86gprintrin.h>
+
+void
+UINTR_hanlder (struct __uintr_frame *frame)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
index d9c759b..a65e7d5 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c
@@ -1,6 +1,7 @@
/* Test that <x86gprintrin.h> is usable with -O -std=c89 -pedantic-errors. */
/* { dg-do compile } */
/* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
+/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
#include <x86gprintrin.h>
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
index 5ea4772..ae56e5e 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
/* { dg-add-options bind_pic_locally } */
+/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
/* Test that the intrinsics in <x86gprintrin.h> compile with optimization.
All of them are defined as inline functions that reference the proper
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
index 01d3f78..c826acd 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */
/* { dg-add-options bind_pic_locally } */
+/* { dg-additional-options "-muintr" { target { ! ia32 } } } */
/* Test that the intrinsics in <x86gprintrin.h> compile without optimization.
All of them are defined as inline functions that reference the proper
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
index 053f07b..e0aa3a7 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c
@@ -14,8 +14,12 @@
#define __inline
#ifndef DIFFERENT_PRAGMAS
+#ifdef __x86_64__
+#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt")
+#else
#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt")
#endif
+#endif
/* popcnintrin.h (POPCNT). */
#ifdef DIFFERENT_PRAGMAS
diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
index fe9c5c7..a28c16a 100644
--- a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
+++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c
@@ -27,6 +27,10 @@
/* rtmintrin.h */
#define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1)
+#ifdef __x86_64__
+#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd")
+#else
#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd")
+#endif
#include <x86gprintrin.h>