diff options
author | Ashutosh Nema <ashu1212@gmail.com> | 2016-05-18 11:59:12 +0000 |
---|---|---|
committer | Ashutosh Nema <ashu1212@gmail.com> | 2016-05-18 11:59:12 +0000 |
commit | 348af9cc6b448d739465de991cc0caf032af0eb9 (patch) | |
tree | 4b9c7faed9c512f32c27d6f104e856957ca83801 /llvm/lib | |
parent | e64e230decbdaa2eab8699641476de9897ce5080 (diff) | |
download | bcm5719-llvm-348af9cc6b448d739465de991cc0caf032af0eb9.tar.gz bcm5719-llvm-348af9cc6b448d739465de991cc0caf032af0eb9.zip |
Add new flag and intrinsic support for MWAITX and MONITORX instructions
Summary:
MONITORX/MWAITX instructions provide similar capability to the MONITOR/MWAIT
pair while adding a timer function, such that another termination of the MWAITX
instruction occurs when the timer expires. The presence of the MONITORX and
MWAITX instructions is indicated by CPUID 8000_0001, ECX, bit 29.
The MONITORX and MWAITX instructions are intercepted by the same bits that
intercept MONITOR and MWAIT. MONITORX instruction establishes a range to be
monitored. MWAITX instruction causes the processor to stop instruction execution
and enter an implementation-dependent optimized state until occurrence of a
class of events.
Opcode of MONITORX instruction is "0F 01 FA". Opcode of MWAITX instruction is
"0F 01 FB". These opcode information is used in adding tests for the
disassembler.
These instructions are enabled for AMD's bdver4 architecture.
Patch by Ganesh Gopalasubramanian!
Reviewers: echristo, craig.topper, RKSimon
Subscribers: RKSimon, joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D19795
llvm-svn: 269911
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Support/Host.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 35 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrSSE.td | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Schedule.td | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 4 |
8 files changed, 44 insertions, 15 deletions
diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index 35c51f77c5b..7e7298ba5b1 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -252,6 +252,7 @@ StringRef sys::getHostCPUName() { GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); bool Em64T = (EDX >> 29) & 0x1; bool HasTBM = (ECX >> 21) & 0x1; + bool HasMWAITX = (ECX >> 29) & 0x1; if (memcmp(text.c, "GenuineIntel", 12) == 0) { switch (Family) { @@ -803,6 +804,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave; Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave; Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); + Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); bool HasLeaf7 = MaxLevel >= 7 && !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 896d0020db9..8267a84518f 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -198,6 +198,8 @@ def FeatureRDSEED : SubtargetFeature<"rdseed", "HasRDSEED", "true", "Support RDSEED instruction">; def FeatureLAHFSAHF : SubtargetFeature<"sahf", "HasLAHFSAHF", "true", "Support LAHF and SAHF instructions">; +def FeatureMWAITX : SubtargetFeature<"mwaitx", "HasMWAITX", "true", + "Enable MONITORX/MWAITX timer functionality">; def FeatureMPX : SubtargetFeature<"mpx", "HasMPX", "true", "Support MPX instructions">; def FeatureLEAForSP : SubtargetFeature<"lea-sp", "UseLeaForSP", "true", @@ -728,7 +730,8 @@ def : Proc<"bdver4", [ FeatureFMA, FeatureXSAVEOPT, FeatureFSGSBase, - FeatureLAHFSAHF + FeatureLAHFSAHF, + FeatureMWAITX ]>; def : Proc<"geode", [FeatureX87, FeatureSlowUAMem16, Feature3DNowA]>; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 1e3b5225bf6..368e265f8e5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -22349,7 +22349,8 @@ static MachineBasicBlock *emitRDPKRU(MachineInstr *MI, MachineBasicBlock *BB, } static MachineBasicBlock *emitMonitor(MachineInstr *MI, MachineBasicBlock *BB, - const X86Subtarget &Subtarget) { + const X86Subtarget &Subtarget, + unsigned Opc) { DebugLoc dl = MI->getDebugLoc(); const TargetInstrInfo *TII = Subtarget.getInstrInfo(); // Address into RAX/EAX, other two args into ECX, EDX. @@ -22366,7 +22367,7 @@ static MachineBasicBlock *emitMonitor(MachineInstr *MI, MachineBasicBlock *BB, .addReg(MI->getOperand(ValOps+1).getReg()); // The instruction doesn't actually take any operands though. - BuildMI(*BB, MI, dl, TII->get(X86::MONITORrrr)); + BuildMI(*BB, MI, dl, TII->get(Opc)); MI->eraseFromParent(); // The pseudo is gone now. return BB; @@ -23867,7 +23868,9 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, // Thread synchronization. case X86::MONITOR: - return emitMonitor(MI, BB, Subtarget); + return emitMonitor(MI, BB, Subtarget, X86::MONITORrrr); + case X86::MONITORX: + return emitMonitor(MI, BB, Subtarget, X86::MONITORXrrr); // PKU feature case X86::WRPKRU: return emitWRPKRU(MI, BB, Subtarget); diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 593e9819c21..dcd3f5395ab 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -847,6 +847,7 @@ def HasPRFCHW : Predicate<"Subtarget->hasPRFCHW()">; def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">; def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">; def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">; +def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">; def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">; def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">; def HasMPX : Predicate<"Subtarget->hasMPX()">; @@ -2401,22 +2402,34 @@ defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>; //===----------------------------------------------------------------------===// // MONITORX/MWAITX Instructions // -let SchedRW = [WriteSystem] in { -let Uses = [EAX, ECX, EDX] in -def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], - IIC_SSE_MONITOR>, TB; -let Uses = [ECX, EAX, EBX] in -def MWAITXrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", [], IIC_SSE_MWAIT>, - TB; +let SchedRW = [ WriteSystem ] in { + let usesCustomInserter = 1 in { + def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3), + [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>, + Requires<[ HasMWAITX ]>; + } + + let Uses = [ EAX, ECX, EDX ] in { + def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>, + TB, Requires<[ HasMWAITX ]>; + } + + let Uses = [ ECX, EAX, EBX ] in { + def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", + [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>, + TB, Requires<[ HasMWAITX ]>; + } } // SchedRW -def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrr)>, Requires<[Not64BitMode]>; -def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrr)>, Requires<[In64BitMode]>; +def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>, + Requires<[ Not64BitMode ]>; +def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>, + Requires<[ In64BitMode ]>; def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>, - Requires<[Not64BitMode]>; + Requires<[ Not64BitMode ]>; def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>, - Requires<[In64BitMode]>; + Requires<[ In64BitMode ]>; //===----------------------------------------------------------------------===// // CLZERO Instruction diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index 52b288926ef..ee2331250c1 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -5802,6 +5802,7 @@ def MONITOR : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3), let Uses = [EAX, ECX, EDX] in def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>, TB, Requires<[HasSSE3]>; + let Uses = [ECX, EAX] in def MWAITrr : I<0x01, MRM_C9, (outs), (ins), "mwait", [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>, diff --git a/llvm/lib/Target/X86/X86Schedule.td b/llvm/lib/Target/X86/X86Schedule.td index 16508edb452..35257f89100 100644 --- a/llvm/lib/Target/X86/X86Schedule.td +++ b/llvm/lib/Target/X86/X86Schedule.td @@ -364,6 +364,8 @@ def IIC_SSE_PALIGNRR : InstrItinClass; def IIC_SSE_PALIGNRM : InstrItinClass; def IIC_SSE_MWAIT : InstrItinClass; def IIC_SSE_MONITOR : InstrItinClass; +def IIC_SSE_MWAITX : InstrItinClass; +def IIC_SSE_MONITORX : InstrItinClass; def IIC_SSE_PREFETCH : InstrItinClass; def IIC_SSE_PAUSE : InstrItinClass; diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index dde29a0c083..5d8276e00cd 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -313,6 +313,7 @@ void X86Subtarget::initializeEnvironment() { HasPRFCHW = false; HasRDSEED = false; HasLAHFSAHF = false; + HasMWAITX = false; HasMPX = false; IsBTMemSlow = false; IsSHLDSlow = false; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index d8cf98b6e2a..06df8689fe8 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -164,6 +164,9 @@ protected: /// Processor has LAHF/SAHF instructions. bool HasLAHFSAHF; + /// Processor has MONITORX/MWAITX instructions. + bool HasMWAITX; + /// Processor has Prefetch with intent to Write instruction bool HasPFPREFETCHWT1; @@ -421,6 +424,7 @@ public: bool hasPRFCHW() const { return HasPRFCHW; } bool hasRDSEED() const { return HasRDSEED; } bool hasLAHFSAHF() const { return HasLAHFSAHF; } + bool hasMWAITX() const { return HasMWAITX; } bool isBTMemSlow() const { return IsBTMemSlow; } bool isSHLDSlow() const { return IsSHLDSlow; } bool isUnalignedMem16Slow() const { return IsUAMem16Slow; } |