diff options
Diffstat (limited to 'contrib/llvm/lib/MC')
34 files changed, 814 insertions, 323 deletions
diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp index 7203b9a..eda0623 100644 --- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp @@ -133,6 +133,11 @@ class ELFObjectWriter : public MCObjectWriter { bool IsPCRel) const { return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); } + const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, IsPCRel); + } bool is64Bit() const { return TargetObjectWriter->is64Bit(); } bool hasRelocationAddend() const { @@ -270,9 +275,10 @@ class ELFObjectWriter : public MCObjectWriter { /// ComputeSymbolTable - Compute the symbol table data /// - /// \param StringTable [out] - The string table data. - /// \param StringIndexMap [out] - Map from symbol names to offsets in the - /// string table. + /// \param Asm - The assembler. + /// \param SectionIndexMap - Maps a section to its index. + /// \param RevGroupMap - Maps a signature symbol to the group section. + /// \param NumRegularSections - Number of non-relocation sections. void ComputeSymbolTable(MCAssembler &Asm, const SectionIndexMapTy &SectionIndexMap, RevGroupMapTy RevGroupMap, @@ -638,7 +644,7 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, if (ASymbol.isUndefined()) { if (Renamed) return Renamed; - return &ASymbol; + return undefinedExplicitRelSym(Target, Fixup, IsPCRel); } if (SD.isExternal()) { @@ -720,10 +726,13 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, MCSymbolData &SD = Asm.getSymbolData(ASymbol); MCFragment *F = SD.getFragment(); - Index = F->getParent()->getOrdinal() + 1; - - // Offset of the symbol in the section - Value += Layout.getSymbolOffset(&SD); + if (F) { + Index = F->getParent()->getOrdinal() + 1; + // Offset of the symbol in the section + Value += Layout.getSymbolOffset(&SD); + } else { + Index = 0; + } } else { if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) WeakrefUsedInReloc.insert(RelocSymbol); @@ -732,8 +741,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, Index = -1; } Addend = Value; - // Compensate for the addend on i386. - if (is64Bit()) + if (hasRelocationAddend()) Value = 0; } diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp index 2e447b0..53960e7 100644 --- a/contrib/llvm/lib/MC/MCAsmBackend.cpp +++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp @@ -12,12 +12,9 @@ using namespace llvm; MCAsmBackend::MCAsmBackend() - : HasReliableSymbolDifference(false) -{ -} + : HasReliableSymbolDifference(false), HasDataInCodeSupport(false) {} -MCAsmBackend::~MCAsmBackend() { -} +MCAsmBackend::~MCAsmBackend() {} const MCFixupKindInfo & MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp index 8da2e0e..7ea0f3b 100644 --- a/contrib/llvm/lib/MC/MCAsmInfo.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp @@ -68,8 +68,8 @@ MCAsmInfo::MCAsmInfo() { GlobalDirective = "\t.globl\t"; HasSetDirective = true; HasAggressiveSymbolFolding = true; - LCOMMDirectiveType = LCOMM::None; COMMDirectiveAlignmentIsInBytes = true; + LCOMMDirectiveAlignmentType = LCOMM::NoAlignment; HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; HasNoDeadStrip = false; diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp index 678e75a..fd79193 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp @@ -19,8 +19,10 @@ void MCAsmInfoCOFF::anchor() { } MCAsmInfoCOFF::MCAsmInfoCOFF() { GlobalPrefix = "_"; + // MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte + // alignment. COMMDirectiveAlignmentIsInBytes = false; - LCOMMDirectiveType = LCOMM::ByteAlignment; + LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment; HasDotTypeDotSizeDirective = false; HasSingleParameterDotFile = false; PrivateGlobalPrefix = "L"; // Prefix for private global symbols diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp index 8e0ac23..a0e3eba 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp @@ -32,6 +32,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { AlignmentIsInBytes = false; COMMDirectiveAlignmentIsInBytes = false; + LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment; InlineAsmStart = " InlineAsm Start"; InlineAsmEnd = " InlineAsm End"; diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp index 373df4b..17a6323 100644 --- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp +++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp @@ -166,7 +166,7 @@ public: /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - /// @param Size - The alignment of the common symbol in bytes. + /// @param ByteAlignment - The alignment of the common symbol in bytes. virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); @@ -251,6 +251,7 @@ public: virtual void EmitPad(int64_t Offset); virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool); + virtual void EmitTCEntry(const MCSymbol &S); virtual void EmitInstruction(const MCInst &Inst); @@ -517,13 +518,19 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, /// @param Size - The size of the common symbol. 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; + switch (MAI.getLCOMMDirectiveAlignmentType()) { + case LCOMM::NoAlignment: + llvm_unreachable("alignment not supported on .lcomm!"); + case LCOMM::ByteAlignment: + OS << ',' << ByteAlign; + break; + case LCOMM::Log2Alignment: + assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2"); + OS << ',' << Log2_32(ByteAlign); + break; + } } EmitEOL(); } @@ -1293,6 +1300,14 @@ void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 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() && "Cannot emit contents before setting section!"); diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp index 05519b5..726ec5a 100644 --- a/contrib/llvm/lib/MC/MCAssembler.cpp +++ b/contrib/llvm/lib/MC/MCAssembler.cpp @@ -199,8 +199,7 @@ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS_) : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), - OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false) -{ + OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false) { } MCAssembler::~MCAssembler() { @@ -325,6 +324,12 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCAlignFragment &AF = cast<MCAlignFragment>(F); unsigned Offset = Layout.getFragmentOffset(&AF); unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); + // If we are padding with nops, force the padding to be larger than the + // minimum nop size. + if (Size > 0 && AF.hasEmitNops()) { + while (Size % getBackend().getMinimumNopSize()) + Size += AF.getAlignment(); + } if (Size > AF.getMaxBytesToEmit()) return 0; return Size; @@ -375,7 +380,7 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) { LastValidFragment[F->getParent()] = F; } -/// WriteFragmentData - Write the \arg F data to the output file. +/// WriteFragmentData - Write the \p F data to the output file. static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment &F) { MCObjectWriter *OW = &Asm.getWriter(); @@ -527,7 +532,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, } uint64_t Start = getWriter().getStream().tell(); - (void) Start; + (void)Start; for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end(); it != ie; ++it) @@ -824,6 +829,7 @@ raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCFragment::dump() { raw_ostream &OS = llvm::errs(); @@ -964,6 +970,7 @@ void MCAssembler::dump() { } OS << "]>\n"; } +#endif // anchors for MC*Fragment vtables void MCDataFragment::anchor() { } diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp index b5b14b9..477bd17 100644 --- a/contrib/llvm/lib/MC/MCContext.cpp +++ b/contrib/llvm/lib/MC/MCContext.cpp @@ -153,6 +153,12 @@ MCSymbol *MCContext::LookupSymbol(StringRef Name) const { return Symbols.lookup(Name); } +MCSymbol *MCContext::LookupSymbol(const Twine &Name) const { + SmallString<128> NameSV; + Name.toVector(NameSV); + return LookupSymbol(NameSV.str()); +} + //===----------------------------------------------------------------------===// // Section Management //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp index 35f675d..5189c9da 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp @@ -184,3 +184,17 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, } llvm_unreachable("Invalid DecodeStatus!"); } + +// +// LLVMSetDisasmOptions() sets the disassembler's options. It returns 1 if it +// can set all the Options and 0 otherwise. +// +int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){ + if (Options & LLVMDisassembler_Option_UseMarkup){ + LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; + MCInstPrinter *IP = DC->getIP(); + IP->setUseMarkup(1); + Options &= ~LLVMDisassembler_Option_UseMarkup; + } + return (Options == 0); +} diff --git a/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp index 1226f1a..eed7a77 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/EDDisassembler.cpp @@ -366,8 +366,9 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, instName = OpcodeToken.getString(); instLoc = OpcodeToken.getLoc(); + ParseInstructionInfo Info; if (NextToken.isNot(AsmToken::Eof) && - TargetParser->ParseInstruction(instName, instLoc, operands)) + TargetParser->ParseInstruction(Info, instName, instLoc, operands)) ret = -1; } else { ret = -1; diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp index 4c63e43..f71b266 100644 --- a/contrib/llvm/lib/MC/MCDwarf.cpp +++ b/contrib/llvm/lib/MC/MCDwarf.cpp @@ -425,9 +425,11 @@ void MCDwarfFile::print(raw_ostream &OS) const { OS << '"' << getName() << '"'; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCDwarfFile::dump() const { print(dbgs()); } +#endif // Utility function to write a tuple for .debug_abbrev. static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) { diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp index 6eb6914..74cd042 100644 --- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -9,6 +9,8 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCValue.h" using namespace llvm; @@ -35,6 +37,12 @@ const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm, return NULL; } +const MCSymbol *MCELFObjectTargetWriter::undefinedExplicitRelSym(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel) const { + const MCSymbol &Symbol = Target.getSymA()->getSymbol(); + return &Symbol.AliasedSymbol(); +} void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp index 2d342dc..14fbc1e 100644 --- a/contrib/llvm/lib/MC/MCELFStreamer.cpp +++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp @@ -98,17 +98,13 @@ public: uint64_t Size, unsigned ByteAlignment = 0) { llvm_unreachable("ELF doesn't support this directive"); } - virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, - unsigned ValueSize = 1, - unsigned MaxBytesToEmit = 0); - virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit = 0); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace); virtual void EmitFileDirective(StringRef Filename); + virtual void EmitTCEntry(const MCSymbol &S); + virtual void FinishImpl(); private: @@ -247,7 +243,6 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, switch (Attribute) { case MCSA_LazyReference: case MCSA_Reference: - case MCSA_NoDeadStrip: case MCSA_SymbolResolver: case MCSA_PrivateExtern: case MCSA_WeakDefinition: @@ -256,6 +251,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_IndirectSymbol: llvm_unreachable("Invalid symbol attribute for ELF!"); + case MCSA_NoDeadStrip: case MCSA_ELF_TypeGnuUniqueObject: // Ignore for now. break; @@ -355,42 +351,6 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); -} - -void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, - int64_t Value, unsigned ValueSize, - unsigned MaxBytesToEmit) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, - getCurrentSectionData()); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - -void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, - getCurrentSectionData()); - F->setEmitNops(true); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { fixSymbolsInTLSFixups(Value); @@ -511,6 +471,12 @@ void MCELFStreamer::FinishImpl() { this->MCObjectStreamer::FinishImpl(); } +void MCELFStreamer::EmitTCEntry(const MCSymbol &S) +{ + // Creates a R_PPC64_TOC relocation + MCObjectStreamer::EmitSymbolValue(&S, 8, 0); +} + MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack) { diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp index 0eb7fcc..e033634 100644 --- a/contrib/llvm/lib/MC/MCExpr.cpp +++ b/contrib/llvm/lib/MC/MCExpr.cpp @@ -60,7 +60,8 @@ void MCExpr::print(raw_ostream &OS) const { SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF || SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF || SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF || - SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1) + SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1 || + SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2) OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); else if (SRE.getKind() != MCSymbolRefExpr::VK_None && SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 && @@ -136,10 +137,12 @@ void MCExpr::print(raw_ostream &OS) const { llvm_unreachable("Invalid expression kind!"); } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCExpr::dump() const { print(dbgs()); dbgs() << '\n'; } +#endif /* *** */ @@ -197,7 +200,9 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_ARM_GOTTPOFF: return "(gottpoff)"; case VK_ARM_TLSGD: return "(tlsgd)"; case VK_ARM_TARGET1: return "(target1)"; - case VK_PPC_TOC: return "toc"; + case VK_ARM_TARGET2: return "(target2)"; + case VK_PPC_TOC: return "tocbase"; + case VK_PPC_TOC_ENTRY: return "toc"; case VK_PPC_DARWIN_HA16: return "ha16"; case VK_PPC_DARWIN_LO16: return "lo16"; case VK_PPC_GAS_HA16: return "ha"; @@ -264,7 +269,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { /* *** */ -void MCTargetExpr::Anchor() {} +void MCTargetExpr::anchor() {} /* *** */ diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp index 7bbfd2e..124cc14 100644 --- a/contrib/llvm/lib/MC/MCInst.cpp +++ b/contrib/llvm/lib/MC/MCInst.cpp @@ -32,10 +32,12 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << ">"; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCOperand::dump() const { print(dbgs(), 0); dbgs() << "\n"; } +#endif void MCInst::print(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << "<MCInst " << getOpcode(); @@ -62,7 +64,9 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI, OS << ">"; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCInst::dump() const { print(dbgs(), 0); dbgs() << "\n"; } +#endif diff --git a/contrib/llvm/lib/MC/MCInstPrinter.cpp b/contrib/llvm/lib/MC/MCInstPrinter.cpp index 847bcc0..41d90ab 100644 --- a/contrib/llvm/lib/MC/MCInstPrinter.cpp +++ b/contrib/llvm/lib/MC/MCInstPrinter.cpp @@ -36,3 +36,17 @@ void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) { OS << " " << MAI.getCommentString() << " " << Annot; } } + +/// Utility functions to make adding mark ups simpler. +StringRef MCInstPrinter::markup(StringRef s) const { + if (getUseMarkup()) + return s; + else + return ""; +} +StringRef MCInstPrinter::markup(StringRef a, StringRef b) const { + if (getUseMarkup()) + return a; + else + return b; +} diff --git a/contrib/llvm/lib/MC/MCLabel.cpp b/contrib/llvm/lib/MC/MCLabel.cpp index 9c0fc92..1d3022a 100644 --- a/contrib/llvm/lib/MC/MCLabel.cpp +++ b/contrib/llvm/lib/MC/MCLabel.cpp @@ -16,6 +16,8 @@ void MCLabel::print(raw_ostream &OS) const { OS << '"' << getInstance() << '"'; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCLabel::dump() const { print(dbgs()); } +#endif diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp index b75fe2c..04b0e86 100644 --- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp +++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp @@ -70,19 +70,11 @@ public: llvm_unreachable("macho doesn't support this directive"); } virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { - llvm_unreachable("macho doesn't support this directive"); - } + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, uint64_t Size = 0, unsigned ByteAlignment = 0); virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0); - virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, - unsigned ValueSize = 1, - unsigned MaxBytesToEmit = 0); - virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit = 0); virtual void EmitFileDirective(StringRef Filename) { // FIXME: Just ignore the .file; it isn't important enough to fail the @@ -141,6 +133,8 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { } void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { + if (!getAssembler().getBackend().hasDataInCodeSupport()) + return; // Create a temporary label to mark the start of the data region. MCSymbol *Start = getContext().CreateTempSymbol(); EmitLabel(Start); @@ -151,6 +145,8 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { } void MCMachOStreamer::EmitDataRegionEnd() { + if (!getAssembler().getBackend().hasDataInCodeSupport()) + return; std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); assert(Regions.size() && "Mismatched .end_data_region!"); DataRegionData &Data = Regions.back(); @@ -325,6 +321,15 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, SD.setCommon(Size, ByteAlignment); } +void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + // '.lcomm' is equivalent to '.zerofill'. + return EmitZerofill(getContext().getMachOSection("__DATA", "__bss", + MCSectionMachO::S_ZEROFILL, + 0, SectionKind::getBSS()), + Symbol, Size, ByteAlignment); +} + void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section); @@ -361,42 +366,6 @@ void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, return; } -void MCMachOStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); -} - -void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment, - int64_t Value, unsigned ValueSize, - unsigned MaxBytesToEmit) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, - getCurrentSectionData()); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - -void MCMachOStreamer::EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit) { - // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into - // MCObjectStreamer. - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, - getCurrentSectionData()); - F->setEmitNops(true); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { MCDataFragment *DF = getOrCreateDataFragment(); diff --git a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp index 29b4a94..2e1604d 100644 --- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp @@ -392,6 +392,18 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { DwarfMacroInfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0, SectionKind::getMetadata()); + DwarfAccelNamesSection = + Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfAccelObjCSection = + Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfAccelNamespaceSection = + Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfAccelTypesSection = + Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); } @@ -430,12 +442,20 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { } - StaticDtorSection = - Ctx->getCOFFSection(".dtors", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); + if (T.getOS() == Triple::Win32) { + StaticDtorSection = + Ctx->getCOFFSection(".CRT$XTX", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); + } else { + StaticDtorSection = + Ctx->getCOFFSection(".dtors", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + } // FIXME: We're emitting LSDA info into a readonly section on COFF, even // though it contains relocatable pointers. In PIC mode, this is probably a @@ -557,6 +577,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, Env = IsMachO; InitMachOMCObjectFileInfo(T); } else if ((Arch == Triple::x86 || Arch == Triple::x86_64) && + (T.getEnvironment() != Triple::ELF) && (T.getOS() == Triple::MinGW32 || T.getOS() == Triple::Cygwin || T.getOS() == Triple::Win32)) { Env = IsCOFF; diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp index bad7cfe..7746323 100644 --- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp +++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp @@ -232,6 +232,31 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); } +void MCObjectStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { + assert(AddrSpace == 0 && "Address space must be 0!"); + getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); +} + +void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, + int64_t Value, + unsigned ValueSize, + unsigned MaxBytesToEmit) { + if (MaxBytesToEmit == 0) + MaxBytesToEmit = ByteAlignment; + new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, + getCurrentSectionData()); + + // Update the maximum alignment on the current section if necessary. + if (ByteAlignment > getCurrentSectionData()->getAlignment()) + getCurrentSectionData()->setAlignment(ByteAlignment); +} + +void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, + unsigned MaxBytesToEmit) { + EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit); + cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true); +} + bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { int64_t Res; @@ -258,12 +283,26 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->addFixup(MCFixup::Create(DF->getContents().size(), - Value, - FK_GPRel_4)); + DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } +// Associate GPRel32 fixup with data and resize data area +void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + + DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); + DF->getContents().resize(DF->getContents().size() + 8, 0); +} + +void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, + unsigned AddrSpace) { + assert(AddrSpace == 0 && "Address space must be 0!"); + // FIXME: A MCFillFragment would be more memory efficient but MCExpr has + // problems evaluating expressions across multiple fragments. + getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); +} + void MCObjectStreamer::FinishImpl() { // Dump out the dwarf file & directory tables and line tables. const MCSymbol *LineSectionSymbol = NULL; diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp index c76052d..f93f685 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -396,8 +396,17 @@ AsmToken AsmLexer::LexToken() { case 0: case ' ': case '\t': - // Ignore whitespace. - return LexToken(); + if (SkipSpace) { + // Ignore whitespace. + return LexToken(); + } else { + int len = 1; + while (*CurPtr==' ' || *CurPtr=='\t') { + CurPtr++; + len++; + } + return AsmToken(AsmToken::Space, StringRef(TokStart, len)); + } case '\n': // FALL THROUGH. case '\r': isAtStartOfLine = true; diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index b67c769..6f2e85e 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -19,6 +19,8 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/AsmCond.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -35,6 +37,8 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <cctype> +#include <set> +#include <string> #include <vector> using namespace llvm; @@ -42,12 +46,14 @@ static cl::opt<bool> FatalAssemblerWarnings("fatal-assembler-warnings", cl::desc("Consider warnings as error")); +MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {} + namespace { /// \brief Helper class for tracking macro definitions. typedef std::vector<AsmToken> MacroArgument; typedef std::vector<MacroArgument> MacroArguments; -typedef StringRef MacroParameter; +typedef std::pair<StringRef, MacroArgument> MacroParameter; typedef std::vector<MacroParameter> MacroParameters; struct Macro { @@ -80,12 +86,34 @@ public: MemoryBuffer *I); }; +//struct AsmRewrite; +struct ParseStatementInfo { + /// ParsedOperands - The parsed operands from the last parsed statement. + SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; + + /// Opcode - The opcode from the last parsed instruction. + unsigned Opcode; + + SmallVectorImpl<AsmRewrite> *AsmRewrites; + + ParseStatementInfo() : Opcode(~0U), AsmRewrites(0) {} + ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) + : Opcode(~0), AsmRewrites(rewrites) {} + + ~ParseStatementInfo() { + // Free any parsed operands. + for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) + delete ParsedOperands[i]; + ParsedOperands.clear(); + } +}; + /// \brief The concrete assembly parser instance. class AsmParser : public MCAsmParser { friend class GenericAsmParser; - AsmParser(const AsmParser &); // DO NOT IMPLEMENT - void operator=(const AsmParser &); // DO NOT IMPLEMENT + AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; + void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; private: AsmLexer Lexer; MCContext &Ctx; @@ -126,20 +154,27 @@ private: StringRef CppHashFilename; int64_t CppHashLineNumber; SMLoc CppHashLoc; + int CppHashBuf; /// AssemblerDialect. ~OU means unset value and use value provided by MAI. unsigned AssemblerDialect; + /// IsDarwin - is Darwin compatibility enabled? + bool IsDarwin; + + /// ParsingInlineAsm - Are we parsing ms-style inline assembly? + bool ParsingInlineAsm; + public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); - ~AsmParser(); + virtual ~AsmParser(); virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false); - void AddDirectiveHandler(MCAsmParserExtension *Object, - StringRef Directive, - DirectiveHandler Handler) { + virtual void AddDirectiveHandler(MCAsmParserExtension *Object, + StringRef Directive, + DirectiveHandler Handler) { DirectiveMap[Directive] = std::make_pair(Object, Handler); } @@ -166,7 +201,19 @@ public: virtual bool Error(SMLoc L, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()); - const AsmToken &Lex(); + virtual const AsmToken &Lex(); + + void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; } + bool isParsingInlineAsm() { return ParsingInlineAsm; } + + bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, + unsigned &NumOutputs, unsigned &NumInputs, + SmallVectorImpl<std::pair<void *,bool> > &OpDecls, + SmallVectorImpl<std::string> &Constraints, + SmallVectorImpl<std::string> &Clobbers, + const MCInstrInfo *MII, + const MCInstPrinter *IP, + MCAsmParserSemaCallback &SI); bool ParseExpression(const MCExpr *&Res); virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc); @@ -178,7 +225,7 @@ public: private: void CheckForValidSection(); - bool ParseStatement(); + bool ParseStatement(ParseStatementInfo &Info); void EatToEndOfLine(); bool ParseCppHashLineFilenameComment(const SMLoc &L); @@ -202,26 +249,28 @@ private: /// This returns true on failure. bool ProcessIncbinFile(const std::string &Filename); - /// \brief Reset the current lexer position to that given by \arg Loc. The + /// \brief Reset the current lexer position to that given by \p Loc. The /// current token is not set; clients should ensure Lex() is called /// subsequently. void JumpToLoc(SMLoc Loc); - void EatToEndOfStatement(); + virtual void EatToEndOfStatement(); - bool ParseMacroArgument(MacroArgument &MA); + bool ParseMacroArgument(MacroArgument &MA, + AsmToken::TokenKind &ArgumentDelimiter); bool ParseMacroArguments(const Macro *M, MacroArguments &A); /// \brief Parse up to the end of statement and a return the contents from the /// current token until the end of the statement; the current token on exit /// will be either the EndOfStatement or EOF. - StringRef ParseStringToEndOfStatement(); + virtual StringRef ParseStringToEndOfStatement(); /// \brief Parse until the end of a statement or a comma is encountered, /// return the contents from the current token up to the end or comma. StringRef ParseStringToComma(); - bool ParseAssignment(StringRef Name, bool allow_redef); + bool ParseAssignment(StringRef Name, bool allow_redef, + bool NoDeadStrip = false); bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc); bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); @@ -229,8 +278,8 @@ private: bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); /// ParseIdentifier - Parse an identifier or string (as a quoted identifier) - /// and set \arg Res to the identifier contents. - bool ParseIdentifier(StringRef &Res); + /// and set \p Res to the identifier contents. + virtual bool ParseIdentifier(StringRef &Res); // Directive Parsing. @@ -282,6 +331,9 @@ private: bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp" bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc" bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr" + + // "_emit" + bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info); }; /// \brief Generic implementations of directive handling, etc. which is shared @@ -406,8 +458,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, const MCAsmInfo &_MAI) : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), GenericParser(new GenericAsmParser), PlatformParser(0), - CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0), - AssemblerDialect(~0U) { + CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0), + AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); SavedDiagContext = SrcMgr.getDiagContext(); @@ -428,6 +480,7 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, } else if (_MAI.hasSubsectionsViaSymbols()) { PlatformParser = createDarwinAsmParser(); PlatformParser->Initialize(*this); + IsDarwin = true; } else { PlatformParser = createELFAsmParser(); PlatformParser->Initialize(*this); @@ -545,7 +598,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // While we have input, parse each statement. while (Lexer.isNot(AsmToken::Eof)) { - if (!ParseStatement()) continue; + ParseStatementInfo Info; + if (!ParseStatement(Info)) continue; // We had an error, validate that one was emitted and recover by skipping to // the next line. @@ -598,7 +652,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { } void AsmParser::CheckForValidSection() { - if (!getStreamer().getCurrentSection()) { + if (!ParsingInlineAsm && !getStreamer().getCurrentSection()) { TokError("expected section directive before assembly directive"); Out.SwitchSection(Ctx.getMachOSection( "__TEXT", "__text", @@ -1024,14 +1078,11 @@ bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, } } - - - /// ParseStatement: /// ::= EndOfStatement /// ::= Label* Directive ...Operands... EndOfStatement /// ::= Label* Identifier OperandList* EndOfStatement -bool AsmParser::ParseStatement() { +bool AsmParser::ParseStatement(ParseStatementInfo &Info) { if (Lexer.is(AsmToken::EndOfStatement)) { Out.AddBlankLine(); Lex(); @@ -1150,7 +1201,7 @@ bool AsmParser::ParseStatement() { return false; } - return ParseStatement(); + return false; } case AsmToken::Equal: @@ -1304,26 +1355,30 @@ bool AsmParser::ParseStatement() { return Error(IDLoc, "unknown directive"); } + // _emit + if (ParsingInlineAsm && IDVal == "_emit") + return ParseDirectiveEmit(IDLoc, Info); + CheckForValidSection(); // Canonicalize the opcode to lower case. - SmallString<128> Opcode; + SmallString<128> OpcodeStr; for (unsigned i = 0, e = IDVal.size(); i != e; ++i) - Opcode.push_back(tolower(IDVal[i])); + OpcodeStr.push_back(tolower(IDVal[i])); - SmallVector<MCParsedAsmOperand*, 8> ParsedOperands; - bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc, - ParsedOperands); + ParseInstructionInfo IInfo(Info.AsmRewrites); + bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr.str(), + IDLoc,Info.ParsedOperands); // Dump the parsed representation, if requested. if (getShowParsedOperands()) { SmallString<256> Str; raw_svector_ostream OS(Str); OS << "parsed instruction: ["; - for (unsigned i = 0; i != ParsedOperands.size(); ++i) { + for (unsigned i = 0; i != Info.ParsedOperands.size(); ++i) { if (i != 0) OS << ", "; - ParsedOperands[i]->print(OS); + Info.ParsedOperands[i]->print(OS); } OS << "]"; @@ -1335,21 +1390,38 @@ bool AsmParser::ParseStatement() { // the instruction. if (!HadError && getContext().getGenDwarfForAssembly() && getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) { + + unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer); + + // If we previously parsed a cpp hash file line comment then make sure the + // current Dwarf File is for the CppHashFilename if not then emit the + // Dwarf File table for it and adjust the line number for the .loc. + const std::vector<MCDwarfFile *> &MCDwarfFiles = + getContext().getMCDwarfFiles(); + if (CppHashFilename.size() != 0) { + if(MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() != + CppHashFilename) + getStreamer().EmitDwarfFileDirective( + getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename); + + unsigned CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc,CppHashBuf); + Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); + } + getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(), - SrcMgr.FindLineNumber(IDLoc, CurBuffer), - 0, DWARF2_LINE_DEFAULT_IS_STMT ? + Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0, 0, 0, StringRef()); } // If parsing succeeded, match the instruction. - if (!HadError) - HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, ParsedOperands, - Out); - - // Free any parsed operands. - for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i) - delete ParsedOperands[i]; + if (!HadError) { + unsigned ErrorInfo; + HadError = getTargetParser().MatchAndEmitInstruction(IDLoc, Info.Opcode, + Info.ParsedOperands, + Out, ErrorInfo, + ParsingInlineAsm); + } // Don't skip the rest of the line, the instruction parser is responsible for // that. @@ -1394,6 +1466,7 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { CppHashLoc = L; CppHashFilename = Filename; CppHashLineNumber = LineNumber; + CppHashBuf = CurBuffer; // Ignore any trailing characters, they're just comment. EatToEndOfLine(); @@ -1454,6 +1527,14 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { NewDiag.print(0, OS); } +// FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The +// difference being that that function accepts '@' as part of identifiers and +// we can't do that. AsmLexer.cpp should probably be changed to handle +// '@' as a special case when needed. +static bool isIdentifierChar(char c) { + return isalnum(c) || c == '_' || c == '$' || c == '.'; +} + bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, const MacroParameters &Parameters, const MacroArguments &A, @@ -1462,6 +1543,8 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, if (NParameters != 0 && NParameters != A.size()) return Error(L, "Wrong number of arguments"); + // A macro without parameters is handled differently on Darwin: + // gas accepts no arguments and does no substitutions while (!Body.empty()) { // Scan for the next substitution. std::size_t End = Body.size(), Pos = 0; @@ -1518,25 +1601,33 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, Pos += 2; } else { unsigned I = Pos + 1; - while (isalnum(Body[I]) && I + 1 != End) + while (isIdentifierChar(Body[I]) && I + 1 != End) ++I; const char *Begin = Body.data() + Pos +1; StringRef Argument(Begin, I - (Pos +1)); unsigned Index = 0; for (; Index < NParameters; ++Index) - if (Parameters[Index] == Argument) + if (Parameters[Index].first == Argument) break; - // FIXME: We should error at the macro definition. - if (Index == NParameters) - return Error(L, "Parameter not found"); - - for (MacroArgument::const_iterator it = A[Index].begin(), - ie = A[Index].end(); it != ie; ++it) - OS << it->getString(); + if (Index == NParameters) { + if (Body[Pos+1] == '(' && Body[Pos+2] == ')') + Pos += 3; + else { + OS << '\\' << Argument; + Pos = I; + } + } else { + for (MacroArgument::const_iterator it = A[Index].begin(), + ie = A[Index].end(); it != ie; ++it) + if (it->getKind() == AsmToken::String) + OS << it->getStringContents(); + else + OS << it->getString(); - Pos += 1 + Argument.size(); + Pos += 1 + Argument.size(); + } } // Update the scan point. Body = Body.substr(Pos); @@ -1551,24 +1642,97 @@ MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL, SMLoc EL, { } +static bool IsOperator(AsmToken::TokenKind kind) +{ + switch (kind) + { + default: + return false; + case AsmToken::Plus: + case AsmToken::Minus: + case AsmToken::Tilde: + case AsmToken::Slash: + case AsmToken::Star: + case AsmToken::Dot: + case AsmToken::Equal: + case AsmToken::EqualEqual: + case AsmToken::Pipe: + case AsmToken::PipePipe: + case AsmToken::Caret: + case AsmToken::Amp: + case AsmToken::AmpAmp: + case AsmToken::Exclaim: + case AsmToken::ExclaimEqual: + case AsmToken::Percent: + case AsmToken::Less: + case AsmToken::LessEqual: + case AsmToken::LessLess: + case AsmToken::LessGreater: + case AsmToken::Greater: + case AsmToken::GreaterEqual: + case AsmToken::GreaterGreater: + return true; + } +} + /// ParseMacroArgument - Extract AsmTokens for a macro argument. /// This is used for both default macro parameter values and the /// arguments in macro invocations -bool AsmParser::ParseMacroArgument(MacroArgument &MA) { +bool AsmParser::ParseMacroArgument(MacroArgument &MA, + AsmToken::TokenKind &ArgumentDelimiter) { unsigned ParenLevel = 0; + unsigned AddTokens = 0; - for (;;) { - SMLoc LastTokenLoc; + // gas accepts arguments separated by whitespace, except on Darwin + if (!IsDarwin) + Lexer.setSkipSpace(false); - if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) + for (;;) { + if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) { + Lexer.setSkipSpace(true); return TokError("unexpected token in macro instantiation"); + } + + if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) { + // Spaces and commas cannot be mixed to delimit parameters + if (ArgumentDelimiter == AsmToken::Eof) + ArgumentDelimiter = AsmToken::Comma; + else if (ArgumentDelimiter != AsmToken::Comma) { + Lexer.setSkipSpace(true); + return TokError("expected ' ' for macro argument separator"); + } + break; + } + + if (Lexer.is(AsmToken::Space)) { + Lex(); // Eat spaces + + // Spaces can delimit parameters, but could also be part an expression. + // If the token after a space is an operator, add the token and the next + // one into this argument + if (ArgumentDelimiter == AsmToken::Space || + ArgumentDelimiter == AsmToken::Eof) { + if (IsOperator(Lexer.getKind())) { + // Check to see whether the token is used as an operator, + // or part of an identifier + const char *NextChar = getTok().getEndLoc().getPointer() + 1; + if (*NextChar == ' ') + AddTokens = 2; + } + + if (!AddTokens && ParenLevel == 0) { + if (ArgumentDelimiter == AsmToken::Eof && + !IsOperator(Lexer.getKind())) + ArgumentDelimiter = AsmToken::Space; + break; + } + } + } // HandleMacroEntry relies on not advancing the lexer here // to be able to fill in the remaining default parameter values if (Lexer.is(AsmToken::EndOfStatement)) break; - if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) - break; // Adjust the current parentheses level. if (Lexer.is(AsmToken::LParen)) @@ -1578,16 +1742,23 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA) { // Append the token to the current argument list. MA.push_back(getTok()); + if (AddTokens) + AddTokens--; Lex(); } + + Lexer.setSkipSpace(true); if (ParenLevel != 0) - return TokError("unbalanced parenthesises in macro argument"); + return TokError("unbalanced parentheses in macro argument"); return false; } // Parse the macro instantiation arguments. bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) { const unsigned NParameters = M ? M->Parameters.size() : 0; + // Argument delimiter is initially unknown. It will be set by + // ParseMacroArgument() + AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; // Parse two kinds of macro invocations: // - macros defined without any parameters accept an arbitrary number of them @@ -1596,13 +1767,30 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) { ++Parameter) { MacroArgument MA; - if (ParseMacroArgument(MA)) + if (ParseMacroArgument(MA, ArgumentDelimiter)) return true; - A.push_back(MA); + if (!MA.empty() || !NParameters) + A.push_back(MA); + else if (NParameters) { + if (!M->Parameters[Parameter].second.empty()) + A.push_back(M->Parameters[Parameter].second); + } - if (Lexer.is(AsmToken::EndOfStatement)) + // At the end of the statement, fill in remaining arguments that have + // default values. If there aren't any, then the next argument is + // required but missing + if (Lexer.is(AsmToken::EndOfStatement)) { + if (NParameters && Parameter < NParameters - 1) { + if (M->Parameters[Parameter + 1].second.empty()) + return TokError("macro argument '" + + Twine(M->Parameters[Parameter + 1].first) + + "' is missing"); + else + continue; + } return false; + } if (Lexer.is(AsmToken::Comma)) Lex(); @@ -1691,7 +1879,8 @@ static bool IsUsedIn(const MCSymbol *Sym, const MCExpr *Value) { llvm_unreachable("Unknown expr kind!"); } -bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) { +bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef, + bool NoDeadStrip) { // FIXME: Use better location, we should use proper tokens. SMLoc EqualLoc = Lexer.getLoc(); @@ -1746,6 +1935,9 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) { // Do the assignment. Out.EmitAssignment(Sym, Value); + if (NoDeadStrip) + Out.EmitSymbolAttribute(Sym, MCSA_NoDeadStrip); + return false; } @@ -1803,7 +1995,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) { return TokError("unexpected token in '" + Twine(IDVal) + "'"); Lex(); - return ParseAssignment(Name, allow_redef); + return ParseAssignment(Name, allow_redef, true); } bool AsmParser::ParseEscapedString(std::string &Data) { @@ -2274,8 +2466,13 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { if (ParseAbsoluteExpression(Pow2Alignment)) return true; + LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType(); + if (IsLocal && LCOMM == LCOMM::NoAlignment) + return Error(Pow2AlignmentLoc, "alignment not supported on this target"); + // If this target takes alignments in bytes (not log) validate and convert. - if (Lexer.getMAI().getAlignmentIsInBytes()) { + if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) || + (IsLocal && LCOMM == LCOMM::ByteAlignment)) { if (!isPowerOf2_64(Pow2Alignment)) return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); Pow2Alignment = Log2_64(Pow2Alignment); @@ -2303,13 +2500,9 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { if (!Sym->isUndefined()) return Error(IDLoc, "invalid symbol redefinition"); - // '.lcomm' is equivalent to '.zerofill'. // Create the Symbol as a common or local common with Size and Pow2Alignment if (IsLocal) { - getStreamer().EmitZerofill(Ctx.getMachOSection( - "__DATA", "__bss", MCSectionMachO::S_ZEROFILL, - 0, SectionKind::getBSS()), - Sym, Size, 1 << Pow2Alignment); + getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); return false; } @@ -3073,25 +3266,33 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive, SMLoc DirectiveLoc) { StringRef Name; if (getParser().ParseIdentifier(Name)) - return TokError("expected identifier in directive"); + return TokError("expected identifier in '.macro' directive"); MacroParameters Parameters; + // Argument delimiter is initially unknown. It will be set by + // ParseMacroArgument() + AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof; if (getLexer().isNot(AsmToken::EndOfStatement)) { - for(;;) { - StringRef Parameter; - if (getParser().ParseIdentifier(Parameter)) - return TokError("expected identifier in directive"); + for (;;) { + MacroParameter Parameter; + if (getParser().ParseIdentifier(Parameter.first)) + return TokError("expected identifier in '.macro' directive"); + + if (getLexer().is(AsmToken::Equal)) { + Lex(); + if (getParser().ParseMacroArgument(Parameter.second, ArgumentDelimiter)) + return true; + } + Parameters.push_back(Parameter); - if (getLexer().isNot(AsmToken::Comma)) + if (getLexer().is(AsmToken::Comma)) + Lex(); + else if (getLexer().is(AsmToken::EndOfStatement)) break; - Lex(); } } - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in '.macro' directive"); - // Eat the end of statement. Lex(); @@ -3296,7 +3497,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { MacroParameters Parameters; MacroParameter Parameter; - if (ParseIdentifier(Parameter)) + if (ParseIdentifier(Parameter.first)) return TokError("expected identifier in '.irp' directive"); Parameters.push_back(Parameter); @@ -3323,9 +3524,8 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) { SmallString<256> Buf; raw_svector_ostream OS(Buf); - for (std::vector<MacroArgument>::iterator i = A.begin(), e = A.end(); i != e; - ++i) { - std::vector<MacroArgument> Args; + for (MacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { + MacroArguments Args; Args.push_back(*i); if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc())) @@ -3343,7 +3543,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { MacroParameters Parameters; MacroParameter Parameter; - if (ParseIdentifier(Parameter)) + if (ParseIdentifier(Parameter.first)) return TokError("expected identifier in '.irpc' directive"); Parameters.push_back(Parameter); @@ -3393,7 +3593,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) { bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { if (ActiveMacros.empty()) - return TokError("unexpected '.endr' directive, no current .rept"); + return TokError("unmatched '.endr' directive"); // The only .repl that should get here are the ones created by // InstantiateMacroLikeBody. @@ -3403,6 +3603,214 @@ bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) { return false; } +bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) { + const MCExpr *Value; + SMLoc ExprLoc = getLexer().getLoc(); + if (ParseExpression(Value)) + return true; + const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value); + if (!MCE) + return Error(ExprLoc, "unexpected expression in _emit"); + uint64_t IntValue = MCE->getValue(); + if (!isUIntN(8, IntValue) && !isIntN(8, IntValue)) + return Error(ExprLoc, "literal value out of range for directive"); + + Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, 5)); + return false; +} + +bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString, + unsigned &NumOutputs, unsigned &NumInputs, + SmallVectorImpl<std::pair<void *, bool> > &OpDecls, + SmallVectorImpl<std::string> &Constraints, + SmallVectorImpl<std::string> &Clobbers, + const MCInstrInfo *MII, + const MCInstPrinter *IP, + MCAsmParserSemaCallback &SI) { + SmallVector<void *, 4> InputDecls; + SmallVector<void *, 4> OutputDecls; + SmallVector<bool, 4> InputDeclsOffsetOf; + SmallVector<bool, 4> OutputDeclsOffsetOf; + SmallVector<std::string, 4> InputConstraints; + SmallVector<std::string, 4> OutputConstraints; + std::set<std::string> ClobberRegs; + + SmallVector<struct AsmRewrite, 4> AsmStrRewrites; + + // Prime the lexer. + Lex(); + + // While we have input, parse each statement. + unsigned InputIdx = 0; + unsigned OutputIdx = 0; + while (getLexer().isNot(AsmToken::Eof)) { + ParseStatementInfo Info(&AsmStrRewrites); + if (ParseStatement(Info)) + return true; + + if (Info.Opcode != ~0U) { + const MCInstrDesc &Desc = MII->get(Info.Opcode); + + // Build the list of clobbers, outputs and inputs. + for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) { + MCParsedAsmOperand *Operand = Info.ParsedOperands[i]; + + // Immediate. + if (Operand->isImm()) { + if (Operand->needAsmRewrite()) + AsmStrRewrites.push_back(AsmRewrite(AOK_ImmPrefix, + Operand->getStartLoc())); + continue; + } + + // Register operand. + if (Operand->isReg() && !Operand->isOffsetOf()) { + unsigned NumDefs = Desc.getNumDefs(); + // Clobber. + if (NumDefs && Operand->getMCOperandNum() < NumDefs) { + std::string Reg; + raw_string_ostream OS(Reg); + IP->printRegName(OS, Operand->getReg()); + ClobberRegs.insert(StringRef(OS.str())); + } + continue; + } + + // Expr/Input or Output. + unsigned Size; + void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc, + Size); + if (OpDecl) { + bool isOutput = (i == 1) && Desc.mayStore(); + if (!Operand->isOffsetOf() && Operand->needSizeDirective()) + AsmStrRewrites.push_back(AsmRewrite(AOK_SizeDirective, + Operand->getStartLoc(), + /*Len*/0, + Operand->getMemSize())); + if (isOutput) { + std::string Constraint = "="; + ++InputIdx; + OutputDecls.push_back(OpDecl); + OutputDeclsOffsetOf.push_back(Operand->isOffsetOf()); + Constraint += Operand->getConstraint().str(); + OutputConstraints.push_back(Constraint); + AsmStrRewrites.push_back(AsmRewrite(AOK_Output, + Operand->getStartLoc(), + Operand->getNameLen())); + } else { + InputDecls.push_back(OpDecl); + InputDeclsOffsetOf.push_back(Operand->isOffsetOf()); + InputConstraints.push_back(Operand->getConstraint().str()); + AsmStrRewrites.push_back(AsmRewrite(AOK_Input, + Operand->getStartLoc(), + Operand->getNameLen())); + } + } + } + } + } + + // Set the number of Outputs and Inputs. + NumOutputs = OutputDecls.size(); + NumInputs = InputDecls.size(); + + // Set the unique clobbers. + for (std::set<std::string>::iterator I = ClobberRegs.begin(), + E = ClobberRegs.end(); I != E; ++I) + Clobbers.push_back(*I); + + // Merge the various outputs and inputs. Output are expected first. + if (NumOutputs || NumInputs) { + unsigned NumExprs = NumOutputs + NumInputs; + OpDecls.resize(NumExprs); + Constraints.resize(NumExprs); + // FIXME: Constraints are hard coded to 'm', but we need an 'r' + // constraint for offsetof. This needs to be cleaned up! + for (unsigned i = 0; i < NumOutputs; ++i) { + OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsOffsetOf[i]); + Constraints[i] = OutputDeclsOffsetOf[i] ? "=r" : OutputConstraints[i]; + } + for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) { + OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsOffsetOf[i]); + Constraints[j] = InputDeclsOffsetOf[i] ? "r" : InputConstraints[i]; + } + } + + // Build the IR assembly string. + std::string AsmStringIR; + AsmRewriteKind PrevKind = AOK_Imm; + raw_string_ostream OS(AsmStringIR); + const char *Start = SrcMgr.getMemoryBuffer(0)->getBufferStart(); + for (SmallVectorImpl<struct AsmRewrite>::iterator + I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) { + const char *Loc = (*I).Loc.getPointer(); + + AsmRewriteKind Kind = (*I).Kind; + + // Emit everything up to the immediate/expression. If the previous rewrite + // was a size directive, then this has already been done. + if (PrevKind != AOK_SizeDirective) + OS << StringRef(Start, Loc - Start); + PrevKind = Kind; + + // Skip the original expression. + if (Kind == AOK_Skip) { + Start = Loc + (*I).Len; + continue; + } + + // Rewrite expressions in $N notation. + switch (Kind) { + default: break; + case AOK_Imm: + OS << Twine("$$"); + OS << (*I).Val; + break; + case AOK_ImmPrefix: + OS << Twine("$$"); + break; + case AOK_Input: + OS << '$'; + OS << InputIdx++; + break; + case AOK_Output: + OS << '$'; + OS << OutputIdx++; + break; + case AOK_SizeDirective: + switch((*I).Val) { + default: break; + case 8: OS << "byte ptr "; break; + case 16: OS << "word ptr "; break; + case 32: OS << "dword ptr "; break; + case 64: OS << "qword ptr "; break; + case 80: OS << "xword ptr "; break; + case 128: OS << "xmmword ptr "; break; + case 256: OS << "ymmword ptr "; break; + } + break; + case AOK_Emit: + OS << ".byte"; + break; + case AOK_DotOperator: + OS << (*I).Val; + break; + } + + // Skip the original expression. + if (Kind != AOK_SizeDirective) + Start = Loc + (*I).Len; + } + + // Emit the remainder of the asm string. + const char *AsmEnd = SrcMgr.getMemoryBuffer(0)->getBufferEnd(); + if (Start != AsmEnd) + OS << StringRef(Start, AsmEnd - Start); + + AsmString = OS.str(); + return false; +} + /// \brief Create an MCAsmParser instance. MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, MCStreamer &Out, diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 9316bb1..d55de1f 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -203,7 +203,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { StringRef Name; if (getParser().ParseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);; + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp index 3a3ff14..384b341 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmLexer.cpp @@ -12,7 +12,8 @@ using namespace llvm; -MCAsmLexer::MCAsmLexer() : CurTok(AsmToken::Error, StringRef()), TokStart(0) { +MCAsmLexer::MCAsmLexer() : CurTok(AsmToken::Error, StringRef()), + TokStart(0), SkipSpace(true) { } MCAsmLexer::~MCAsmLexer() { diff --git a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp index 3a825f0..6967fee 100644 --- a/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCAsmParser.cpp @@ -44,5 +44,7 @@ bool MCAsmParser::ParseExpression(const MCExpr *&Res) { } void MCParsedAsmOperand::dump() const { +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dbgs() << " " << *this; +#endif } diff --git a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp index 6fb1ba4..60a3a3b 100644 --- a/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/MCTargetAsmParser.cpp @@ -11,7 +11,7 @@ using namespace llvm; MCTargetAsmParser::MCTargetAsmParser() - : AvailableFeatures(0) + : AvailableFeatures(0), ParsingInlineAsm(false) { } diff --git a/contrib/llvm/lib/MC/MCRegisterInfo.cpp b/contrib/llvm/lib/MC/MCRegisterInfo.cpp index 4d1aff3..5c71106 100644 --- a/contrib/llvm/lib/MC/MCRegisterInfo.cpp +++ b/contrib/llvm/lib/MC/MCRegisterInfo.cpp @@ -24,6 +24,8 @@ unsigned MCRegisterInfo::getMatchingSuperReg(unsigned Reg, unsigned SubIdx, } unsigned MCRegisterInfo::getSubReg(unsigned Reg, unsigned Idx) const { + assert(Idx && Idx < getNumSubRegIndices() && + "This is not a subregister index"); // Get a pointer to the corresponding SubRegIndices list. This list has the // name of each sub-register in the same order as MCSubRegIterator. const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices; @@ -34,6 +36,7 @@ unsigned MCRegisterInfo::getSubReg(unsigned Reg, unsigned Idx) const { } unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const { + assert(SubReg && SubReg < getNumRegs() && "This is not a register"); // Get a pointer to the corresponding SubRegIndices list. This list has the // name of each sub-register in the same order as MCSubRegIterator. const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices; diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp index 0bac24d..afece0b 100644 --- a/contrib/llvm/lib/MC/MCStreamer.cpp +++ b/contrib/llvm/lib/MC/MCStreamer.cpp @@ -561,6 +561,10 @@ void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { abort(); } +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. diff --git a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp index 05c83f7..80a1f02 100644 --- a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp @@ -19,11 +19,28 @@ using namespace llvm; MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors. +/// InitMCProcessorInfo - Set or change the CPU (optionally supplemented +/// with feature string). Recompute feature bits and scheduling model. +void +MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { + SubtargetFeatures Features(FS); + FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs, + ProcFeatures, NumFeatures); + + if (!CPU.empty()) + CPUSchedModel = getSchedModelForCPU(CPU); + else + CPUSchedModel = &MCSchedModel::DefaultSchedModel; +} + void MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, const SubtargetFeatureKV *PF, const SubtargetFeatureKV *PD, const SubtargetInfoKV *ProcSched, + const MCWriteProcResEntry *WPR, + const MCWriteLatencyEntry *WL, + const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC, const unsigned *FP, @@ -31,26 +48,18 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, TargetTriple = TT; ProcFeatures = PF; ProcDesc = PD; - ProcSchedModel = ProcSched; + ProcSchedModels = ProcSched; + WriteProcResTable = WPR; + WriteLatencyTable = WL; + ReadAdvanceTable = RA; + Stages = IS; OperandCycles = OC; ForwardingPaths = FP; NumFeatures = NF; NumProcs = NP; - SubtargetFeatures Features(FS); - FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs, - ProcFeatures, NumFeatures); -} - - -/// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with -/// feature string) and recompute feature bits. -uint64_t MCSubtargetInfo::ReInitMCSubtargetInfo(StringRef CPU, StringRef FS) { - SubtargetFeatures Features(FS); - FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs, - ProcFeatures, NumFeatures); - return FeatureBits; + InitMCProcessorInfo(CPU, FS); } /// ToggleFeature - Toggle a feature and returns the re-computed feature @@ -70,13 +79,13 @@ uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) { } -MCSchedModel * +const MCSchedModel * MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { - assert(ProcSchedModel && "Processor machine model not available!"); + assert(ProcSchedModels && "Processor machine model not available!"); #ifndef NDEBUG for (size_t i = 1; i < NumProcs; i++) { - assert(strcmp(ProcSchedModel[i - 1].Key, ProcSchedModel[i].Key) < 0 && + assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 && "Processor machine model table is not sorted"); } #endif @@ -85,19 +94,25 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { SubtargetInfoKV KV; KV.Key = CPU.data(); const SubtargetInfoKV *Found = - std::lower_bound(ProcSchedModel, ProcSchedModel+NumProcs, KV); - if (Found == ProcSchedModel+NumProcs || StringRef(Found->Key) != CPU) { + std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, KV); + if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) { errs() << "'" << CPU << "' is not a recognized processor for this target" << " (ignoring processor)\n"; return &MCSchedModel::DefaultSchedModel; } assert(Found->Value && "Missing processor SchedModel value"); - return (MCSchedModel *)Found->Value; + return (const MCSchedModel *)Found->Value; } InstrItineraryData MCSubtargetInfo::getInstrItineraryForCPU(StringRef CPU) const { - MCSchedModel *SchedModel = getSchedModelForCPU(CPU); + const MCSchedModel *SchedModel = getSchedModelForCPU(CPU); return InstrItineraryData(SchedModel, Stages, OperandCycles, ForwardingPaths); } + +/// Initialize an InstrItineraryData instance. +void MCSubtargetInfo::initInstrItins(InstrItineraryData &InstrItins) const { + InstrItins = + InstrItineraryData(CPUSchedModel, Stages, OperandCycles, ForwardingPaths); +} diff --git a/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp index f7f9184..b973c57 100644 --- a/contrib/llvm/lib/MC/MCSymbol.cpp +++ b/contrib/llvm/lib/MC/MCSymbol.cpp @@ -26,7 +26,7 @@ static bool isAcceptableChar(char C) { return true; } -/// NameNeedsQuoting - Return true if the identifier \arg Str needs quotes to be +/// NameNeedsQuoting - Return true if the identifier \p Str needs quotes to be /// syntactically correct. static bool NameNeedsQuoting(StringRef Str) { assert(!Str.empty() && "Cannot create an empty MCSymbol"); @@ -76,6 +76,8 @@ void MCSymbol::print(raw_ostream &OS) const { OS << '"' << getName() << '"'; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCSymbol::dump() const { print(dbgs()); } +#endif diff --git a/contrib/llvm/lib/MC/MCValue.cpp b/contrib/llvm/lib/MC/MCValue.cpp index c6ea16c..4393777 100644 --- a/contrib/llvm/lib/MC/MCValue.cpp +++ b/contrib/llvm/lib/MC/MCValue.cpp @@ -31,6 +31,8 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const { OS << " + " << getConstant(); } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCValue::dump() const { print(dbgs(), 0); } +#endif diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp index 5820a22..a94b214 100644 --- a/contrib/llvm/lib/MC/MachObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp @@ -68,6 +68,11 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD, // If this is a variable, then recursively evaluate now. if (S.isVariable()) { + if (const MCConstantExpr *C = + dyn_cast<const MCConstantExpr>(S.getVariableValue())) + return C->getValue(); + + MCValue Target; if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout)) report_fatal_error("unable to evaluate offset for variable '" + @@ -140,8 +145,8 @@ void MachObjectWriter::WriteHeader(unsigned NumLoadCommands, /// WriteSegmentLoadCommand - Write a segment load command. /// -/// \arg NumSections - The number of sections in this segment. -/// \arg SectionDataSize - The total size of the sections. +/// \param NumSections The number of sections in this segment. +/// \param SectionDataSize The total size of the sections. void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections, uint64_t VMSize, uint64_t SectionDataStartOffset, @@ -315,11 +320,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD, // Compute the symbol address. if (Symbol.isDefined()) { - if (Symbol.isAbsolute()) { - Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue(); - } else { - Address = getSymbolAddress(&Data, Layout); - } + Address = getSymbolAddress(&Data, Layout); } else if (Data.isCommon()) { // Common symbols are encoded with the size in the address // field, and their alignment in the flags. @@ -396,8 +397,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { continue; // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; + IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); Asm.getOrCreateSymbolData(*it->Symbol); } @@ -414,8 +414,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { continue; // Initialize the section indirect symbol base, if necessary. - if (!IndirectSymBase.count(it->SectionData)) - IndirectSymBase[it->SectionData] = IndirectIndex; + IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); // Set the symbol type to undefined lazy, but only on construction. // @@ -559,6 +558,26 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, } } +void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm, + const MCAsmLayout &Layout) { + for (MCAssembler::symbol_iterator i = Asm.symbol_begin(), + e = Asm.symbol_end(); + i != e; ++i) { + MCSymbolData &SD = *i; + if (!SD.getSymbol().isVariable()) + continue; + + // Is the variable is a symbol difference (SA - SB + C) expression, + // and neither symbol is external, mark the variable as absolute. + const MCExpr *Expr = SD.getSymbol().getVariableValue(); + MCValue Value; + if (Expr->EvaluateAsRelocatable(Value, Layout)) { + if (Value.getSymA() && Value.getSymB()) + const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute(); + } + } +} + void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { computeSectionAddresses(Asm, Layout); @@ -566,6 +585,10 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // Create symbol data for any indirect symbols. BindIndirectSymbols(Asm); + // Mark symbol difference expressions in variables (from .set or = directives) + // as absolute. + markAbsoluteVariableSymbols(Asm, Layout); + // Compute symbol table information and bind symbol indices. ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, UndefinedSymbolData); @@ -797,8 +820,12 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, it = Asm.data_region_begin(), ie = Asm.data_region_end(); it != ie; ++it) { const DataRegionData *Data = &(*it); - uint64_t Start = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), Layout); - uint64_t End = getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), Layout); + uint64_t Start = + getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), + Layout); + uint64_t End = + getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), + Layout); DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind << " start: " << Start << "(" << Data->Start->getName() << ")" << " end: " << End << "(" << Data->End->getName() << ")" diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp index 0a44e77..7625abd 100644 --- a/contrib/llvm/lib/MC/SubtargetFeature.cpp +++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp @@ -119,14 +119,15 @@ void SubtargetFeatures::AddFeature(const StringRef String, } /// Find KV in array using binary search. -template<typename T> const T *Find(const StringRef S, const T *A, size_t L) { +static const SubtargetFeatureKV *Find(StringRef S, const SubtargetFeatureKV *A, + size_t L) { // Make the lower bound element we're looking for - T KV; + SubtargetFeatureKV KV; KV.Key = S.data(); // Determine the end of the array - const T *Hi = A + L; + const SubtargetFeatureKV *Hi = A + L; // Binary search the array - const T *F = std::lower_bound(A, Hi, KV); + const SubtargetFeatureKV *F = std::lower_bound(A, Hi, KV); // If not found then return NULL if (F == Hi || StringRef(F->Key) != S) return NULL; // Return the found array item @@ -336,30 +337,6 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, return Bits; } -/// Get scheduling itinerary of a CPU. -void *SubtargetFeatures::getItinerary(const StringRef CPU, - const SubtargetInfoKV *Table, - size_t TableSize) { - assert(Table && "missing table"); -#ifndef NDEBUG - for (size_t i = 1; i < TableSize; i++) { - assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted"); - } -#endif - - // Find entry - const SubtargetInfoKV *Entry = Find(CPU, Table, TableSize); - - if (Entry) { - return Entry->Value; - } else { - errs() << "'" << CPU - << "' is not a recognized processor for this target" - << " (ignoring processor)\n"; - return NULL; - } -} - /// print - Print feature string. /// void SubtargetFeatures::print(raw_ostream &OS) const { @@ -368,11 +345,13 @@ void SubtargetFeatures::print(raw_ostream &OS) const { OS << "\n"; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// dump - Dump feature info. /// void SubtargetFeatures::dump() const { print(dbgs()); } +#endif /// getDefaultSubtargetFeatures - Return a string listing the features /// associated with the target triple. diff --git a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp index b026277..702eec0 100644 --- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp @@ -70,11 +70,6 @@ public: uint64_t Size,unsigned ByteAlignment); virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); - virtual void EmitBytes(StringRef Data, unsigned AddrSpace); - virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, - unsigned ValueSize, unsigned MaxBytesToEmit); - virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit); virtual void EmitFileDirective(StringRef Filename); virtual void EmitInstruction(const MCInst &Instruction); virtual void EmitWin64EHHandlerData(); @@ -333,43 +328,6 @@ void WinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { - // TODO: This is copied exactly from the MachOStreamer. Consider merging into - // MCObjectStreamer? - getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); -} - -void WinCOFFStreamer::EmitValueToAlignment(unsigned ByteAlignment, - int64_t Value, - unsigned ValueSize, - unsigned MaxBytesToEmit) { - // TODO: This is copied exactly from the MachOStreamer. Consider merging into - // MCObjectStreamer? - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit, - getCurrentSectionData()); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - -void WinCOFFStreamer::EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit) { - // TODO: This is copied exactly from the MachOStreamer. Consider merging into - // MCObjectStreamer? - if (MaxBytesToEmit == 0) - MaxBytesToEmit = ByteAlignment; - MCAlignFragment *F = new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit, - getCurrentSectionData()); - F->setEmitNops(true); - - // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); -} - void WinCOFFStreamer::EmitFileDirective(StringRef Filename) { // Ignore for now, linkers don't care, and proper debug // info will be a much large effort. |