X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCAsmStreamer.cpp;h=6aabfe188a32abf4a4726ced9c4b4840618a1060;hb=2d7a53aec2c6426eba9e5dd6462cc9e86432b410;hp=217daed7fe020dfad935c69e0454f88e75218b3b;hpb=32a006e606742b1c5401e49607e33717bb5441f0;p=oota-llvm.git diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 217daed7fe0..6aabfe188a3 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -12,6 +12,7 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCSectionMachO.h" @@ -23,7 +24,10 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetAsmBackend.h" +#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetLoweringObjectFile.h" +#include using namespace llvm; namespace { @@ -33,34 +37,33 @@ class MCAsmStreamer : public MCStreamer { const MCAsmInfo &MAI; OwningPtr InstPrinter; OwningPtr Emitter; + OwningPtr AsmBackend; SmallString<128> CommentToEmit; raw_svector_ostream CommentStream; - const TargetLoweringObjectFile *TLOF; - int PointerSize; - - unsigned IsLittleEndian : 1; unsigned IsVerboseAsm : 1; unsigned ShowInst : 1; + unsigned UseLoc : 1; + + bool needsSet(const MCExpr *Value); public: MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, - bool isLittleEndian, bool isVerboseAsm, - const TargetLoweringObjectFile *tlof, int pointerSize, - MCInstPrinter *printer, MCCodeEmitter *emitter, bool showInst) + bool isVerboseAsm, + bool useLoc, + MCInstPrinter *printer, MCCodeEmitter *emitter, + TargetAsmBackend *asmbackend, + bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), - InstPrinter(printer), Emitter(emitter), CommentStream(CommentToEmit), - TLOF(tlof), PointerSize(pointerSize), - IsLittleEndian(isLittleEndian), IsVerboseAsm(isVerboseAsm), - ShowInst(showInst) { + InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), + CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), + ShowInst(showInst), UseLoc(useLoc) { if (InstPrinter && IsVerboseAsm) InstPrinter->setCommentStream(CommentStream); } ~MCAsmStreamer() {} - bool isLittleEndian() const { return IsLittleEndian; } - inline void EmitEOL() { // If we don't have any comments, just emit a \n. if (!IsVerboseAsm) { @@ -150,8 +153,10 @@ public: virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValue(const MCExpr *Value, unsigned Size,unsigned AddrSpace, - bool UseSet = false); + virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, + bool isPCRel, unsigned AddrSpace); + virtual void EmitIntValue(uint64_t Value, unsigned Size, + unsigned AddrSpace = 0); virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); @@ -184,8 +189,8 @@ public: virtual bool EmitCFIDefCfaOffset(int64_t Offset); virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); - virtual bool EmitCFIPersonality(const MCSymbol *Sym); - virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); virtual void EmitInstruction(const MCInst &Inst); @@ -304,7 +309,8 @@ void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label) { - EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); + EmitDwarfSetLineAddr(LineDelta, Label, + getContext().getTargetAsmInfo().getPointerSize()); } void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, @@ -504,9 +510,15 @@ void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { EmitEOL(); } -void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace, bool UseSet) { +void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, + unsigned AddrSpace) { + EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace); +} + +void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + bool isPCRel, unsigned AddrSpace) { assert(CurSection && "Cannot emit contents before setting section!"); + assert(!isPCRel && "Cannot emit pc relative relocations!"); const char *Directive = 0; switch (Size) { default: break; @@ -520,7 +532,7 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, int64_t IntValue; if (!Value->EvaluateAsAbsolute(IntValue)) report_fatal_error("Don't know how to emit this value."); - if (isLittleEndian()) { + if (getContext().getTargetAsmInfo().isLittleEndian()) { EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); } else { @@ -531,14 +543,6 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, } assert(Directive && "Invalid size for machine code value!"); - if (UseSet && MAI.hasSetDirective()) { - MCSymbol *SetLabel = getContext().CreateTempSymbol(); - EmitAssignment(SetLabel, Value); - OS << Directive << *SetLabel; - EmitEOL(); - return; - } - OS << Directive << *Value; EmitEOL(); } @@ -546,10 +550,7 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace) { int64_t IntValue; if (Value->EvaluateAsAbsolute(IntValue)) { - SmallString<32> Tmp; - raw_svector_ostream OSE(Tmp); - MCObjectWriter::EncodeULEB128(IntValue, OSE); - EmitBytes(OSE.str(), AddrSpace); + EmitULEB128IntValue(IntValue, AddrSpace); return; } assert(MAI.hasLEB128() && "Cannot print a .uleb"); @@ -560,10 +561,7 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace) { void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace) { int64_t IntValue; if (Value->EvaluateAsAbsolute(IntValue)) { - SmallString<32> Tmp; - raw_svector_ostream OSE(Tmp); - MCObjectWriter::EncodeSLEB128(IntValue, OSE); - EmitBytes(OSE.str(), AddrSpace); + EmitSLEB128IntValue(IntValue, AddrSpace); return; } assert(MAI.hasLEB128() && "Cannot print a .sleb"); @@ -668,7 +666,7 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { } bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Filename){ - if (!TLOF) { + if (UseLoc) { OS << "\t.file\t" << FileNo << ' '; PrintQuotedString(Filename, OS); EmitEOL(); @@ -682,7 +680,7 @@ void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Discriminator) { this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags, Isa, Discriminator); - if (TLOF) + if (!UseLoc) return; OS << "\t.loc\t" << FileNo << " " << Line << " " << Column; @@ -714,7 +712,7 @@ bool MCAsmStreamer::EmitCFIStartProc() { if (this->MCStreamer::EmitCFIStartProc()) return true; - OS << ".cfi_startproc"; + OS << "\t.cfi_startproc"; EmitEOL(); return false; @@ -724,7 +722,7 @@ bool MCAsmStreamer::EmitCFIEndProc() { if (this->MCStreamer::EmitCFIEndProc()) return true; - OS << ".cfi_endproc"; + OS << "\t.cfi_endproc"; EmitEOL(); return false; @@ -734,7 +732,7 @@ bool MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { if (this->MCStreamer::EmitCFIDefCfaOffset(Offset)) return true; - OS << ".cfi_def_cfa_offset " << Offset; + OS << "\t.cfi_def_cfa_offset " << Offset; EmitEOL(); return false; @@ -744,7 +742,7 @@ bool MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { if (this->MCStreamer::EmitCFIDefCfaRegister(Register)) return true; - OS << ".cfi_def_cfa_register " << Register; + OS << "\t.cfi_def_cfa_register " << Register; EmitEOL(); return false; @@ -754,27 +752,28 @@ bool MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { if (this->MCStreamer::EmitCFIOffset(Register, Offset)) return true; - OS << ".cfi_offset " << Register << ", " << Offset; + OS << "\t.cfi_offset " << Register << ", " << Offset; EmitEOL(); return false; } -bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym) { - if (this->MCStreamer::EmitCFIPersonality(Sym)) +bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, + unsigned Encoding) { + if (this->MCStreamer::EmitCFIPersonality(Sym, Encoding)) return true; - OS << ".cfi_personality 0, " << *Sym; + OS << "\t.cfi_personality " << Encoding << ", " << *Sym; EmitEOL(); return false; } -bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym) { - if (this->MCStreamer::EmitCFILsda(Sym)) +bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { + if (this->MCStreamer::EmitCFILsda(Sym, Encoding)) return true; - OS << ".cfi_lsda 0, " << *Sym; + OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; EmitEOL(); return false; @@ -798,7 +797,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { MCFixup &F = Fixups[i]; - const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind()); + const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); for (unsigned j = 0; j != Info.TargetSize; ++j) { unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j; assert(Index < Code.size() * 8 && "Invalid offset in fixup!"); @@ -806,6 +805,8 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { } } + // FIXME: Node the fixup comments for Thumb2 are completely bogus since the + // high order halfword of a 32-bit Thumb2 instruction is emitted first. OS << "encoding: ["; for (unsigned i = 0, e = Code.size(); i != e; ++i) { if (i) @@ -825,8 +826,12 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { if (MapEntry == 0) { OS << format("0x%02x", uint8_t(Code[i])); } else { - assert(Code[i] == 0 && "Encoder wrote into fixed up bit!"); - OS << char('A' + MapEntry - 1); + if (Code[i]) { + // FIXME: Some of the 8 bits require fix up. + OS << format("0x%02x", uint8_t(Code[i])) << '\'' + << char('A' + MapEntry - 1) << '\''; + } else + OS << char('A' + MapEntry - 1); } } else { // Otherwise, write out in binary. @@ -835,7 +840,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { unsigned Bit = (Code[i] >> j) & 1; unsigned FixupBit; - if (IsLittleEndian) + if (getContext().getTargetAsmInfo().isLittleEndian()) FixupBit = i * 8 + j; else FixupBit = i * 8 + (7-j); @@ -852,7 +857,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { MCFixup &F = Fixups[i]; - const MCFixupKindInfo &Info = Emitter->getFixupKindInfo(F.getKind()); + const MCFixupKindInfo &Info = AsmBackend->getFixupKindInfo(F.getKind()); OS << " fixup " << char('A' + i) << " - " << "offset: " << F.getOffset() << ", value: " << *F.getValue() << ", kind: " << Info.Name << "\n"; } @@ -861,7 +866,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { assert(CurSection && "Cannot emit contents before setting section!"); - if (TLOF) + if (!UseLoc) MCLineEntry::Make(this, getCurrentSection()); // Show the encoding in a comment if we have a code emitter. @@ -894,29 +899,15 @@ void MCAsmStreamer::EmitRawText(StringRef String) { void MCAsmStreamer::Finish() { // Dump out the dwarf file & directory tables and line tables. - if (getContext().hasDwarfFiles() && TLOF) - MCDwarfFileTable::Emit(this, TLOF->getDwarfLineSection(), - TLOF->getTextSection()); + if (getContext().hasDwarfFiles() && !UseLoc) + MCDwarfFileTable::Emit(this); } MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, - bool isLittleEndian, - bool isVerboseAsm, MCInstPrinter *IP, - MCCodeEmitter *CE, bool ShowInst) { - return new MCAsmStreamer(Context, OS, isLittleEndian, isVerboseAsm, - NULL, 0, IP, CE, ShowInst); -} - - -MCStreamer *llvm::createAsmStreamerNoLoc(MCContext &Context, - formatted_raw_ostream &OS, - bool isLittleEndian, - bool isVerboseAsm, - const TargetLoweringObjectFile *TLOF, - int PointerSize, - MCInstPrinter *IP, - MCCodeEmitter *CE, bool ShowInst) { - return new MCAsmStreamer(Context, OS, isLittleEndian, isVerboseAsm, - TLOF, PointerSize, IP, CE, ShowInst); + bool isVerboseAsm, bool useLoc, + MCInstPrinter *IP, MCCodeEmitter *CE, + TargetAsmBackend *TAB, bool ShowInst) { + return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, + IP, CE, TAB, ShowInst); }