From e7b05504faa86a5c0b80a62ddb60cbb0cf163d5d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 30 Oct 2011 19:57:21 +0000 Subject: [PATCH] Add intrinsics and feature flag for read/write FS/GS base instructions. Also add AVX2 feature flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143319 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IntrinsicsX86.td | 22 +++++++++++++++++++++ lib/Target/X86/X86.td | 17 ++++++++++------ lib/Target/X86/X86InstrInfo.td | 2 ++ lib/Target/X86/X86InstrSystem.td | 34 ++++++++++++++++++++------------ lib/Target/X86/X86Subtarget.cpp | 11 +++++++++++ lib/Target/X86/X86Subtarget.h | 8 ++++++++ 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index 618761827e4..912307b9392 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -1651,3 +1651,25 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_bmi_pext_64 : GCCBuiltin<"__builtin_ia32_pext_di">, Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; } + +//===----------------------------------------------------------------------===// +// FS/GS Base + +let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". + def int_x86_rdfsbase_32 : GCCBuiltin<"__builtin_ia32_rdfsbase32">, + Intrinsic<[llvm_i32_ty], []>; + def int_x86_rdgsbase_32 : GCCBuiltin<"__builtin_ia32_rdgsbase32">, + Intrinsic<[llvm_i32_ty], []>; + def int_x86_rdfsbase_64 : GCCBuiltin<"__builtin_ia32_rdfsbase64">, + Intrinsic<[llvm_i64_ty], []>; + def int_x86_rdgsbase_64 : GCCBuiltin<"__builtin_ia32_rdgsbase64">, + Intrinsic<[llvm_i64_ty], []>; + def int_x86_wrfsbase_32 : GCCBuiltin<"__builtin_ia32_wrfsbase32">, + Intrinsic<[], [llvm_i32_ty]>; + def int_x86_wrgsbase_32 : GCCBuiltin<"__builtin_ia32_wrgsbase32">, + Intrinsic<[], [llvm_i32_ty]>; + def int_x86_wrfsbase_64 : GCCBuiltin<"__builtin_ia32_wrfsbase64">, + Intrinsic<[], [llvm_i64_ty]>; + def int_x86_wrgsbase_64 : GCCBuiltin<"__builtin_ia32_wrgsbase64">, + Intrinsic<[], [llvm_i64_ty]>; +} diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 986196005f4..62a70166912 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -82,6 +82,9 @@ def FeatureSSE4A : SubtargetFeature<"sse4a", "HasSSE4A", "true", def FeatureAVX : SubtargetFeature<"avx", "HasAVX", "true", "Enable AVX instructions">; +def FeatureAVX2 : SubtargetFeature<"avx2", "HasAVX2", "true", + "Enable AVX2 instructions", + [FeatureAVX]>; def FeatureCLMUL : SubtargetFeature<"clmul", "HasCLMUL", "true", "Enable carry-less multiplication instructions">; def FeatureFMA3 : SubtargetFeature<"fma3", "HasFMA3", "true", @@ -99,6 +102,8 @@ def FeatureRDRAND : SubtargetFeature<"rdrand", "HasRDRAND", "true", "Support RDRAND instruction">; def FeatureF16C : SubtargetFeature<"f16c", "HasF16C", "true", "Support 16-bit floating point conversion instructions">; +def FeatureFSGSBase : SubtargetFeature<"fsgsbase", "HasFSGSBase", "true", + "Support FS/GS Base instructions">; def FeatureLZCNT : SubtargetFeature<"lzcnt", "HasLZCNT", "true", "Support LZCNT instruction">; def FeatureBMI : SubtargetFeature<"bmi", "HasBMI", "true", @@ -157,13 +162,14 @@ def : Proc<"corei7-avx", [FeatureSSE42, FeatureCMPXCHG16B, // Ivy Bridge def : Proc<"core-avx-i", [FeatureSSE42, FeatureCMPXCHG16B, FeatureAES, FeatureCLMUL, - FeatureRDRAND, FeatureF16C]>; + FeatureRDRAND, FeatureF16C, FeatureFSGSBase]>; // Haswell +// FIXME: Disabling AVX/AVX2 for now since it's not ready. def : Proc<"core-avx2", [FeatureSSE42, FeatureCMPXCHG16B, FeatureAES, FeatureCLMUL, FeatureRDRAND, FeatureF16C, - FeatureFMA3, FeatureMOVBE, FeatureLZCNT, - FeatureBMI, FeatureBMI2]>; + FeatureFSGSBase, FeatureFMA3, FeatureMOVBE, + FeatureLZCNT, FeatureBMI, FeatureBMI2]>; def : Proc<"k6", [FeatureMMX]>; def : Proc<"k6-2", [Feature3DNow]>; @@ -194,9 +200,8 @@ def : Proc<"barcelona", [FeatureSSE3, FeatureSSE4A, Feature3DNowA, FeatureCMPXCHG16B, FeatureSlowBTMem]>; def : Proc<"istanbul", [Feature3DNowA, FeatureCMPXCHG16B, - FeatureSSE4A, Feature3DNowA]>; -def : Proc<"shanghai", [Feature3DNowA, FeatureCMPXCHG16B, FeatureSSE4A, - Feature3DNowA]>; + FeatureSSE4A]>; +def : Proc<"shanghai", [Feature3DNowA, FeatureCMPXCHG16B, FeatureSSE4A]>; def : Proc<"winchip-c6", [FeatureMMX]>; def : Proc<"winchip2", [Feature3DNow]>; diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 2a85ba193f3..79ce509412f 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -472,6 +472,7 @@ def HasSSE42 : Predicate<"Subtarget->hasSSE42()">; def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">; def HasAVX : Predicate<"Subtarget->hasAVX()">; +def HasAVX2 : Predicate<"Subtarget->hasAVX2()">; def HasXMMInt : Predicate<"Subtarget->hasXMMInt()">; def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">; @@ -482,6 +483,7 @@ def HasFMA4 : Predicate<"Subtarget->hasFMA4()">; def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">; def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">; def HasF16C : Predicate<"Subtarget->hasF16C()">; +def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">; def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">; def HasBMI : Predicate<"Subtarget->hasBMI()">; def HasBMI2 : Predicate<"Subtarget->hasBMI2()">; diff --git a/lib/Target/X86/X86InstrSystem.td b/lib/Target/X86/X86InstrSystem.td index be3500adeca..1b43838ee52 100644 --- a/lib/Target/X86/X86InstrSystem.td +++ b/lib/Target/X86/X86InstrSystem.td @@ -446,23 +446,31 @@ let Defs = [RAX, RDX, RSI], Uses = [RAX, RSI] in //===----------------------------------------------------------------------===// // FS/GS Base Instructions -let Predicates = [In64BitMode] in { +let Predicates = [HasFSGSBase, In64BitMode] in { def RDFSBASE : I<0xAE, MRM0r, (outs GR32:$dst), (ins), - "rdfsbase{l}\t$dst", []>, TB, XS; + "rdfsbase{l}\t$dst", + [(set GR32:$dst, (int_x86_rdfsbase_32))]>, TB, XS; def RDFSBASE64 : RI<0xAE, MRM0r, (outs GR64:$dst), (ins), - "rdfsbase{q}\t$dst", []>, TB, XS; + "rdfsbase{q}\t$dst", + [(set GR64:$dst, (int_x86_rdfsbase_64))]>, TB, XS; def RDGSBASE : I<0xAE, MRM1r, (outs GR32:$dst), (ins), - "rdgsbase{l}\t$dst", []>, TB, XS; + "rdgsbase{l}\t$dst", + [(set GR32:$dst, (int_x86_rdgsbase_32))]>, TB, XS; def RDGSBASE64 : RI<0xAE, MRM1r, (outs GR64:$dst), (ins), - "rdgsbase{q}\t$dst", []>, TB, XS; - def WRFSBASE : I<0xAE, MRM2r, (outs), (ins GR32:$dst), - "wrfsbase{l}\t$dst", []>, TB, XS; - def WRFSBASE64 : RI<0xAE, MRM2r, (outs), (ins GR64:$dst), - "wrfsbase{q}\t$dst", []>, TB, XS; - def WRGSBASE : I<0xAE, MRM3r, (outs), (ins GR32:$dst), - "wrgsbase{l}\t$dst", []>, TB, XS; - def WRGSBASE64 : RI<0xAE, MRM3r, (outs), (ins GR64:$dst), - "wrgsbase{q}\t$dst", []>, TB, XS; + "rdgsbase{q}\t$dst", + [(set GR64:$dst, (int_x86_rdgsbase_64))]>, TB, XS; + def WRFSBASE : I<0xAE, MRM2r, (outs), (ins GR32:$src), + "wrfsbase{l}\t$src", + [(int_x86_wrfsbase_32 GR32:$src)]>, TB, XS; + def WRFSBASE64 : RI<0xAE, MRM2r, (outs), (ins GR64:$src), + "wrfsbase{q}\t$src", + [(int_x86_wrfsbase_64 GR64:$src)]>, TB, XS; + def WRGSBASE : I<0xAE, MRM3r, (outs), (ins GR32:$src), + "wrgsbase{l}\t$src", + [(int_x86_wrgsbase_32 GR32:$src)]>, TB, XS; + def WRGSBASE64 : RI<0xAE, MRM3r, (outs), (ins GR64:$src), + "wrgsbase{q}\t$src", + [(int_x86_wrgsbase_64 GR64:$src)]>, TB, XS; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index fd8ef19139f..e7bcbf898be 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -279,10 +279,19 @@ void X86Subtarget::AutoDetectSubtargetFeatures() { if (IsIntel && MaxLevel >= 7) { if (!X86_MC::GetCpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX)) { + if (EBX & 0x1) { + HasFSGSBase = true; + ToggleFeature(X86::FeatureFSGSBase); + } if ((EBX >> 3) & 0x1) { HasBMI = true; ToggleFeature(X86::FeatureBMI); } + // FIXME: AVX2 codegen support is not ready. + //if ((EBX >> 5) & 0x1) { + // HasAVX2 = true; + // ToggleFeature(X86::FeatureAVX2); + //} if ((EBX >> 8) & 0x1) { HasBMI2 = true; ToggleFeature(X86::FeatureBMI2); @@ -303,6 +312,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, , HasPOPCNT(false) , HasSSE4A(false) , HasAVX(false) + , HasAVX2(false) , HasAES(false) , HasCLMUL(false) , HasFMA3(false) @@ -310,6 +320,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, , HasMOVBE(false) , HasRDRAND(false) , HasF16C(false) + , HasFSGSBase(false) , HasLZCNT(false) , HasBMI(false) , HasBMI2(false) diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 5e08f014e7d..763fb432f4a 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -78,6 +78,9 @@ protected: /// HasAVX - Target has AVX instructions bool HasAVX; + /// HasAVX2 - Target has AVX2 instructions + bool HasAVX2; + /// HasAES - Target has AES instructions bool HasAES; @@ -99,6 +102,9 @@ protected: /// HasF16C - Processor has 16-bit floating point conversion instructions. bool HasF16C; + /// HasFSGSBase - Processor has FS/GS base insturctions. + bool HasFSGSBase; + /// HasLZCNT - Processor has LZCNT instruction. bool HasLZCNT; @@ -181,6 +187,7 @@ public: bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; } bool hasPOPCNT() const { return HasPOPCNT; } bool hasAVX() const { return HasAVX; } + bool hasAVX2() const { return HasAVX2; } bool hasXMM() const { return hasSSE1() || hasAVX(); } bool hasXMMInt() const { return hasSSE2() || hasAVX(); } bool hasAES() const { return HasAES; } @@ -190,6 +197,7 @@ public: bool hasMOVBE() const { return HasMOVBE; } bool hasRDRAND() const { return HasRDRAND; } bool hasF16C() const { return HasF16C; } + bool hasFSGSBase() const { return HasFSGSBase; } bool hasLZCNT() const { return HasLZCNT; } bool hasBMI() const { return HasBMI; } bool hasBMI2() const { return HasBMI2; }