mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 08:51:43 +00:00
[x86] invpcid LLVM intrinsic
Re-add the feature flag for invpcid, which was removed in r294561. Add an intrinsic, which always uses a 32 bit integer as first argument, while the instruction actually uses a 64 bit register in 64 bit mode for the INVPCID_TYPE argument. Reviewers: craig.topper Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D47141 llvm-svn: 333255
This commit is contained in:
parent
eee57c60ef
commit
311b0dd621
@ -6186,3 +6186,11 @@ let TargetPrefix = "x86" in {
|
||||
def int_x86_ptwrite64 : GCCBuiltin<"__builtin_ia32_ptwrite64">,
|
||||
Intrinsic<[], [llvm_i64_ty], []>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// INVPCID - Invalidate Process-Context Identifier
|
||||
|
||||
let TargetPrefix = "x86" in {
|
||||
def int_x86_invpcid : GCCBuiltin<"__builtin_ia32_invpcid">,
|
||||
Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], []>;
|
||||
}
|
||||
|
@ -1231,6 +1231,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
|
||||
// AVX2 is only supported if we have the OS save support from AVX.
|
||||
Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave;
|
||||
Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1);
|
||||
Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1);
|
||||
Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1);
|
||||
// AVX512 is only supported if the OS supports the context save for it.
|
||||
Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
|
||||
|
@ -245,6 +245,8 @@ def FeatureSlowDivide64 : SubtargetFeature<"idivq-to-divl",
|
||||
def FeaturePadShortFunctions : SubtargetFeature<"pad-short-functions",
|
||||
"PadShortFunctions", "true",
|
||||
"Pad short functions">;
|
||||
def FeatureINVPCID : SubtargetFeature<"invpcid", "HasINVPCID", "true",
|
||||
"Invalidate Process-Context Identifier">;
|
||||
def FeatureSGX : SubtargetFeature<"sgx", "HasSGX", "true",
|
||||
"Enable Software Guard Extensions">;
|
||||
def FeatureCLFLUSHOPT : SubtargetFeature<"clflushopt", "HasCLFLUSHOPT", "true",
|
||||
@ -730,6 +732,7 @@ def HSWFeatures : ProcessorFeatures<IVBFeatures.Value, [
|
||||
FeatureBMI2,
|
||||
FeatureERMSB,
|
||||
FeatureFMA,
|
||||
FeatureINVPCID,
|
||||
FeatureLZCNT,
|
||||
FeatureMOVBE,
|
||||
FeatureFastVariableShuffle
|
||||
|
@ -904,6 +904,7 @@ def HasCLWB : Predicate<"Subtarget->hasCLWB()">;
|
||||
def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">;
|
||||
def HasRDPID : Predicate<"Subtarget->hasRDPID()">;
|
||||
def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">;
|
||||
def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">;
|
||||
def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
|
||||
def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
|
||||
def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
|
||||
|
@ -635,13 +635,27 @@ let Predicates = [HasFSGSBase, In64BitMode], SchedRW = [WriteSystem] in {
|
||||
// INVPCID Instruction
|
||||
let SchedRW = [WriteSystem] in {
|
||||
def INVPCID32 : I<0x82, MRMSrcMem, (outs), (ins GR32:$src1, i128mem:$src2),
|
||||
"invpcid\t{$src2, $src1|$src1, $src2}", []>, T8PD,
|
||||
Requires<[Not64BitMode]>;
|
||||
"invpcid\t{$src2, $src1|$src1, $src2}",
|
||||
[(int_x86_invpcid GR32:$src1, addr:$src2)]>, T8PD,
|
||||
Requires<[Not64BitMode, HasINVPCID]>;
|
||||
def INVPCID64 : I<0x82, MRMSrcMem, (outs), (ins GR64:$src1, i128mem:$src2),
|
||||
"invpcid\t{$src2, $src1|$src1, $src2}", []>, T8PD,
|
||||
Requires<[In64BitMode]>;
|
||||
Requires<[In64BitMode, HasINVPCID]>;
|
||||
} // SchedRW
|
||||
|
||||
let Predicates = [In64BitMode, HasINVPCID] in {
|
||||
// The instruction can only use a 64 bit register as the register argument
|
||||
// in 64 bit mode, while the intrinsic only accepts a 32 bit argument
|
||||
// corresponding to it.
|
||||
// The accepted values for now are 0,1,2,3 anyways (see Intel SDM -- INVCPID
|
||||
// type),/ so it doesn't hurt us that one can't supply a 64 bit value here.
|
||||
def : Pat<(int_x86_invpcid GR32:$src1, addr:$src2),
|
||||
(INVPCID64
|
||||
(SUBREG_TO_REG (i64 0), (MOV32rr GR32:$src1), sub_32bit),
|
||||
addr:$src2)>;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SMAP Instruction
|
||||
let Defs = [EFLAGS], SchedRW = [WriteSystem] in {
|
||||
|
@ -322,6 +322,7 @@ void X86Subtarget::initializeEnvironment() {
|
||||
HasPTWRITE = false;
|
||||
HasMPX = false;
|
||||
HasSHSTK = false;
|
||||
HasINVPCID = false;
|
||||
HasSGX = false;
|
||||
HasPCONFIG = false;
|
||||
HasCLFLUSHOPT = false;
|
||||
|
@ -360,6 +360,9 @@ protected:
|
||||
/// using Shadow Stack
|
||||
bool HasSHSTK;
|
||||
|
||||
/// Processor supports Invalidate Process-Context Identifier
|
||||
bool HasINVPCID;
|
||||
|
||||
/// Processor has Software Guard Extensions
|
||||
bool HasSGX;
|
||||
|
||||
@ -644,6 +647,7 @@ public:
|
||||
bool hasWAITPKG() const { return HasWAITPKG; }
|
||||
bool hasPCONFIG() const { return HasPCONFIG; }
|
||||
bool hasSGX() const { return HasSGX; }
|
||||
bool hasINVPCID() const { return HasINVPCID; }
|
||||
bool useRetpoline() const { return UseRetpoline; }
|
||||
bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; }
|
||||
|
||||
|
43
test/CodeGen/X86/invpcid-intrinsic.ll
Normal file
43
test/CodeGen/X86/invpcid-intrinsic.ll
Normal file
@ -0,0 +1,43 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+invpcid | FileCheck %s --check-prefix=X86
|
||||
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+invpcid | FileCheck %s --check-prefix=X86_64
|
||||
|
||||
define void @test_invpcid(i32 %type, i8* %descriptor) {
|
||||
; X86-LABEL: test_invpcid:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; X86-NEXT: invpcid (%eax), %ecx
|
||||
; X86-NEXT: retl
|
||||
;
|
||||
; X86_64-LABEL: test_invpcid:
|
||||
; X86_64: # %bb.0: # %entry
|
||||
; X86_64-NEXT: movl %edi, %eax
|
||||
; X86_64-NEXT: invpcid (%rsi), %rax
|
||||
; X86_64-NEXT: retq
|
||||
entry:
|
||||
call void @llvm.x86.invpcid(i32 %type, i8* %descriptor)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_invpcid2(i32* readonly %type, i8* %descriptor) {
|
||||
; X86-LABEL: test_invpcid2:
|
||||
; X86: # %bb.0: # %entry
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
|
||||
; X86-NEXT: movl (%ecx), %ecx
|
||||
; X86-NEXT: invpcid (%eax), %ecx
|
||||
; X86-NEXT: retl
|
||||
;
|
||||
; X86_64-LABEL: test_invpcid2:
|
||||
; X86_64: # %bb.0: # %entry
|
||||
; X86_64-NEXT: movl (%rdi), %eax
|
||||
; X86_64-NEXT: invpcid (%rsi), %rax
|
||||
; X86_64-NEXT: retq
|
||||
entry:
|
||||
%0 = load i32, i32* %type, align 4
|
||||
tail call void @llvm.x86.invpcid(i32 %0, i8* %descriptor) #1
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.x86.invpcid(i32, i8*)
|
Loading…
Reference in New Issue
Block a user