X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCAsmStreamer.cpp;h=3fcbb05907bcf564fd52707729994386793ae406;hb=3699261d3f49d65cee6a645c849c41cdca51a01f;hp=603ae837b6deb51a3da569b1725c15f915315571;hpb=713c4bfc36260bfc9273d414b14757bd7819f9b1;p=oota-llvm.git diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 603ae837b6d..3fcbb05907b 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -15,29 +15,33 @@ #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #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 { class MCAsmStreamer : public MCStreamer { +protected: formatted_raw_ostream &OS; const MCAsmInfo &MAI; +private: OwningPtr InstPrinter; OwningPtr Emitter; - OwningPtr AsmBackend; + OwningPtr AsmBackend; SmallString<128> CommentToEmit; raw_svector_ostream CommentStream; @@ -54,11 +58,13 @@ class MCAsmStreamer : public MCStreamer { bool needsSet(const MCExpr *Value); + void EmitRegisterName(int64_t Register); + public: MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc, bool useCFI, MCInstPrinter *printer, MCCodeEmitter *emitter, - TargetAsmBackend *asmbackend, + MCAsmBackend *asmbackend, bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), @@ -132,7 +138,8 @@ public: virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label); + const MCSymbol *Label, + unsigned PointerSize); virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); @@ -151,7 +158,9 @@ public: /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size); + /// @param Size - The alignment of the common symbol in bytes. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); @@ -208,6 +217,21 @@ public: virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); + virtual void EmitWin64EHStartProc(const MCSymbol *Symbol); + virtual void EmitWin64EHEndProc(); + virtual void EmitWin64EHStartChained(); + virtual void EmitWin64EHEndChained(); + virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except); + virtual void EmitWin64EHHandlerData(); + virtual void EmitWin64EHPushReg(unsigned Register); + virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); + virtual void EmitWin64EHAllocStack(unsigned Size); + virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); + virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); + virtual void EmitWin64EHPushFrame(bool Code); + virtual void EmitWin64EHEndProlog(); + virtual void EmitFnStart(); virtual void EmitFnEnd(); virtual void EmitCantUnwind(); @@ -313,8 +337,9 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { default: assert(0 && "Invalid flag!"); case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; - case MCAF_Code16: OS << "\t.code\t16"; break; - case MCAF_Code32: OS << "\t.code\t32"; break; + case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break; + case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break; + case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break; } EmitEOL(); } @@ -323,7 +348,8 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { // This needs to emit to a temporary string to get properly quoted // MCSymbols when they have spaces in them. OS << "\t.thumb_func"; - if (Func) + // Only Mach-O hasSubsectionsViaSymbols() + if (MAI.hasSubsectionsViaSymbols()) OS << '\t' << *Func; EmitEOL(); } @@ -343,16 +369,16 @@ void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label) { - EmitDwarfSetLineAddr(LineDelta, Label, - getContext().getTargetAsmInfo().getPointerSize()); + const MCSymbol *Label, + unsigned PointerSize) { + EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); } void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label) { EmitIntValue(dwarf::DW_CFA_advance_loc4, 1); const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); - AddrDelta = ForceExpAbs(this, getContext(), AddrDelta); + AddrDelta = ForceExpAbs(AddrDelta); EmitValue(AddrDelta, 4); } @@ -460,9 +486,16 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. -void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { - assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!"); +void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlign) { + assert(MAI.getLCOMMDirectiveType() != LCOMM::None && + "Doesn't have .lcomm, can't emit it!"); OS << "\t.lcomm\t" << *Symbol << ',' << Size; + if (ByteAlign > 1) { + assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment && + "Alignment not supported on .lcomm!"); + OS << ',' << ByteAlign; + } EmitEOL(); } @@ -582,7 +615,7 @@ void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, int64_t IntValue; if (!Value->EvaluateAsAbsolute(IntValue)) report_fatal_error("Don't know how to emit this value."); - if (getContext().getTargetAsmInfo().isLittleEndian()) { + if (getContext().getAsmInfo().isLittleEndian()) { EmitIntValue((uint32_t)(IntValue >> 0 ), 4, AddrSpace); EmitIntValue((uint32_t)(IntValue >> 32), 4, AddrSpace); } else { @@ -803,13 +836,25 @@ void MCAsmStreamer::EmitCFIEndProc() { EmitEOL(); } +void MCAsmStreamer::EmitRegisterName(int64_t Register) { + if (InstPrinter && !MAI.useDwarfRegNumForCFI()) { + const MCRegisterInfo &MRI = getContext().getRegisterInfo(); + unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true); + InstPrinter->printRegName(OS, LLVMRegister); + } else { + OS << Register; + } +} + void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { MCStreamer::EmitCFIDefCfa(Register, Offset); if (!UseCFI) return; - OS << ".cfi_def_cfa " << Register << ", " << Offset; + OS << "\t.cfi_def_cfa "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } @@ -829,7 +874,8 @@ void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { if (!UseCFI) return; - OS << "\t.cfi_def_cfa_register " << Register; + OS << "\t.cfi_def_cfa_register "; + EmitRegisterName(Register); EmitEOL(); } @@ -839,7 +885,9 @@ void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { if (!UseCFI) return; - OS << "\t.cfi_offset " << Register << ", " << Offset; + OS << "\t.cfi_offset "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } @@ -890,7 +938,8 @@ void MCAsmStreamer::EmitCFISameValue(int64_t Register) { if (!UseCFI) return; - OS << "\t.cfi_same_value " << Register; + OS << "\t.cfi_same_value "; + EmitRegisterName(Register); EmitEOL(); } @@ -900,7 +949,9 @@ void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { if (!UseCFI) return; - OS << "\t.cfi_rel_offset " << Register << ", " << Offset; + OS << "\t.cfi_rel_offset "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } @@ -914,6 +965,127 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { EmitEOL(); } +void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { + MCStreamer::EmitWin64EHStartProc(Symbol); + + OS << ".seh_proc " << *Symbol; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHEndProc() { + MCStreamer::EmitWin64EHEndProc(); + + OS << "\t.seh_endproc"; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHStartChained() { + MCStreamer::EmitWin64EHStartChained(); + + OS << "\t.seh_startchained"; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHEndChained() { + MCStreamer::EmitWin64EHEndChained(); + + OS << "\t.seh_endchained"; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, + bool Except) { + MCStreamer::EmitWin64EHHandler(Sym, Unwind, Except); + + OS << "\t.seh_handler " << *Sym; + if (Unwind) + OS << ", @unwind"; + if (Except) + OS << ", @except"; + EmitEOL(); +} + +static const MCSection *getWin64EHTableSection(StringRef suffix, + MCContext &context) { + // FIXME: This doesn't belong in MCObjectFileInfo. However, + /// this duplicate code in MCWin64EH.cpp. + if (suffix == "") + return context.getObjectFileInfo()->getXDataSection(); + return context.getCOFFSection((".xdata"+suffix).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} + +void MCAsmStreamer::EmitWin64EHHandlerData() { + MCStreamer::EmitWin64EHHandlerData(); + + // Switch sections. Don't call SwitchSection directly, because that will + // cause the section switch to be visible in the emitted assembly. + // We only do this so the section switch that terminates the handler + // data block is visible. + MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); + StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function); + const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext()); + if (xdataSect) + SwitchSectionNoChange(xdataSect); + + OS << "\t.seh_handlerdata"; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) { + MCStreamer::EmitWin64EHPushReg(Register); + + OS << "\t.seh_pushreg " << Register; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { + MCStreamer::EmitWin64EHSetFrame(Register, Offset); + + OS << "\t.seh_setframe " << Register << ", " << Offset; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) { + MCStreamer::EmitWin64EHAllocStack(Size); + + OS << "\t.seh_stackalloc " << Size; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { + MCStreamer::EmitWin64EHSaveReg(Register, Offset); + + OS << "\t.seh_savereg " << Register << ", " << Offset; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { + MCStreamer::EmitWin64EHSaveXMM(Register, Offset); + + OS << "\t.seh_savexmm " << Register << ", " << Offset; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHPushFrame(bool Code) { + MCStreamer::EmitWin64EHPushFrame(Code); + + OS << "\t.seh_pushframe"; + if (Code) + OS << " @code"; + EmitEOL(); +} + +void MCAsmStreamer::EmitWin64EHEndProlog(void) { + MCStreamer::EmitWin64EHEndProlog(); + + OS << "\t.seh_endprologue"; + EmitEOL(); +} + void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { raw_ostream &OS = GetCommentOS(); SmallString<256> Code; @@ -940,7 +1112,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { } } - // FIXME: Node the fixup comments for Thumb2 are completely bogus since the + // FIXME: Note 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) { @@ -975,7 +1147,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { unsigned Bit = (Code[i] >> j) & 1; unsigned FixupBit; - if (getContext().getTargetAsmInfo().isLittleEndian()) + if (getContext().getAsmInfo().isLittleEndian()) FixupBit = i * 8 + j; else FixupBit = i * 8 + (7-j); @@ -1024,8 +1196,10 @@ void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) { } void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { - OS << "\t.setfp\t" << InstPrinter->getRegName(FpReg) - << ", " << InstPrinter->getRegName(SpReg); + OS << "\t.setfp\t"; + InstPrinter->printRegName(OS, FpReg); + OS << ", "; + InstPrinter->printRegName(OS, SpReg); if (Offset) OS << ", #" << Offset; EmitEOL(); @@ -1044,10 +1218,12 @@ void MCAsmStreamer::EmitRegSave(const SmallVectorImpl &RegList, else OS << "\t.save\t{"; - OS << InstPrinter->getRegName(RegList[0]); + InstPrinter->printRegName(OS, RegList[0]); - for (unsigned i = 1, e = RegList.size(); i != e; ++i) - OS << ", " << InstPrinter->getRegName(RegList[i]); + for (unsigned i = 1, e = RegList.size(); i != e; ++i) { + OS << ", "; + InstPrinter->printRegName(OS, RegList[i]); + } OS << "}"; EmitEOL(); @@ -1068,7 +1244,7 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { // If we have an AsmPrinter, use that to print, otherwise print the MCInst. if (InstPrinter) - InstPrinter->printInst(&Inst, OS); + InstPrinter->printInst(&Inst, OS, ""); else Inst.print(OS, &MAI); EmitEOL(); @@ -1092,13 +1268,12 @@ void MCAsmStreamer::Finish() { if (!UseCFI) EmitFrames(false); } - MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, - bool useCFI, - MCInstPrinter *IP, MCCodeEmitter *CE, - TargetAsmBackend *TAB, bool ShowInst) { + bool useCFI, MCInstPrinter *IP, + MCCodeEmitter *CE, MCAsmBackend *MAB, + bool ShowInst) { return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, - IP, CE, TAB, ShowInst); + IP, CE, MAB, ShowInst); }