Index: include/clang/Basic/BuiltinsX86.def =================================================================== --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1879,6 +1879,14 @@ // CLZERO TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero") +// 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 @@ -2610,6 +2610,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 @@ -91,6 +91,7 @@ bool HasXSAVES = false; bool HasMWAITX = false; bool HasCLZERO = 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 @@ -802,6 +802,8 @@ HasRetpolineExternalThunk = true; } else if (Feature == "+sahf") { HasLAHFSAHF = true; + } else if (Feature == "+pconfig") { + HasPCONFIG = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1145,6 +1147,8 @@ Builder.defineMacro("__CLZERO__"); if (HasRDPID) Builder.defineMacro("__RDPID__"); + if (HasPCONFIG) + Builder.defineMacro("__PCONFIG__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1271,6 +1275,7 @@ .Case("mpx", true) .Case("mwaitx", true) .Case("pclmul", true) + .Case("pconfig", true) .Case("pku", true) .Case("popcnt", true) .Case("prefetchwt1", true) @@ -1344,6 +1349,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 @@ -8985,6 +8985,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 @@ -71,10 +71,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 @@ -190,6 +190,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 @@ -63,6 +63,7 @@ textual header "fma4intrin.h" textual header "mwaitxintrin.h" textual header "clzerointrin.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,43 @@ +/*===---- 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); +} + +#endif Index: lib/Headers/sgxintrin.h =================================================================== --- /dev/null +++ lib/Headers/sgxintrin.h @@ -0,0 +1,53 @@ +/*===---- 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); +} + +#endif Index: lib/Headers/x86intrin.h =================================================================== --- lib/Headers/x86intrin.h +++ lib/Headers/x86intrin.h @@ -88,4 +88,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 -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 -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 +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 +pconfig -fsyntax-only -o %t %s #ifdef USE_ALL #define USE_3DNOW @@ -295,6 +295,9 @@ (void) __builtin_ia32_monitorx(tmp_vp, tmp_Ui, tmp_Ui); (void) __builtin_ia32_mwaitx(tmp_Ui, tmp_Ui, tmp_Ui); (void) __builtin_ia32_clzero(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 @@ -139,3 +139,8 @@ // RUN: %clang -target i386-linux-gnu -mretpoline -mno-retpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-RETPOLINE-EXTERNAL-THUNK %s // RETPOLINE-EXTERNAL-THUNK: "-target-feature" "+retpoline-external-thunk" // NO-RETPOLINE-EXTERNAL-THUNK: "-target-feature" "-retpoline-external-thunk" + +// 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"