[llvm-commits] [llvm] r134641 - in /llvm/trunk: lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h lib/Target/X86/X86.td lib/Target/X86/X86Subtarget.cpp lib/Target/X86/X86Subtarget.h lib/Target/X86/X86Ta
Eli Friedman
eli.friedman at gmail.com
Fri Jul 8 13:03:59 PDT 2011
On Thu, Jul 7, 2011 at 2:06 PM, Evan Cheng <evan.cheng at apple.com> wrote:
> Author: evancheng
> Date: Thu Jul 7 16:06:52 2011
> New Revision: 134641
>
> URL: http://llvm.org/viewvc/llvm-project?rev=134641&view=rev
> Log:
> Add Mode64Bit feature and sink it down to MC layer.
>
> Modified:
> llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
> llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
> llvm/trunk/lib/Target/X86/X86.td
> llvm/trunk/lib/Target/X86/X86Subtarget.cpp
> llvm/trunk/lib/Target/X86/X86Subtarget.h
> llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
> llvm/trunk/test/CodeGen/X86/2010-04-08-CoalescerBug.ll
> llvm/trunk/test/CodeGen/X86/2010-06-25-CoalescerSubRegDefDead.ll
> llvm/trunk/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll
> llvm/trunk/test/CodeGen/X86/memcpy.ll
> llvm/trunk/test/CodeGen/X86/tlv-1.ll
>
> Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp?rev=134641&r1=134640&r2=134641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp (original)
> +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp Thu Jul 7 16:06:52 2011
> @@ -16,6 +16,8 @@
> #include "llvm/MC/MCRegisterInfo.h"
> #include "llvm/MC/MCSubtargetInfo.h"
> #include "llvm/Target/TargetRegistry.h"
> +#include "llvm/ADT/Triple.h"
> +#include "llvm/Support/Host.h"
>
> #define GET_REGINFO_MC_DESC
> #include "X86GenRegisterInfo.inc"
> @@ -28,6 +30,104 @@
>
> using namespace llvm;
>
> +
> +std::string X86_MC::ParseX86Triple(StringRef TT) {
> + Triple TheTriple(TT);
> + if (TheTriple.getArch() == Triple::x86_64)
> + return "+64bit-mode";
> + return "";
> +}
> +
> +/// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
> +/// specified arguments. If we can't run cpuid on the host, return true.
> +bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
> + unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
> +#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
> + #if defined(__GNUC__)
> + // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
> + asm ("movq\t%%rbx, %%rsi\n\t"
> + "cpuid\n\t"
> + "xchgq\t%%rbx, %%rsi\n\t"
> + : "=a" (*rEAX),
> + "=S" (*rEBX),
> + "=c" (*rECX),
> + "=d" (*rEDX)
> + : "a" (value));
> + return false;
> + #elif defined(_MSC_VER)
> + int registers[4];
> + __cpuid(registers, value);
> + *rEAX = registers[0];
> + *rEBX = registers[1];
> + *rECX = registers[2];
> + *rEDX = registers[3];
> + return false;
> + #endif
> +#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
> + #if defined(__GNUC__)
> + asm ("movl\t%%ebx, %%esi\n\t"
> + "cpuid\n\t"
> + "xchgl\t%%ebx, %%esi\n\t"
> + : "=a" (*rEAX),
> + "=S" (*rEBX),
> + "=c" (*rECX),
> + "=d" (*rEDX)
> + : "a" (value));
> + return false;
> + #elif defined(_MSC_VER)
> + __asm {
> + mov eax,value
> + cpuid
> + mov esi,rEAX
> + mov dword ptr [esi],eax
> + mov esi,rEBX
> + mov dword ptr [esi],ebx
> + mov esi,rECX
> + mov dword ptr [esi],ecx
> + mov esi,rEDX
> + mov dword ptr [esi],edx
> + }
> + return false;
> + #endif
> +#endif
> + return true;
> +}
> +
> +void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
> + unsigned &Model) {
> + Family = (EAX >> 8) & 0xf; // Bits 8 - 11
> + Model = (EAX >> 4) & 0xf; // Bits 4 - 7
> + if (Family == 6 || Family == 0xf) {
> + if (Family == 0xf)
> + // Examine extended family ID if family ID is F.
> + Family += (EAX >> 20) & 0xff; // Bits 20 - 27
> + // Examine extended model ID if family ID is 6 or F.
> + Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
> + }
> +}
> +
> +static bool hasX86_64() {
> + // FIXME: Code duplication. See X86Subtarget::AutoDetectSubtargetFeatures.
> + unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
> + union {
> + unsigned u[3];
> + char c[12];
> + } text;
> +
> + if (X86_MC::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
> + return false;
> +
> + bool IsIntel = memcmp(text.c, "GenuineIntel", 12) == 0;
> + bool IsAMD = !IsIntel && memcmp(text.c, "AuthenticAMD", 12) == 0;
> + if (IsIntel || IsAMD) {
> + X86_MC::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
> + if ((EDX >> 29) & 0x1)
> + return true;
> + }
> +
> + return false;
> +}
> +
> MCInstrInfo *createX86MCInstrInfo() {
> MCInstrInfo *X = new MCInstrInfo();
> InitX86MCInstrInfo(X);
> @@ -42,8 +142,24 @@
>
> MCSubtargetInfo *createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
> StringRef FS) {
> + std::string ArchFS = X86_MC::ParseX86Triple(TT);
> + if (!FS.empty()) {
> + if (!ArchFS.empty())
> + ArchFS = ArchFS + "," + FS.str();
> + else
> + ArchFS = FS;
> + }
> +
> + std::string CPUName = CPU;
> + if (CPUName.empty())
> + CPUName = sys::getHostCPUName();
> +
> + if (ArchFS.empty() && CPUName.empty() && hasX86_64())
> + // Auto-detect if host is 64-bit capable, it's the default if true.
> + ArchFS = "+64bit-mode";
> +
> MCSubtargetInfo *X = new MCSubtargetInfo();
> - InitX86MCSubtargetInfo(X, CPU, FS);
> + InitX86MCSubtargetInfo(X, CPU, ArchFS);
> return X;
> }
>
>
> Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h?rev=134641&r1=134640&r2=134641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h Thu Jul 7 16:06:52 2011
> @@ -14,10 +14,24 @@
> #ifndef X86MCTARGETDESC_H
> #define X86MCTARGETDESC_H
>
> +#include <string>
> +
> namespace llvm {
> class Target;
> +class StringRef;
>
> extern Target TheX86_32Target, TheX86_64Target;
> +
> +namespace X86_MC {
> + std::string ParseX86Triple(StringRef TT);
> +
> + /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in
> + /// the specified arguments. If we can't run cpuid on the host, return true.
> + bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
> + unsigned *rEBX, unsigned *rECX, unsigned *rEDX);
> +
> + void DetectFamilyModel(unsigned EAX, unsigned &Family, unsigned &Model);
> +}
> } // End llvm namespace
>
> // Defines symbolic names for X86 registers. This defines a mapping from
>
> Modified: llvm/trunk/lib/Target/X86/X86.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=134641&r1=134640&r2=134641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86.td (original)
> +++ llvm/trunk/lib/Target/X86/X86.td Thu Jul 7 16:06:52 2011
> @@ -17,6 +17,13 @@
> include "llvm/Target/Target.td"
>
> //===----------------------------------------------------------------------===//
> +// X86 Subtarget state.
> +//
> +
> +def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true",
> + "64-bit mode (x86_64)">;
> +
> +//===----------------------------------------------------------------------===//
> // X86 Subtarget features.
> //===----------------------------------------------------------------------===//
>
>
> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=134641&r1=134640&r2=134641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Thu Jul 7 16:06:52 2011
> @@ -158,7 +158,7 @@
> /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls
> /// to immediate address.
> bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const {
> - if (Is64Bit)
> + if (In64BitMode)
> return false;
> return isTargetELF() || TM.getRelocationModel() == Reloc::Static;
> }
> @@ -174,73 +174,6 @@
> return 200;
> }
>
> -/// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
> -/// specified arguments. If we can't run cpuid on the host, return true.
> -static bool GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
> - unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
> -#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
> - #if defined(__GNUC__)
> - // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
> - asm ("movq\t%%rbx, %%rsi\n\t"
> - "cpuid\n\t"
> - "xchgq\t%%rbx, %%rsi\n\t"
> - : "=a" (*rEAX),
> - "=S" (*rEBX),
> - "=c" (*rECX),
> - "=d" (*rEDX)
> - : "a" (value));
> - return false;
> - #elif defined(_MSC_VER)
> - int registers[4];
> - __cpuid(registers, value);
> - *rEAX = registers[0];
> - *rEBX = registers[1];
> - *rECX = registers[2];
> - *rEDX = registers[3];
> - return false;
> - #endif
> -#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
> - #if defined(__GNUC__)
> - asm ("movl\t%%ebx, %%esi\n\t"
> - "cpuid\n\t"
> - "xchgl\t%%ebx, %%esi\n\t"
> - : "=a" (*rEAX),
> - "=S" (*rEBX),
> - "=c" (*rECX),
> - "=d" (*rEDX)
> - : "a" (value));
> - return false;
> - #elif defined(_MSC_VER)
> - __asm {
> - mov eax,value
> - cpuid
> - mov esi,rEAX
> - mov dword ptr [esi],eax
> - mov esi,rEBX
> - mov dword ptr [esi],ebx
> - mov esi,rECX
> - mov dword ptr [esi],ecx
> - mov esi,rEDX
> - mov dword ptr [esi],edx
> - }
> - return false;
> - #endif
> -#endif
> - return true;
> -}
> -
> -static void DetectFamilyModel(unsigned EAX, unsigned &Family, unsigned &Model) {
> - Family = (EAX >> 8) & 0xf; // Bits 8 - 11
> - Model = (EAX >> 4) & 0xf; // Bits 4 - 7
> - if (Family == 6 || Family == 0xf) {
> - if (Family == 0xf)
> - // Examine extended family ID if family ID is F.
> - Family += (EAX >> 20) & 0xff; // Bits 20 - 27
> - // Examine extended model ID if family ID is 6 or F.
> - Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
> - }
> -}
> -
> void X86Subtarget::AutoDetectSubtargetFeatures() {
> unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
> union {
> @@ -248,10 +181,10 @@
> char c[12];
> } text;
>
> - if (GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
> + if (X86_MC::GetCpuIDAndInfo(0, &EAX, text.u+0, text.u+2, text.u+1))
> return;
>
> - GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
> + X86_MC::GetCpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
>
> if ((EDX >> 15) & 1) HasCMov = true;
> if ((EDX >> 23) & 1) X86SSELevel = MMX;
> @@ -276,13 +209,13 @@
> // Determine if bit test memory instructions are slow.
> unsigned Family = 0;
> unsigned Model = 0;
> - DetectFamilyModel(EAX, Family, Model);
> + X86_MC::DetectFamilyModel(EAX, Family, Model);
> IsBTMemSlow = IsAMD || (Family == 6 && Model >= 13);
> // If it's Nehalem, unaligned memory access is fast.
> if (Family == 15 && Model == 26)
> IsUAMemFast = true;
>
> - GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
> + X86_MC::GetCpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
> HasX86_64 = (EDX >> 29) & 0x1;
> HasSSE4A = IsAMD && ((ECX >> 6) & 0x1);
> HasFMA4 = IsAMD && ((ECX >> 16) & 0x1);
> @@ -291,7 +224,7 @@
>
> X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
> const std::string &FS,
> - bool is64Bit, unsigned StackAlignOverride)
> + unsigned StackAlignOverride)
> : X86GenSubtargetInfo(TT, CPU, FS)
> , PICStyle(PICStyles::None)
> , X86SSELevel(NoMMXSSE)
> @@ -312,15 +245,26 @@
> // FIXME: this is a known good value for Yonah. How about others?
> , MaxInlineSizeThreshold(128)
> , TargetTriple(TT)
> - , Is64Bit(is64Bit) {
> + , In64BitMode(false) {
> + // Insert the architecture feature derived from the target triple into the
> + // feature string. This is important for setting features that are implied
> + // based on the architecture version.
> + std::string ArchFS = X86_MC::ParseX86Triple(TT);
> + if (!FS.empty()) {
> + if (!ArchFS.empty())
> + ArchFS = ArchFS + "," + FS;
> + else
> + ArchFS = FS;
> + }
> +
> + std::string CPUName = CPU;
> + if (CPUName.empty())
> + CPUName = sys::getHostCPUName();
>
> // Determine default and user specified characteristics
> - if (!CPU.empty() || !FS.empty()) {
> + if (!CPUName.empty() || !ArchFS.empty()) {
> // If feature string is not empty, parse features string.
> - std::string CPUName = CPU;
> - if (CPUName.empty())
> - CPUName = sys::getHostCPUName();
> - ParseSubtargetFeatures(CPUName, FS);
> + ParseSubtargetFeatures(CPUName, ArchFS);
> // All X86-64 CPUs also have SSE2, however user might request no SSE via
> // -mattr, so don't force SSELevel here.
> if (HasAVX)
> @@ -328,14 +272,19 @@
> } else {
> // Otherwise, use CPUID to auto-detect feature set.
> AutoDetectSubtargetFeatures();
> +
> + // If CPU is 64-bit capable, default to 64-bit mode if not specified.
> + In64BitMode = HasX86_64;
> +
> // Make sure SSE2 is enabled; it is available on all X86-64 CPUs.
> - if (Is64Bit && !HasAVX && X86SSELevel < SSE2)
> + if (In64BitMode && !HasAVX && X86SSELevel < SSE2)
> X86SSELevel = SSE2;
> }
>
> // If requesting codegen for X86-64, make sure that 64-bit features
> // are enabled.
> - if (Is64Bit) {
> + // FIXME: Remove this feature since it's not actually being used.
> + if (In64BitMode) {
> HasX86_64 = true;
>
> // All 64-bit cpus have cmov support.
> @@ -345,7 +294,7 @@
> DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
> << ", 3DNowLevel " << X863DNowLevel
> << ", 64bit " << HasX86_64 << "\n");
> - assert((!Is64Bit || HasX86_64) &&
> + assert((!In64BitMode || HasX86_64) &&
> "64-bit code requested on a subtarget that doesn't support it!");
>
> // Stack alignment is 16 bytes on Darwin, FreeBSD, Linux and Solaris (both
> @@ -353,6 +302,6 @@
> if (StackAlignOverride)
> stackAlignment = StackAlignOverride;
> else if (isTargetDarwin() || isTargetFreeBSD() || isTargetLinux() ||
> - isTargetSolaris() || Is64Bit)
> + isTargetSolaris() || In64BitMode)
> stackAlignment = 16;
> }
The bit of this change in X86Subtarget.cpp appears to break tests
anywhere that sys::getHostCPUName doesn't return the name of a known
64-bit-capable x86 CPU (ARM, older x86 CPUs, very new x86 CPUS).
Please fix or revert.
-Eli
More information about the llvm-commits
mailing list