Index: include/clang/Basic/BuiltinsX86.def =================================================================== --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -638,6 +638,16 @@ TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec") TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves") +// SHSTK +TARGET_BUILTIN(__builtin_ia32_incsspd, "vUi", "u", "shstk") +TARGET_BUILTIN(__builtin_ia32_rdsspd, "UiUi", "Un", "shstk") +TARGET_BUILTIN(__builtin_ia32_saveprevssp, "v", "", "shstk") +TARGET_BUILTIN(__builtin_ia32_rstorssp, "vv*", "", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrssd, "vUiv*", "", "shstk") +TARGET_BUILTIN(__builtin_ia32_wrussd, "vUiv*", "", "shstk") +TARGET_BUILTIN(__builtin_ia32_setssbsy, "v", "", "shstk") +TARGET_BUILTIN(__builtin_ia32_clrssbsy, "vv*", "", "shstk") + //CLFLUSHOPT TARGET_BUILTIN(__builtin_ia32_clflushopt, "vvC*", "", "clflushopt") Index: include/clang/Basic/BuiltinsX86_64.def =================================================================== --- include/clang/Basic/BuiltinsX86_64.def +++ include/clang/Basic/BuiltinsX86_64.def @@ -60,6 +60,10 @@ TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves") TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec") TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves") +TARGET_BUILTIN(__builtin_ia32_incsspq, "vULLi","u","shstk") +TARGET_BUILTIN(__builtin_ia32_rdsspq, "ULLiULLi","Un","shstk") +TARGET_BUILTIN(__builtin_ia32_wrssq, "vULLiv*","","shstk") +TARGET_BUILTIN(__builtin_ia32_wrussq, "vULLiv*","","shstk") TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx") TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "") TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2535,7 +2535,10 @@ def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group; def mxsaves : Flag<["-"], "mxsaves">, Group; def mno_xsaves : Flag<["-"], "mno-xsaves">, Group; - +def mshstk : Flag<["-"], "mshstk">, Group; +def mno_shstk : Flag<["-"], "mno-shstk">, Group; +def mibt : Flag<["-"], "mibt">, Group; +def mno_ibt : Flag<["-"], "mno-ibt">, Group; // These are legacy user-facing driver-level option spellings. They are always // aliases for options that are spelled using the more common Unix / GNU flag Index: lib/Basic/Targets/X86.h =================================================================== --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -74,6 +74,8 @@ bool HasAVX512IFMA = false; bool HasSHA = false; bool HasMPX = false; + bool HasSHSTK = false; + bool HasIBT = false; bool HasSGX = false; bool HasCX16 = false; bool HasFXSR = false; Index: lib/Basic/Targets/X86.cpp =================================================================== --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -681,6 +681,10 @@ HasSHA = true; } else if (Feature == "+mpx") { HasMPX = true; + } else if (Feature == "+shstk") { + HasSHSTK = true; + } else if (Feature == "+ibt") { + HasIBT = true; } else if (Feature == "+movbe") { HasMOVBE = true; } else if (Feature == "+sgx") { @@ -1029,6 +1033,8 @@ Builder.defineMacro("__CLWB__"); if (HasMPX) Builder.defineMacro("__MPX__"); + if (HasSHSTK) + Builder.defineMacro("__SHSTK__"); if (HasSGX) Builder.defineMacro("__SGX__"); if (HasPREFETCHWT1) @@ -1215,6 +1221,8 @@ .Case("mmx", MMX3DNowLevel >= MMX) .Case("movbe", HasMOVBE) .Case("mpx", HasMPX) + .Case("shstk", HasSHSTK) + .Case("ibt", HasIBT) .Case("pclmul", HasPCLMUL) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) Index: lib/Headers/CMakeLists.txt =================================================================== --- lib/Headers/CMakeLists.txt +++ lib/Headers/CMakeLists.txt @@ -30,6 +30,7 @@ __clang_cuda_intrinsics.h __clang_cuda_math_forward_declares.h __clang_cuda_runtime_wrapper.h + cetintrin.h clzerointrin.h cpuid.h clflushoptintrin.h Index: lib/Headers/cetintrin.h =================================================================== --- /dev/null +++ lib/Headers/cetintrin.h @@ -0,0 +1,93 @@ +/*===---- cetintrin.h - CET intrinsic ------------------------------------=== + * + * 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 __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __CETINTRIN_H +#define __CETINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("shstk"))) + +static __inline__ void __DEFAULT_FN_ATTRS _incsspd(int __a) { + __builtin_ia32_incsspd(__a); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS _incsspq(unsigned long long __a) { + __builtin_ia32_incsspq(__a); +} +#endif /* __x86_64__ */ + +static __inline__ unsigned int __DEFAULT_FN_ATTRS _rdsspd(unsigned int __a) { + return __builtin_ia32_rdsspd(__a); +} + +#ifdef __x86_64__ +static __inline__ unsigned long long __DEFAULT_FN_ATTRS _rdsspq(unsigned long long __a) { + return __builtin_ia32_rdsspq(__a); +} +#endif /* __x86_64__ */ + +static __inline__ void __DEFAULT_FN_ATTRS _saveprevssp() { + __builtin_ia32_saveprevssp(); +} + +static __inline__ void __DEFAULT_FN_ATTRS _rstorssp(void * __p) { + __builtin_ia32_rstorssp(__p); +} + +static __inline__ void __DEFAULT_FN_ATTRS _wrssd(unsigned int __a, void * __p) { + __builtin_ia32_wrssd(__a, __p); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS _wrssq(unsigned long long __a, void * __p) { + __builtin_ia32_wrssq(__a, __p); +} +#endif /* __x86_64__ */ + +static __inline__ void __DEFAULT_FN_ATTRS _wrussd(unsigned int __a, void * __p) { + __builtin_ia32_wrussd(__a, __p); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS _wrussq(unsigned long long __a, void * __p) { + __builtin_ia32_wrussq(__a, __p); +} +#endif /* __x86_64__ */ + +static __inline__ void __DEFAULT_FN_ATTRS _setssbsy() { + __builtin_ia32_setssbsy(); +} + +static __inline__ void __DEFAULT_FN_ATTRS _clrssbsy(void * __p) { + __builtin_ia32_clrssbsy(__p); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* __CETINTRIN_H */ Index: lib/Headers/immintrin.h =================================================================== --- lib/Headers/immintrin.h +++ lib/Headers/immintrin.h @@ -319,6 +319,10 @@ #include #endif +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__SHSTK__) +#include +#endif + /* Some intrinsics inside adxintrin.h are available only on processors with ADX, * whereas others are also available at all times. */ #include 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 -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 +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 -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 #ifdef USE_ALL #define USE_3DNOW @@ -257,6 +257,19 @@ tmp_V8c = __builtin_ia32_packuswb(tmp_V4s, tmp_V4s); tmp_i = __builtin_ia32_vec_ext_v2si(tmp_V2i, 0); + __builtin_ia32_incsspd(tmp_Ui); + __builtin_ia32_incsspq(tmp_ULLi); + tmp_Ui = __builtin_ia32_rdsspd(tmp_Ui); + tmp_ULLi = __builtin_ia32_rdsspq(tmp_ULLi); + __builtin_ia32_saveprevssp(); + __builtin_ia32_rstorssp(tmp_vp); + __builtin_ia32_wrssd(tmp_Ui, tmp_vp); + __builtin_ia32_wrssq(tmp_ULLi, tmp_vp); + __builtin_ia32_wrussd(tmp_Ui, tmp_vp); + __builtin_ia32_wrussq(tmp_ULLi, tmp_vp); + __builtin_ia32_setssbsy(); + __builtin_ia32_clrssbsy(tmp_vp); + (void) __builtin_ia32_ldmxcsr(tmp_Ui); (void) _mm_setcsr(tmp_Ui); tmp_Ui = __builtin_ia32_stmxcsr(); Index: test/CodeGen/cetintrin.c =================================================================== --- /dev/null +++ test/CodeGen/cetintrin.c @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -ffreestanding %s -triple=i386-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +shstk -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=X86_64 + +#include + +void test_incsspd(int a) { + // CHECK-LABEL: @test_incsspd + // CHECK: call void @llvm.x86.incsspd(i32 %{{[0-9]+}}) + _incsspd(a); +} + +#ifdef __x86_64__ +void test_incsspq(int a) { + // X86_64-LABEL: @test_incsspq + // X86_64: call void @llvm.x86.incsspq(i64 %{{[a-z0-9.]+}}) + _incsspq(a); +} +#endif + +unsigned int test_rdsspd(unsigned int a) { + // CHECK-LABEL: @test_rdsspd + // CHECK: call i32 @llvm.x86.rdsspd(i32 %{{[a-z0-9.]+}}) + return _rdsspd(a); +} + +#ifdef __x86_64__ +unsigned long long test_rdsspq(unsigned long long a) { + // X86_64-LABEL: @test_rdsspq + // X86_64: call i64 @llvm.x86.rdsspq(i64 %{{[a-z0-9.]+}}) + return _rdsspq(a); +} +#endif + +void test_saveprevssp() { + // CHECK-LABEL: @test_saveprevssp + // CHECK: call void @llvm.x86.saveprevssp() + _saveprevssp(); +} + +void test_rstorssp(void * __p) { + // CHECK-LABEL: @test_rstorssp + // CHECK: call void @llvm.x86.rstorssp(i8* %{{[a-z0-9.]+}}) + _rstorssp(__p); +} + +void test_wrssd(unsigned int __a, void * __p) { + // CHECK-LABEL: @test_wrssd + // CHECK: call void @llvm.x86.wrssd(i32 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}}) + _wrssd(__a, __p); +} + +#ifdef __x86_64__ +void test_wrssq(unsigned long long __a, void * __p) { + // X86_64-LABEL: @test_wrssq + // X86_64: call void @llvm.x86.wrssq(i64 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}}) + _wrssq(__a, __p); +} +#endif + +void test_wrussd(unsigned int __a, void * __p) { + // CHECK-LABEL: @test_wrussd + // CHECK: call void @llvm.x86.wrussd(i32 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}}) + _wrussd(__a, __p); +} + +#ifdef __x86_64__ +void test_wrussq(unsigned long long __a, void * __p) { + // X86_64-LABEL: @test_wrussq + // X86_64: call void @llvm.x86.wrussq(i64 %{{[a-z0-9.]+}}, i8* %{{[a-z0-9.]+}}) + _wrussq(__a, __p); +} +#endif + +void test_setssbsy() { + // CHECK-LABEL: @test_setssbsy + // CHECK: call void @llvm.x86.setssbsy() + _setssbsy(); +} + +void test_clrssbsy(void * __p) { + // CHECK-LABEL: @test_clrssbsy + // CHECK: call void @llvm.x86.clrssbsy(i8* %{{[a-z0-9.]+}}) + _clrssbsy(__p); +} Index: test/Driver/x86-target-features.c =================================================================== --- test/Driver/x86-target-features.c +++ test/Driver/x86-target-features.c @@ -70,6 +70,16 @@ // MPX: "-target-feature" "+mpx" // NO-MPX: "-target-feature" "-mpx" +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mshstk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CETSS %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-shstk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CETSS %s +// CETSS: "-target-feature" "+shstk" +// NO-CETSS: "-target-feature" "-shstk" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mibt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CETIBT %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-ibt %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-CETIBT %s +// CETIBT: "-target-feature" "+ibt" +// NO-CETIBT: "-target-feature" "-ibt" + // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -msgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SGX %s // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-sgx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SGX %s // SGX: "-target-feature" "+sgx" Index: test/Preprocessor/x86_target_features.c =================================================================== --- test/Preprocessor/x86_target_features.c +++ test/Preprocessor/x86_target_features.c @@ -333,6 +333,14 @@ // ADX: #define __ADX__ 1 +// RUN: %clang -target i386-unknown-unknown -mcet -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CET %s + +// CET: #define __SHSTK__ 1 + +// RUN: %clang -target i386-unknown-unknown -mshstk -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=CETSS %s + +// CETSS: #define __SHSTK__ 1 + // RUN: %clang -target i386-unknown-unknown -march=atom -mrdseed -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=RDSEED %s // RDSEED: #define __RDSEED__ 1