Index: include/clang/Basic/BuiltinsX86.def =================================================================== --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1883,6 +1883,14 @@ // CLDEMOTE TARGET_BUILTIN(__builtin_ia32_cldemote, "vvC*", "", "cldemote") +// PCONFIG +TARGET_BUILTIN(__builtin_ia32_pconfig, "UiUiz*z*z*", "", "pconfig") + +// SGX +TARGET_BUILTIN(__builtin_ia32_enclu, "UiUiz*z*z*", "", "sgx") +TARGET_BUILTIN(__builtin_ia32_encls, "UiUiz*z*z*", "", "sgx") +TARGET_BUILTIN(__builtin_ia32_enclv, "UiUiz*z*z*", "", "sgx") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2657,6 +2657,8 @@ def mno_pku : Flag<["-"], "mno-pku">, Group; def mpclmul : Flag<["-"], "mpclmul">, Group; def mno_pclmul : Flag<["-"], "mno-pclmul">, Group; +def mpconfig : Flag<["-"], "mpconfig">, Group; +def mno_pconfig : Flag<["-"], "mno-pconfig">, Group; def mpopcnt : Flag<["-"], "mpopcnt">, Group; def mno_popcnt : Flag<["-"], "mno-popcnt">, Group; def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group; Index: lib/Basic/Targets/X86.h =================================================================== --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -92,6 +92,7 @@ bool HasMWAITX = false; bool HasCLZERO = false; bool HasCLDEMOTE = false; + bool HasPCONFIG = false; bool HasPKU = false; bool HasCLFLUSHOPT = false; bool HasCLWB = false; Index: lib/Basic/Targets/X86.cpp =================================================================== --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -154,6 +154,7 @@ break; case CK_IcelakeServer: + setFeatureEnabledImpl(Features, "pconfig", true); setFeatureEnabledImpl(Features, "wbnoinvd", true); LLVM_FALLTHROUGH; case CK_IcelakeClient: @@ -821,6 +822,8 @@ HasLAHFSAHF = true; } else if (Feature == "+waitpkg") { HasWAITPKG = true; + } else if (Feature == "+pconfig") { + HasPCONFIG = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1177,6 +1180,8 @@ Builder.defineMacro("__CLDEMOTE__"); if (HasWAITPKG) Builder.defineMacro("__WAITPKG__"); + if (HasPCONFIG) + Builder.defineMacro("__PCONFIG__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1304,6 +1309,7 @@ .Case("mpx", true) .Case("mwaitx", true) .Case("pclmul", true) + .Case("pconfig", true) .Case("pku", true) .Case("popcnt", true) .Case("prefetchwt1", true) @@ -1380,6 +1386,7 @@ .Case("mpx", HasMPX) .Case("mwaitx", HasMWAITX) .Case("pclmul", HasPCLMUL) + .Case("pconfig", HasPCONFIG) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) .Case("prefetchwt1", HasPREFETCHWT1) Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -9268,6 +9268,59 @@ Ops[0]); return Builder.CreateExtractValue(Call, 1); } + case X86::BI__builtin_ia32_enclu: + case X86::BI__builtin_ia32_encls: + case X86::BI__builtin_ia32_enclv: + case X86::BI__builtin_ia32_pconfig: { + Intrinsic::ID ID; + + if (IntPtrTy->getBitWidth() == 64) { + switch (BuiltinID) { + default: llvm_unreachable("Unsupported intrinsic!"); + case X86::BI__builtin_ia32_enclu: + ID = Intrinsic::x86_enclu_64; + break; + case X86::BI__builtin_ia32_encls: + ID = Intrinsic::x86_encls_64; + break; + case X86::BI__builtin_ia32_enclv: + ID = Intrinsic::x86_enclv_64; + break; + case X86::BI__builtin_ia32_pconfig: + ID = Intrinsic::x86_pconfig_64; + break; + } + } else { + switch (BuiltinID) { + default: llvm_unreachable("Unsupported intrinsic!"); + case X86::BI__builtin_ia32_enclu: + ID = Intrinsic::x86_enclu_32; + break; + case X86::BI__builtin_ia32_encls: + ID = Intrinsic::x86_encls_32; + break; + case X86::BI__builtin_ia32_enclv: + ID = Intrinsic::x86_enclv_32; + break; + case X86::BI__builtin_ia32_pconfig: + ID = Intrinsic::x86_pconfig_32; + break; + } + } + + Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID), + {Ops[0], + Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(1))), + Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(2))), + Builder.CreateLoad(EmitPointerWithAlignment(E->getArg(3)))}); + Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 1), + Ops[1]); + Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 2), + Ops[2]); + Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 3), + Ops[3]); + return Builder.CreateExtractValue(Call, 0); + } case X86::BI__builtin_ia32_cmpps128_mask: case X86::BI__builtin_ia32_cmpps256_mask: Index: lib/Headers/CMakeLists.txt =================================================================== --- lib/Headers/CMakeLists.txt +++ lib/Headers/CMakeLists.txt @@ -72,10 +72,12 @@ opencl-c.h pkuintrin.h pmmintrin.h + pconfigintrin.h popcntintrin.h prfchwintrin.h rdseedintrin.h rtmintrin.h + sgxintrin.h s390intrin.h shaintrin.h smmintrin.h Index: lib/Headers/cpuid.h =================================================================== --- lib/Headers/cpuid.h +++ lib/Headers/cpuid.h @@ -192,6 +192,7 @@ /* Features in %edx for leaf 7 sub-leaf 0 */ #define bit_AVX5124VNNIW 0x00000004 #define bit_AVX5124FMAPS 0x00000008 +#define bit_PCONFIG 0x00040000 #define bit_IBT 0x00100000 /* Features in %eax for leaf 13 sub-leaf 1 */ Index: lib/Headers/module.modulemap =================================================================== --- lib/Headers/module.modulemap +++ lib/Headers/module.modulemap @@ -66,6 +66,7 @@ textual header "wbnoinvdintrin.h" textual header "cldemoteintrin.h" textual header "waitpkgintrin.h" + textual header "pconfigintrin.h" explicit module mm_malloc { requires !freestanding Index: lib/Headers/pconfigintrin.h =================================================================== --- /dev/null +++ lib/Headers/pconfigintrin.h @@ -0,0 +1,45 @@ +/*===---- pconfigintrin.h - X86 platform configuration ---------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __PCONFIGINTRIN_H +#define __PCONFIGINTRIN_H + +#define _MKTME_KEY_PROGRAM 0x00000001 + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("pconfig"))) + +static __inline unsigned int __DEFAULT_FN_ATTRS +_pconfig_u32(unsigned int __leaf, __SIZE_TYPE__ __D[]) +{ + return __builtin_ia32_pconfig(__leaf, __D, __D + 1, __D + 2); +} + +#undef __DEFAULT_FN_ATTRS + +#endif Index: lib/Headers/sgxintrin.h =================================================================== --- /dev/null +++ lib/Headers/sgxintrin.h @@ -0,0 +1,55 @@ +/*===---- sgxintrin.h - X86 SGX intrinsics configuration -------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __SGXINTRIN_H +#define __SGXINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("sgx"))) + +static __inline unsigned int __DEFAULT_FN_ATTRS +_enclu_u32(unsigned int __leaf, __SIZE_TYPE__ __D[]) +{ + return __builtin_ia32_enclu(__leaf, __D, __D + 1, __D + 2); +} + +static __inline unsigned int __DEFAULT_FN_ATTRS +_encls_u32(unsigned int __leaf, __SIZE_TYPE__ __D[]) +{ + return __builtin_ia32_encls(__leaf, __D, __D + 1, __D + 2); +} + +static __inline unsigned int __DEFAULT_FN_ATTRS +_enclv_u32(unsigned int __leaf, __SIZE_TYPE__ __D[]) +{ + return __builtin_ia32_enclv(__leaf, __D, __D + 1, __D + 2); +} + +#undef __DEFAULT_FN_ATTRS + +#endif Index: lib/Headers/x86intrin.h =================================================================== --- lib/Headers/x86intrin.h +++ lib/Headers/x86intrin.h @@ -100,4 +100,12 @@ #include #endif +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__PCONFIG__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__SGX__) +#include +#endif + #endif /* __X86INTRIN_H */ Index: test/CodeGen/builtins-x86.c =================================================================== --- test/CodeGen/builtins-x86.c +++ test/CodeGen/builtins-x86.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -target-feature +ibt -target-feature +shstk -target-feature +wbnoinvd -target-feature +cldemote -emit-llvm -o %t %s -// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +ibt -target-feature +shstk -target-feature +clzero -target-feature +wbnoinvd -target-feature +cldemote -fsyntax-only -o %t %s +// RUN: %clang_cc1 -DUSE_64 -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +clzero -target-feature +ibt -target-feature +shstk -target-feature +wbnoinvd -target-feature +cldemote -target-feature +pconfig -emit-llvm -o %t %s +// RUN: %clang_cc1 -DUSE_ALL -triple x86_64-unknown-unknown -target-feature +fxsr -target-feature +avx -target-feature +xsaveopt -target-feature +xsaves -target-feature +xsavec -target-feature +mwaitx -target-feature +ibt -target-feature +shstk -target-feature +clzero -target-feature +wbnoinvd -target-feature +cldemote -target-feature +pconfig -fsyntax-only -o %t %s #ifdef USE_ALL #define USE_3DNOW @@ -296,6 +296,9 @@ (void) __builtin_ia32_mwaitx(tmp_Ui, tmp_Ui, tmp_Ui); (void) __builtin_ia32_clzero(tmp_vp); (void) __builtin_ia32_cldemote(tmp_vp); + (void) __builtin_ia32_pconfig(1, (__SIZE_TYPE__*)tmp_vp, + ((__SIZE_TYPE__*)tmp_vp) + 1, + ((__SIZE_TYPE__*)tmp_vp) + 2); tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i); tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f); Index: test/CodeGen/pconfig.c =================================================================== --- /dev/null +++ test/CodeGen/pconfig.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-apple-darwin -emit-llvm -target-feature +pconfig -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-64 +// RUN: %clang_cc1 %s -ffreestanding -triple i386 -emit-llvm -target-feature +pconfig -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-32 + +#include + +#include + +unsigned int test_pconfig(unsigned int leaf, size_t arguments[]) { + //CHECK-LABEL: @test_pconfig + //CHECK-64: @llvm.x86.pconfig.64 + //CHECK-32: @llvm.x86.pconfig.32 + return _pconfig_u32(leaf, arguments); +} + Index: test/CodeGen/sgx.c =================================================================== --- /dev/null +++ test/CodeGen/sgx.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-unknown-unknown -emit-llvm -target-feature +sgx -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-64 +// RUN: %clang_cc1 %s -ffreestanding -triple i386-unknown-unknown -emit-llvm -target-feature +sgx -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-32 + +#include + +#include + +unsigned int test_encls(unsigned int leaf, size_t arguments[]) { + //CHECK-LABEL: @test_encls + //CHECK-64: @llvm.x86.encls.64 + //CHECK-32: @llvm.x86.encls.32 + return _encls_u32(leaf, arguments); +} + +unsigned int test_enclu(unsigned int leaf, size_t arguments[]) { + //CHECK-LABEL: @test_enclu + //CHECK-64: @llvm.x86.enclu.64 + //CHECK-32: @llvm.x86.enclu.32 + return _enclu_u32(leaf, arguments); +} + +unsigned int test_enclv(unsigned int leaf, size_t arguments[]) { + //CHECK-LABEL: @test_enclv + //CHECK-64: @llvm.x86.enclv.64 + //CHECK-32: @llvm.x86.enclv.32 + return _enclv_u32(leaf, arguments); +} Index: test/Driver/x86-target-features.c =================================================================== --- test/Driver/x86-target-features.c +++ test/Driver/x86-target-features.c @@ -149,3 +149,8 @@ // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" // NO-WAITPKG: "-target-feature" "-waitpkg" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mpconfig %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PCONFIG %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-pconfig %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-PCONFIG %s +// PCONFIG: "-target-feature" "+pconfig" +// NO-PCONFIG: "-target-feature" "-pconfig" Index: test/Preprocessor/predefined-arch-macros.c =================================================================== --- test/Preprocessor/predefined-arch-macros.c +++ test/Preprocessor/predefined-arch-macros.c @@ -1204,6 +1204,7 @@ // CHECK_ICX_M32: #define __MMX__ 1 // CHECK_ICX_M32: #define __MPX__ 1 // CHECK_ICX_M32: #define __PCLMUL__ 1 +// CHECK_ICX_M32: #define __PCONFIG__ 1 // CHECK_ICX_M32: #define __PKU__ 1 // CHECK_ICX_M32: #define __POPCNT__ 1 // CHECK_ICX_M32: #define __PRFCHW__ 1 @@ -1261,6 +1262,7 @@ // CHECK_ICX_M64: #define __MMX__ 1 // CHECK_ICX_M64: #define __MPX__ 1 // CHECK_ICX_M64: #define __PCLMUL__ 1 +// CHECK_ICX_M64: #define __PCONFIG__ 1 // CHECK_ICX_M64: #define __PKU__ 1 // CHECK_ICX_M64: #define __POPCNT__ 1 // CHECK_ICX_M64: #define __PRFCHW__ 1