mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 04:09:45 +00:00
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:
parent
26c46ba11c
commit
320296a4cf
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
/// @{
|
||||
|
@ -19,7 +19,7 @@ namespace {
|
||||
|
||||
class MCNullStreamer : public MCStreamer {
|
||||
public:
|
||||
MCNullStreamer(MCContext &Context) : MCStreamer(Context) {}
|
||||
MCNullStreamer(MCContext &Context) : MCStreamer(Context, 0) {}
|
||||
|
||||
/// @name MCStreamer Interface
|
||||
/// @{
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
/// @{
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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() {}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ add_llvm_library(LLVMMipsDesc
|
||||
MipsMCTargetDesc.cpp
|
||||
MipsELFObjectWriter.cpp
|
||||
MipsReginfo.cpp
|
||||
MipsELFStreamer.cpp
|
||||
)
|
||||
|
||||
add_dependencies(LLVMMipsDesc MipsCommonTableGen)
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
23
lib/Target/Mips/MipsTargetStreamer.h
Normal file
23
lib/Target/Mips/MipsTargetStreamer.h
Normal 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
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
22
lib/Target/PowerPC/PPCTargetStreamer.h
Normal file
22
lib/Target/PowerPC/PPCTargetStreamer.h
Normal 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
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user