diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 76369ccb231..0f45a93f95d 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -28,20 +28,14 @@ class MCSymbolData; class raw_ostream; class MCELFStreamer : public MCObjectStreamer { -protected: - MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {} - public: MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, TAB, OS, Emitter) {} MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, MCAssembler *Assembler) - : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter, - Assembler) {} + : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} virtual ~MCELFStreamer(); @@ -88,11 +82,6 @@ public: virtual void Flush(); virtual void FinishImpl(); - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer; - } private: virtual void EmitInstToFragment(const MCInst &Inst); @@ -122,6 +111,15 @@ private: void SetSectionBss(); }; +MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack); + +MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack, + bool IsThumb); + } // end namespace llvm #endif diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 0affeee08ca..f6a7e713c4c 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -40,11 +40,10 @@ class MCObjectStreamer : public MCStreamer { virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame); protected: - MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB, - raw_ostream &_OS, MCCodeEmitter *_Emitter, - MCAssembler *_Assembler); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, + MCCodeEmitter *_Emitter); + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, + MCCodeEmitter *_Emitter, MCAssembler *_Assembler); ~MCObjectStreamer(); public: @@ -116,12 +115,6 @@ public: virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue); virtual void EmitZeros(uint64_t NumBytes); virtual void FinishImpl(); - - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer; - } }; } // end namespace llvm diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index a5f8bc05bc7..3cd5c773c1a 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -49,23 +49,6 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair; /// a .s file, and implementations that write out .o files of various formats. /// class MCStreamer { -public: - enum StreamerKind { - SK_AsmStreamer, - SK_NullStreamer, - SK_RecordStreamer, - - // MCObjectStreamer subclasses. - SK_ELFStreamer, - SK_ARMELFStreamer, - SK_MachOStreamer, - SK_PureStreamer, - SK_MipsELFStreamer, - SK_WinCOFFStreamer - }; - -private: - const StreamerKind Kind; MCContext &Context; MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION; @@ -97,7 +80,7 @@ private: bool AutoInitSections; protected: - MCStreamer(StreamerKind Kind, MCContext &Ctx); + MCStreamer(MCContext &Ctx); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, const MCSymbol *B); @@ -118,8 +101,6 @@ protected: public: virtual ~MCStreamer(); - StreamerKind getKind() const { return Kind; } - /// State management /// virtual void reset(); @@ -632,6 +613,10 @@ public: virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); + /// Mips-related methods. + virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); + /// PPC-related methods. /// FIXME: Eventually replace it with some "target MC streamer" and move /// these methods there. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 48e44c017a3..71838bdd694 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -683,8 +683,10 @@ unsigned DwarfDebug::getOrCreateSourceID(StringRef FileName, StringRef DirName, unsigned CUID) { // If we use .loc in assembly, we can't separate .file entries according to // compile units. Thus all files will belong to the default compile unit. - if (Asm->TM.hasMCUseLoc() && - Asm->OutStreamer.getKind() == MCStreamer::SK_AsmStreamer) + + // FIXME: add a better feature test than hasRawTextSupport. Even better, + // extend .file to support this. + if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) CUID = 0; // If FE did not provide a file name, then assume stdin. @@ -752,9 +754,8 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { // Use a single line table if we are using .loc and generating assembly. bool UseTheFirstCU = - (Asm->TM.hasMCUseLoc() && - Asm->OutStreamer.getKind() == MCStreamer::SK_AsmStreamer) || - (NewCU->getUniqueID() == 0); + (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) || + (NewCU->getUniqueID() == 0); if (!useSplitDwarf()) { // DW_AT_stmt_list is a offset of line number information for this @@ -1601,8 +1602,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); assert(TheCU && "Unable to find compile unit!"); - if (Asm->TM.hasMCUseLoc() && - Asm->OutStreamer.getKind() == MCStreamer::SK_AsmStreamer) + if (Asm->TM.hasMCUseLoc() && Asm->OutStreamer.hasRawTextSupport()) // Use a single line table if we are using .loc and generating assembly. Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); else diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index fc8bf0c5809..207e85c1c94 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -591,8 +591,7 @@ namespace { return Symbols.end(); } - RecordStreamer(MCContext &Context) - : MCStreamer(SK_RecordStreamer, Context) {} + RecordStreamer(MCContext &Context) : MCStreamer(Context) {} virtual void EmitInstruction(const MCInst &Inst) { // Scan for values. @@ -667,10 +666,6 @@ namespace { virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { RecordProcEnd(Frame); } - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_RecordStreamer; - } }; } // end anonymous namespace diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index cf3c9e949af..0f9a327a48f 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" @@ -33,6 +34,9 @@ #include <cctype> using namespace llvm; +static cl::opt<bool> PrintHackDirectives("print-hack-directives", + cl::init(false), cl::Hidden); + namespace { class MCAsmStreamer : public MCStreamer { @@ -71,7 +75,7 @@ public: MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) - : MCStreamer(SK_AsmStreamer, Context), OS(os), MAI(Context.getAsmInfo()), + : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI), @@ -255,6 +259,11 @@ public: virtual void EmitPad(int64_t Offset); virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool); + /// Mips-related methods. + virtual void emitMipsHackELFFlags(unsigned Flags); + virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); + + virtual void EmitTCEntry(const MCSymbol &S); virtual void EmitInstruction(const MCInst &Inst); @@ -269,12 +278,6 @@ public: virtual void EmitRawText(StringRef String); virtual void FinishImpl(); - - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_AsmStreamer; - } }; } // end anonymous namespace. @@ -1373,6 +1376,26 @@ void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, EmitEOL(); } +void MCAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_stocg "; + OS << Sym->getName(); + OS << ", "; + OS << Val; + EmitEOL(); +} + +void MCAsmStreamer::emitMipsHackELFFlags(unsigned Flags) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_elf_flags 0x"; + OS.write_hex(Flags); + EmitEOL(); +} + void MCAsmStreamer::EmitTCEntry(const MCSymbol &S) { OS << "\t.tc "; OS << S.getName(); diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 2c4707f58ce..8eaa254cd5e 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -37,7 +37,7 @@ private: public: MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(SK_MachOStreamer, Context, MAB, OS, Emitter) {} + : MCObjectStreamer(Context, MAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ @@ -86,12 +86,6 @@ public: } virtual void FinishImpl(); - - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_MachOStreamer; - } }; } // end anonymous namespace. diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 2ddc4f0f71e..8d5da44a069 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -19,7 +19,7 @@ namespace { class MCNullStreamer : public MCStreamer { public: - MCNullStreamer(MCContext &Context) : MCStreamer(SK_NullStreamer, Context) {} + MCNullStreamer(MCContext &Context) : MCStreamer(Context) {} /// @name MCStreamer Interface /// @{ @@ -109,13 +109,6 @@ namespace { virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { RecordProcEnd(Frame); } - - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_NullStreamer; - } - }; } diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 36a923ab44d..cbcd5fd0211 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -22,19 +22,17 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; -MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context, - MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter_) - : MCStreamer(Kind, Context), +MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter_) + : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, *Emitter_, *TAB.createObjectWriter(OS), OS)), CurSectionData(0) {} -MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context, - MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter_, +MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter_, MCAssembler *_Assembler) - : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {} + : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) {} MCObjectStreamer::~MCObjectStreamer() { delete &Assembler->getBackend(); diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index a83caf6080b..f64aa0caba2 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -29,7 +29,7 @@ private: public: MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(SK_PureStreamer, Context, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, TAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ @@ -98,12 +98,6 @@ public: StringRef Filename, unsigned CUID = 0) { report_fatal_error("unsupported directive in pure streamer"); } - - /// @} - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_PureStreamer; - } }; } // end anonymous namespace. diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 79242edfc2b..bac58063a40 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -22,8 +22,8 @@ #include <cstdlib> using namespace llvm; -MCStreamer::MCStreamer(StreamerKind Kind, MCContext &Ctx) - : Kind(Kind), Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), +MCStreamer::MCStreamer(MCContext &Ctx) + : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) { SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); } @@ -603,6 +603,12 @@ void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { abort(); } +void MCStreamer::emitMipsHackELFFlags(unsigned Flags) { +} + +void MCStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { +} + void MCStreamer::EmitTCEntry(const MCSymbol &S) { llvm_unreachable("Unsupported method"); } diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index dd98aa5f304..5f3bf3b73bd 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -75,10 +75,6 @@ public: virtual void EmitWin64EHHandlerData(); virtual void FinishImpl(); - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_WinCOFFStreamer; - } - private: virtual void EmitInstToData(const MCInst &Inst) { MCDataFragment *DF = getOrCreateDataFragment(); @@ -134,8 +130,7 @@ private: WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, MCCodeEmitter &CE, raw_ostream &OS) - : MCObjectStreamer(SK_WinCOFFStreamer, Context, MAB, OS, &CE), - CurSymbol(NULL) {} + : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(NULL) {} void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, bool External) { diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index ee01fcfb669..eab0e98e948 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -731,11 +731,6 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { // generates code that does this, it is always safe to set. OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); } - // FIXME: This should eventually end up somewhere else where more - // intelligent flag decisions can be made. For now we are just maintaining - // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. - if (MCELFStreamer *MES = dyn_cast<MCELFStreamer>(&OutStreamer)) - MES->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 71f98abe1d4..f482912d27c 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -260,13 +260,6 @@ public: // Not in an ITBlock to start with. ITState.CurPosition = ~0U; - - // Set ELF header flags. - // FIXME: This should eventually end up somewhere else where more - // intelligent flag decisions can be made. For now we are just maintaining - // the statu/parseDirects quo for ARM and setting EF_ARM_EABI_VER5 as the default. - if (MCELFStreamer *MES = dyn_cast<MCELFStreamer>(&Parser.getStreamer())) - MES->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); } // Implementation of the MCTargetAsmParser interface: diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 37a80d5b8cf..d38fde1564f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -63,8 +63,8 @@ class ARMELFStreamer : public MCELFStreamer { public: ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool IsThumb) - : MCELFStreamer(SK_ARMELFStreamer, Context, TAB, OS, Emitter), - IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) { + : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb), + MappingSymbolCounter(0), LastEMS(EMS_None) { Reset(); } @@ -141,10 +141,6 @@ public: } } - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_ARMELFStreamer; - } - private: enum ElfMappingSymbol { EMS_None, @@ -498,6 +494,11 @@ namespace llvm { bool RelaxAll, bool NoExecStack, bool IsThumb) { ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); + // FIXME: This should eventually end up somewhere else where more + // intelligent flag decisions can be made. For now we are just maintaining + // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. + S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); + if (RelaxAll) S->getAssembler().setRelaxAll(true); if (NoExecStack) diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h deleted file mode 100644 index 77ae5d23628..00000000000 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.h +++ /dev/null @@ -1,27 +0,0 @@ -//===-- ARMELFStreamer.h - ELF Streamer for ARM ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements ELF streamer information for the ARM backend. -// -//===----------------------------------------------------------------------===// - -#ifndef ARM_ELF_STREAMER_H -#define ARM_ELF_STREAMER_H - -#include "llvm/MC/MCELFStreamer.h" - -namespace llvm { - - MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack, - bool IsThumb); -} - -#endif // ARM_ELF_STREAMER_H diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 28d921213c7..2beb500d883 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -12,16 +12,15 @@ //===----------------------------------------------------------------------===// #include "ARMBaseInfo.h" -#include "ARMELFStreamer.h" #include "ARMMCAsmInfo.h" #include "ARMMCTargetDesc.h" #include "InstPrinter/ARMInstPrinter.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 447e7dc6e1c..1f39f48259c 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -180,6 +180,8 @@ class MipsAsmParser : public MCTargetAsmParser { bool isEvaluated(const MCExpr *Expr); bool parseDirectiveSet(); + bool parseDirectiveMipsHackStocg(); + bool parseDirectiveMipsHackELFFlags(); bool parseSetAtDirective(); bool parseSetNoAtDirective(); @@ -2098,6 +2100,34 @@ bool MipsAsmParser::parseDirectiveSet() { return true; } +bool MipsAsmParser::parseDirectiveMipsHackStocg() { + MCAsmParser &Parser = getParser(); + StringRef Name; + if (Parser.parseIdentifier(Name)) + reportParseError("expected identifier"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token"); + Lex(); + + int64_t Flags = 0; + if (Parser.parseAbsoluteExpression(Flags)) + return TokError("unexpected token"); + + Parser.getStreamer().emitMipsHackSTOCG(Sym, Flags); + return false; +} + +bool MipsAsmParser::parseDirectiveMipsHackELFFlags() { + int64_t Flags = 0; + if (Parser.parseAbsoluteExpression(Flags)) + return TokError("unexpected token"); + + Parser.getStreamer().emitMipsHackELFFlags(Flags); + return false; +} + /// parseDirectiveWord /// ::= .word [ expression (, expression)* ] bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { @@ -2172,6 +2202,12 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { return false; } + if (IDVal == ".mips_hack_stocg") + return parseDirectiveMipsHackStocg(); + + if (IDVal == ".mips_hack_elf_flags") + return parseDirectiveMipsHackELFFlags(); + return true; } diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp index cfcb877805a..1779b92f107 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -6,88 +6,50 @@ // License. See LICENSE.TXT for details. // //===-------------------------------------------------------------------===// -#include "MCTargetDesc/MipsELFStreamer.h" #include "MipsSubtarget.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELF.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" +using namespace llvm; + +namespace { +class MipsELFStreamer : public MCELFStreamer { +public: + MipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, + MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack) + : MCELFStreamer(Context, TAB, OS, Emitter) {} + + ~MipsELFStreamer() {} + void emitMipsHackELFFlags(unsigned Flags); + void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val); +}; +} namespace llvm { - - MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) { - MipsELFStreamer *S = new MipsELFStreamer(Context, TAB, OS, Emitter, - RelaxAll, NoExecStack); - return S; - } - - // For llc. Set a group of ELF header flags - void - MipsELFStreamer::emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget) { - - if (hasRawTextSupport()) - return; - - // Update e_header flags - MCAssembler& MCA = getAssembler(); - unsigned EFlags = MCA.getELFHeaderEFlags(); - - // TODO: Need to add -mabicalls and -mno-abicalls flags. - // Currently we assume that -mabicalls is the default. - EFlags |= ELF::EF_MIPS_CPIC; - - if (Subtarget.inMips16Mode()) - EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; - else - EFlags |= ELF::EF_MIPS_NOREORDER; - - // Architecture - if (Subtarget.hasMips64r2()) - EFlags |= ELF::EF_MIPS_ARCH_64R2; - else if (Subtarget.hasMips64()) - EFlags |= ELF::EF_MIPS_ARCH_64; - else if (Subtarget.hasMips32r2()) - EFlags |= ELF::EF_MIPS_ARCH_32R2; - else - EFlags |= ELF::EF_MIPS_ARCH_32; - - if (Subtarget.inMicroMipsMode()) - EFlags |= ELF::EF_MIPS_MICROMIPS; - - // ABI - if (Subtarget.isABI_O32()) - EFlags |= ELF::EF_MIPS_ABI_O32; - - // Relocation Model - Reloc::Model RM = Subtarget.getRelocationModel(); - if (RM == Reloc::PIC_ || RM == Reloc::Default) - EFlags |= ELF::EF_MIPS_PIC; - else if (RM == Reloc::Static) - ; // Do nothing for Reloc::Static - else - llvm_unreachable("Unsupported relocation model for e_flags"); - - MCA.setELFHeaderEFlags(EFlags); - } - - // For llc. Set a symbol's STO flags - void - MipsELFStreamer::emitMipsSTOCG(const MipsSubtarget &Subtarget, - MCSymbol *Sym, - unsigned Val) { - - if (hasRawTextSupport()) - return; - - MCSymbolData &Data = getOrCreateSymbolData(Sym); - // The "other" values are stored in the last 6 bits of the second byte - // The traditional defines for STO values assume the full byte and thus - // the shift to pack it. - MCELF::setOther(Data, Val >> 2); - } - +MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack) { + MipsELFStreamer *S = + new MipsELFStreamer(Context, TAB, OS, Emitter, RelaxAll, NoExecStack); + return S; +} } // namespace llvm + +void MipsELFStreamer::emitMipsHackELFFlags(unsigned Flags) { + MCAssembler &MCA = getAssembler(); + + MCA.setELFHeaderEFlags(Flags); +} + +// Set a symbol's STO flags +void MipsELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + MCSymbolData &Data = getOrCreateSymbolData(Sym); + // The "other" values are stored in the last 6 bits of the second byte + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + MCELF::setOther(Data, Val >> 2); +} diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h deleted file mode 100644 index b10ccc78e66..00000000000 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ /dev/null @@ -1,43 +0,0 @@ -//=== MipsELFStreamer.h - MipsELFStreamer ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENCE.TXT for details. -// -//===-------------------------------------------------------------------===// -#ifndef MIPSELFSTREAMER_H_ -#define MIPSELFSTREAMER_H_ - -#include "llvm/MC/MCELFStreamer.h" - -namespace llvm { -class MipsAsmPrinter; -class MipsSubtarget; -class MCSymbol; - -class MipsELFStreamer : public MCELFStreamer { -public: - MipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) - : MCELFStreamer(SK_MipsELFStreamer, Context, TAB, OS, Emitter) { - } - - ~MipsELFStreamer() {} - void emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget); - void emitMipsSTOCG(const MipsSubtarget &Subtarget, - MCSymbol *Sym, - unsigned Val); - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_MipsELFStreamer; - } -}; - - MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack); -} - -#endif /* MIPSELFSTREAMER_H_ */ diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 837fabee76a..e0284c684c6 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -11,14 +11,13 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/MipsELFStreamer.h" #include "MipsMCTargetDesc.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMCAsmInfo.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 1dc33265783..b32c2597c58 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -15,7 +15,6 @@ #define DEBUG_TYPE "mips-asm-printer" #include "InstPrinter/MipsInstPrinter.h" #include "MCTargetDesc/MipsBaseInfo.h" -#include "MCTargetDesc/MipsELFStreamer.h" #include "Mips.h" #include "MipsAsmPrinter.h" #include "MipsInstrInfo.h" @@ -33,8 +32,8 @@ #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" #include "llvm/Support/TargetRegistry.h" @@ -238,9 +237,8 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() { } if (Subtarget->inMicroMipsMode()) - if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer)) - MES->emitMipsSTOCG(*Subtarget, CurrentFnSym, - (unsigned)ELF::STO_MIPS_MICROMIPS); + OutStreamer.emitMipsHackSTOCG(CurrentFnSym, + (unsigned)ELF::STO_MIPS_MICROMIPS); OutStreamer.EmitLabel(CurrentFnSym); } @@ -587,15 +585,54 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { } +static void +emitELFHeaderFlagsCG(MCStreamer &Streamer, const MipsSubtarget &Subtarget) { + // Update e_header flags + unsigned EFlags = 0; + + // TODO: Need to add -mabicalls and -mno-abicalls flags. + // Currently we assume that -mabicalls is the default. + EFlags |= ELF::EF_MIPS_CPIC; + + if (Subtarget.inMips16Mode()) + EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; + else + EFlags |= ELF::EF_MIPS_NOREORDER; + + // Architecture + if (Subtarget.hasMips64r2()) + EFlags |= ELF::EF_MIPS_ARCH_64R2; + else if (Subtarget.hasMips64()) + EFlags |= ELF::EF_MIPS_ARCH_64; + else if (Subtarget.hasMips32r2()) + EFlags |= ELF::EF_MIPS_ARCH_32R2; + else + EFlags |= ELF::EF_MIPS_ARCH_32; + + if (Subtarget.inMicroMipsMode()) + EFlags |= ELF::EF_MIPS_MICROMIPS; + + // ABI + if (Subtarget.isABI_O32()) + EFlags |= ELF::EF_MIPS_ABI_O32; + + // Relocation Model + Reloc::Model RM = Subtarget.getRelocationModel(); + if (RM == Reloc::PIC_ || RM == Reloc::Default) + EFlags |= ELF::EF_MIPS_PIC; + else if (RM == Reloc::Static) + ; // Do nothing for Reloc::Static + else + llvm_unreachable("Unsupported relocation model for e_flags"); + + Streamer.emitMipsHackELFFlags(EFlags); +} + void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { - - if (OutStreamer.hasRawTextSupport()) return; - // Emit Mips ELF register info Subtarget->getMReginfo().emitMipsReginfoSectionCG( OutStreamer, getObjFileLowering(), *Subtarget); - if (MipsELFStreamer *MES = dyn_cast<MipsELFStreamer>(&OutStreamer)) - MES->emitELFHeaderFlagsCG(*Subtarget); + emitELFHeaderFlagsCG(OutStreamer, *Subtarget); } void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, diff --git a/test/MC/ARM/elf-eflags-eabi-cg.ll b/test/MC/ARM/elf-eflags-eabi-cg.ll deleted file mode 100644 index 0b9de7f2a62..00000000000 --- a/test/MC/ARM/elf-eflags-eabi-cg.ll +++ /dev/null @@ -1,14 +0,0 @@ -; Codegen version to check for ELF header flags. -; -; RUN: llc %s -mtriple=thumbv7-linux-gnueabi -relocation-model=pic \ -; RUN: -filetype=obj -o - | llvm-readobj -h | \ -; RUN: FileCheck %s - -define void @bar() nounwind { -entry: - ret void -} - -; For now the only e_flag set is EF_ARM_EABI_VER5 -; CHECK: ElfHeader { -; CHECK: Flags [ (0x5000000) diff --git a/test/MC/Mips/elf_eflags.ll b/test/MC/Mips/elf_eflags.ll index 91217bce071..9432dcf59c3 100644 --- a/test/MC/Mips/elf_eflags.ll +++ b/test/MC/Mips/elf_eflags.ll @@ -16,53 +16,53 @@ ; Note that EF_MIPS_CPIC is set by -mabicalls which is the default on Linux ; TODO need to support -mno-abicalls -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32 %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32_PIC %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32R2 %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32R2_PIC %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -relocation-model=static %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE32R2 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE32R2-MICROMIPS_PIC %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE64 %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64 %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE64_PIC %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE64R2 %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips64r2 %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-BE64R2_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 -relocation-model=static %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64 %s -print-hack-directives -o - | FileCheck -check-prefix=CHECK-BE64_PIC %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -relocation-model=static -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips64r2 -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-BE64R2_PIC %s -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic %s -o - | llvm-readobj -h | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+mips16 -relocation-model=pic -print-hack-directives %s -o - | FileCheck -check-prefix=CHECK-LE32R2-MIPS16 %s ; 32(R1) bit with NO_REORDER and static -; CHECK-BE32: Flags [ (0x50001005) +; CHECK-BE32: .mips_hack_elf_flags 0x50001005 ; ; 32(R1) bit with NO_REORDER and PIC -; CHECK-BE32_PIC: Flags [ (0x50001007) +; CHECK-BE32_PIC: .mips_hack_elf_flags 0x50001007 ; ; 32R2 bit with NO_REORDER and static -; CHECK-BE32R2: Flags [ (0x70001005) +; CHECK-BE32R2: .mips_hack_elf_flags 0x70001005 ; ; 32R2 bit with NO_REORDER and PIC -; CHECK-BE32R2_PIC: Flags [ (0x70001007) +; CHECK-BE32R2_PIC: .mips_hack_elf_flags 0x70001007 ; ; 32R2 bit MICROMIPS with NO_REORDER and static -; CHECK-BE32R2-MICROMIPS: Flags [ (0x72001005) +; CHECK-BE32R2-MICROMIPS: .mips_hack_elf_flags 0x72001005 ; ; 32R2 bit MICROMIPS with NO_REORDER and PIC -;CHECK-BE32R2-MICROMIPS_PIC: Flags [ (0x72001007) +; CHECK-BE32R2-MICROMIPS_PIC: .mips_hack_elf_flags 0x72001007 ; ; 64(R1) bit with NO_REORDER and static -; CHECK-BE64: Flags [ (0x60000005) +; CHECK-BE64: .mips_hack_elf_flags 0x60000005 ; ; 64(R1) bit with NO_REORDER and PIC -; CHECK-BE64_PIC: Flags [ (0x60000007) +; CHECK-BE64_PIC: .mips_hack_elf_flags 0x60000007 ; ; 64R2 bit with NO_REORDER and static -; CHECK-BE64R2: Flags [ (0x80000005) +; CHECK-BE64R2: .mips_hack_elf_flags 0x80000005 ; ; 64R2 bit with NO_REORDER and PIC -; CHECK-BE64R2_PIC: Flags [ (0x80000007) +; CHECK-BE64R2_PIC: .mips_hack_elf_flags 0x80000007 ; ; 32R2 bit MIPS16 with PIC -; CHECK-LE32R2-MIPS16: Flags [ (0x74001006) - +; CHECK-LE32R2-MIPS16: .mips_hack_elf_flags 0x74001006 + define i32 @main() nounwind { entry: ret i32 0 diff --git a/test/MC/Mips/elf_eflags.s b/test/MC/Mips/elf_eflags.s new file mode 100644 index 00000000000..c56596444ae --- /dev/null +++ b/test/MC/Mips/elf_eflags.s @@ -0,0 +1,5 @@ +// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o -| llvm-readobj -h | FileCheck %s + + .mips_hack_elf_flags 0x50001005 + +// CHECK: Flags [ (0x50001005) diff --git a/test/MC/Mips/elf_st_other.ll b/test/MC/Mips/elf_st_other.ll index bc56c0033e5..31294c88f87 100644 --- a/test/MC/Mips/elf_st_other.ll +++ b/test/MC/Mips/elf_st_other.ll @@ -1,12 +1,11 @@ ; This tests value of ELF st_other field for function symbol table entries. ; For microMIPS value should be equal to STO_MIPS_MICROMIPS. -; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips %s -o - | llvm-readobj -t | FileCheck %s +; RUN: llc -mtriple mipsel-unknown-linux -mcpu=mips32r2 -mattr=+micromips -print-hack-directives %s -o - | FileCheck %s define i32 @main() nounwind { entry: ret i32 0 } -; CHECK: Name: main -; CHECK: Other: 128 +; CHECK: .mips_hack_stocg main, 128 diff --git a/test/MC/Mips/elf_st_other.s b/test/MC/Mips/elf_st_other.s new file mode 100644 index 00000000000..2d632887799 --- /dev/null +++ b/test/MC/Mips/elf_st_other.s @@ -0,0 +1,13 @@ +// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux %s -o -| llvm-readobj -t | FileCheck %s + + .text + .globl main + .align 2 + .type main,@function + .set nomips16 # @main + .ent main + .mips_hack_stocg main, 128 +main: + +// CHECK: Name: main +// CHECK: Other: 128