From 2b5e96004b23c9506bbf8ec3480861fb9157ceb8 Mon Sep 17 00:00:00 2001 From: Gabor Buella Date: Tue, 8 May 2018 06:47:36 +0000 Subject: [PATCH] [x86] Introduce the pconfig instruction Reviewers: craig.topper, zvi Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D46430 llvm-svn: 331739 --- llvm/lib/Support/Host.cpp | 12 ++++++++++++ llvm/lib/Target/X86/X86.td | 3 +++ llvm/lib/Target/X86/X86InstrInfo.td | 1 + llvm/lib/Target/X86/X86InstrSystem.td | 17 +++++++++++++++++ llvm/lib/Target/X86/X86Subtarget.cpp | 1 + llvm/lib/Target/X86/X86Subtarget.h | 4 ++++ llvm/test/MC/Disassembler/X86/x86-32.txt | 3 +++ llvm/test/MC/Disassembler/X86/x86-64.txt | 3 +++ llvm/test/MC/X86/x86-32-coverage.s | 4 ++++ llvm/test/MC/X86/x86-64.s | 4 ++++ 10 files changed, 52 insertions(+) diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index ff3a71f..d13aa8d 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -1266,6 +1266,18 @@ bool sys::getHostCPUFeatures(StringMap &Features) { Features["ibt"] = HasLeaf7 && ((EDX >> 20) & 1); + // There are two CPUID leafs which information associated with the pconfig + // instruction: + // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th + // bit of EDX), while the EAX=0x1b leaf returns information on the + // availability of specific pconfig leafs. + // The target feature here only refers to the the first of these two. + // Users might need to check for the availability of specific pconfig + // leaves using cpuid, since that information is ignored while + // detecting features using the "-march=native" flag. + // For more info, see X86 ISA docs. + Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1); + bool HasLeafD = MaxLevel >= 0xd && !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 1c83c95..9e004d0 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -280,6 +280,8 @@ def FeaturePOPCNTFalseDeps : SubtargetFeature<"false-deps-popcnt", def FeatureLZCNTFalseDeps : SubtargetFeature<"false-deps-lzcnt-tzcnt", "HasLZCNTFalseDeps", "true", "LZCNT/TZCNT have a false dependency on dest register">; +def FeaturePCONFIG : SubtargetFeature<"pconfig", "HasPCONFIG", "true", + "platform configuration instruction">; // On recent X86 (port bound) processors, its preferable to combine to a single shuffle // using a variable mask over multiple fixed shuffles. def FeatureFastVariableShuffle @@ -868,6 +870,7 @@ def : IcelakeClientProc<"icelake-client">; class IcelakeServerProc : ProcModel; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 01caeac..08b57de 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -904,6 +904,7 @@ def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">; def HasRDPID : Predicate<"Subtarget->hasRDPID()">; def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; +def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">; def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">; def In64BitMode : Predicate<"Subtarget->is64Bit()">, diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index 5cc71eb..cba7d8d 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -701,3 +701,20 @@ def PTWRITEr : I<0xAE, MRM4r, (outs), (ins GR32:$dst), def PTWRITE64r : RI<0xAE, MRM4r, (outs), (ins GR64:$dst), "ptwrite{q}\t$dst", []>, XS, Requires<[In64BitMode]>; } // SchedRW + +//===----------------------------------------------------------------------===// +// Platform Configuration instruction + +// From ISA docs: +// "This instruction is used to execute functions for configuring platform +// features. +// EAX: Leaf function to be invoked. +// RBX/RCX/RDX: Leaf-specific purpose." +// "Successful execution of the leaf clears RAX (set to zero) and ZF, CF, PF, +// AF, OF, and SF are cleared. In case of failure, the failure reason is +// indicated in RAX with ZF set to 1 and CF, PF, AF, OF, and SF are cleared." +// Thus all these mentioned registers are considered clobbered. + +let Uses = [RAX, RBX, RCX, RDX], Defs = [RAX, RBX, RCX, RDX, EFLAGS] in + def PCONFIG : I<0x01, MRM_C5, (outs), (ins), "pconfig", []>, TB, + Requires<[HasPCONFIG]>; diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 31de53c..188c0a1 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -323,6 +323,7 @@ void X86Subtarget::initializeEnvironment() { HasSHSTK = false; HasIBT = false; HasSGX = false; + HasPCONFIG = false; HasCLFLUSHOPT = false; HasCLWB = false; HasWBNOINVD = false; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 996eb01..9181781 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -379,6 +379,9 @@ protected: /// Processor supports WaitPKG instructions bool HasWAITPKG; + /// Processor supports PCONFIG instruction + bool HasPCONFIG; + /// Use a retpoline thunk rather than indirect calls to block speculative /// execution. bool UseRetpoline; @@ -640,6 +643,7 @@ public: bool hasWBNOINVD() const { return HasWBNOINVD; } bool hasRDPID() const { return HasRDPID; } bool hasWAITPKG() const { return HasWAITPKG; } + bool hasPCONFIG() const { return HasPCONFIG; } bool useRetpoline() const { return UseRetpoline; } bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; } diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt index ddf5dff..493ca7c 100644 --- a/llvm/test/MC/Disassembler/X86/x86-32.txt +++ b/llvm/test/MC/Disassembler/X86/x86-32.txt @@ -871,3 +871,6 @@ #CHECK: movdir64b (%si), %ax 0x67 0x66 0x0f 0x38 0xf8 0x04 + +#CHECK: pconfig +0x0f 0x01 0xc5 diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt index 63c6050..13f1b98 100644 --- a/llvm/test/MC/Disassembler/X86/x86-64.txt +++ b/llvm/test/MC/Disassembler/X86/x86-64.txt @@ -564,3 +564,6 @@ #CHECK: movdir64b 485498096, %eax 0x67 0x66 0x0f 0x38 0xf8 0x04 0x25 0xf0 0x1c 0xf0 0x1c + +#CHECK: pconfig +0x0f 0x01 0xc5 diff --git a/llvm/test/MC/X86/x86-32-coverage.s b/llvm/test/MC/X86/x86-32-coverage.s index a81a5dc..1b1cd3f 100644 --- a/llvm/test/MC/X86/x86-32-coverage.s +++ b/llvm/test/MC/X86/x86-32-coverage.s @@ -10792,3 +10792,7 @@ btcl $4, (%eax) // CHECK: movdir64b (%si), %ax // CHECK: # encoding: [0x67,0x66,0x0f,0x38,0xf8,0x04] movdir64b (%si), %ax + +// CHECK: pconfig +// CHECK: # encoding: [0x0f,0x01,0xc5] +pconfig diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s index 0ccb3d5..ce93d89 100644 --- a/llvm/test/MC/X86/x86-64.s +++ b/llvm/test/MC/X86/x86-64.s @@ -1619,6 +1619,10 @@ movdir64b 485498096, %eax // CHECK: # encoding: [0x66,0x44,0x0f,0x38,0xf8,0x3a] movdir64b (%rdx), %r15 +// CHECK: pconfig +// CHECK: # encoding: [0x0f,0x01,0xc5] +pconfig + // __asm __volatile( // "pushf \n\t" // "popf \n\t" -- 2.7.4