From 581fe82c84839f769a7275cf4cde7ea209f5ed04 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 3 Oct 2011 17:28:23 +0000 Subject: [PATCH] Add support for MOVBE and RDRAND instructions for the assembler and disassembler. Includes feature flag checking, but no instrinsic support. Fixes PR10832, PR11026 and PR11027. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141007 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86.td | 4 +++ lib/Target/X86/X86InstrInfo.td | 32 +++++++++++++++++++++++ lib/Target/X86/X86InstrSSE.td | 1 - lib/Target/X86/X86Subtarget.cpp | 4 +++ lib/Target/X86/X86Subtarget.h | 8 ++++++ test/MC/Disassembler/X86/simple-tests.txt | 27 +++++++++++++++++++ test/MC/Disassembler/X86/x86-32.txt | 18 +++++++++++++ 7 files changed, 93 insertions(+), 1 deletion(-) diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 345cecf5d42..c5c6c4d16a1 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -96,6 +96,10 @@ def FeatureVectorUAMem : SubtargetFeature<"vector-unaligned-mem", "Allow unaligned memory operands on vector/SIMD instructions">; def FeatureAES : SubtargetFeature<"aes", "HasAES", "true", "Enable AES instructions">; +def FeatureMOVBE : SubtargetFeature<"movbe", "HasMOVBE", "true", + "Support MOVBE instruction">; +def FeatureRDRAND : SubtargetFeature<"rdrand", "HasRDRAND", "true", + "Support RDRAND instruction">; //===----------------------------------------------------------------------===// // X86 processors supported. diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index e60b867d8d6..61e4b57a854 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -473,6 +473,8 @@ def HasAES : Predicate<"Subtarget->hasAES()">; def HasCLMUL : Predicate<"Subtarget->hasCLMUL()">; def HasFMA3 : Predicate<"Subtarget->hasFMA3()">; def HasFMA4 : Predicate<"Subtarget->hasFMA4()">; +def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">; +def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">; def FPStackf32 : Predicate<"!Subtarget->hasXMM()">; def FPStackf64 : Predicate<"!Subtarget->hasXMMInt()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; @@ -1296,6 +1298,36 @@ def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$src), (ins GR16:$dst), def ARPL16mr : I<0x63, MRMSrcMem, (outs GR16:$src), (ins i16mem:$dst), "arpl\t{$src, $dst|$dst, $src}", []>, Requires<[In32BitMode]>; +//===----------------------------------------------------------------------===// +// MOVBE Instructions +// +let Predicates = [HasMOVBE] in { + def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), + "movbe{w}\t{$src, $dst|$dst, $src}", []>, OpSize, T8; + def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), + "movbe{l}\t{$src, $dst|$dst, $src}", []>, T8; + def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), + "movbe{q}\t{$src, $dst|$dst, $src}", []>, T8; + def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), + "movbe{w}\t{$src, $dst|$dst, $src}", []>, OpSize, T8; + def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), + "movbe{l}\t{$src, $dst|$dst, $src}", []>, T8; + def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), + "movbe{q}\t{$src, $dst|$dst, $src}", []>, T8; +} + +//===----------------------------------------------------------------------===// +// RDRAND Instruction +// +let Predicates = [HasRDRAND], Defs = [EFLAGS] in { + def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins), + "rdrand{w}\t$dst", []>, OpSize, TB; + def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins), + "rdrand{l}\t$dst", []>, TB; + def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins), + "rdrand{q}\t$dst", []>, TB; +} + //===----------------------------------------------------------------------===// // Subsystems. //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td index 4a51edfc5ad..b584b554a25 100644 --- a/lib/Target/X86/X86InstrSSE.td +++ b/lib/Target/X86/X86InstrSSE.td @@ -6748,4 +6748,3 @@ let Defs = [YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, def VZEROUPPER : I<0x77, RawFrm, (outs), (ins), "vzeroupper", [(int_x86_avx_vzeroupper)]>, TB, VEX, Requires<[HasAVX]>; } - diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index bb04f015aac..2d24a5ed15a 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -203,8 +203,10 @@ void X86Subtarget::AutoDetectSubtargetFeatures() { HasCLMUL = IsIntel && ((ECX >> 1) & 0x1); ToggleFeature(X86::FeatureCLMUL); HasFMA3 = IsIntel && ((ECX >> 12) & 0x1); ToggleFeature(X86::FeatureFMA3); + HasMOVBE = IsIntel && ((ECX >> 22) & 0x1); ToggleFeature(X86::FeatureMOVBE); HasPOPCNT = IsIntel && ((ECX >> 23) & 0x1); ToggleFeature(X86::FeaturePOPCNT); HasAES = IsIntel && ((ECX >> 25) & 0x1); ToggleFeature(X86::FeatureAES); + HasRDRAND = IsIntel && ((ECX >> 30) & 0x1); ToggleFeature(X86::FeatureRDRAND); HasCmpxchg16b = ((ECX >> 13) & 0x1); ToggleFeature(X86::FeatureCMPXCHG16B); if (IsIntel || IsAMD) { @@ -254,6 +256,8 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, , HasCLMUL(false) , HasFMA3(false) , HasFMA4(false) + , HasMOVBE(false) + , HasRDRAND(false) , IsBTMemSlow(false) , IsUAMemFast(false) , HasVectorUAMem(false) diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 843a3b7660b..8a6977cc056 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -90,6 +90,12 @@ protected: /// HasFMA4 - Target has 4-operand fused multiply-add bool HasFMA4; + /// HasMOVBE - True if the processor has the MOVBE instruction; + bool HasMOVBE; + + /// HasRDRAND - True if the processor has the RDRAND instruction; + bool HasRDRAND; + /// IsBTMemSlow - True if BT (bit test) of memory instructions are slow. bool IsBTMemSlow; @@ -172,6 +178,8 @@ public: bool hasCLMUL() const { return HasCLMUL; } bool hasFMA3() const { return HasFMA3; } bool hasFMA4() const { return HasFMA4; } + bool hasMOVBE() const { return HasMOVBE; } + bool hasRDRAND() const { return HasRDRAND; } bool isBTMemSlow() const { return IsBTMemSlow; } bool isUnalignedMemAccessFast() const { return IsUAMemFast; } bool hasVectorUAMem() const { return HasVectorUAMem; } diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index a9e6f41a734..e0868789876 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -368,3 +368,30 @@ # CHECK: vaddps %xmm3, %xmm15, %xmm0 0xc4 0xe1 0x00 0x58 0xc3 + +# CHECK: movbel (%rax), %eax +0x0f 0x38 0xf0 0x00 + +# CHECK: movbel %eax, (%rax) +0x0f 0x38 0xf1 0x00 + +# CHECK: movbew (%rax), %ax +0x66 0x0f 0x38 0xf0 0x00 + +# CHECK: movbew %ax, (%rax) +0x66 0x0f 0x38 0xf1 0x00 + +# CHECK: movbeq (%rax), %rax +0x48 0x0f 0x38 0xf0 0x00 + +# CHECK: movbeq %rax, (%rax) +0x48 0x0f 0x38 0xf1 0x00 + +# CHECK: rdrandw %ax +0x66 0x0f 0xc7 0xf0 + +# CHECK: rdrandl %eax +0x0f 0xc7 0xf0 + +# CHECK: rdrandq %rax +0x48 0x0f 0xc7 0xf0 diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index 35015c67d0c..54568116754 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -387,3 +387,21 @@ # CHECK: vaddps %xmm3, %xmm7, %xmm0 0xc4 0xe1 0x00 0x58 0xc3 + +# CHECK: movbel (%eax), %eax +0x0f 0x38 0xf0 0x00 + +# CHECK: movbel %eax, (%eax) +0x0f 0x38 0xf1 0x00 + +# CHECK: movbew (%eax), %ax +0x66 0x0f 0x38 0xf0 0x00 + +# CHECK: movbew %ax, (%eax) +0x66 0x0f 0x38 0xf1 0x00 + +# CHECK: rdrandw %ax +0x66 0x0f 0xc7 0xf0 + +# CHECK: rdrandl %eax +0x0f 0xc7 0xf0