Add a MCTargetStreamer interface.

This patch fixes an old FIXME by creating a MCTargetStreamer interface
and moving the target specific functions for ARM, Mips and PPC to it.

The ARM streamer is still declared in a common place because it is
used from lib/CodeGen/ARMException.cpp, but the Mips and PPC are
completely hidden in the corresponding Target directories.

I will send an email to llvmdev with instructions on how to use this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192181 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2013-10-08 13:08:17 +00:00
parent 26c46ba11c
commit 320296a4cf
34 changed files with 559 additions and 394 deletions

View File

@ -29,13 +29,15 @@ class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
public:
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCObjectStreamer(Context, TAB, OS, Emitter) {}
MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter)
: MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter) {}
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter, MCAssembler *Assembler)
: MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
MCELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
MCAssembler *Assembler)
: MCObjectStreamer(Context, TargetStreamer, TAB, OS, Emitter, Assembler) {
}
virtual ~MCELFStreamer();
@ -75,8 +77,6 @@ public:
virtual void EmitFileDirective(StringRef Filename);
virtual void EmitTCEntry(const MCSymbol &S);
virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
virtual void Flush();
@ -111,10 +111,6 @@ 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,

View File

@ -40,10 +40,12 @@ class MCObjectStreamer : public MCStreamer {
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
protected:
MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &_OS,
MCCodeEmitter *_Emitter);
MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
MCObjectStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter,
MCAssembler *_Assembler);
~MCObjectStreamer();
public:

View File

@ -31,6 +31,7 @@ class MCExpr;
class MCInst;
class MCInstPrinter;
class MCSection;
class MCStreamer;
class MCSymbol;
class StringRef;
class Twine;
@ -39,6 +40,55 @@ class formatted_raw_ostream;
typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
/// Target specific streamer interface. This is used so that targets can
/// implement support for target specific assembly directives.
///
/// If target foo wants to use this, it should implement 3 classes:
/// * FooTargetStreamer : public MCTargetStreamer
/// * FooTargetAsmSreamer : public FooTargetStreamer
/// * FooTargetELFStreamer : public FooTargetStreamer
///
/// FooTargetStreamer should have a pure virtual method for each directive. For
/// example, for a ".bar symbol_name" directive, it should have
/// virtual emitBar(const MCSymbol &Symbol) = 0;
///
/// The FooTargetAsmSreamer and FooTargetELFStreamer classes implement the
/// method. The assembly streamer just prints ".bar symbol_name". The object
/// streamer does whatever is needed to implement .bar in the object file.
///
/// In the assembly printer and parser the target streamer can be used by
/// calling getTargetStreamer and casting it to FooTargetStreamer:
///
/// MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
/// FooTargetStreamer &ATS = static_cast<FooTargetStreamer &>(TS);
///
/// The base classes FooTargetAsmSreamer and FooTargetELFStreamer should *never*
/// be treated differently. Callers should always talk to a FooTargetStreamer.
class MCTargetStreamer {
protected:
OwningPtr<MCStreamer> Streamer;
public:
virtual ~MCTargetStreamer();
void setStreamer(MCStreamer *S) { Streamer.reset(S); }
};
// FIXME: declared here because it is used from
// lib/CodeGen/AsmPrinter/ARMException.cpp.
class ARMTargetStreamer : public MCTargetStreamer {
public:
virtual void emitFnStart() = 0;
virtual void emitFnEnd() = 0;
virtual void emitCantUnwind() = 0;
virtual void emitPersonality(const MCSymbol *Personality) = 0;
virtual void emitHandlerData() = 0;
virtual void emitSetFP(unsigned FpReg, unsigned SpReg,
int64_t Offset = 0) = 0;
virtual void emitPad(int64_t Offset) = 0;
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) = 0;
};
/// MCStreamer - Streaming machine code generation interface. This interface
/// is intended to provide a programatic interface that is very similar to the
/// level that an assembler .s file provides. It has callbacks to emit bytes,
@ -50,6 +100,7 @@ typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair;
///
class MCStreamer {
MCContext &Context;
MCTargetStreamer *TargetStreamer;
MCStreamer(const MCStreamer &) LLVM_DELETED_FUNCTION;
MCStreamer &operator=(const MCStreamer &) LLVM_DELETED_FUNCTION;
@ -80,7 +131,7 @@ class MCStreamer {
bool AutoInitSections;
protected:
MCStreamer(MCContext &Ctx);
MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
const MCSymbol *B);
@ -107,6 +158,11 @@ public:
MCContext &getContext() const { return Context; }
MCTargetStreamer &getTargetStreamer() {
assert(TargetStreamer);
return *TargetStreamer;
}
unsigned getNumFrameInfos() { return FrameInfos.size(); }
const MCDwarfFrameInfo &getFrameInfo(unsigned i) { return FrameInfos[i]; }
@ -600,28 +656,6 @@ public:
virtual void EmitRawText(StringRef String);
void EmitRawText(const Twine &String);
/// ARM-related methods.
/// FIXME: Eventually we should have some "target MC streamer" and move
/// these methods there.
virtual void EmitFnStart();
virtual void EmitFnEnd();
virtual void EmitCantUnwind();
virtual void EmitPersonality(const MCSymbol *Personality);
virtual void EmitHandlerData();
virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
virtual void EmitPad(int64_t Offset);
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.
virtual void EmitTCEntry(const MCSymbol &S);
/// Flush - Causes any cached state to be written out.
virtual void Flush() {}
@ -652,9 +686,9 @@ MCStreamer *createNullStreamer(MCContext &Ctx);
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCStreamer *createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &OS, bool isVerboseAsm,
bool useLoc, bool useCFI, bool useDwarfDirectory,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0, MCAsmBackend *TAB = 0,
bool ShowInst = false);
@ -677,8 +711,9 @@ MCStreamer *createWinCOFFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
/// createELFStreamer - Create a machine code streamer which will generate
/// ELF format object files.
MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll,
MCStreamer *createELFStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *CE, bool RelaxAll,
bool NoExecStack);
/// createPureStreamer - Create a machine code streamer which will generate

View File

@ -46,18 +46,18 @@ namespace llvm {
class MCRelocationInfo;
class MCTargetAsmParser;
class TargetMachine;
class MCTargetStreamer;
class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm,
MCStreamer *createAsmStreamer(MCContext &Ctx,
MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &OS, bool isVerboseAsm,
bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst);
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
@ -235,10 +235,22 @@ namespace llvm {
/// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
MCSymbolizerCtorTy MCSymbolizerCtorFn;
static MCStreamer *
createDefaultAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory, MCInstPrinter *InstPrint,
MCCodeEmitter *CE, MCAsmBackend *TAB,
bool ShowInst) {
return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
public:
Target() : AsmStreamerCtorFn(llvm::createAsmStreamer),
MCRelocationInfoCtorFn(llvm::createMCRelocationInfo),
MCSymbolizerCtorFn(llvm::createMCSymbolizer) {}
Target()
: AsmStreamerCtorFn(createDefaultAsmStreamer),
MCRelocationInfoCtorFn(llvm::createMCRelocationInfo),
MCSymbolizerCtorFn(llvm::createMCSymbolizer) {}
/// @name Target Information
/// @{
@ -816,7 +828,7 @@ namespace llvm {
/// @param T - The target being registered.
/// @param Fn - A function to construct an MCStreamer for the target.
static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
if (T.AsmStreamerCtorFn == createAsmStreamer)
if (T.AsmStreamerCtorFn == Target::createDefaultAsmStreamer)
T.AsmStreamerCtorFn = Fn;
}

View File

@ -47,13 +47,18 @@ ARMException::ARMException(AsmPrinter *A)
ARMException::~ARMException() {}
ARMTargetStreamer &ARMException::getTargetStreamer() {
MCTargetStreamer &TS = Asm->OutStreamer.getTargetStreamer();
return static_cast<ARMTargetStreamer &>(TS);
}
void ARMException::EndModule() {
}
/// BeginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void ARMException::BeginFunction(const MachineFunction *MF) {
Asm->OutStreamer.EmitFnStart();
getTargetStreamer().emitFnStart();
if (Asm->MF->getFunction()->needsUnwindTableEntry())
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
Asm->getFunctionNumber()));
@ -62,8 +67,9 @@ void ARMException::BeginFunction(const MachineFunction *MF) {
/// EndFunction - Gather and emit post-function exception information.
///
void ARMException::EndFunction() {
ARMTargetStreamer &ATS = getTargetStreamer();
if (!Asm->MF->getFunction()->needsUnwindTableEntry())
Asm->OutStreamer.EmitCantUnwind();
ATS.emitCantUnwind();
else {
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));
@ -78,11 +84,11 @@ void ARMException::EndFunction() {
MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
MCSymbol *PerSym = Asm->Mang->getSymbol(Personality);
Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
Asm->OutStreamer.EmitPersonality(PerSym);
ATS.emitPersonality(PerSym);
}
// Emit .handlerdata directive.
Asm->OutStreamer.EmitHandlerData();
ATS.emitHandlerData();
// Emit actual exception table
EmitExceptionTable();
@ -90,7 +96,7 @@ void ARMException::EndFunction() {
}
}
Asm->OutStreamer.EmitFnEnd();
ATS.emitFnEnd();
}
void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {

View File

@ -29,6 +29,7 @@ class MCAsmInfo;
class MCExpr;
class MCSymbol;
class Function;
class ARMTargetStreamer;
class AsmPrinter;
//===----------------------------------------------------------------------===//
@ -177,6 +178,8 @@ public:
class ARMException : public DwarfException {
void EmitTypeInfos(unsigned TTypeEncoding);
ARMTargetStreamer &getTargetStreamer();
public:
//===--------------------------------------------------------------------===//
// Main entry points.

View File

@ -591,7 +591,7 @@ namespace {
return Symbols.end();
}
RecordStreamer(MCContext &Context) : MCStreamer(Context) {}
RecordStreamer(MCContext &Context) : MCStreamer(Context, 0) {}
virtual void EmitInstruction(const MCInst &Inst) {
// Scan for values.

View File

@ -34,9 +34,6 @@
#include <cctype>
using namespace llvm;
static cl::opt<bool> PrintHackDirectives("print-hack-directives",
cl::init(false), cl::Hidden);
namespace {
class MCAsmStreamer : public MCStreamer {
@ -69,17 +66,15 @@ private:
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
public:
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend,
bool showInst)
: MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
UseDwarfDirectory(useDwarfDirectory) {
MCAsmStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc,
bool useCFI, bool useDwarfDirectory, MCInstPrinter *printer,
MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst)
: MCStreamer(Context, TargetStreamer), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
UseDwarfDirectory(useDwarfDirectory) {
if (InstPrinter && IsVerboseAsm)
InstPrinter->setCommentStream(CommentStream);
}
@ -250,22 +245,6 @@ public:
virtual void EmitWin64EHPushFrame(bool Code);
virtual void EmitWin64EHEndProlog();
virtual void EmitFnStart();
virtual void EmitFnEnd();
virtual void EmitCantUnwind();
virtual void EmitPersonality(const MCSymbol *Personality);
virtual void EmitHandlerData();
virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
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);
virtual void EmitBundleAlignMode(unsigned AlignPow2);
@ -1317,93 +1296,6 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) {
}
}
void MCAsmStreamer::EmitFnStart() {
OS << "\t.fnstart";
EmitEOL();
}
void MCAsmStreamer::EmitFnEnd() {
OS << "\t.fnend";
EmitEOL();
}
void MCAsmStreamer::EmitCantUnwind() {
OS << "\t.cantunwind";
EmitEOL();
}
void MCAsmStreamer::EmitHandlerData() {
OS << "\t.handlerdata";
EmitEOL();
}
void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
OS << "\t.personality " << Personality->getName();
EmitEOL();
}
void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
OS << "\t.setfp\t";
InstPrinter->printRegName(OS, FpReg);
OS << ", ";
InstPrinter->printRegName(OS, SpReg);
if (Offset)
OS << ", #" << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitPad(int64_t Offset) {
OS << "\t.pad\t#" << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) {
assert(RegList.size() && "RegList should not be empty");
if (isVector)
OS << "\t.vsave\t{";
else
OS << "\t.save\t{";
InstPrinter->printRegName(OS, RegList[0]);
for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
OS << ", ";
InstPrinter->printRegName(OS, RegList[i]);
}
OS << "}";
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();
OS << "[TC],";
OS << S.getName();
EmitEOL();
}
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
@ -1469,11 +1361,12 @@ void MCAsmStreamer::FinishImpl() {
}
MCStreamer *llvm::createAsmStreamer(MCContext &Context,
MCTargetStreamer *TargetStreamer,
formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc,
bool useCFI, bool useDwarfDirectory,
MCInstPrinter *IP, MCCodeEmitter *CE,
MCAsmBackend *MAB, bool ShowInst) {
return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI,
useDwarfDirectory, IP, CE, MAB, ShowInst);
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory, MCInstPrinter *IP,
MCCodeEmitter *CE, MCAsmBackend *MAB,
bool ShowInst) {
return new MCAsmStreamer(Context, TargetStreamer, OS, isVerboseAsm, useLoc,
useCFI, useDwarfDirectory, IP, CE, MAB, ShowInst);
}

View File

@ -560,15 +560,12 @@ void MCELFStreamer::FinishImpl() {
this->MCObjectStreamer::FinishImpl();
}
void MCELFStreamer::EmitTCEntry(const MCSymbol &S) {
// Creates a R_PPC64_TOC relocation
MCObjectStreamer::EmitSymbolValue(&S, 8);
}
MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll, bool NoExecStack) {
MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE);
MCStreamer *llvm::createELFStreamer(MCContext &Context,
MCTargetStreamer *Streamer,
MCAsmBackend &MAB, raw_ostream &OS,
MCCodeEmitter *CE, bool RelaxAll,
bool NoExecStack) {
MCELFStreamer *S = new MCELFStreamer(Context, Streamer, MAB, OS, CE);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
if (NoExecStack)

View File

@ -37,7 +37,7 @@ private:
public:
MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCObjectStreamer(Context, MAB, OS, Emitter) {}
: MCObjectStreamer(Context, 0, MAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{

View File

@ -19,7 +19,7 @@ namespace {
class MCNullStreamer : public MCStreamer {
public:
MCNullStreamer(MCContext &Context) : MCStreamer(Context) {}
MCNullStreamer(MCContext &Context) : MCStreamer(Context, 0) {}
/// @name MCStreamer Interface
/// @{

View File

@ -22,17 +22,22 @@
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter_)
: MCStreamer(Context),
MCObjectStreamer::MCObjectStreamer(MCContext &Context,
MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter_)
: MCStreamer(Context, TargetStreamer),
Assembler(new MCAssembler(Context, TAB, *Emitter_,
*TAB.createObjectWriter(OS), OS)),
CurSectionData(0) {}
MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter_,
MCObjectStreamer::MCObjectStreamer(MCContext &Context,
MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter_,
MCAssembler *_Assembler)
: MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) {}
: MCStreamer(Context, TargetStreamer), Assembler(_Assembler),
CurSectionData(0) {}
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();

View File

@ -29,7 +29,7 @@ private:
public:
MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCObjectStreamer(Context, TAB, OS, Emitter) {}
: MCObjectStreamer(Context, 0, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{

View File

@ -22,10 +22,15 @@
#include <cstdlib>
using namespace llvm;
MCStreamer::MCStreamer(MCContext &Ctx)
: Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) {
MCTargetStreamer::~MCTargetStreamer() {}
MCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer)
: Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true),
EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0),
AutoInitSections(false) {
SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
if (TargetStreamer)
TargetStreamer->setStreamer(this);
}
MCStreamer::~MCStreamer() {
@ -563,56 +568,6 @@ void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
llvm_unreachable("This file format doesn't support this directive");
}
void MCStreamer::EmitFnStart() {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitFnEnd() {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitCantUnwind() {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitHandlerData() {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitPersonality(const MCSymbol *Personality) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitPad(int64_t Offset) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::emitMipsHackELFFlags(unsigned Flags) {
}
void MCStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) {
}
void MCStreamer::EmitTCEntry(const MCSymbol &S) {
llvm_unreachable("Unsupported method");
}
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.

View File

@ -130,7 +130,7 @@ private:
WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
MCCodeEmitter &CE, raw_ostream &OS)
: MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(NULL) {}
: MCObjectStreamer(Context, 0, MAB, OS, &CE), CurSymbol(NULL) {}
void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, bool External) {

View File

@ -55,11 +55,10 @@ namespace {
/// by MachO. Beware!
class AArch64ELFStreamer : public MCELFStreamer {
public:
AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
: MCELFStreamer(Context, TAB, OS, Emitter),
MappingSymbolCounter(0), LastEMS(EMS_None) {
}
AArch64ELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter)
: MCELFStreamer(Context, 0, TAB, OS, Emitter), MappingSymbolCounter(0),
LastEMS(EMS_None) {}
~AArch64ELFStreamer() {}

View File

@ -1152,6 +1152,8 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
assert(MI->getFlag(MachineInstr::FrameSetup) &&
"Only instruction which are involved into frame setup code are allowed");
MCTargetStreamer &TS = OutStreamer.getTargetStreamer();
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
const MachineFunction &MF = *MI->getParent()->getParent();
const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>();
@ -1214,7 +1216,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
RegList.push_back(SrcReg);
break;
}
OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
} else {
// Changes of stack / frame pointer.
if (SrcReg == ARM::SP) {
@ -1262,11 +1264,11 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
if (DstReg == FramePtr && FramePtr != ARM::SP)
// Set-up of the frame pointer. Positive values correspond to "add"
// instruction.
OutStreamer.EmitSetFP(FramePtr, ARM::SP, -Offset);
ATS.emitSetFP(FramePtr, ARM::SP, -Offset);
else if (DstReg == ARM::SP) {
// Change of SP by an offset. Positive values correspond to "sub"
// instruction.
OutStreamer.EmitPad(Offset);
ATS.emitPad(Offset);
} else {
MI->dump();
llvm_unreachable("Unsupported opcode for unwinding information");

View File

@ -52,6 +52,11 @@ class ARMAsmParser : public MCTargetAsmParser {
const MCInstrInfo &MII;
const MCRegisterInfo *MRI;
ARMTargetStreamer &getTargetStreamer() {
MCTargetStreamer &TS = getParser().getStreamer().getTargetStreamer();
return static_cast<ARMTargetStreamer &>(TS);
}
// Unwind directives state
SMLoc FnStartLoc;
SMLoc CantUnwindLoc;
@ -7961,7 +7966,7 @@ bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
}
FnStartLoc = L;
getParser().getStreamer().EmitFnStart();
getTargetStreamer().emitFnStart();
return false;
}
@ -7974,8 +7979,7 @@ bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
// Reset the unwind directives parser state
resetUnwindDirectiveParserState();
getParser().getStreamer().EmitFnEnd();
getTargetStreamer().emitFnEnd();
return false;
}
@ -7997,7 +8001,7 @@ bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
return true;
}
getParser().getStreamer().EmitCantUnwind();
getTargetStreamer().emitCantUnwind();
return false;
}
@ -8028,7 +8032,7 @@ bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
Parser.Lex();
MCSymbol *PR = getParser().getContext().GetOrCreateSymbol(Name);
getParser().getStreamer().EmitPersonality(PR);
getTargetStreamer().emitPersonality(PR);
return false;
}
@ -8045,7 +8049,7 @@ bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
return true;
}
getParser().getStreamer().EmitHandlerData();
getTargetStreamer().emitHandlerData();
return false;
}
@ -8105,9 +8109,8 @@ bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
Offset = CE->getValue();
}
getParser().getStreamer().EmitSetFP(static_cast<unsigned>(NewFPReg),
static_cast<unsigned>(NewSPReg),
Offset);
getTargetStreamer().emitSetFP(static_cast<unsigned>(NewFPReg),
static_cast<unsigned>(NewSPReg), Offset);
return false;
}
@ -8136,7 +8139,7 @@ bool ARMAsmParser::parseDirectivePad(SMLoc L) {
if (!CE)
return Error(ExLoc, "pad offset must be an immediate");
getParser().getStreamer().EmitPad(CE->getValue());
getTargetStreamer().emitPad(CE->getValue());
return false;
}
@ -8168,7 +8171,7 @@ bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
if (IsVector && !Op->isDPRRegList())
return Error(L, ".vsave expects DPR registers");
getParser().getStreamer().EmitRegSave(Op->getRegList(), IsVector);
getTargetStreamer().emitRegSave(Op->getRegList(), IsVector);
return false;
}

View File

@ -27,6 +27,7 @@
#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
@ -36,6 +37,7 @@
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@ -47,6 +49,80 @@ static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
namespace {
class ARMELFStreamer;
class ARMTargetAsmStreamer : public ARMTargetStreamer {
formatted_raw_ostream &OS;
MCInstPrinter &InstPrinter;
virtual void emitFnStart();
virtual void emitFnEnd();
virtual void emitCantUnwind();
virtual void emitPersonality(const MCSymbol *Personality);
virtual void emitHandlerData();
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
public:
ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter);
};
ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS,
MCInstPrinter &InstPrinter)
: OS(OS), InstPrinter(InstPrinter) {}
void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
OS << "\t.personality " << Personality->getName() << '\n';
}
void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
int64_t Offset) {
OS << "\t.setfp\t";
InstPrinter.printRegName(OS, FpReg);
OS << ", ";
InstPrinter.printRegName(OS, SpReg);
if (Offset)
OS << ", #" << Offset;
OS << '\n';
}
void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
OS << "\t.pad\t#" << Offset << '\n';
}
void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) {
assert(RegList.size() && "RegList should not be empty");
if (isVector)
OS << "\t.vsave\t{";
else
OS << "\t.save\t{";
InstPrinter.printRegName(OS, RegList[0]);
for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
OS << ", ";
InstPrinter.printRegName(OS, RegList[i]);
}
OS << "}\n";
}
class ARMTargetELFStreamer : public ARMTargetStreamer {
ARMELFStreamer &getStreamer();
virtual void emitFnStart();
virtual void emitFnEnd();
virtual void emitCantUnwind();
virtual void emitPersonality(const MCSymbol *Personality);
virtual void emitHandlerData();
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
};
/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
/// the appropriate points in the object files. These symbols are defined in the
/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
@ -61,27 +137,27 @@ namespace {
/// by MachO. Beware!
class ARMELFStreamer : public MCELFStreamer {
public:
ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
MCCodeEmitter *Emitter, bool IsThumb)
: MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb),
MappingSymbolCounter(0), LastEMS(EMS_None) {
friend class ARMTargetELFStreamer;
ARMELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
bool IsThumb)
: MCELFStreamer(Context, TargetStreamer, TAB, OS, Emitter),
IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {
Reset();
}
~ARMELFStreamer() {}
// ARM exception handling directives
virtual void EmitFnStart();
virtual void EmitFnEnd();
virtual void EmitCantUnwind();
virtual void EmitPersonality(const MCSymbol *Per);
virtual void EmitHandlerData();
virtual void EmitSetFP(unsigned NewFpReg,
unsigned NewSpReg,
int64_t Offset = 0);
virtual void EmitPad(int64_t Offset);
virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
void emitFnStart();
void emitFnEnd();
void emitCantUnwind();
void emitPersonality(const MCSymbol *Per);
void emitHandlerData();
void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
void emitPad(int64_t Offset);
void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
virtual void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
@ -228,6 +304,32 @@ private:
};
} // end anonymous namespace
ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
ARMELFStreamer *S = static_cast<ARMELFStreamer *>(Streamer.get());
return *S;
}
void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
getStreamer().emitPersonality(Personality);
}
void ARMTargetELFStreamer::emitHandlerData() {
getStreamer().emitHandlerData();
}
void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
int64_t Offset) {
getStreamer().emitSetFP(FpReg, SpReg, Offset);
}
void ARMTargetELFStreamer::emitPad(int64_t Offset) {
getStreamer().emitPad(Offset);
}
void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) {
getStreamer().emitRegSave(RegList, isVector);
}
inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
unsigned Type,
unsigned Flags,
@ -291,29 +393,13 @@ void ARMELFStreamer::Reset() {
UnwindOpAsm.Reset();
}
// Add the R_ARM_NONE fixup at the same position
void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
const MCSymbolRefExpr *PersonalityRef =
MCSymbolRefExpr::Create(PersonalitySym,
MCSymbolRefExpr::VK_ARM_NONE,
getContext());
AddValueSymbols(PersonalityRef);
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(
MCFixup::Create(DF->getContents().size(), PersonalityRef,
MCFixup::getKindForSize(4, false)));
}
void ARMELFStreamer::EmitFnStart() {
void ARMELFStreamer::emitFnStart() {
assert(FnStart == 0);
FnStart = getContext().CreateTempSymbol();
EmitLabel(FnStart);
}
void ARMELFStreamer::EmitFnEnd() {
void ARMELFStreamer::emitFnEnd() {
assert(FnStart && ".fnstart must preceeds .fnend");
// Emit unwind opcodes if there is no .handlerdata directive
@ -361,8 +447,20 @@ void ARMELFStreamer::EmitFnEnd() {
Reset();
}
void ARMELFStreamer::EmitCantUnwind() {
CantUnwind = true;
void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
// Add the R_ARM_NONE fixup at the same position
void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
AddValueSymbols(PersonalityRef);
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
PersonalityRef,
MCFixup::getKindForSize(4, false)));
}
void ARMELFStreamer::FlushPendingOffset() {
@ -425,17 +523,14 @@ void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
EmitIntValue(0, 4);
}
void ARMELFStreamer::EmitHandlerData() {
FlushUnwindOpcodes(false);
}
void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) {
void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
Personality = Per;
UnwindOpAsm.setPersonality(Per);
}
void ARMELFStreamer::EmitSetFP(unsigned NewFPReg,
unsigned NewSPReg,
void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
int64_t Offset) {
assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
"the operand of .setfp directive should be either $sp or $fp");
@ -449,7 +544,7 @@ void ARMELFStreamer::EmitSetFP(unsigned NewFPReg,
FPOffset += Offset;
}
void ARMELFStreamer::EmitPad(int64_t Offset) {
void ARMELFStreamer::emitPad(int64_t Offset) {
// Track the change of the $sp offset
SPOffset -= Offset;
@ -458,7 +553,7 @@ void ARMELFStreamer::EmitPad(int64_t Offset) {
PendingOffset -= Offset;
}
void ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool IsVector) {
// Collect the registers in the register list
unsigned Count = 0;
@ -489,11 +584,26 @@ void ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
}
namespace llvm {
MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst) {
ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint);
return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter,
bool RelaxAll, bool NoExecStack,
bool IsThumb) {
ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
ARMTargetELFStreamer *TS = new ARMTargetELFStreamer();
ARMELFStreamer *S =
new ARMELFStreamer(Context, TS, 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.

View File

@ -350,6 +350,10 @@ extern "C" void LLVMInitializeARMTargetMC() {
TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer);
TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer);
// Register the asm streamer.
TargetRegistry::RegisterAsmStreamer(TheARMTarget, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(TheThumbTarget, createMCAsmStreamer);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);

View File

@ -18,13 +18,16 @@
#include <string>
namespace llvm {
class formatted_raw_ostream;
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCInstPrinter;
class MCObjectWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCStreamer;
class MCRelocationInfo;
class StringRef;
class Target;
@ -42,6 +45,12 @@ namespace ARM_MC {
StringRef FS);
}
MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,

View File

@ -9,6 +9,7 @@
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "MipsRegisterInfo.h"
#include "MipsTargetStreamer.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@ -56,6 +57,11 @@ private:
namespace {
class MipsAsmParser : public MCTargetAsmParser {
MipsTargetStreamer &getTargetStreamer() {
MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
return static_cast<MipsTargetStreamer &>(TS);
}
MCSubtargetInfo &STI;
MCAsmParser &Parser;
MipsAssemblerOptions Options;
@ -2115,7 +2121,7 @@ bool MipsAsmParser::parseDirectiveMipsHackStocg() {
if (Parser.parseAbsoluteExpression(Flags))
return TokError("unexpected token");
Parser.getStreamer().emitMipsHackSTOCG(Sym, Flags);
getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
return false;
}
@ -2124,7 +2130,7 @@ bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
if (Parser.parseAbsoluteExpression(Flags))
return TokError("unexpected token");
Parser.getStreamer().emitMipsHackELFFlags(Flags);
getTargetStreamer().emitMipsHackELFFlags(Flags);
return false;
}

View File

@ -5,7 +5,6 @@ add_llvm_library(LLVMMipsDesc
MipsMCTargetDesc.cpp
MipsELFObjectWriter.cpp
MipsReginfo.cpp
MipsELFStreamer.cpp
)
add_dependencies(LLVMMipsDesc MipsCommonTableGen)

View File

@ -1,55 +0,0 @@
//===-- MipsELFStreamer.cpp - MipsELFStreamer ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===-------------------------------------------------------------------===//
#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;
}
} // 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);
}

View File

@ -14,13 +14,18 @@
#include "MipsMCTargetDesc.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MipsMCAsmInfo.h"
#include "MipsTargetStreamer.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCELF.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
@ -34,6 +39,9 @@
using namespace llvm;
static cl::opt<bool> PrintHackDirectives("print-hack-directives",
cl::init(false), cl::Hidden);
static std::string ParseMipsTriple(StringRef TT, StringRef CPU) {
std::string MipsArchFeature;
size_t DashPosition = 0;
@ -123,15 +131,85 @@ static MCInstPrinter *createMipsMCInstPrinter(const Target &T,
return new MipsInstPrinter(MAI, MII, MRI);
}
static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
MCContext &Ctx, MCAsmBackend &MAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
bool RelaxAll,
bool NoExecStack) {
Triple TheTriple(TT);
namespace {
class MipsTargetAsmStreamer : public MipsTargetStreamer {
formatted_raw_ostream &OS;
return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
public:
MipsTargetAsmStreamer(formatted_raw_ostream &OS);
virtual void emitMipsHackELFFlags(unsigned Flags);
virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val);
};
MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS)
: OS(OS) {}
void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) {
if (!PrintHackDirectives)
return;
OS << "\t.mips_hack_elf_flags 0x";
OS.write_hex(Flags);
OS << '\n';
}
void MipsTargetAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) {
if (!PrintHackDirectives)
return;
OS << "\t.mips_hack_stocg ";
OS << Sym->getName();
OS << ", ";
OS << Val;
OS << '\n';
}
class MipsTargetELFStreamer : public MipsTargetStreamer {
public:
MCELFStreamer &getStreamer();
MipsTargetELFStreamer();
virtual void emitMipsHackELFFlags(unsigned Flags);
virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val);
};
MipsTargetELFStreamer::MipsTargetELFStreamer() {}
MCELFStreamer &MipsTargetELFStreamer::getStreamer() {
return static_cast<MCELFStreamer &>(*Streamer);
}
void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) {
MCAssembler &MCA = getStreamer().getAssembler();
MCA.setELFHeaderEFlags(Flags);
}
// Set a symbol's STO flags
void MipsTargetELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) {
MCSymbolData &Data = getStreamer().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);
}
}
static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
MCContext &Context, MCAsmBackend &MAB,
raw_ostream &OS, MCCodeEmitter *Emitter,
bool RelaxAll, bool NoExecStack) {
MipsTargetELFStreamer *S = new MipsTargetELFStreamer();
return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
}
static MCStreamer *
createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory, MCInstPrinter *InstPrint,
MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
MipsTargetAsmStreamer *S = new MipsTargetAsmStreamer(OS);
return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
extern "C" void LLVMInitializeMipsTargetMC() {
@ -182,6 +260,12 @@ extern "C" void LLVMInitializeMipsTargetMC() {
TargetRegistry::RegisterMCObjectStreamer(TheMips64elTarget,
createMCStreamer);
// Register the asm streamer.
TargetRegistry::RegisterAsmStreamer(TheMipsTarget, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(TheMipselTarget, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(TheMips64Target, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(TheMips64elTarget, createMCAsmStreamer);
// Register the asm backend.
TargetRegistry::RegisterMCAsmBackend(TheMipsTarget,
createMipsAsmBackendEB32);

View File

@ -19,6 +19,7 @@
#include "MipsAsmPrinter.h"
#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
#include "MipsTargetStreamer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
@ -44,6 +45,10 @@
using namespace llvm;
MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() {
return static_cast<MipsTargetStreamer &>(OutStreamer.getTargetStreamer());
}
bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Initialize TargetLoweringObjectFile.
if (Subtarget->allowMixed16_32())
@ -237,8 +242,8 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() {
}
if (Subtarget->inMicroMipsMode())
OutStreamer.emitMipsHackSTOCG(CurrentFnSym,
(unsigned)ELF::STO_MIPS_MICROMIPS);
getTargetStreamer().emitMipsHackSTOCG(CurrentFnSym,
(unsigned)ELF::STO_MIPS_MICROMIPS);
OutStreamer.EmitLabel(CurrentFnSym);
}
@ -585,8 +590,8 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
static void
emitELFHeaderFlagsCG(MCStreamer &Streamer, const MipsSubtarget &Subtarget) {
static void emitELFHeaderFlagsCG(MipsTargetStreamer &TargetStreamer,
const MipsSubtarget &Subtarget) {
// Update e_header flags
unsigned EFlags = 0;
@ -625,14 +630,14 @@ emitELFHeaderFlagsCG(MCStreamer &Streamer, const MipsSubtarget &Subtarget) {
else
llvm_unreachable("Unsupported relocation model for e_flags");
Streamer.emitMipsHackELFFlags(EFlags);
TargetStreamer.emitMipsHackELFFlags(EFlags);
}
void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
// Emit Mips ELF register info
Subtarget->getMReginfo().emitMipsReginfoSectionCG(
OutStreamer, getObjFileLowering(), *Subtarget);
emitELFHeaderFlagsCG(OutStreamer, *Subtarget);
emitELFHeaderFlagsCG(getTargetStreamer(), *Subtarget);
}
void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,

View File

@ -25,10 +25,12 @@ namespace llvm {
class MCStreamer;
class MachineInstr;
class MachineBasicBlock;
class MipsTargetStreamer;
class Module;
class raw_ostream;
class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
MipsTargetStreamer &getTargetStreamer();
void EmitInstrWithMacroNoAT(const MachineInstr *MI);

View File

@ -0,0 +1,23 @@
//===-- MipsTargetStreamer.h - Mips Target Streamer ------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MIPSTARGETSTREAMER_H
#define MIPSTARGETSTREAMER_H
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class MipsTargetStreamer : public MCTargetStreamer {
public:
virtual void emitMipsHackELFFlags(unsigned Flags) = 0;
virtual void emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) = 0;
};
}
#endif

View File

@ -14,13 +14,16 @@
#include "PPCMCTargetDesc.h"
#include "InstPrinter/PPCInstPrinter.h"
#include "PPCMCAsmInfo.h"
#include "PPCTargetStreamer.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
@ -101,6 +104,29 @@ static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM,
return X;
}
namespace {
class PPCTargetAsmStreamer : public PPCTargetStreamer {
formatted_raw_ostream &OS;
public:
PPCTargetAsmStreamer(formatted_raw_ostream &OS) : OS(OS) {}
virtual void emitTCEntry(const MCSymbol &S) {
OS << "\t.tc ";
OS << S.getName();
OS << "[TC],";
OS << S.getName();
OS << '\n';
}
};
class PPCTargetELFStreamer : public PPCTargetStreamer {
virtual void emitTCEntry(const MCSymbol &S) {
// Creates a R_PPC64_TOC relocation
Streamer->EmitSymbolValue(&S, 8);
}
};
}
// This is duplicated code. Refactor this.
static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
MCContext &Ctx, MCAsmBackend &MAB,
@ -111,7 +137,20 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
if (Triple(TT).isOSDarwin())
return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll);
return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
PPCTargetStreamer *S = new PPCTargetELFStreamer();
return createELFStreamer(Ctx, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
}
static MCStreamer *
createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useLoc, bool useCFI,
bool useDwarfDirectory, MCInstPrinter *InstPrint,
MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) {
PPCTargetStreamer *S = new PPCTargetAsmStreamer(OS);
return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
useDwarfDirectory, InstPrint, CE, TAB,
ShowInst);
}
static MCInstPrinter *createPPCMCInstPrinter(const Target &T,
@ -171,6 +210,11 @@ extern "C" void LLVMInitializePowerPCTargetMC() {
TargetRegistry::RegisterMCObjectStreamer(ThePPC64Target, createMCStreamer);
TargetRegistry::RegisterMCObjectStreamer(ThePPC64LETarget, createMCStreamer);
// Register the asm streamer.
TargetRegistry::RegisterAsmStreamer(ThePPC32Target, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(ThePPC64Target, createMCAsmStreamer);
TargetRegistry::RegisterAsmStreamer(ThePPC64LETarget, createMCAsmStreamer);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter);
TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter);

View File

@ -23,6 +23,7 @@
#include "MCTargetDesc/PPCMCExpr.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
#include "PPCTargetStreamer.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@ -771,6 +772,9 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
bool isPPC64 = TD->getPointerSizeInBits() == 64;
PPCTargetStreamer &TS =
static_cast<PPCTargetStreamer &>(OutStreamer.getTargetStreamer());
if (isPPC64 && !TOC.empty()) {
const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
@ -781,7 +785,7 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
E = TOC.end(); I != E; ++I) {
OutStreamer.EmitLabel(I->second);
MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
OutStreamer.EmitTCEntry(*S);
TS.emitTCEntry(*S);
}
}

View File

@ -0,0 +1,22 @@
//===-- PPCTargetStreamer.h - PPC Target Streamer --s-----------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef PPCTARGETSTREAMER_H
#define PPCTARGETSTREAMER_H
#include "llvm/MC/MCStreamer.h"
namespace llvm {
class PPCTargetStreamer : public MCTargetStreamer {
public:
virtual void emitTCEntry(const MCSymbol &S) = 0;
};
}
#endif

View File

@ -88,7 +88,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
MCCodeEmitter *_Emitter,
bool RelaxAll,
bool NoExecStack) {
return createELFStreamer(Ctx, MAB, _OS, _Emitter, false, false);
return createELFStreamer(Ctx, 0, MAB, _OS, _Emitter, false, false);
}
extern "C" void LLVMInitializeR600TargetMC() {

View File

@ -187,7 +187,7 @@ static MCStreamer *createSystemZMCObjectStreamer(const Target &T, StringRef TT,
MCCodeEmitter *Emitter,
bool RelaxAll,
bool NoExecStack) {
return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack);
return createELFStreamer(Ctx, 0, MAB, OS, Emitter, RelaxAll, NoExecStack);
}
extern "C" void LLVMInitializeSystemZTargetMC() {

View File

@ -368,7 +368,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll);
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
return createELFStreamer(Ctx, 0, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
}
static MCInstPrinter *createX86MCInstPrinter(const Target &T,