X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86AsmBackend.cpp;h=4d7d96dcb36bd9150ceae86304626bab8a6bd936;hb=865f09334f67edb2000fb38c6c3c28283b88b3bf;hp=d137875e2cf60e33a8c520c9417ca6a8bc9005ba;hpb=5d05d9769ec98cdee359fd934a56c9455e21232b;p=oota-llvm.git diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp index d137875e2cf..4d7d96dcb36 100644 --- a/lib/Target/X86/X86AsmBackend.cpp +++ b/lib/Target/X86/X86AsmBackend.cpp @@ -12,15 +12,16 @@ #include "X86FixupKinds.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCMachObjectWriter.h" -#include "llvm/MC/MCObjectFormat.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Object/MachOFormat.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -28,6 +29,13 @@ #include "llvm/Target/TargetAsmBackend.h" using namespace llvm; +// Option to allow disabling arithmetic relaxation to workaround PR9807, which +// is useful when running bitwise comparison experiments on Darwin. We should be +// able to remove this once PR9807 is resolved. +static cl::opt +MCDisableArithRelaxation("mc-x86-disable-arith-relaxation", + cl::desc("Disable relaxation of arithmetic instruction for X86")); + static unsigned getFixupKindLog2Size(unsigned Kind) { switch (Kind) { default: assert(0 && "invalid fixup kind!"); @@ -41,16 +49,18 @@ static unsigned getFixupKindLog2Size(unsigned Kind) { case X86::reloc_signed_4byte: case X86::reloc_global_offset_table: case FK_Data_4: return 2; + case FK_PCRel_8: case FK_Data_8: return 3; } } namespace { -class X86MachObjectWriter : public MCMachObjectTargetWriter { + +class X86ELFObjectWriter : public MCELFObjectTargetWriter { public: - X86MachObjectWriter(bool Is64Bit, uint32_t CPUType, - uint32_t CPUSubtype) - : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype) {} + X86ELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine, + bool HasRelocationAddend) + : MCELFObjectTargetWriter(is64Bit, OSType, EMachine, HasRelocationAddend) {} }; class X86AsmBackend : public TargetAsmBackend { @@ -181,6 +191,9 @@ static unsigned getRelaxedOpcodeArith(unsigned Op) { case X86::CMP32mi8: return X86::CMP32mi; case X86::CMP64ri8: return X86::CMP64ri32; case X86::CMP64mi8: return X86::CMP64mi32; + + // PUSH + case X86::PUSHi8: return X86::PUSHi32; } } @@ -196,6 +209,9 @@ bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst) const { if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) return true; + if (MCDisableArithRelaxation) + return false; + // Check if this instruction is ever relaxable. if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) return false; @@ -283,23 +299,16 @@ bool X86AsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { namespace { class ELFX86AsmBackend : public X86AsmBackend { - MCELFObjectFormat Format; - public: Triple::OSType OSType; ELFX86AsmBackend(const Target &T, Triple::OSType _OSType) : X86AsmBackend(T), OSType(_OSType) { - HasScatteredSymbols = true; HasReliableSymbolDifference = true; } - virtual const MCObjectFormat &getObjectFormat() const { - return Format; - } - virtual bool doesSectionRequireSymbols(const MCSection &Section) const { const MCSectionELF &ES = static_cast(Section); - return ES.getFlags() & MCSectionELF::SHF_MERGE; + return ES.getFlags() & ELF::SHF_MERGE; } }; @@ -309,10 +318,12 @@ public: : ELFX86AsmBackend(T, OSType) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createELFObjectWriter(OS, /*Is64Bit=*/false, - OSType, ELF::EM_386, - /*IsLittleEndian=*/true, - /*HasRelocationAddend=*/false); + return createELFObjectWriter(createELFObjectTargetWriter(), + OS, /*IsLittleEndian*/ true); + } + + MCELFObjectTargetWriter *createELFObjectTargetWriter() const { + return new X86ELFObjectWriter(false, OSType, ELF::EM_386, false); } }; @@ -322,26 +333,22 @@ public: : ELFX86AsmBackend(T, OSType) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createELFObjectWriter(OS, /*Is64Bit=*/true, - OSType, ELF::EM_X86_64, - /*IsLittleEndian=*/true, - /*HasRelocationAddend=*/true); + return createELFObjectWriter(createELFObjectTargetWriter(), + OS, /*IsLittleEndian*/ true); + } + + MCELFObjectTargetWriter *createELFObjectTargetWriter() const { + return new X86ELFObjectWriter(true, OSType, ELF::EM_X86_64, true); } }; class WindowsX86AsmBackend : public X86AsmBackend { bool Is64Bit; - MCCOFFObjectFormat Format; public: WindowsX86AsmBackend(const Target &T, bool is64Bit) : X86AsmBackend(T) , Is64Bit(is64Bit) { - HasScatteredSymbols = true; - } - - virtual const MCObjectFormat &getObjectFormat() const { - return Format; } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { @@ -350,17 +357,9 @@ public: }; class DarwinX86AsmBackend : public X86AsmBackend { - MCMachOObjectFormat Format; - public: DarwinX86AsmBackend(const Target &T) - : X86AsmBackend(T) { - HasScatteredSymbols = true; - } - - virtual const MCObjectFormat &getObjectFormat() const { - return Format; - } + : X86AsmBackend(T) { } }; class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { @@ -369,11 +368,9 @@ public: : DarwinX86AsmBackend(T) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createMachObjectWriter(new X86MachObjectWriter( - /*Is64Bit=*/false, - object::mach::CTM_i386, - object::mach::CSX86_ALL), - OS, /*IsLittleEndian=*/true); + return createX86MachObjectWriter(OS, /*Is64Bit=*/false, + object::mach::CTM_i386, + object::mach::CSX86_ALL); } }; @@ -385,11 +382,9 @@ public: } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { - return createMachObjectWriter(new X86MachObjectWriter( - /*Is64Bit=*/true, - object::mach::CTM_x86_64, - object::mach::CSX86_ALL), - OS, /*IsLittleEndian=*/true); + return createX86MachObjectWriter(OS, /*Is64Bit=*/true, + object::mach::CTM_x86_64, + object::mach::CSX86_ALL); } virtual bool doesSectionRequireSymbols(const MCSection &Section) const { @@ -430,28 +425,26 @@ public: TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T, const std::string &TT) { - switch (Triple(TT).getOS()) { - case Triple::Darwin: + Triple TheTriple(TT); + + if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) return new DarwinX86_32AsmBackend(T); - case Triple::MinGW32: - case Triple::Cygwin: - case Triple::Win32: + + if (TheTriple.isOSWindows()) return new WindowsX86AsmBackend(T, false); - default: - return new ELFX86_32AsmBackend(T, Triple(TT).getOS()); - } + + return new ELFX86_32AsmBackend(T, TheTriple.getOS()); } TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T, const std::string &TT) { - switch (Triple(TT).getOS()) { - case Triple::Darwin: + Triple TheTriple(TT); + + if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) return new DarwinX86_64AsmBackend(T); - case Triple::MinGW64: - case Triple::Cygwin: - case Triple::Win32: + + if (TheTriple.isOSWindows()) return new WindowsX86AsmBackend(T, true); - default: - return new ELFX86_64AsmBackend(T, Triple(TT).getOS()); - } + + return new ELFX86_64AsmBackend(T, TheTriple.getOS()); }