X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FMCTargetDesc%2FX86AsmBackend.cpp;h=60e223e5bd1e8e2af9a4c1d66a88dff1955513ba;hb=d3c452a5062b6336e0cf4d8ef220e1ffed49da60;hp=5311e429294be74570a0270a26f0a343012716a5;hpb=4eb048a6f1b9777d31d71684204deb1b39aa1795;p=oota-llvm.git diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 5311e429294..60e223e5bd1 100644 --- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -11,7 +11,6 @@ #include "MCTargetDesc/X86FixupKinds.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmBackend.h" -#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" @@ -37,23 +36,29 @@ MCDisableArithRelaxation("mc-x86-disable-arith-relaxation", static unsigned getFixupKindLog2Size(unsigned Kind) { switch (Kind) { - default: llvm_unreachable("invalid fixup kind!"); + default: + llvm_unreachable("invalid fixup kind!"); case FK_PCRel_1: case FK_SecRel_1: - case FK_Data_1: return 0; + case FK_Data_1: + return 0; case FK_PCRel_2: case FK_SecRel_2: - case FK_Data_2: return 1; + case FK_Data_2: + return 1; case FK_PCRel_4: case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_movq_load: case X86::reloc_signed_4byte: case X86::reloc_global_offset_table: case FK_SecRel_4: - case FK_Data_4: return 2; + case FK_Data_4: + return 2; case FK_PCRel_8: case FK_SecRel_8: - case FK_Data_8: return 3; + case FK_Data_8: + case X86::reloc_global_offset_table8: + return 3; } } @@ -67,11 +72,12 @@ public: }; class X86AsmBackend : public MCAsmBackend { - StringRef CPU; + const StringRef CPU; bool HasNopl; + const uint64_t MaxNopLength; public: X86AsmBackend(const Target &T, StringRef _CPU) - : MCAsmBackend(), CPU(_CPU) { + : MCAsmBackend(), CPU(_CPU), MaxNopLength(_CPU == "slm" ? 7 : 15) { HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" && CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" && CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" && @@ -79,11 +85,11 @@ public: CPU != "c3" && CPU != "c3-2"; } - unsigned getNumFixupKinds() const { + unsigned getNumFixupKinds() const override { return X86::NumTargetFixupKinds; } - const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, @@ -100,7 +106,7 @@ public: } void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value) const { + uint64_t Value, bool IsPCRel) const override { unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); assert(Fixup.getOffset() + Size <= DataSize && @@ -117,16 +123,15 @@ public: Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); } - bool mayNeedRelaxation(const MCInst &Inst) const; + bool mayNeedRelaxation(const MCInst &Inst) const override; - bool fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, + bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const; + const MCAsmLayout &Layout) const override; - void relaxInstruction(const MCInst &Inst, MCInst &Res) const; + void relaxInstruction(const MCInst &Inst, MCInst &Res) const override; - bool writeNopData(uint64_t Count, MCObjectWriter *OW) const; + bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override; }; } // end anonymous namespace @@ -326,7 +331,7 @@ bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { // 15 is the longest single nop instruction. Emit as many 15-byte nops as // needed, then emit a nop of the remaining length. do { - const uint8_t ThisNopLength = (uint8_t) std::min(Count, (uint64_t) 15); + const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength); const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; for (uint8_t i = 0; i < Prefixes; i++) OW->Write8(0x66); @@ -355,17 +360,28 @@ public: ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) : ELFX86AsmBackend(T, OSABI, CPU) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386); } }; +class ELFX86_X32AsmBackend : public ELFX86AsmBackend { +public: + ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) + : ELFX86AsmBackend(T, OSABI, CPU) {} + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { + return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, + ELF::EM_X86_64); + } +}; + class ELFX86_64AsmBackend : public ELFX86AsmBackend { public: ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) : ELFX86AsmBackend(T, OSABI, CPU) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64); } }; @@ -379,7 +395,7 @@ public: , Is64Bit(is64Bit) { } - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { return createX86WinCOFFObjectWriter(OS, Is64Bit); } }; @@ -420,10 +436,30 @@ class DarwinX86AsmBackend : public X86AsmBackend { bool Is64Bit; unsigned OffsetSize; ///< Offset of a "push" instruction. - unsigned PushInstrSize; ///< Size of a "push" instruction. unsigned MoveInstrSize; ///< Size of a "move" instruction. - unsigned StackDivide; ///< Amount to adjust stack stize by. + unsigned StackDivide; ///< Amount to adjust stack size by. protected: + /// \brief Size of a "push" instruction for the given register. + unsigned PushInstrSize(unsigned Reg) const { + switch (Reg) { + case X86::EBX: + case X86::ECX: + case X86::EDX: + case X86::EDI: + case X86::ESI: + case X86::EBP: + case X86::RBX: + case X86::RBP: + return 1; + case X86::R12: + case X86::R13: + case X86::R14: + case X86::R15: + return 2; + } + return 1; + } + /// \brief Implementation of algorithm to generate the compact unwind encoding /// for the CFI instructions. uint32_t @@ -476,7 +512,7 @@ protected: // Defines a new offset for the CFA. E.g. // // With frame: - // + // // pushq %rbp // L0: // .cfi_def_cfa_offset 16 @@ -513,7 +549,7 @@ protected: unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true); SavedRegs[SavedRegIdx++] = Reg; StackAdjust += OffsetSize; - InstrOffset += PushInstrSize; + InstrOffset += PushInstrSize(Reg); break; } } @@ -707,48 +743,41 @@ public: OffsetSize = Is64Bit ? 8 : 4; MoveInstrSize = Is64Bit ? 3 : 2; StackDivide = Is64Bit ? 8 : 4; - PushInstrSize = 1; } }; class DarwinX86_32AsmBackend : public DarwinX86AsmBackend { - bool SupportsCU; public: DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, - StringRef CPU, bool SupportsCU) - : DarwinX86AsmBackend(T, MRI, CPU, false), SupportsCU(SupportsCU) {} + StringRef CPU) + : DarwinX86AsmBackend(T, MRI, CPU, false) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { return createX86MachObjectWriter(OS, /*Is64Bit=*/false, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL); } /// \brief Generate the compact unwind encoding for the CFI instructions. - virtual uint32_t - generateCompactUnwindEncoding(ArrayRef Instrs) const { - return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0; + uint32_t generateCompactUnwindEncoding( + ArrayRef Instrs) const override { + return generateCompactUnwindEncodingImpl(Instrs); } }; class DarwinX86_64AsmBackend : public DarwinX86AsmBackend { - bool SupportsCU; const MachO::CPUSubTypeX86 Subtype; public: DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, - StringRef CPU, bool SupportsCU, - MachO::CPUSubTypeX86 st) - : DarwinX86AsmBackend(T, MRI, CPU, true), SupportsCU(SupportsCU), - Subtype(st) { - HasReliableSymbolDifference = true; - } + StringRef CPU, MachO::CPUSubTypeX86 st) + : DarwinX86AsmBackend(T, MRI, CPU, true), Subtype(st) {} - MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { return createX86MachObjectWriter(OS, /*Is64Bit=*/true, MachO::CPU_TYPE_X86_64, Subtype); } - virtual bool doesSectionRequireSymbols(const MCSection &Section) const { + bool doesSectionRequireSymbols(const MCSection &Section) const override { // Temporary labels in the string literals sections require symbols. The // issue is that the x86_64 relocation format does not allow symbol + // offset, and so the linker does not have enough information to resolve the @@ -758,33 +787,33 @@ public: // // See . const MCSectionMachO &SMO = static_cast(Section); - return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS; + return SMO.getType() == MachO::S_CSTRING_LITERALS; } - virtual bool isSectionAtomizable(const MCSection &Section) const { + bool isSectionAtomizable(const MCSection &Section) const override { const MCSectionMachO &SMO = static_cast(Section); // Fixed sized data sections are uniqued, they cannot be diced into atoms. switch (SMO.getType()) { default: return true; - case MCSectionMachO::S_4BYTE_LITERALS: - case MCSectionMachO::S_8BYTE_LITERALS: - case MCSectionMachO::S_16BYTE_LITERALS: - case MCSectionMachO::S_LITERAL_POINTERS: - case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS: - case MCSectionMachO::S_LAZY_SYMBOL_POINTERS: - case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS: - case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS: - case MCSectionMachO::S_INTERPOSING: + case MachO::S_4BYTE_LITERALS: + case MachO::S_8BYTE_LITERALS: + case MachO::S_16BYTE_LITERALS: + case MachO::S_LITERAL_POINTERS: + case MachO::S_NON_LAZY_SYMBOL_POINTERS: + case MachO::S_LAZY_SYMBOL_POINTERS: + case MachO::S_MOD_INIT_FUNC_POINTERS: + case MachO::S_MOD_TERM_FUNC_POINTERS: + case MachO::S_INTERPOSING: return false; } } /// \brief Generate the compact unwind encoding for the CFI instructions. - virtual uint32_t - generateCompactUnwindEncoding(ArrayRef Instrs) const { - return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0; + uint32_t generateCompactUnwindEncoding( + ArrayRef Instrs) const override { + return generateCompactUnwindEncodingImpl(Instrs); } }; @@ -797,9 +826,7 @@ MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, Triple TheTriple(TT); if (TheTriple.isOSBinFormatMachO()) - return new DarwinX86_32AsmBackend(T, MRI, CPU, - TheTriple.isMacOSX() && - !TheTriple.isMacOSXVersionLT(10, 7)); + return new DarwinX86_32AsmBackend(T, MRI, CPU); if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) return new WindowsX86AsmBackend(T, false, CPU); @@ -819,14 +846,15 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringSwitch(TheTriple.getArchName()) .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) .Default(MachO::CPU_SUBTYPE_X86_64_ALL); - return new DarwinX86_64AsmBackend(T, MRI, CPU, - TheTriple.isMacOSX() && - !TheTriple.isMacOSXVersionLT(10, 7), CS); + return new DarwinX86_64AsmBackend(T, MRI, CPU, CS); } if (TheTriple.isOSWindows() && !TheTriple.isOSBinFormatELF()) return new WindowsX86AsmBackend(T, true, CPU); uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); + + if (TheTriple.getEnvironment() == Triple::GNUX32) + return new ELFX86_X32AsmBackend(T, OSABI, CPU); return new ELFX86_64AsmBackend(T, OSABI, CPU); }