X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCAsmStreamer.cpp;h=b6ebb1abbfdaa906c5f10556d77df0a301980faa;hb=5e63990271f7cea4d32b923f39a27f58a091a253;hp=9ea9b4342ca916342ced53fa89849ecda65301de;hpb=4a0abd80f18f9c2a10bf5b14cd6731d51972a426;p=oota-llvm.git diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 9ea9b4342ca..b6ebb1abbfd 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -9,14 +9,14 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/ADT/SmallString.h" -#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" -#include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" @@ -28,12 +28,12 @@ namespace { class MCAsmStreamer : public MCStreamer { raw_ostream &OS; const MCAsmInfo &MAI; - AsmPrinter *Printer; + MCInstPrinter *InstPrinter; MCCodeEmitter *Emitter; public: MCAsmStreamer(MCContext &Context, raw_ostream &_OS, const MCAsmInfo &tai, - AsmPrinter *_Printer, MCCodeEmitter *_Emitter) - : MCStreamer(Context), OS(_OS), MAI(tai), Printer(_Printer), + MCInstPrinter *_Printer, MCCodeEmitter *_Emitter) + : MCStreamer(Context), OS(_OS), MAI(tai), InstPrinter(_Printer), Emitter(_Emitter) {} ~MCAsmStreamer() {} @@ -46,30 +46,27 @@ public: virtual void EmitAssemblerFlag(AssemblerFlag Flag); - virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value, - bool MakeAbsolute = false); + virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); - virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value); - virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, - unsigned Pow2Alignment, bool IsLocal); + unsigned ByteAlignment); - virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = NULL, - unsigned Size = 0, unsigned Pow2Alignment = 0); + virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + unsigned Size = 0, unsigned ByteAlignment = 0); - virtual void EmitBytes(const StringRef &Data); + virtual void EmitBytes(StringRef Data); - virtual void EmitValue(const MCValue &Value, unsigned Size); + virtual void EmitValue(const MCExpr *Value, unsigned Size); virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, unsigned ValueSize = 1, unsigned MaxBytesToEmit = 0); - virtual void EmitValueToOffset(const MCValue &Offset, + virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); virtual void EmitInstruction(const MCInst &Inst); @@ -81,26 +78,15 @@ public: } // end anonymous namespace. -/// Allow printing symbols directly to a raw_ostream with proper quoting. -static inline raw_ostream &operator<<(raw_ostream &os, const MCSymbol *S) { - S->print(os); - return os; -} - -/// Allow printing values directly to a raw_ostream. -static inline raw_ostream &operator<<(raw_ostream &os, const MCValue &Value) { - Value.print(os); - return os; -} - static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { assert(Bytes && "Invalid size!"); return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); } -static inline MCValue truncateToSize(const MCValue &Value, unsigned Bytes) { - return MCValue::get(Value.getSymA(), Value.getSymB(), - truncateToSize(Value.getConstant(), Bytes)); +static inline const MCExpr *truncateToSize(const MCExpr *Value, + unsigned Bytes) { + // FIXME: Do we really need this routine? + return Value; } void MCAsmStreamer::SwitchSection(const MCSection *Section) { @@ -115,7 +101,8 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); assert(CurSection && "Cannot emit before setting section!"); - OS << Symbol << ":\n"; + Symbol->print(OS, &MAI); + OS << ":\n"; Symbol->setSection(*CurSection); } @@ -127,70 +114,61 @@ void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag) { OS << '\n'; } -void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value, - bool MakeAbsolute) { +void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { // Only absolute symbols can be redefined. assert((Symbol->isUndefined() || Symbol->isAbsolute()) && "Cannot define a symbol twice!"); - if (MakeAbsolute) { - OS << ".set " << Symbol << ", " << Value << '\n'; + Symbol->print(OS, &MAI); + OS << " = "; + Value->print(OS, &MAI); + OS << '\n'; - // HACK: If the value isn't already absolute, set the symbol value to - // itself, we want to use the .set absolute value, not the actual - // expression. - if (!Value.isAbsolute()) - getContext().SetSymbolValue(Symbol, MCValue::get(Symbol)); - else - getContext().SetSymbolValue(Symbol, Value); - } else { - OS << Symbol << " = " << Value << '\n'; - getContext().SetSymbolValue(Symbol, Value); - } + // FIXME: Lift context changes into super class. + // FIXME: Set associated section. + Symbol->setValue(Value); } -void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, +void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute) { switch (Attribute) { - case Global: OS << ".globl"; break; - case Hidden: OS << ".hidden"; break; + case Global: OS << ".globl"; break; + case Hidden: OS << ".hidden"; break; case IndirectSymbol: OS << ".indirect_symbol"; break; - case Internal: OS << ".internal"; break; - case LazyReference: OS << ".lazy_reference"; break; - case NoDeadStrip: OS << ".no_dead_strip"; break; - case PrivateExtern: OS << ".private_extern"; break; - case Protected: OS << ".protected"; break; - case Reference: OS << ".reference"; break; - case Weak: OS << ".weak"; break; + case Internal: OS << ".internal"; break; + case LazyReference: OS << ".lazy_reference"; break; + case NoDeadStrip: OS << ".no_dead_strip"; break; + case PrivateExtern: OS << ".private_extern"; break; + case Protected: OS << ".protected"; break; + case Reference: OS << ".reference"; break; + case Weak: OS << ".weak"; break; case WeakDefinition: OS << ".weak_definition"; break; - case WeakReference: OS << ".weak_reference"; break; + case WeakReference: OS << ".weak_reference"; break; } - OS << ' ' << Symbol << '\n'; + OS << ' '; + Symbol->print(OS, &MAI); + OS << '\n'; } void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { - OS << ".desc" << ' ' << Symbol << ',' << DescValue << '\n'; -} - -void MCAsmStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) { - OS << ".lsym" << ' ' << Symbol << ',' << Value << '\n'; + OS << ".desc" << ' '; + Symbol->print(OS, &MAI); + OS << ',' << DescValue << '\n'; } void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, - unsigned Pow2Alignment, bool IsLocal) { - if (IsLocal) - OS << ".lcomm"; - else - OS << ".comm"; - OS << ' ' << Symbol << ',' << Size; - if (Pow2Alignment != 0) - OS << ',' << Pow2Alignment; + unsigned ByteAlignment) { + OS << ".comm "; + Symbol->print(OS, &MAI); + OS << ',' << Size; + if (ByteAlignment != 0) + OS << ',' << Log2_32(ByteAlignment); OS << '\n'; } -void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, - unsigned Size, unsigned Pow2Alignment) { +void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, + unsigned Size, unsigned ByteAlignment) { // Note: a .zerofill directive does not switch sections. OS << ".zerofill "; @@ -199,20 +177,22 @@ void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); if (Symbol != NULL) { - OS << ',' << Symbol << ',' << Size; - if (Pow2Alignment != 0) - OS << ',' << Pow2Alignment; + OS << ','; + Symbol->print(OS, &MAI); + OS << ',' << Size; + if (ByteAlignment != 0) + OS << ',' << Log2_32(ByteAlignment); } OS << '\n'; } -void MCAsmStreamer::EmitBytes(const StringRef &Data) { +void MCAsmStreamer::EmitBytes(StringRef Data) { assert(CurSection && "Cannot emit contents before setting section!"); for (unsigned i = 0, e = Data.size(); i != e; ++i) OS << ".byte " << (unsigned) (unsigned char) Data[i] << '\n'; } -void MCAsmStreamer::EmitValue(const MCValue &Value, unsigned Size) { +void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size) { assert(CurSection && "Cannot emit contents before setting section!"); // Need target hooks to know how to print this. switch (Size) { @@ -224,7 +204,9 @@ void MCAsmStreamer::EmitValue(const MCValue &Value, unsigned Size) { case 8: OS << ".quad"; break; } - OS << ' ' << truncateToSize(Value, Size) << '\n'; + OS << ' '; + truncateToSize(Value, Size)->print(OS, &MAI); + OS << '\n'; } void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, @@ -248,7 +230,8 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, OS << Log2_32(ByteAlignment); if (Value || MaxBytesToEmit) { - OS << ", " << truncateToSize(Value, ValueSize); + OS << ", 0x"; + OS.write_hex(truncateToSize(Value, ValueSize)); if (MaxBytesToEmit) OS << ", " << MaxBytesToEmit; @@ -274,61 +257,46 @@ void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, OS << '\n'; } -void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset, +void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { // FIXME: Verify that Offset is associated with the current section. - OS << ".org " << Offset << ", " << (unsigned) Value << '\n'; -} - -static raw_ostream &operator<<(raw_ostream &OS, const MCOperand &Op) { - if (Op.isReg()) - return OS << "reg:" << Op.getReg(); - if (Op.isImm()) - return OS << "imm:" << Op.getImm(); - if (Op.isMBBLabel()) - return OS << "mbblabel:(" - << Op.getMBBLabelFunction() << ", " << Op.getMBBLabelBlock(); - assert(Op.isMCValue() && "Invalid operand!"); - return OS << "val:" << Op.getMCValue(); + OS << ".org "; + Offset->print(OS, &MAI); + OS << ", " << (unsigned) Value << '\n'; } void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { assert(CurSection && "Cannot emit contents before setting section!"); - // Show the encoding if we have a code emitter. - if (Emitter) { - SmallString<256> Code; - raw_svector_ostream VecOS(Code); - Emitter->EncodeInstruction(Inst, VecOS); - VecOS.flush(); - - OS.indent(20); - OS << " # encoding: ["; - for (unsigned i = 0, e = Code.size(); i != e; ++i) { - if (i + 1 != e) - OS << ','; - OS << format("%#04x", Code[i]); + // If we have an AsmPrinter, use that to print. + if (InstPrinter) { + InstPrinter->printInst(&Inst); + OS << '\n'; + + // Show the encoding if we have a code emitter. + if (Emitter) { + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + Emitter->EncodeInstruction(Inst, VecOS); + VecOS.flush(); + + OS.indent(20); + OS << " # encoding: ["; + for (unsigned i = 0, e = Code.size(); i != e; ++i) { + if (i) + OS << ','; + OS << format("%#04x", uint8_t(Code[i])); + } + OS << "]\n"; } - OS << "]\n"; - } - // If we have an AsmPrinter, use that to print. - if (Printer) { - Printer->printMCInst(&Inst); return; } // Otherwise fall back to a structural printing for now. Eventually we should // always have access to the target specific printer. - OS << "MCInst(" - << "opcode=" << Inst.getOpcode() << ", " - << "operands=["; - for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { - if (i) - OS << ", "; - OS << Inst.getOperand(i); - } - OS << "])\n"; + Inst.print(OS, &MAI); + OS << '\n'; } void MCAsmStreamer::Finish() { @@ -336,7 +304,7 @@ void MCAsmStreamer::Finish() { } MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS, - const MCAsmInfo &MAI, AsmPrinter *AP, + const MCAsmInfo &MAI, MCInstPrinter *IP, MCCodeEmitter *CE) { - return new MCAsmStreamer(Context, OS, MAI, AP, CE); + return new MCAsmStreamer(Context, OS, MAI, IP, CE); }