aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2013-03-14 10:51:38 +0000
committerAlexander Kornienko <alexfh@google.com>2013-03-14 10:51:38 +0000
commit647735c781c5b37061ee03d6e9e6c7dda92218e2 (patch)
tree5a5e56606d41060263048b5a5586b3d2380898ba /lib/MC
parent6aed25d93d1cfcde5809a73ffa7dc1b0d6396f66 (diff)
parentf635ef401786c84df32090251a8cf45981ecca33 (diff)
Updating branches/google/stable to r176857
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@177040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/ELFObjectWriter.cpp56
-rw-r--r--lib/MC/MCAsmInfo.cpp3
-rw-r--r--lib/MC/MCAsmStreamer.cpp72
-rw-r--r--lib/MC/MCAssembler.cpp313
-rw-r--r--lib/MC/MCContext.cpp50
-rw-r--r--lib/MC/MCDisassembler/CMakeLists.txt5
-rw-r--r--lib/MC/MCDisassembler/Disassembler.cpp16
-rw-r--r--lib/MC/MCDisassembler/Disassembler.h4
-rw-r--r--lib/MC/MCDisassembler/EDDisassembler.cpp400
-rw-r--r--lib/MC/MCDisassembler/EDDisassembler.h269
-rw-r--r--lib/MC/MCDisassembler/EDInfo.h84
-rw-r--r--lib/MC/MCDisassembler/EDInst.cpp211
-rw-r--r--lib/MC/MCDisassembler/EDInst.h182
-rw-r--r--lib/MC/MCDisassembler/EDMain.cpp276
-rw-r--r--lib/MC/MCDisassembler/EDOperand.cpp315
-rw-r--r--lib/MC/MCDisassembler/EDOperand.h91
-rw-r--r--lib/MC/MCDisassembler/EDToken.cpp214
-rw-r--r--lib/MC/MCDisassembler/EDToken.h139
-rw-r--r--lib/MC/MCDwarf.cpp103
-rw-r--r--lib/MC/MCELF.cpp15
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp5
-rw-r--r--lib/MC/MCELFStreamer.cpp140
-rw-r--r--lib/MC/MCExpr.cpp19
-rw-r--r--lib/MC/MCMachOStreamer.cpp30
-rw-r--r--lib/MC/MCNullStreamer.cpp20
-rw-r--r--lib/MC/MCObjectFileInfo.cpp45
-rw-r--r--lib/MC/MCObjectStreamer.cpp82
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp80
-rw-r--r--lib/MC/MCParser/AsmParser.cpp2517
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp81
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp241
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp103
-rw-r--r--lib/MC/MCParser/MCAsmLexer.cpp2
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp4
-rw-r--r--lib/MC/MCPureStreamer.cpp27
-rw-r--r--lib/MC/MCSectionMachO.cpp4
-rw-r--r--lib/MC/MCStreamer.cpp39
-rw-r--r--lib/MC/MCTargetAsmLexer.cpp16
-rw-r--r--lib/MC/MachObjectWriter.cpp67
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp53
-rw-r--r--lib/MC/WinCOFFStreamer.cpp99
42 files changed, 2722 insertions, 3771 deletions
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index 99bff96bb9..db882c020b 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -36,7 +36,6 @@ add_llvm_library(LLVMMC
MCStreamer.cpp
MCSubtargetInfo.cpp
MCSymbol.cpp
- MCTargetAsmLexer.cpp
MCValue.cpp
MCWin64EH.cpp
MachObjectWriter.cpp
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index bfe1709462..3d995484e7 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -1,4 +1,4 @@
-//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===//
+//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -135,16 +135,14 @@ class ELFObjectWriter : public MCObjectWriter {
const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, IsPCRel);
+ return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup,
+ IsPCRel);
}
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool hasRelocationAddend() const {
return TargetObjectWriter->hasRelocationAddend();
}
- unsigned getEFlags() const {
- return TargetObjectWriter->getEFlags();
- }
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const {
@@ -152,13 +150,12 @@ class ELFObjectWriter : public MCObjectWriter {
IsRelocWithSymbol, Addend);
}
-
public:
ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_ostream &_OS, bool IsLittleEndian)
: MCObjectWriter(_OS, IsLittleEndian),
TargetObjectWriter(MOTW),
- NeedsGOT(false), NeedsSymtabShndx(false){
+ NeedsGOT(false), NeedsSymtabShndx(false) {
}
virtual ~ELFObjectWriter();
@@ -233,7 +230,8 @@ class ELFObjectWriter : public MCObjectWriter {
F.getContents().append(&buf[0], &buf[8]);
}
- void WriteHeader(uint64_t SectionDataSize,
+ void WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
unsigned NumberOfSections);
void WriteSymbolEntry(MCDataFragment *SymtabF,
@@ -373,7 +371,8 @@ ELFObjectWriter::~ELFObjectWriter()
{}
// Emit the ELF header.
-void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
+void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
unsigned NumberOfSections) {
// ELF Header
// ----------
@@ -411,7 +410,7 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
- Write32(getEFlags());
+ Write32(Asm.getELFHeaderEFlags());
// e_ehsize = ELF header size
Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
@@ -547,12 +546,17 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
Data.getSymbol().isVariable();
+ // Binding and Type share the same byte as upper and lower nibbles
uint8_t Binding = MCELF::GetBinding(OrigData);
- uint8_t Visibility = MCELF::GetVisibility(OrigData);
uint8_t Type = MCELF::GetType(Data);
-
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
- uint8_t Other = Visibility;
+
+ // Other and Visibility share the same byte with Visability using the lower
+ // 2 bits
+ uint8_t Visibility = MCELF::GetVisibility(OrigData);
+ uint8_t Other = MCELF::getOther(OrigData) <<
+ (ELF_Other_Shift - ELF_STV_Shift);
+ Other |= Visibility;
uint64_t Value = SymbolValue(Data, Layout);
uint64_t Size = 0;
@@ -865,7 +869,7 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
if (NeedsGOT) {
- llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
+ StringRef Name = "_GLOBAL_OFFSET_TABLE_";
MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name);
MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym);
Data.setExternal(true);
@@ -974,7 +978,7 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
- if (NumRegularSections > ELF::SHN_LORESERVE)
+ if (Index >= ELF::SHN_LORESERVE)
NeedsSymtabShndx = true;
}
@@ -1319,6 +1323,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
case ELF::SHT_FINI_ARRAY:
case ELF::SHT_PREINIT_ARRAY:
case ELF::SHT_X86_64_UNWIND:
+ case ELF::SHT_MIPS_REGINFO:
+ case ELF::SHT_MIPS_OPTIONS:
// Nothing to do.
break;
@@ -1332,6 +1338,24 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
break;
}
+ if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
+ Section.getType() == ELF::SHT_ARM_EXIDX) {
+ StringRef SecName(Section.getSectionName());
+ if (SecName == ".ARM.exidx") {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(".text",
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ } else if (SecName.startswith(".ARM.exidx")) {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1),
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ }
+ }
+
WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
Alignment, Section.getEntrySize());
@@ -1532,7 +1556,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
}
// Write out the ELF header ...
- WriteHeader(SectionHeaderOffset, NumSections + 1);
+ WriteHeader(Asm, SectionHeaderOffset, NumSections + 1);
// ... then the regular sections ...
// + because of .shstrtab
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index 7ea0f3b85a..51bb435710 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -24,6 +24,8 @@ using namespace llvm;
MCAsmInfo::MCAsmInfo() {
PointerSize = 4;
+ CalleeSaveStackSlotSize = 4;
+
IsLittleEndian = true;
StackGrowsUp = false;
HasSubsectionsViaSymbols = false;
@@ -37,6 +39,7 @@ MCAsmInfo::MCAsmInfo() {
CommentColumn = 40;
CommentString = "#";
LabelSuffix = ":";
+ DebugLabelSuffix = ":";
GlobalPrefix = "";
PrivateGlobalPrefix = ".";
LinkerPrivateGlobalPrefix = "";
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 6537e4e685..35613b411c 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -71,7 +71,7 @@ public:
MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend,
bool showInst)
- : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
+ : MCStreamer(SK_AsmStreamer, Context), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
@@ -127,17 +127,25 @@ public:
virtual void ChangeSection(const MCSection *Section);
virtual void InitSections() {
+ InitToTextSection();
+ }
+
+ virtual void InitToTextSection() {
// FIXME, this is MachO specific, but the testsuite
// expects this.
- SwitchSection(getContext().getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind::getText()));
+ SwitchSection(getContext().getMachOSection(
+ "__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 0, SectionKind::getText()));
}
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
@@ -207,7 +215,7 @@ public:
virtual void EmitFileDirective(StringRef Filename);
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename);
+ StringRef Filename, unsigned CUID = 0);
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
@@ -257,6 +265,10 @@ public:
virtual void EmitInstruction(const MCInst &Inst);
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+
/// 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.
@@ -265,6 +277,10 @@ public:
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_AsmStreamer;
+ }
};
} // end anonymous namespace.
@@ -345,6 +361,14 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
EmitEOL();
}
+void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+ MCStreamer::EmitDebugLabel(Symbol);
+
+ OS << *Symbol << MAI.getDebugLabelSuffix();
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
@@ -356,6 +380,16 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
EmitEOL();
}
+void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
+ assert(!Options.empty() && "At least one option is required!");
+ OS << "\t.linker_option \"" << Options[0] << '"';
+ for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
+ ie = Options.end(); it != ie; ++it) {
+ OS << ", " << '"' << *it << '"';
+ }
+ OS << "\n";
+}
+
void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
MCContext &Ctx = getContext();
const MCAsmInfo &MAI = Ctx.getAsmInfo();
@@ -794,14 +828,14 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
}
bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename) {
+ StringRef Filename, unsigned CUID) {
if (!UseDwarfDirectory && !Directory.empty()) {
if (sys::path::is_absolute(Filename))
- return EmitDwarfFileDirective(FileNo, "", Filename);
+ return EmitDwarfFileDirective(FileNo, "", Filename, CUID);
SmallString<128> FullPathName = Directory;
sys::path::append(FullPathName, Filename);
- return EmitDwarfFileDirective(FileNo, "", FullPathName);
+ return EmitDwarfFileDirective(FileNo, "", FullPathName, CUID);
}
if (UseLoc) {
@@ -812,8 +846,11 @@ bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
}
PrintQuotedString(Filename, OS);
EmitEOL();
+ // All .file will belong to a single CUID.
+ CUID = 0;
}
- return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename);
+ return this->MCStreamer::EmitDwarfFileDirective(FileNo, Directory, Filename,
+ CUID);
}
void MCAsmStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -1351,6 +1388,23 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
EmitEOL();
}
+void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
+ OS << "\t.bundle_align_mode " << AlignPow2;
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitBundleLock(bool AlignToEnd) {
+ OS << "\t.bundle_lock";
+ if (AlignToEnd)
+ OS << " align_to_end";
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitBundleUnlock() {
+ OS << "\t.bundle_unlock";
+ EmitEOL();
+}
+
/// 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/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 8f8ec151e5..1829266f96 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -34,10 +34,12 @@ using namespace llvm;
namespace {
namespace stats {
STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");
-STATISTIC(EmittedInstFragments,
- "Number of emitted assembler fragments - instruction");
+STATISTIC(EmittedRelaxableFragments,
+ "Number of emitted assembler fragments - relaxable");
STATISTIC(EmittedDataFragments,
"Number of emitted assembler fragments - data");
+STATISTIC(EmittedCompactEncodedInstFragments,
+ "Number of emitted assembler fragments - compact encoded inst");
STATISTIC(EmittedAlignFragments,
"Number of emitted assembler fragments - align");
STATISTIC(EmittedFillFragments,
@@ -71,7 +73,7 @@ MCAsmLayout::MCAsmLayout(MCAssembler &Asm)
SectionOrder.push_back(&*it);
}
-bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const {
+bool MCAsmLayout::isFragmentValid(const MCFragment *F) const {
const MCSectionData &SD = *F->getParent();
const MCFragment *LastValid = LastValidFragment.lookup(&SD);
if (!LastValid)
@@ -80,17 +82,18 @@ bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const {
return F->getLayoutOrder() <= LastValid->getLayoutOrder();
}
-void MCAsmLayout::invalidateFragmentsAfter(MCFragment *F) {
- // If this fragment wasn't already up-to-date, we don't need to do anything.
- if (!isFragmentUpToDate(F))
+void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) {
+ // If this fragment wasn't already valid, we don't need to do anything.
+ if (!isFragmentValid(F))
return;
- // Otherwise, reset the last valid fragment to this fragment.
+ // Otherwise, reset the last valid fragment to the previous fragment
+ // (if this is the first fragment, it will be NULL).
const MCSectionData &SD = *F->getParent();
- LastValidFragment[&SD] = F;
+ LastValidFragment[&SD] = F->getPrevNode();
}
-void MCAsmLayout::EnsureValid(const MCFragment *F) const {
+void MCAsmLayout::ensureValid(const MCFragment *F) const {
MCSectionData &SD = *F->getParent();
MCFragment *Cur = LastValidFragment[&SD];
@@ -99,15 +102,16 @@ void MCAsmLayout::EnsureValid(const MCFragment *F) const {
else
Cur = Cur->getNextNode();
- // Advance the layout position until the fragment is up-to-date.
- while (!isFragmentUpToDate(F)) {
- const_cast<MCAsmLayout*>(this)->LayoutFragment(Cur);
+ // Advance the layout position until the fragment is valid.
+ while (!isFragmentValid(F)) {
+ assert(Cur && "Layout bookkeeping error");
+ const_cast<MCAsmLayout*>(this)->layoutFragment(Cur);
Cur = Cur->getNextNode();
}
}
uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
- EnsureValid(F);
+ ensureValid(F);
assert(F->Offset != ~UINT64_C(0) && "Address not set!");
return F->Offset;
}
@@ -159,6 +163,46 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
return getSectionAddressSize(SD);
}
+uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize) {
+ uint64_t BundleSize = Assembler.getBundleAlignSize();
+ assert(BundleSize > 0 &&
+ "computeBundlePadding should only be called if bundling is enabled");
+ uint64_t BundleMask = BundleSize - 1;
+ uint64_t OffsetInBundle = FOffset & BundleMask;
+ uint64_t EndOfFragment = OffsetInBundle + FSize;
+
+ // There are two kinds of bundling restrictions:
+ //
+ // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
+ // *end* on a bundle boundary.
+ // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
+ // would, add padding until the end of the bundle so that the fragment
+ // will start in a new one.
+ if (F->alignToBundleEnd()) {
+ // Three possibilities here:
+ //
+ // A) The fragment just happens to end at a bundle boundary, so we're good.
+ // B) The fragment ends before the current bundle boundary: pad it just
+ // enough to reach the boundary.
+ // C) The fragment ends after the current bundle boundary: pad it until it
+ // reaches the end of the next bundle boundary.
+ //
+ // Note: this code could be made shorter with some modulo trickery, but it's
+ // intentionally kept in its more explicit form for simplicity.
+ if (EndOfFragment == BundleSize)
+ return 0;
+ else if (EndOfFragment < BundleSize)
+ return BundleSize - EndOfFragment;
+ else { // EndOfFragment > BundleSize
+ return 2 * BundleSize - EndOfFragment;
+ }
+ } else if (EndOfFragment > BundleSize)
+ return BundleSize - OffsetInBundle;
+ else
+ return 0;
+}
+
/* *** */
MCFragment::MCFragment() : Kind(FragmentType(~0)) {
@@ -181,12 +225,18 @@ MCEncodedFragment::~MCEncodedFragment() {
/* *** */
+MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
+}
+
+/* *** */
+
MCSectionData::MCSectionData() : Section(0) {}
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
: Section(&_Section),
Ordinal(~UINT32_C(0)),
Alignment(1),
+ BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false),
HasInstructions(false)
{
if (A)
@@ -214,12 +264,32 @@ 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_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false),
+ SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
}
MCAssembler::~MCAssembler() {
}
+void MCAssembler::reset() {
+ Sections.clear();
+ Symbols.clear();
+ SectionMap.clear();
+ SymbolMap.clear();
+ IndirectSymbols.clear();
+ DataRegions.clear();
+ ThumbFuncs.clear();
+ RelaxAll = false;
+ NoExecStack = false;
+ SubsectionsViaSymbols = false;
+ ELFHeaderEFlags = 0;
+
+ // reset objects owned by us
+ getBackend().reset();
+ getEmitter().reset();
+ getWriter().reset();
+}
+
bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
// Non-temporary labels should always be visible to the linker.
if (!Symbol.isTemporary())
@@ -326,11 +396,11 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const {
switch (F.getKind()) {
case MCFragment::FT_Data:
- return cast<MCDataFragment>(F).getContents().size();
+ case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
+ return cast<MCEncodedFragment>(F).getContents().size();
case MCFragment::FT_Fill:
return cast<MCFillFragment>(F).getSize();
- case MCFragment::FT_Inst:
- return cast<MCInstFragment>(F).getInstSize();
case MCFragment::FT_LEB:
return cast<MCLEBFragment>(F).getContents().size();
@@ -351,7 +421,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
}
case MCFragment::FT_Org: {
- MCOrgFragment &OF = cast<MCOrgFragment>(F);
+ const MCOrgFragment &OF = cast<MCOrgFragment>(F);
int64_t TargetLocation;
if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout))
report_fatal_error("expected assembly-time absolute expression");
@@ -374,31 +444,61 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
llvm_unreachable("invalid fragment kind");
}
-void MCAsmLayout::LayoutFragment(MCFragment *F) {
+void MCAsmLayout::layoutFragment(MCFragment *F) {
MCFragment *Prev = F->getPrevNode();
- // We should never try to recompute something which is up-to-date.
- assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!");
- // We should never try to compute the fragment layout if it's predecessor
- // isn't up-to-date.
- assert((!Prev || isFragmentUpToDate(Prev)) &&
- "Attempt to compute fragment before it's predecessor!");
+ // We should never try to recompute something which is valid.
+ assert(!isFragmentValid(F) && "Attempt to recompute a valid fragment!");
+ // We should never try to compute the fragment layout if its predecessor
+ // isn't valid.
+ assert((!Prev || isFragmentValid(Prev)) &&
+ "Attempt to compute fragment before its predecessor!");
++stats::FragmentLayouts;
// Compute fragment offset and size.
- uint64_t Offset = 0;
if (Prev)
- Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
-
- F->Offset = Offset;
+ F->Offset = Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
+ else
+ F->Offset = 0;
LastValidFragment[F->getParent()] = F;
+
+ // If bundling is enabled and this fragment has instructions in it, it has to
+ // obey the bundling restrictions. With padding, we'll have:
+ //
+ //
+ // BundlePadding
+ // |||
+ // -------------------------------------
+ // Prev |##########| F |
+ // -------------------------------------
+ // ^
+ // |
+ // F->Offset
+ //
+ // The fragment's offset will point to after the padding, and its computed
+ // size won't include the padding.
+ //
+ if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
+ assert(isa<MCEncodedFragment>(F) &&
+ "Only MCEncodedFragment implementations have instructions");
+ uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
+
+ if (FSize > Assembler.getBundleAlignSize())
+ report_fatal_error("Fragment can't be larger than a bundle size");
+
+ uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize);
+ if (RequiredBundlePadding > UINT8_MAX)
+ report_fatal_error("Padding cannot exceed 255 bytes");
+ F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
+ F->Offset += RequiredBundlePadding;
+ }
}
/// \brief Write the contents of a fragment to the given object writer. Expects
/// a MCEncodedFragment.
static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
- MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
+ const MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
OW->WriteBytes(EF.getContents());
}
@@ -406,17 +506,50 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment &F) {
MCObjectWriter *OW = &Asm.getWriter();
+
+ // FIXME: Embed in fragments instead?
+ uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
+
+ // Should NOP padding be written out before this fragment?
+ unsigned BundlePadding = F.getBundlePadding();
+ if (BundlePadding > 0) {
+ assert(Asm.isBundlingEnabled() &&
+ "Writing bundle padding with disabled bundling");
+ assert(F.hasInstructions() &&
+ "Writing bundle padding for a fragment without instructions");
+
+ unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize);
+ if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) {
+ // If the padding itself crosses a bundle boundary, it must be emitted
+ // in 2 pieces, since even nop instructions must not cross boundaries.
+ // v--------------v <- BundleAlignSize
+ // v---------v <- BundlePadding
+ // ----------------------------
+ // | Prev |####|####| F |
+ // ----------------------------
+ // ^-------------------^ <- TotalLength
+ unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize();
+ if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW))
+ report_fatal_error("unable to write NOP sequence of " +
+ Twine(DistanceToBoundary) + " bytes");
+ BundlePadding -= DistanceToBoundary;
+ }
+ if (!Asm.getBackend().writeNopData(BundlePadding, OW))
+ report_fatal_error("unable to write NOP sequence of " +
+ Twine(BundlePadding) + " bytes");
+ }
+
+ // This variable (and its dummy usage) is to participate in the assert at
+ // the end of the function.
uint64_t Start = OW->getStream().tell();
(void) Start;
++stats::EmittedFragments;
- // FIXME: Embed in fragments instead?
- uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
switch (F.getKind()) {
case MCFragment::FT_Align: {
++stats::EmittedAlignFragments;
- MCAlignFragment &AF = cast<MCAlignFragment>(F);
+ const MCAlignFragment &AF = cast<MCAlignFragment>(F);
uint64_t Count = FragmentSize / AF.getValueSize();
assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");
@@ -459,14 +592,19 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
writeFragmentContents(F, OW);
break;
- case MCFragment::FT_Inst:
- ++stats::EmittedInstFragments;
+ case MCFragment::FT_Relaxable:
+ ++stats::EmittedRelaxableFragments;
+ writeFragmentContents(F, OW);
+ break;
+
+ case MCFragment::FT_CompactEncodedInst:
+ ++stats::EmittedCompactEncodedInstFragments;
writeFragmentContents(F, OW);
break;
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
- MCFillFragment &FF = cast<MCFillFragment>(F);
+ const MCFillFragment &FF = cast<MCFillFragment>(F);
assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!");
@@ -483,14 +621,14 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
}
case MCFragment::FT_LEB: {
- MCLEBFragment &LF = cast<MCLEBFragment>(F);
+ const MCLEBFragment &LF = cast<MCLEBFragment>(F);
OW->WriteBytes(LF.getContents().str());
break;
}
case MCFragment::FT_Org: {
++stats::EmittedOrgFragments;
- MCOrgFragment &OF = cast<MCOrgFragment>(F);
+ const MCOrgFragment &OF = cast<MCOrgFragment>(F);
for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
OW->Write8(uint8_t(OF.getValue()));
@@ -510,7 +648,8 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
}
}
- assert(OW->getStream().tell() - Start == FragmentSize);
+ assert(OW->getStream().tell() - Start == FragmentSize &&
+ "The stream should advance by fragment size");
}
void MCAssembler::writeSectionData(const MCSectionData *SD,
@@ -528,7 +667,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
// Check that we aren't trying to write a non-zero contents (or fixups)
// into a virtual section. This is to support clients which use standard
// directives to fill the contents of virtual sections.
- MCDataFragment &DF = cast<MCDataFragment>(*it);
+ const MCDataFragment &DF = cast<MCDataFragment>(*it);
assert(DF.fixup_begin() == DF.fixup_end() &&
"Cannot have fixups in virtual section!");
for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)
@@ -605,9 +744,9 @@ void MCAssembler::Finish() {
SD->setLayoutOrder(i);
unsigned FragmentIndex = 0;
- for (MCSectionData::iterator it2 = SD->begin(),
- ie2 = SD->end(); it2 != ie2; ++it2)
- it2->setLayoutOrder(FragmentIndex++);
+ for (MCSectionData::iterator iFrag = SD->begin(), iFragEnd = SD->end();
+ iFrag != iFragEnd; ++iFrag)
+ iFrag->setLayoutOrder(FragmentIndex++);
}
// Layout until everything fits.
@@ -635,9 +774,10 @@ void MCAssembler::Finish() {
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
for (MCSectionData::iterator it2 = it->begin(),
ie2 = it->end(); it2 != ie2; ++it2) {
- MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(it2);
+ MCEncodedFragmentWithFixups *F =
+ dyn_cast<MCEncodedFragmentWithFixups>(it2);
if (F) {
- for (MCEncodedFragment::fixup_iterator it3 = F->fixup_begin(),
+ for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(),
ie3 = F->fixup_end(); it3 != ie3; ++it3) {
MCFixup &Fixup = *it3;
uint64_t FixedValue = handleFixup(Layout, *F, Fixup);
@@ -655,11 +795,8 @@ void MCAssembler::Finish() {
}
bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,
- const MCInstFragment *DF,
+ const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const {
- if (getRelaxAll())
- return true;
-
// If we cannot resolve the fixup value, it requires relaxation.
MCValue Target;
uint64_t Value;
@@ -669,25 +806,25 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,
return getBackend().fixupNeedsRelaxation(Fixup, Value, DF, Layout);
}
-bool MCAssembler::fragmentNeedsRelaxation(const MCInstFragment *IF,
+bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F,
const MCAsmLayout &Layout) const {
// If this inst doesn't ever need relaxation, ignore it. This occurs when we
// are intentionally pushing out inst fragments, or because we relaxed a
// previous instruction to one that doesn't need relaxation.
- if (!getBackend().mayNeedRelaxation(IF->getInst()))
+ if (!getBackend().mayNeedRelaxation(F->getInst()))
return false;
- for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(),
- ie = IF->fixup_end(); it != ie; ++it)
- if (fixupNeedsRelaxation(*it, IF, Layout))
+ for (MCRelaxableFragment::const_fixup_iterator it = F->fixup_begin(),
+ ie = F->fixup_end(); it != ie; ++it)
+ if (fixupNeedsRelaxation(*it, F, Layout))
return true;
return false;
}
bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
- MCInstFragment &IF) {
- if (!fragmentNeedsRelaxation(&IF, Layout))
+ MCRelaxableFragment &F) {
+ if (!fragmentNeedsRelaxation(&F, Layout))
return false;
++stats::RelaxedInstructions;
@@ -698,7 +835,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
// Relax the fragment.
MCInst Relaxed;
- getBackend().relaxInstruction(IF.getInst(), Relaxed);
+ getBackend().relaxInstruction(F.getInst(), Relaxed);
// Encode the new instruction.
//
@@ -710,10 +847,10 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
VecOS.flush();
- // Update the instruction fragment.
- IF.setInst(Relaxed);
- IF.getContents() = Code;
- IF.getFixups() = Fixups;
+ // Update the fragment.
+ F.setInst(Relaxed);
+ F.getContents() = Code;
+ F.getFixups() = Fixups;
return true;
}
@@ -770,17 +907,21 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) {
// Holds the first fragment which needed relaxing during this layout. It will
// remain NULL if none were relaxed.
- MCFragment *FirstInvalidFragment = NULL;
+ // When a fragment is relaxed, all the fragments following it should get
+ // invalidated because their offset is going to change.
+ MCFragment *FirstRelaxedFragment = NULL;
- // Scan for fragments that need relaxation.
+ // Attempt to relax all the fragments in the section.
for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) {
// Check if this is a fragment that needs relaxation.
bool RelaxedFrag = false;
switch(I->getKind()) {
default:
break;
- case MCFragment::FT_Inst:
- RelaxedFrag = relaxInstruction(Layout, *cast<MCInstFragment>(I));
+ case MCFragment::FT_Relaxable:
+ assert(!getRelaxAll() &&
+ "Did not expect a MCRelaxableFragment in RelaxAll mode");
+ RelaxedFrag = relaxInstruction(Layout, *cast<MCRelaxableFragment>(I));
break;
case MCFragment::FT_Dwarf:
RelaxedFrag = relaxDwarfLineAddr(Layout,
@@ -795,11 +936,11 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) {
RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(I));
break;
}
- if (RelaxedFrag && !FirstInvalidFragment)
- FirstInvalidFragment = I;
+ if (RelaxedFrag && !FirstRelaxedFragment)
+ FirstRelaxedFragment = I;
}
- if (FirstInvalidFragment) {
- Layout.invalidateFragmentsAfter(FirstInvalidFragment);
+ if (FirstRelaxedFragment) {
+ Layout.invalidateFragmentsFrom(FirstRelaxedFragment);
return true;
}
return false;
@@ -846,8 +987,10 @@ void MCFragment::dump() {
switch (getKind()) {
case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
case MCFragment::FT_Data: OS << "MCDataFragment"; break;
+ case MCFragment::FT_CompactEncodedInst:
+ OS << "MCCompactEncodedInstFragment"; break;
case MCFragment::FT_Fill: OS << "MCFillFragment"; break;
- case MCFragment::FT_Inst: OS << "MCInstFragment"; break;
+ case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break;
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
@@ -855,7 +998,9 @@ void MCFragment::dump() {
}
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
- << " Offset:" << Offset << ">";
+ << " Offset:" << Offset
+ << " HasInstructions:" << hasInstructions()
+ << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">";
switch (getKind()) {
case MCFragment::FT_Align: {
@@ -891,17 +1036,30 @@ void MCFragment::dump() {
}
break;
}
+ case MCFragment::FT_CompactEncodedInst: {
+ const MCCompactEncodedInstFragment *CEIF =
+ cast<MCCompactEncodedInstFragment>(this);
+ OS << "\n ";
+ OS << " Contents:[";
+ const SmallVectorImpl<char> &Contents = CEIF->getContents();
+ for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
+ if (i) OS << ",";
+ OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
+ }
+ OS << "] (" << Contents.size() << " bytes)";
+ break;
+ }
case MCFragment::FT_Fill: {
const MCFillFragment *FF = cast<MCFillFragment>(this);
OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize()
<< " Size:" << FF->getSize();
break;
}
- case MCFragment::FT_Inst: {
- const MCInstFragment *IF = cast<MCInstFragment>(this);
+ case MCFragment::FT_Relaxable: {
+ const MCRelaxableFragment *F = cast<MCRelaxableFragment>(this);
OS << "\n ";
OS << " Inst:";
- IF->getInst().dump_pretty(OS);
+ F->getInst().dump_pretty(OS);
break;
}
case MCFragment::FT_Org: {
@@ -937,7 +1095,8 @@ void MCSectionData::dump() {
raw_ostream &OS = llvm::errs();
OS << "<MCSectionData";
- OS << " Alignment:" << getAlignment() << " Fragments:[\n ";
+ OS << " Alignment:" << getAlignment()
+ << " Fragments:[\n ";
for (iterator it = begin(), ie = end(); it != ie; ++it) {
if (it != begin()) OS << ",\n ";
it->dump();
@@ -983,8 +1142,10 @@ void MCAssembler::dump() {
// anchors for MC*Fragment vtables
void MCEncodedFragment::anchor() { }
+void MCEncodedFragmentWithFixups::anchor() { }
void MCDataFragment::anchor() { }
-void MCInstFragment::anchor() { }
+void MCCompactEncodedInstFragment::anchor() { }
+void MCRelaxableFragment::anchor() { }
void MCAlignFragment::anchor() { }
void MCFillFragment::anchor() { }
void MCOrgFragment::anchor() { }
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 23ec0bb12d..26d378e6c0 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -21,6 +21,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
using namespace llvm;
@@ -32,13 +33,15 @@ typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
const MCObjectFileInfo *mofi, const SourceMgr *mgr,
- bool DoAutoInitializationFinalization ) :
+ bool DoAutoReset) :
SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi),
Allocator(), Symbols(Allocator), UsedNames(Allocator),
NextUniqueID(0),
- CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
- AllowTemporaryLabels(true),
- AutoInitializationFinalization(DoAutoInitializationFinalization) {
+ CompilationDir(llvm::sys::Path::GetCurrentDirectory().str()),
+ CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
+ DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0),
+ AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
+
MachOUniquingMap = 0;
ELFUniquingMap = 0;
COFFUniquingMap = 0;
@@ -47,14 +50,16 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
SecureLog = 0;
SecureLogUsed = false;
- if (AutoInitializationFinalization)
- doInitialization();
+ if (SrcMgr && SrcMgr->getNumBuffers() > 0)
+ MainFileName = SrcMgr->getMemoryBuffer(0)->getBufferIdentifier();
+ else
+ MainFileName = "";
}
MCContext::~MCContext() {
- if (AutoInitializationFinalization)
- doFinalization();
+ if (AutoReset)
+ reset();
// NOTE: The symbols are all allocated out of a bump pointer allocator,
// we don't need to free them here.
@@ -67,25 +72,19 @@ MCContext::~MCContext() {
// Module Lifetime Management
//===----------------------------------------------------------------------===//
-void MCContext::doInitialization() {
- NextUniqueID = 0;
- AllowTemporaryLabels = true;
- DwarfLocSeen = false;
- GenDwarfForAssembly = false;
- GenDwarfFileNumber = 0;
-}
-
-void MCContext::doFinalization() {
+void MCContext::reset() {
UsedNames.clear();
Symbols.clear();
Allocator.Reset();
Instances.clear();
- MCDwarfFiles.clear();
- MCDwarfDirs.clear();
+ MCDwarfFilesCUMap.clear();
+ MCDwarfDirsCUMap.clear();
MCGenDwarfLabelEntries.clear();
DwarfDebugFlags = StringRef();
MCLineSections.clear();
MCLineSectionOrder.clear();
+ DwarfCompileUnitID = 0;
+ MCLineTableSymbols.clear();
CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
// If we have the MachO uniquing map, free it.
@@ -95,6 +94,12 @@ void MCContext::doFinalization() {
MachOUniquingMap = 0;
ELFUniquingMap = 0;
COFFUniquingMap = 0;
+
+ NextUniqueID = 0;
+ AllowTemporaryLabels = true;
+ DwarfLocSeen = false;
+ GenDwarfForAssembly = false;
+ GenDwarfFileNumber = 0;
}
//===----------------------------------------------------------------------===//
@@ -294,11 +299,13 @@ const MCSection *MCContext::getCOFFSection(StringRef Section,
/// error and zero is returned and the client reports the error, else the
/// allocated file number is returned. The file numbers may be in any order.
unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
- unsigned FileNumber) {
+ unsigned FileNumber, unsigned CUID) {
// TODO: a FileNumber of zero says to use the next available file number.
// Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
// to not be less than one. This needs to be change to be not less than zero.
+ std::vector<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
+ std::vector<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
// Make space for this FileNumber in the MCDwarfFiles vector if needed.
if (FileNumber >= MCDwarfFiles.size()) {
MCDwarfFiles.resize(FileNumber + 1);
@@ -358,7 +365,8 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
/// currently is assigned and false otherwise.
-bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) {
+bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
+ std::vector<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
return false;
diff --git a/lib/MC/MCDisassembler/CMakeLists.txt b/lib/MC/MCDisassembler/CMakeLists.txt
index 5e2cd8387d..5195b9e23d 100644
--- a/lib/MC/MCDisassembler/CMakeLists.txt
+++ b/lib/MC/MCDisassembler/CMakeLists.txt
@@ -1,8 +1,3 @@
add_llvm_library(LLVMMCDisassembler
Disassembler.cpp
- EDDisassembler.cpp
- EDInst.cpp
- EDMain.cpp
- EDOperand.cpp
- EDToken.cpp
)
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp
index ac583ac127..d3fa906a06 100644
--- a/lib/MC/MCDisassembler/Disassembler.cpp
+++ b/lib/MC/MCDisassembler/Disassembler.cpp
@@ -195,5 +195,21 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){
IP->setPrintImmHex(1);
Options &= ~LLVMDisassembler_Option_PrintImmHex;
}
+ if (Options & LLVMDisassembler_Option_AsmPrinterVariant){
+ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+ // Try to set up the new instruction printer.
+ const MCAsmInfo *MAI = DC->getAsmInfo();
+ const MCInstrInfo *MII = DC->getInstrInfo();
+ const MCRegisterInfo *MRI = DC->getRegisterInfo();
+ const MCSubtargetInfo *STI = DC->getSubtargetInfo();
+ int AsmPrinterVariant = MAI->getAssemblerDialect();
+ AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0;
+ MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter(
+ AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
+ if (IP) {
+ DC->setIP(IP);
+ Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
+ }
+ }
return (Options == 0);
}
diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h
index 28cf04b95d..6eb59d0c57 100644
--- a/lib/MC/MCDisassembler/Disassembler.h
+++ b/lib/MC/MCDisassembler/Disassembler.h
@@ -109,7 +109,11 @@ public:
const Target *getTarget() const { return TheTarget; }
const MCDisassembler *getDisAsm() const { return DisAsm.get(); }
const MCAsmInfo *getAsmInfo() const { return MAI.get(); }
+ const MCInstrInfo *getInstrInfo() const { return MII.get(); }
+ const MCRegisterInfo *getRegisterInfo() const { return MRI.get(); }
+ const MCSubtargetInfo *getSubtargetInfo() const { return MSI.get(); }
MCInstPrinter *getIP() { return IP.get(); }
+ void setIP(MCInstPrinter *NewIP) { IP.reset(NewIP); }
};
} // namespace llvm
diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp
deleted file mode 100644
index e667920791..0000000000
--- a/lib/MC/MCDisassembler/EDDisassembler.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Enhanced Disassembly library's disassembler class.
-// The disassembler is responsible for vending individual instructions according
-// to a given architecture and disassembly syntax.
-//
-//===----------------------------------------------------------------------===//
-
-#include "EDDisassembler.h"
-#include "EDInst.h"
-#include "llvm/MC/EDInstInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCParser/AsmLexer.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetAsmLexer.h"
-#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/MemoryObject.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-using namespace llvm;
-
-EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
-
-struct TripleMap {
- Triple::ArchType Arch;
- const char *String;
-};
-
-static const struct TripleMap triplemap[] = {
- { Triple::x86, "i386-unknown-unknown" },
- { Triple::x86_64, "x86_64-unknown-unknown" },
- { Triple::arm, "arm-unknown-unknown" },
- { Triple::thumb, "thumb-unknown-unknown" }
-};
-
-/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
-/// or NULL if there is an error
-///
-/// @arg arch - The Triple::ArchType for the desired architecture
-static const char *tripleFromArch(Triple::ArchType arch) {
- unsigned int infoIndex;
-
- for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) {
- if (arch == triplemap[infoIndex].Arch)
- return triplemap[infoIndex].String;
- }
-
- return NULL;
-}
-
-/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
-/// for the desired assembly syntax, suitable for passing to
-/// Target::createMCInstPrinter()
-///
-/// @arg arch - The target architecture
-/// @arg syntax - The assembly syntax in sd form
-static int getLLVMSyntaxVariant(Triple::ArchType arch,
- EDDisassembler::AssemblySyntax syntax) {
- switch (syntax) {
- // Mappings below from X86AsmPrinter.cpp
- case EDDisassembler::kEDAssemblySyntaxX86ATT:
- if (arch == Triple::x86 || arch == Triple::x86_64)
- return 0;
- break;
- case EDDisassembler::kEDAssemblySyntaxX86Intel:
- if (arch == Triple::x86 || arch == Triple::x86_64)
- return 1;
- break;
- case EDDisassembler::kEDAssemblySyntaxARMUAL:
- if (arch == Triple::arm || arch == Triple::thumb)
- return 0;
- break;
- }
-
- return -1;
-}
-
-EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
- AssemblySyntax syntax) {
- const char *triple = tripleFromArch(arch);
- return getDisassembler(StringRef(triple), syntax);
-}
-
-EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
- AssemblySyntax syntax) {
- CPUKey key;
- key.Triple = str.str();
- key.Syntax = syntax;
-
- EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
-
- if (i != sDisassemblers.end()) {
- return i->second;
- }
-
- EDDisassembler *sdd = new EDDisassembler(key);
- if (!sdd->valid()) {
- delete sdd;
- return NULL;
- }
-
- sDisassemblers[key] = sdd;
-
- return sdd;
-}
-
-EDDisassembler::EDDisassembler(CPUKey &key) :
- Valid(false),
- HasSemantics(false),
- ErrorStream(nulls()),
- Key(key),
- TgtTriple(key.Triple.c_str()) {
-
- LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax);
-
- if (LLVMSyntaxVariant < 0)
- return;
-
- std::string tripleString(key.Triple);
- std::string errorString;
-
- Tgt = TargetRegistry::lookupTarget(key.Triple,
- errorString);
-
- if (!Tgt)
- return;
-
- MRI.reset(Tgt->createMCRegInfo(tripleString));
-
- if (!MRI)
- return;
-
- initMaps(*MRI);
-
- AsmInfo.reset(Tgt->createMCAsmInfo(tripleString));
-
- if (!AsmInfo)
- return;
-
- STI.reset(Tgt->createMCSubtargetInfo(tripleString, "", ""));
-
- if (!STI)
- return;
-
- Disassembler.reset(Tgt->createMCDisassembler(*STI));
-
- if (!Disassembler)
- return;
-
- InstInfos = Disassembler->getEDInfo();
-
- MII.reset(Tgt->createMCInstrInfo());
-
- if (!MII)
- return;
-
- InstString.reset(new std::string);
- InstStream.reset(new raw_string_ostream(*InstString));
- InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo,
- *MII, *MRI, *STI));
-
- if (!InstPrinter)
- return;
-
- GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
- SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo));
- SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
-
- initMaps(*MRI);
-
- Valid = true;
-}
-
-EDDisassembler::~EDDisassembler() {
- if (!valid())
- return;
-}
-
-namespace {
- /// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
- /// as provided by the sd interface. See MemoryObject.
- class EDMemoryObject : public llvm::MemoryObject {
- private:
- EDByteReaderCallback Callback;
- void *Arg;
- public:
- EDMemoryObject(EDByteReaderCallback callback,
- void *arg) : Callback(callback), Arg(arg) { }
- ~EDMemoryObject() { }
- uint64_t getBase() const { return 0x0; }
- uint64_t getExtent() const { return (uint64_t)-1; }
- int readByte(uint64_t address, uint8_t *ptr) const {
- if (!Callback)
- return -1;
-
- if (Callback(ptr, address, Arg))
- return -1;
-
- return 0;
- }
- };
-}
-
-EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
- uint64_t address,
- void *arg) {
- EDMemoryObject memoryObject(byteReader, arg);
-
- MCInst* inst = new MCInst;
- uint64_t byteSize;
-
- MCDisassembler::DecodeStatus S;
- S = Disassembler->getInstruction(*inst, byteSize, memoryObject, address,
- ErrorStream, nulls());
- switch (S) {
- case MCDisassembler::Fail:
- case MCDisassembler::SoftFail:
- // FIXME: Do something different on soft failure mode?
- delete inst;
- return NULL;
-
- case MCDisassembler::Success: {
- const llvm::EDInstInfo *thisInstInfo = NULL;
-
- if (InstInfos) {
- thisInstInfo = &InstInfos[inst->getOpcode()];
- }
-
- EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
- return sdInst;
- }
- }
- return NULL;
-}
-
-void EDDisassembler::initMaps(const MCRegisterInfo &registerInfo) {
- unsigned numRegisters = registerInfo.getNumRegs();
- unsigned registerIndex;
-
- for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
- const char* registerName = registerInfo.getName(registerIndex);
-
- RegVec.push_back(registerName);
- RegRMap[registerName] = registerIndex;
- }
-
- switch (TgtTriple.getArch()) {
- default:
- break;
- case Triple::x86:
- case Triple::x86_64:
- stackPointers.insert(registerIDWithName("SP"));
- stackPointers.insert(registerIDWithName("ESP"));
- stackPointers.insert(registerIDWithName("RSP"));
-
- programCounters.insert(registerIDWithName("IP"));
- programCounters.insert(registerIDWithName("EIP"));
- programCounters.insert(registerIDWithName("RIP"));
- break;
- case Triple::arm:
- case Triple::thumb:
- stackPointers.insert(registerIDWithName("SP"));
-
- programCounters.insert(registerIDWithName("PC"));
- break;
- }
-}
-
-const char *EDDisassembler::nameWithRegisterID(unsigned registerID) const {
- if (registerID >= RegVec.size())
- return NULL;
- else
- return RegVec[registerID].c_str();
-}
-
-unsigned EDDisassembler::registerIDWithName(const char *name) const {
- regrmap_t::const_iterator iter = RegRMap.find(std::string(name));
- if (iter == RegRMap.end())
- return 0;
- else
- return (*iter).second;
-}
-
-bool EDDisassembler::registerIsStackPointer(unsigned registerID) {
- return (stackPointers.find(registerID) != stackPointers.end());
-}
-
-bool EDDisassembler::registerIsProgramCounter(unsigned registerID) {
- return (programCounters.find(registerID) != programCounters.end());
-}
-
-int EDDisassembler::printInst(std::string &str, MCInst &inst) {
- PrinterMutex.acquire();
-
- InstPrinter->printInst(&inst, *InstStream, "");
- InstStream->flush();
- str = *InstString;
- InstString->clear();
-
- PrinterMutex.release();
-
- return 0;
-}
-
-static void diag_handler(const SMDiagnostic &diag, void *context) {
- if (context)
- diag.print("", static_cast<EDDisassembler*>(context)->ErrorStream);
-}
-
-int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
- SmallVectorImpl<AsmToken> &tokens,
- const std::string &str) {
- int ret = 0;
-
- switch (TgtTriple.getArch()) {
- default:
- return -1;
- case Triple::x86:
- case Triple::x86_64:
- case Triple::arm:
- case Triple::thumb:
- break;
- }
-
- const char *cStr = str.c_str();
- MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
-
- StringRef instName;
- SMLoc instLoc;
-
- SourceMgr sourceMgr;
- sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this));
- sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
- MCContext context(*AsmInfo, *MRI, NULL);
- OwningPtr<MCStreamer> streamer(createNullStreamer(context));
- OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr,
- context, *streamer,
- *AsmInfo));
-
- OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", ""));
- OwningPtr<MCTargetAsmParser>
- TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
-
- AsmToken OpcodeToken = genericParser->Lex();
- AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to
-
- if (OpcodeToken.is(AsmToken::Identifier)) {
- instName = OpcodeToken.getString();
- instLoc = OpcodeToken.getLoc();
-
- ParseInstructionInfo Info;
- if (NextToken.isNot(AsmToken::Eof) &&
- TargetParser->ParseInstruction(Info, instName, instLoc, operands))
- ret = -1;
- } else {
- ret = -1;
- }
-
- ParserMutex.acquire();
-
- if (!ret) {
- GenericAsmLexer->setBuffer(buf);
-
- while (SpecificAsmLexer->Lex(),
- SpecificAsmLexer->isNot(AsmToken::Eof) &&
- SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
- if (SpecificAsmLexer->is(AsmToken::Error)) {
- ret = -1;
- break;
- }
- tokens.push_back(SpecificAsmLexer->getTok());
- }
- }
-
- ParserMutex.release();
-
- return ret;
-}
-
-int EDDisassembler::llvmSyntaxVariant() const {
- return LLVMSyntaxVariant;
-}
diff --git a/lib/MC/MCDisassembler/EDDisassembler.h b/lib/MC/MCDisassembler/EDDisassembler.h
deleted file mode 100644
index 942b9067e6..0000000000
--- a/lib/MC/MCDisassembler/EDDisassembler.h
+++ /dev/null
@@ -1,269 +0,0 @@
-//===-- EDDisassembler.h - LLVM Enhanced Disassembler -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for the Enhanced Disassembly library's
-// disassembler class. The disassembler is responsible for vending individual
-// instructions according to a given architecture and disassembly syntax.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EDDISASSEMBLER_H
-#define LLVM_EDDISASSEMBLER_H
-
-#include "EDInfo.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/raw_ostream.h"
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-namespace llvm {
-class AsmLexer;
-class AsmParser;
-class AsmToken;
-class MCContext;
-class MCAsmInfo;
-class MCAsmLexer;
-class MCDisassembler;
-class MCInst;
-class MCInstPrinter;
-class MCInstrInfo;
-class MCParsedAsmOperand;
-class MCRegisterInfo;
-class MCStreamer;
-class MCSubtargetInfo;
-class MCTargetAsmLexer;
-class MCTargetAsmParser;
-template <typename T> class SmallVectorImpl;
-class SourceMgr;
-class Target;
-
-struct EDInstInfo;
-struct EDInst;
-struct EDOperand;
-struct EDToken;
-
-typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
-
-/// EDDisassembler - Encapsulates a disassembler for a single architecture and
-/// disassembly syntax. Also manages the static disassembler registry.
-struct EDDisassembler {
- typedef enum {
- /*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
- kEDAssemblySyntaxX86Intel = 0,
- /*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
- kEDAssemblySyntaxX86ATT = 1,
- kEDAssemblySyntaxARMUAL = 2
- } AssemblySyntax;
-
-
- ////////////////////
- // Static members //
- ////////////////////
-
- /// CPUKey - Encapsulates the descriptor of an architecture/disassembly-syntax
- /// pair
- struct CPUKey {
- /// The architecture type
- std::string Triple;
-
- /// The assembly syntax
- AssemblySyntax Syntax;
-
- /// operator== - Equality operator
- bool operator==(const CPUKey &key) const {
- return (Triple == key.Triple &&
- Syntax == key.Syntax);
- }
-
- /// operator< - Less-than operator
- bool operator<(const CPUKey &key) const {
- return ((Triple < key.Triple) ||
- ((Triple == key.Triple) && Syntax < (key.Syntax)));
- }
- };
-
- typedef std::map<CPUKey, EDDisassembler*> DisassemblerMap_t;
-
- /// A map from disassembler specifications to disassemblers. Populated
- /// lazily.
- static DisassemblerMap_t sDisassemblers;
-
- /// getDisassembler - Returns the specified disassemble, or NULL on failure
- ///
- /// @arg arch - The desired architecture
- /// @arg syntax - The desired disassembly syntax
- static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch,
- AssemblySyntax syntax);
-
- /// getDisassembler - Returns the disassembler for a given combination of
- /// CPU type, CPU subtype, and assembly syntax, or NULL on failure
- ///
- /// @arg str - The string representation of the architecture triple, e.g.,
- /// "x86_64-apple-darwin"
- /// @arg syntax - The disassembly syntax for the required disassembler
- static EDDisassembler *getDisassembler(llvm::StringRef str,
- AssemblySyntax syntax);
-
- ////////////////////////
- // Per-object members //
- ////////////////////////
-
- /// True only if the object has been successfully initialized
- bool Valid;
- /// True if the disassembler can provide semantic information
- bool HasSemantics;
-
- /// The stream to write errors to
- llvm::raw_ostream &ErrorStream;
-
- /// The triple/syntax pair for the current architecture
- CPUKey Key;
- /// The Triple fur the current architecture
- Triple TgtTriple;
- /// The LLVM target corresponding to the disassembler
- const llvm::Target *Tgt;
- /// The assembly information for the target architecture
- llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
- /// The subtarget information for the target architecture
- llvm::OwningPtr<const llvm::MCSubtargetInfo> STI;
- // The instruction information for the target architecture.
- llvm::OwningPtr<const llvm::MCInstrInfo> MII;
- // The register information for the target architecture.
- llvm::OwningPtr<const llvm::MCRegisterInfo> MRI;
- /// The disassembler for the target architecture
- llvm::OwningPtr<const llvm::MCDisassembler> Disassembler;
- /// The output string for the instruction printer; must be guarded with
- /// PrinterMutex
- llvm::OwningPtr<std::string> InstString;
- /// The output stream for the disassembler; must be guarded with
- /// PrinterMutex
- llvm::OwningPtr<llvm::raw_string_ostream> InstStream;
- /// The instruction printer for the target architecture; must be guarded with
- /// PrinterMutex when printing
- llvm::OwningPtr<llvm::MCInstPrinter> InstPrinter;
- /// The mutex that guards the instruction printer's printing functions, which
- /// use a shared stream
- llvm::sys::Mutex PrinterMutex;
- /// The array of instruction information provided by the TableGen backend for
- /// the target architecture
- const llvm::EDInstInfo *InstInfos;
- /// The target-specific lexer for use in tokenizing strings, in
- /// target-independent and target-specific portions
- llvm::OwningPtr<llvm::AsmLexer> GenericAsmLexer;
- llvm::OwningPtr<llvm::MCTargetAsmLexer> SpecificAsmLexer;
- /// The guard for the above
- llvm::sys::Mutex ParserMutex;
- /// The LLVM number used for the target disassembly syntax variant
- int LLVMSyntaxVariant;
-
- typedef std::vector<std::string> regvec_t;
- typedef std::map<std::string, unsigned> regrmap_t;
-
- /// A vector of registers for quick mapping from LLVM register IDs to names
- regvec_t RegVec;
- /// A map of registers for quick mapping from register names to LLVM IDs
- regrmap_t RegRMap;
-
- /// A set of register IDs for aliases of the stack pointer for the current
- /// architecture
- std::set<unsigned> stackPointers;
- /// A set of register IDs for aliases of the program counter for the current
- /// architecture
- std::set<unsigned> programCounters;
-
- /// Constructor - initializes a disassembler with all the necessary objects,
- /// which come pre-allocated from the registry accessor function
- ///
- /// @arg key - the architecture and disassembly syntax for the
- /// disassembler
- EDDisassembler(CPUKey& key);
-
- /// valid - reports whether there was a failure in the constructor.
- bool valid() {
- return Valid;
- }
-
- /// hasSemantics - reports whether the disassembler can provide operands and
- /// tokens.
- bool hasSemantics() {
- return HasSemantics;
- }
-
- ~EDDisassembler();
-
- /// createInst - creates and returns an instruction given a callback and
- /// memory address, or NULL on failure
- ///
- /// @arg byteReader - A callback function that provides machine code bytes
- /// @arg address - The address of the first byte of the instruction,
- /// suitable for passing to byteReader
- /// @arg arg - An opaque argument for byteReader
- EDInst *createInst(EDByteReaderCallback byteReader,
- uint64_t address,
- void *arg);
-
- /// initMaps - initializes regVec and regRMap using the provided register
- /// info
- ///
- /// @arg registerInfo - the register information to use as a source
- void initMaps(const llvm::MCRegisterInfo &registerInfo);
- /// nameWithRegisterID - Returns the name (owned by the EDDisassembler) of a
- /// register for a given register ID, or NULL on failure
- ///
- /// @arg registerID - the ID of the register to be queried
- const char *nameWithRegisterID(unsigned registerID) const;
- /// registerIDWithName - Returns the ID of a register for a given register
- /// name, or (unsigned)-1 on failure
- ///
- /// @arg name - The name of the register
- unsigned registerIDWithName(const char *name) const;
-
- /// registerIsStackPointer - reports whether a register ID is an alias for the
- /// stack pointer register
- ///
- /// @arg registerID - The LLVM register ID
- bool registerIsStackPointer(unsigned registerID);
- /// registerIsStackPointer - reports whether a register ID is an alias for the
- /// stack pointer register
- ///
- /// @arg registerID - The LLVM register ID
- bool registerIsProgramCounter(unsigned registerID);
-
- /// printInst - prints an MCInst to a string, returning 0 on success, or -1
- /// otherwise
- ///
- /// @arg str - A reference to a string which is filled in with the string
- /// representation of the instruction
- /// @arg inst - A reference to the MCInst to be printed
- int printInst(std::string& str,
- llvm::MCInst& inst);
-
- /// parseInst - extracts operands and tokens from a string for use in
- /// tokenizing the string. Returns 0 on success, or -1 otherwise.
- ///
- /// @arg operands - A reference to a vector that will be filled in with the
- /// parsed operands
- /// @arg tokens - A reference to a vector that will be filled in with the
- /// tokens
- /// @arg str - The string representation of the instruction
- int parseInst(llvm::SmallVectorImpl<llvm::MCParsedAsmOperand*> &operands,
- llvm::SmallVectorImpl<llvm::AsmToken> &tokens,
- const std::string &str);
-
- /// llvmSyntaxVariant - returns the LLVM syntax variant for this disassembler
- int llvmSyntaxVariant() const;
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/MC/MCDisassembler/EDInfo.h b/lib/MC/MCDisassembler/EDInfo.h
deleted file mode 100644
index e43ad16352..0000000000
--- a/lib/MC/MCDisassembler/EDInfo.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- EDInfo.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EDINFO_H
-#define LLVM_EDINFO_H
-
-enum {
- EDIS_MAX_OPERANDS = 13,
- EDIS_MAX_SYNTAXES = 2
-};
-
-enum OperandTypes {
- kOperandTypeNone,
- kOperandTypeImmediate,
- kOperandTypeRegister,
- kOperandTypeX86Memory,
- kOperandTypeX86EffectiveAddress,
- kOperandTypeX86PCRelative,
- kOperandTypeARMBranchTarget,
- kOperandTypeARMSoReg,
- kOperandTypeARMSoImm,
- kOperandTypeARMRotImm,
- kOperandTypeARMSoImm2Part,
- kOperandTypeARMPredicate,
- kOperandTypeAddrModeImm12,
- kOperandTypeLdStSOReg,
- kOperandTypeARMAddrMode2,
- kOperandTypeARMAddrMode2Offset,
- kOperandTypeARMAddrMode3,
- kOperandTypeARMAddrMode3Offset,
- kOperandTypeARMAddrMode4,
- kOperandTypeARMAddrMode5,
- kOperandTypeARMAddrMode6,
- kOperandTypeARMAddrMode6Offset,
- kOperandTypeARMAddrMode7,
- kOperandTypeARMAddrModePC,
- kOperandTypeARMRegisterList,
- kOperandTypeARMDPRRegisterList,
- kOperandTypeARMSPRRegisterList,
- kOperandTypeARMTBAddrMode,
- kOperandTypeThumbITMask,
- kOperandTypeThumbAddrModeRegS1,
- kOperandTypeThumbAddrModeRegS2,
- kOperandTypeThumbAddrModeRegS4,
- kOperandTypeThumbAddrModeImmS1,
- kOperandTypeThumbAddrModeImmS2,
- kOperandTypeThumbAddrModeImmS4,
- kOperandTypeThumbAddrModeRR,
- kOperandTypeThumbAddrModeSP,
- kOperandTypeThumbAddrModePC,
- kOperandTypeThumb2AddrModeReg,
- kOperandTypeThumb2SoReg,
- kOperandTypeThumb2SoImm,
- kOperandTypeThumb2AddrModeImm8,
- kOperandTypeThumb2AddrModeImm8Offset,
- kOperandTypeThumb2AddrModeImm12,
- kOperandTypeThumb2AddrModeSoReg,
- kOperandTypeThumb2AddrModeImm8s4,
- kOperandTypeThumb2AddrModeImm8s4Offset
-};
-
-enum OperandFlags {
- kOperandFlagSource = 0x1,
- kOperandFlagTarget = 0x2
-};
-
-enum InstructionTypes {
- kInstructionTypeNone,
- kInstructionTypeMove,
- kInstructionTypeBranch,
- kInstructionTypePush,
- kInstructionTypePop,
- kInstructionTypeCall,
- kInstructionTypeReturn
-};
-
-
-#endif
diff --git a/lib/MC/MCDisassembler/EDInst.cpp b/lib/MC/MCDisassembler/EDInst.cpp
deleted file mode 100644
index 4c4fdd2568..0000000000
--- a/lib/MC/MCDisassembler/EDInst.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-//===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Enhanced Disassembly library's instruction class.
-// The instruction is responsible for vending the string representation,
-// individual tokens, and operands for a single instruction.
-//
-//===----------------------------------------------------------------------===//
-
-#include "EDInst.h"
-#include "EDDisassembler.h"
-#include "EDOperand.h"
-#include "EDToken.h"
-#include "llvm/MC/EDInstInfo.h"
-#include "llvm/MC/MCInst.h"
-
-using namespace llvm;
-
-EDInst::EDInst(llvm::MCInst *inst,
- uint64_t byteSize,
- EDDisassembler &disassembler,
- const llvm::EDInstInfo *info) :
- Disassembler(disassembler),
- Inst(inst),
- ThisInstInfo(info),
- ByteSize(byteSize),
- BranchTarget(-1),
- MoveSource(-1),
- MoveTarget(-1) {
- OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
-}
-
-EDInst::~EDInst() {
- unsigned int index;
- unsigned int numOperands = Operands.size();
-
- for (index = 0; index < numOperands; ++index)
- delete Operands[index];
-
- unsigned int numTokens = Tokens.size();
-
- for (index = 0; index < numTokens; ++index)
- delete Tokens[index];
-
- delete Inst;
-}
-
-uint64_t EDInst::byteSize() {
- return ByteSize;
-}
-
-int EDInst::stringify() {
- if (StringifyResult.valid())
- return StringifyResult.result();
-
- if (Disassembler.printInst(String, *Inst))
- return StringifyResult.setResult(-1);
-
- String.push_back('\n');
-
- return StringifyResult.setResult(0);
-}
-
-int EDInst::getString(const char*& str) {
- if (stringify())
- return -1;
-
- str = String.c_str();
-
- return 0;
-}
-
-unsigned EDInst::instID() {
- return Inst->getOpcode();
-}
-
-bool EDInst::isBranch() {
- if (ThisInstInfo)
- return
- ThisInstInfo->instructionType == kInstructionTypeBranch ||
- ThisInstInfo->instructionType == kInstructionTypeCall;
- else
- return false;
-}
-
-bool EDInst::isMove() {
- if (ThisInstInfo)
- return ThisInstInfo->instructionType == kInstructionTypeMove;
- else
- return false;
-}
-
-int EDInst::parseOperands() {
- if (ParseResult.valid())
- return ParseResult.result();
-
- if (!ThisInstInfo)
- return ParseResult.setResult(-1);
-
- unsigned int opIndex;
- unsigned int mcOpIndex = 0;
-
- for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) {
- if (isBranch() &&
- (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) {
- BranchTarget = opIndex;
- }
- else if (isMove()) {
- if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource)
- MoveSource = opIndex;
- else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)
- MoveTarget = opIndex;
- }
-
- EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex);
-
- Operands.push_back(operand);
- }
-
- return ParseResult.setResult(0);
-}
-
-int EDInst::branchTargetID() {
- if (parseOperands())
- return -1;
- return BranchTarget;
-}
-
-int EDInst::moveSourceID() {
- if (parseOperands())
- return -1;
- return MoveSource;
-}
-
-int EDInst::moveTargetID() {
- if (parseOperands())
- return -1;
- return MoveTarget;
-}
-
-int EDInst::numOperands() {
- if (parseOperands())
- return -1;
- return Operands.size();
-}
-
-int EDInst::getOperand(EDOperand *&operand, unsigned int index) {
- if (parseOperands())
- return -1;
-
- if (index >= Operands.size())
- return -1;
-
- operand = Operands[index];
- return 0;
-}
-
-int EDInst::tokenize() {
- if (TokenizeResult.valid())
- return TokenizeResult.result();
-
- if (ThisInstInfo == NULL)
- return TokenizeResult.setResult(-1);
-
- if (stringify())
- return TokenizeResult.setResult(-1);
-
- return TokenizeResult.setResult(EDToken::tokenize(Tokens,
- String,
- OperandOrder,
- Disassembler));
-
-}
-
-int EDInst::numTokens() {
- if (tokenize())
- return -1;
- return Tokens.size();
-}
-
-int EDInst::getToken(EDToken *&token, unsigned int index) {
- if (tokenize())
- return -1;
- token = Tokens[index];
- return 0;
-}
-
-#ifdef __BLOCKS__
-int EDInst::visitTokens(EDTokenVisitor_t visitor) {
- if (tokenize())
- return -1;
-
- tokvec_t::iterator iter;
-
- for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) {
- int ret = visitor(*iter);
- if (ret == 1)
- return 0;
- if (ret != 0)
- return -1;
- }
-
- return 0;
-}
-#endif
diff --git a/lib/MC/MCDisassembler/EDInst.h b/lib/MC/MCDisassembler/EDInst.h
deleted file mode 100644
index cc0b562130..0000000000
--- a/lib/MC/MCDisassembler/EDInst.h
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- EDInst.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for the Enhanced Disassembly library's
-// instruction class. The instruction is responsible for vending the string
-// representation, individual tokens and operands for a single instruction.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EDINST_H
-#define LLVM_EDINST_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/DataTypes.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
- class MCInst;
- struct EDInstInfo;
- struct EDToken;
- struct EDDisassembler;
- struct EDOperand;
-
-#ifdef __BLOCKS__
- typedef int (^EDTokenVisitor_t)(EDToken *token);
-#endif
-
-/// CachedResult - Encapsulates the result of a function along with the validity
-/// of that result, so that slow functions don't need to run twice
-struct CachedResult {
- /// True if the result has been obtained by executing the function
- bool Valid;
- /// The result last obtained from the function
- int Result;
-
- /// Constructor - Initializes an invalid result
- CachedResult() : Valid(false) { }
- /// valid - Returns true if the result has been obtained by executing the
- /// function and false otherwise
- bool valid() { return Valid; }
- /// result - Returns the result of the function or an undefined value if
- /// valid() is false
- int result() { return Result; }
- /// setResult - Sets the result of the function and declares it valid
- /// returning the result (so that setResult() can be called from inside a
- /// return statement)
- /// @arg result - The result of the function
- int setResult(int result) { Result = result; Valid = true; return result; }
-};
-
-/// EDInst - Encapsulates a single instruction, which can be queried for its
-/// string representation, as well as its operands and tokens
-struct EDInst {
- /// The parent disassembler
- EDDisassembler &Disassembler;
- /// The containing MCInst
- llvm::MCInst *Inst;
- /// The instruction information provided by TableGen for this instruction
- const llvm::EDInstInfo *ThisInstInfo;
- /// The number of bytes for the machine code representation of the instruction
- uint64_t ByteSize;
-
- /// The result of the stringify() function
- CachedResult StringifyResult;
- /// The string representation of the instruction
- std::string String;
- /// The order in which operands from the InstInfo's operand information appear
- /// in String
- const signed char* OperandOrder;
-
- /// The result of the parseOperands() function
- CachedResult ParseResult;
- typedef llvm::SmallVector<EDOperand*, 5> opvec_t;
- /// The instruction's operands
- opvec_t Operands;
- /// The operand corresponding to the target, if the instruction is a branch
- int BranchTarget;
- /// The operand corresponding to the source, if the instruction is a move
- int MoveSource;
- /// The operand corresponding to the target, if the instruction is a move
- int MoveTarget;
-
- /// The result of the tokenize() function
- CachedResult TokenizeResult;
- typedef std::vector<EDToken*> tokvec_t;
- /// The instruction's tokens
- tokvec_t Tokens;
-
- /// Constructor - initializes an instruction given the output of the LLVM
- /// C++ disassembler
- ///
- /// @arg inst - The MCInst, which will now be owned by this object
- /// @arg byteSize - The size of the consumed instruction, in bytes
- /// @arg disassembler - The parent disassembler
- /// @arg instInfo - The instruction information produced by the table
- /// generator for this instruction
- EDInst(llvm::MCInst *inst,
- uint64_t byteSize,
- EDDisassembler &disassembler,
- const llvm::EDInstInfo *instInfo);
- ~EDInst();
-
- /// byteSize - returns the number of bytes consumed by the machine code
- /// representation of the instruction
- uint64_t byteSize();
- /// instID - returns the LLVM instruction ID of the instruction
- unsigned instID();
-
- /// stringify - populates the String and AsmString members of the instruction,
- /// returning 0 on success or -1 otherwise
- int stringify();
- /// getString - retrieves a pointer to the string representation of the
- /// instructinon, returning 0 on success or -1 otherwise
- ///
- /// @arg str - A reference to a pointer that, on success, is set to point to
- /// the string representation of the instruction; this string is still owned
- /// by the instruction and will be deleted when it is
- int getString(const char *&str);
-
- /// isBranch - Returns true if the instruction is a branch
- bool isBranch();
- /// isMove - Returns true if the instruction is a move
- bool isMove();
-
- /// parseOperands - populates the Operands member of the instruction,
- /// returning 0 on success or -1 otherwise
- int parseOperands();
- /// branchTargetID - returns the ID (suitable for use with getOperand()) of
- /// the target operand if the instruction is a branch, or -1 otherwise
- int branchTargetID();
- /// moveSourceID - returns the ID of the source operand if the instruction
- /// is a move, or -1 otherwise
- int moveSourceID();
- /// moveTargetID - returns the ID of the target operand if the instruction
- /// is a move, or -1 otherwise
- int moveTargetID();
-
- /// numOperands - returns the number of operands available to retrieve, or -1
- /// on error
- int numOperands();
- /// getOperand - retrieves an operand from the instruction's operand list by
- /// index, returning 0 on success or -1 on error
- ///
- /// @arg operand - A reference whose target is pointed at the operand on
- /// success, although the operand is still owned by the EDInst
- /// @arg index - The index of the operand in the instruction
- int getOperand(EDOperand *&operand, unsigned int index);
-
- /// tokenize - populates the Tokens member of the instruction, returning 0 on
- /// success or -1 otherwise
- int tokenize();
- /// numTokens - returns the number of tokens in the instruction, or -1 on
- /// error
- int numTokens();
- /// getToken - retrieves a token from the instruction's token list by index,
- /// returning 0 on success or -1 on error
- ///
- /// @arg token - A reference whose target is pointed at the token on success,
- /// although the token is still owned by the EDInst
- /// @arg index - The index of the token in the instrcutino
- int getToken(EDToken *&token, unsigned int index);
-
-#ifdef __BLOCKS__
- /// visitTokens - Visits each token in turn and applies a block to it,
- /// returning 0 if all blocks are visited and/or the block signals
- /// termination by returning 1; returns -1 on error
- ///
- /// @arg visitor - The visitor block to apply to all tokens.
- int visitTokens(EDTokenVisitor_t visitor);
-#endif
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/MC/MCDisassembler/EDMain.cpp b/lib/MC/MCDisassembler/EDMain.cpp
deleted file mode 100644
index 5c065dbf0c..0000000000
--- a/lib/MC/MCDisassembler/EDMain.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the enhanced disassembler's public C API.
-//
-//===----------------------------------------------------------------------===//
-
-#include "EDDisassembler.h"
-#include "EDInst.h"
-#include "EDOperand.h"
-#include "EDToken.h"
-#include "llvm-c/EnhancedDisassembly.h"
-using namespace llvm;
-
-int EDGetDisassembler(EDDisassemblerRef *disassembler,
- const char *triple,
- EDAssemblySyntax_t syntax) {
- EDDisassembler::AssemblySyntax Syntax;
- switch (syntax) {
- default: llvm_unreachable("Unknown assembly syntax!");
- case kEDAssemblySyntaxX86Intel:
- Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
- break;
- case kEDAssemblySyntaxX86ATT:
- Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
- break;
- case kEDAssemblySyntaxARMUAL:
- Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
- break;
- }
-
- EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
-
- if (!ret)
- return -1;
- *disassembler = ret;
- return 0;
-}
-
-int EDGetRegisterName(const char** regName,
- EDDisassemblerRef disassembler,
- unsigned regID) {
- const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
- if (!name)
- return -1;
- *regName = name;
- return 0;
-}
-
-int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
- unsigned regID) {
- return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
-}
-
-int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
- unsigned regID) {
- return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
-}
-
-unsigned int EDCreateInsts(EDInstRef *insts,
- unsigned int count,
- EDDisassemblerRef disassembler,
- ::EDByteReaderCallback byteReader,
- uint64_t address,
- void *arg) {
- unsigned int index;
-
- for (index = 0; index < count; ++index) {
- EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
- address, arg);
-
- if (!inst)
- return index;
-
- insts[index] = inst;
- address += inst->byteSize();
- }
-
- return count;
-}
-
-void EDReleaseInst(EDInstRef inst) {
- delete ((EDInst*)inst);
-}
-
-int EDInstByteSize(EDInstRef inst) {
- return ((EDInst*)inst)->byteSize();
-}
-
-int EDGetInstString(const char **buf,
- EDInstRef inst) {
- return ((EDInst*)inst)->getString(*buf);
-}
-
-int EDInstID(unsigned *instID, EDInstRef inst) {
- *instID = ((EDInst*)inst)->instID();
- return 0;
-}
-
-int EDInstIsBranch(EDInstRef inst) {
- return ((EDInst*)inst)->isBranch();
-}
-
-int EDInstIsMove(EDInstRef inst) {
- return ((EDInst*)inst)->isMove();
-}
-
-int EDBranchTargetID(EDInstRef inst) {
- return ((EDInst*)inst)->branchTargetID();
-}
-
-int EDMoveSourceID(EDInstRef inst) {
- return ((EDInst*)inst)->moveSourceID();
-}
-
-int EDMoveTargetID(EDInstRef inst) {
- return ((EDInst*)inst)->moveTargetID();
-}
-
-int EDNumTokens(EDInstRef inst) {
- return ((EDInst*)inst)->numTokens();
-}
-
-int EDGetToken(EDTokenRef *token,
- EDInstRef inst,
- int index) {
- return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
-}
-
-int EDGetTokenString(const char **buf,
- EDTokenRef token) {
- return ((EDToken*)token)->getString(*buf);
-}
-
-int EDOperandIndexForToken(EDTokenRef token) {
- return ((EDToken*)token)->operandID();
-}
-
-int EDTokenIsWhitespace(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
-}
-
-int EDTokenIsPunctuation(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
-}
-
-int EDTokenIsOpcode(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
-}
-
-int EDTokenIsLiteral(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
-}
-
-int EDTokenIsRegister(EDTokenRef token) {
- return ((EDToken*)token)->type() == EDToken::kTokenRegister;
-}
-
-int EDTokenIsNegativeLiteral(EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
- return -1;
-
- return ((EDToken*)token)->literalSign();
-}
-
-int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
- return -1;
-
- return ((EDToken*)token)->literalAbsoluteValue(*value);
-}
-
-int EDRegisterTokenValue(unsigned *registerID,
- EDTokenRef token) {
- if (((EDToken*)token)->type() != EDToken::kTokenRegister)
- return -1;
-
- return ((EDToken*)token)->registerID(*registerID);
-}
-
-int EDNumOperands(EDInstRef inst) {
- return ((EDInst*)inst)->numOperands();
-}
-
-int EDGetOperand(EDOperandRef *operand,
- EDInstRef inst,
- int index) {
- return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
-}
-
-int EDOperandIsRegister(EDOperandRef operand) {
- return ((EDOperand*)operand)->isRegister();
-}
-
-int EDOperandIsImmediate(EDOperandRef operand) {
- return ((EDOperand*)operand)->isImmediate();
-}
-
-int EDOperandIsMemory(EDOperandRef operand) {
- return ((EDOperand*)operand)->isMemory();
-}
-
-int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
- if (!((EDOperand*)operand)->isRegister())
- return -1;
- *value = ((EDOperand*)operand)->regVal();
- return 0;
-}
-
-int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
- if (!((EDOperand*)operand)->isImmediate())
- return -1;
- *value = ((EDOperand*)operand)->immediateVal();
- return 0;
-}
-
-int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
- ::EDRegisterReaderCallback regReader, void *arg) {
- return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
-}
-
-#ifdef __BLOCKS__
-
-struct ByteReaderWrapper {
- EDByteBlock_t byteBlock;
-};
-
-static int readerWrapperCallback(uint8_t *byte,
- uint64_t address,
- void *arg) {
- struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
- return wrapper->byteBlock(byte, address);
-}
-
-unsigned int EDBlockCreateInsts(EDInstRef *insts,
- int count,
- EDDisassemblerRef disassembler,
- EDByteBlock_t byteBlock,
- uint64_t address) {
- struct ByteReaderWrapper wrapper;
- wrapper.byteBlock = byteBlock;
-
- return EDCreateInsts(insts, count, disassembler, readerWrapperCallback,
- address, (void*)&wrapper);
-}
-
-int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
- EDRegisterBlock_t regBlock) {
- return ((EDOperand*)operand)->evaluate(*result, regBlock);
-}
-
-int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
- return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
-}
-
-#else
-
-extern "C" unsigned int EDBlockCreateInsts() {
- return 0;
-}
-
-extern "C" int EDBlockEvaluateOperand() {
- return -1;
-}
-
-extern "C" int EDBlockVisitTokens() {
- return -1;
-}
-
-#endif
diff --git a/lib/MC/MCDisassembler/EDOperand.cpp b/lib/MC/MCDisassembler/EDOperand.cpp
deleted file mode 100644
index 48b374659d..0000000000
--- a/lib/MC/MCDisassembler/EDOperand.cpp
+++ /dev/null
@@ -1,315 +0,0 @@
-//===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Enhanced Disassembly library's operand class. The
-// operand is responsible for allowing evaluation given a particular register
-// context.
-//
-//===----------------------------------------------------------------------===//
-
-#include "EDOperand.h"
-#include "EDDisassembler.h"
-#include "EDInst.h"
-#include "llvm/MC/EDInstInfo.h"
-#include "llvm/MC/MCInst.h"
-using namespace llvm;
-
-EDOperand::EDOperand(const EDDisassembler &disassembler,
- const EDInst &inst,
- unsigned int opIndex,
- unsigned int &mcOpIndex) :
- Disassembler(disassembler),
- Inst(inst),
- OpIndex(opIndex),
- MCOpIndex(mcOpIndex) {
- unsigned int numMCOperands = 0;
-
- Triple::ArchType arch = Disassembler.TgtTriple.getArch();
-
- if (arch == Triple::x86 ||
- arch == Triple::x86_64) {
- uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
-
- switch (operandType) {
- default:
- break;
- case kOperandTypeImmediate:
- numMCOperands = 1;
- break;
- case kOperandTypeRegister:
- numMCOperands = 1;
- break;
- case kOperandTypeX86Memory:
- numMCOperands = 5;
- break;
- case kOperandTypeX86EffectiveAddress:
- numMCOperands = 4;
- break;
- case kOperandTypeX86PCRelative:
- numMCOperands = 1;
- break;
- }
- }
- else if (arch == Triple::arm ||
- arch == Triple::thumb) {
- uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
-
- switch (operandType) {
- default:
- case kOperandTypeARMRegisterList:
- case kOperandTypeARMDPRRegisterList:
- case kOperandTypeARMSPRRegisterList:
- break;
- case kOperandTypeImmediate:
- case kOperandTypeRegister:
- case kOperandTypeARMBranchTarget:
- case kOperandTypeARMSoImm:
- case kOperandTypeARMRotImm:
- case kOperandTypeThumb2SoImm:
- case kOperandTypeARMSoImm2Part:
- case kOperandTypeARMPredicate:
- case kOperandTypeThumbITMask:
- case kOperandTypeThumb2AddrModeImm8Offset:
- case kOperandTypeARMTBAddrMode:
- case kOperandTypeThumb2AddrModeImm8s4Offset:
- case kOperandTypeARMAddrMode7:
- case kOperandTypeThumb2AddrModeReg:
- numMCOperands = 1;
- break;
- case kOperandTypeThumb2SoReg:
- case kOperandTypeAddrModeImm12:
- case kOperandTypeARMAddrMode2Offset:
- case kOperandTypeARMAddrMode3Offset:
- case kOperandTypeARMAddrMode4:
- case kOperandTypeARMAddrMode5:
- case kOperandTypeARMAddrModePC:
- case kOperandTypeThumb2AddrModeImm8:
- case kOperandTypeThumb2AddrModeImm12:
- case kOperandTypeThumb2AddrModeImm8s4:
- case kOperandTypeThumbAddrModeImmS1:
- case kOperandTypeThumbAddrModeImmS2:
- case kOperandTypeThumbAddrModeImmS4:
- case kOperandTypeThumbAddrModeRR:
- case kOperandTypeThumbAddrModeSP:
- case kOperandTypeThumbAddrModePC:
- numMCOperands = 2;
- break;
- case kOperandTypeARMSoReg:
- case kOperandTypeLdStSOReg:
- case kOperandTypeARMAddrMode2:
- case kOperandTypeARMAddrMode3:
- case kOperandTypeThumb2AddrModeSoReg:
- case kOperandTypeThumbAddrModeRegS1:
- case kOperandTypeThumbAddrModeRegS2:
- case kOperandTypeThumbAddrModeRegS4:
- case kOperandTypeARMAddrMode6Offset:
- numMCOperands = 3;
- break;
- case kOperandTypeARMAddrMode6:
- numMCOperands = 4;
- break;
- }
- }
-
- mcOpIndex += numMCOperands;
-}
-
-EDOperand::~EDOperand() {
-}
-
-int EDOperand::evaluate(uint64_t &result,
- EDRegisterReaderCallback callback,
- void *arg) {
- uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
-
- Triple::ArchType arch = Disassembler.TgtTriple.getArch();
-
- switch (arch) {
- default:
- return -1;
- case Triple::x86:
- case Triple::x86_64:
- switch (operandType) {
- default:
- return -1;
- case kOperandTypeImmediate:
- result = Inst.Inst->getOperand(MCOpIndex).getImm();
- return 0;
- case kOperandTypeRegister:
- {
- unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
- return callback(&result, reg, arg);
- }
- case kOperandTypeX86PCRelative:
- {
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
-
- uint64_t ripVal;
-
- // TODO fix how we do this
-
- if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
- return -1;
-
- result = ripVal + displacement;
- return 0;
- }
- case kOperandTypeX86Memory:
- case kOperandTypeX86EffectiveAddress:
- {
- unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
- uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
- unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
-
- uint64_t addr = 0;
-
- unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
-
- if (segmentReg != 0 && arch == Triple::x86_64) {
- unsigned fsID = Disassembler.registerIDWithName("FS");
- unsigned gsID = Disassembler.registerIDWithName("GS");
-
- if (segmentReg == fsID ||
- segmentReg == gsID) {
- uint64_t segmentBase;
- if (!callback(&segmentBase, segmentReg, arg))
- addr += segmentBase;
- }
- }
-
- if (baseReg) {
- uint64_t baseVal;
- if (callback(&baseVal, baseReg, arg))
- return -1;
- addr += baseVal;
- }
-
- if (indexReg) {
- uint64_t indexVal;
- if (callback(&indexVal, indexReg, arg))
- return -1;
- addr += (scaleAmount * indexVal);
- }
-
- addr += displacement;
-
- result = addr;
- return 0;
- }
- } // switch (operandType)
- case Triple::arm:
- case Triple::thumb:
- switch (operandType) {
- default:
- return -1;
- case kOperandTypeImmediate:
- if (!Inst.Inst->getOperand(MCOpIndex).isImm())
- return -1;
-
- result = Inst.Inst->getOperand(MCOpIndex).getImm();
- return 0;
- case kOperandTypeRegister:
- {
- if (!Inst.Inst->getOperand(MCOpIndex).isReg())
- return -1;
-
- unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
- return callback(&result, reg, arg);
- }
- case kOperandTypeARMBranchTarget:
- {
- if (!Inst.Inst->getOperand(MCOpIndex).isImm())
- return -1;
-
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
-
- uint64_t pcVal;
-
- if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
- return -1;
-
- result = pcVal + displacement;
- return 0;
- }
- }
- }
-}
-
-int EDOperand::isRegister() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
-}
-
-unsigned EDOperand::regVal() {
- return Inst.Inst->getOperand(MCOpIndex).getReg();
-}
-
-int EDOperand::isImmediate() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
-}
-
-uint64_t EDOperand::immediateVal() {
- return Inst.Inst->getOperand(MCOpIndex).getImm();
-}
-
-int EDOperand::isMemory() {
- uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
-
- switch (operandType) {
- default:
- return 0;
- case kOperandTypeX86Memory:
- case kOperandTypeX86PCRelative:
- case kOperandTypeX86EffectiveAddress:
- case kOperandTypeARMSoReg:
- case kOperandTypeARMSoImm:
- case kOperandTypeARMAddrMode2:
- case kOperandTypeARMAddrMode2Offset:
- case kOperandTypeARMAddrMode3:
- case kOperandTypeARMAddrMode3Offset:
- case kOperandTypeARMAddrMode4:
- case kOperandTypeARMAddrMode5:
- case kOperandTypeARMAddrMode6:
- case kOperandTypeARMAddrMode7:
- case kOperandTypeARMAddrModePC:
- case kOperandTypeARMBranchTarget:
- case kOperandTypeThumbAddrModeRegS1:
- case kOperandTypeThumbAddrModeRegS2:
- case kOperandTypeThumbAddrModeRegS4:
- case kOperandTypeThumbAddrModeRR:
- case kOperandTypeThumbAddrModeSP:
- case kOperandTypeThumb2SoImm:
- case kOperandTypeThumb2AddrModeImm8:
- case kOperandTypeThumb2AddrModeImm8Offset:
- case kOperandTypeThumb2AddrModeImm12:
- case kOperandTypeThumb2AddrModeSoReg:
- case kOperandTypeThumb2AddrModeImm8s4:
- case kOperandTypeThumb2AddrModeReg:
- return 1;
- }
-}
-
-#ifdef __BLOCKS__
-namespace {
- struct RegisterReaderWrapper {
- EDOperand::EDRegisterBlock_t regBlock;
- };
-}
-
-static int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
- RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
- return wrapper->regBlock(value, regID);
-}
-
-int EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
- RegisterReaderWrapper wrapper;
- wrapper.regBlock = regBlock;
- return evaluate(result, readerWrapperCallback, (void*)&wrapper);
-}
-#endif
diff --git a/lib/MC/MCDisassembler/EDOperand.h b/lib/MC/MCDisassembler/EDOperand.h
deleted file mode 100644
index 50260ec965..0000000000
--- a/lib/MC/MCDisassembler/EDOperand.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-EDOperand.h - LLVM Enhanced Disassembler ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for the Enhanced Disassembly library's
-// operand class. The operand is responsible for allowing evaluation given a
-// particular register context.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EDOPERAND_H
-#define LLVM_EDOPERAND_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-struct EDDisassembler;
-struct EDInst;
-
-typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
- void* arg);
-
-
-/// EDOperand - Encapsulates a single operand, which can be evaluated by the
-/// client
-struct EDOperand {
- /// The parent disassembler
- const EDDisassembler &Disassembler;
- /// The parent instruction
- const EDInst &Inst;
-
- /// The index of the operand in the EDInst
- unsigned int OpIndex;
- /// The index of the first component of the operand in the MCInst
- unsigned int MCOpIndex;
-
- /// Constructor - Initializes an EDOperand
- ///
- /// @arg disassembler - The disassembler responsible for the operand
- /// @arg inst - The instruction containing this operand
- /// @arg opIndex - The index of the operand in inst
- /// @arg mcOpIndex - The index of the operand in the original MCInst
- EDOperand(const EDDisassembler &disassembler,
- const EDInst &inst,
- unsigned int opIndex,
- unsigned int &mcOpIndex);
- ~EDOperand();
-
- /// evaluate - Returns the numeric value of an operand to the extent possible,
- /// returning 0 on success or -1 if there was some problem (such as a
- /// register not being readable)
- ///
- /// @arg result - A reference whose target is filled in with the value of
- /// the operand (the address if it is a memory operand)
- /// @arg callback - A function to call to obtain register values
- /// @arg arg - An opaque argument to pass to callback
- int evaluate(uint64_t &result,
- EDRegisterReaderCallback callback,
- void *arg);
-
- /// isRegister - Returns 1 if the operand is a register or 0 otherwise
- int isRegister();
- /// regVal - Returns the register value.
- unsigned regVal();
-
- /// isImmediate - Returns 1 if the operand is an immediate or 0 otherwise
- int isImmediate();
- /// immediateVal - Returns the immediate value.
- uint64_t immediateVal();
-
- /// isMemory - Returns 1 if the operand is a memory location or 0 otherwise
- int isMemory();
-
-#ifdef __BLOCKS__
- typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
-
- /// evaluate - Like evaluate for a callback, but uses a block instead
- int evaluate(uint64_t &result,
- EDRegisterBlock_t regBlock);
-#endif
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/MC/MCDisassembler/EDToken.cpp b/lib/MC/MCDisassembler/EDToken.cpp
deleted file mode 100644
index a7fb1eb3c1..0000000000
--- a/lib/MC/MCDisassembler/EDToken.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-//===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Enhanced Disassembler library's token class. The
-// token is responsible for vending information about the token, such as its
-// type and logical value.
-//
-//===----------------------------------------------------------------------===//
-
-#include "EDToken.h"
-#include "EDDisassembler.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/MC/MCParser/MCAsmLexer.h"
-#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
-using namespace llvm;
-
-EDToken::EDToken(StringRef str,
- enum tokenType type,
- uint64_t localType,
- EDDisassembler &disassembler) :
- Disassembler(disassembler),
- Str(str),
- Type(type),
- LocalType(localType),
- OperandID(-1) {
-}
-
-EDToken::~EDToken() {
-}
-
-void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
- Type = kTokenLiteral;
- LiteralSign = sign;
- LiteralAbsoluteValue = absoluteValue;
-}
-
-void EDToken::makeRegister(unsigned registerID) {
- Type = kTokenRegister;
- RegisterID = registerID;
-}
-
-void EDToken::setOperandID(int operandID) {
- OperandID = operandID;
-}
-
-enum EDToken::tokenType EDToken::type() const {
- return Type;
-}
-
-uint64_t EDToken::localType() const {
- return LocalType;
-}
-
-StringRef EDToken::string() const {
- return Str;
-}
-
-int EDToken::operandID() const {
- return OperandID;
-}
-
-int EDToken::literalSign() const {
- if (Type != kTokenLiteral)
- return -1;
- return (LiteralSign ? 1 : 0);
-}
-
-int EDToken::literalAbsoluteValue(uint64_t &value) const {
- if (Type != kTokenLiteral)
- return -1;
- value = LiteralAbsoluteValue;
- return 0;
-}
-
-int EDToken::registerID(unsigned &registerID) const {
- if (Type != kTokenRegister)
- return -1;
- registerID = RegisterID;
- return 0;
-}
-
-int EDToken::tokenize(std::vector<EDToken*> &tokens,
- std::string &str,
- const signed char *operandOrder,
- EDDisassembler &disassembler) {
- SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
- SmallVector<AsmToken, 10> asmTokens;
-
- if (disassembler.parseInst(parsedOperands, asmTokens, str))
- {
- for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
- delete parsedOperands[i];
- return -1;
- }
-
- SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
- unsigned int operandIndex;
- SmallVectorImpl<AsmToken>::iterator tokenIterator;
-
- operandIterator = parsedOperands.begin();
- operandIndex = 0;
-
- bool readOpcode = false;
-
- const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
-
- for (tokenIterator = asmTokens.begin();
- tokenIterator != asmTokens.end();
- ++tokenIterator) {
- SMLoc tokenLoc = tokenIterator->getLoc();
-
- const char *tokenPointer = tokenLoc.getPointer();
-
- if (tokenPointer > wsPointer) {
- unsigned long wsLength = tokenPointer - wsPointer;
-
- EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
- EDToken::kTokenWhitespace,
- 0,
- disassembler);
-
- tokens.push_back(whitespaceToken);
- }
-
- wsPointer = tokenPointer + tokenIterator->getString().size();
-
- while (operandIterator != parsedOperands.end() &&
- tokenLoc.getPointer() >
- (*operandIterator)->getEndLoc().getPointer()) {
- ++operandIterator;
- ++operandIndex;
- }
-
- EDToken *token;
-
- switch (tokenIterator->getKind()) {
- case AsmToken::Identifier:
- if (!readOpcode) {
- token = new EDToken(tokenIterator->getString(),
- EDToken::kTokenOpcode,
- (uint64_t)tokenIterator->getKind(),
- disassembler);
- readOpcode = true;
- break;
- }
- // any identifier that isn't an opcode is mere punctuation; so we fall
- // through
- default:
- token = new EDToken(tokenIterator->getString(),
- EDToken::kTokenPunctuation,
- (uint64_t)tokenIterator->getKind(),
- disassembler);
- break;
- case AsmToken::Integer:
- {
- token = new EDToken(tokenIterator->getString(),
- EDToken::kTokenLiteral,
- (uint64_t)tokenIterator->getKind(),
- disassembler);
-
- int64_t intVal = tokenIterator->getIntVal();
-
- if (intVal < 0)
- token->makeLiteral(true, -intVal);
- else
- token->makeLiteral(false, intVal);
- break;
- }
- case AsmToken::Register:
- {
- token = new EDToken(tokenIterator->getString(),
- EDToken::kTokenLiteral,
- (uint64_t)tokenIterator->getKind(),
- disassembler);
-
- token->makeRegister((unsigned)tokenIterator->getRegVal());
- break;
- }
- }
-
- if (operandIterator != parsedOperands.end() &&
- tokenLoc.getPointer() >=
- (*operandIterator)->getStartLoc().getPointer()) {
- /// operandIndex == 0 means the operand is the instruction (which the
- /// AsmParser treats as an operand but edis does not). We therefore skip
- /// operandIndex == 0 and subtract 1 from all other operand indices.
-
- if (operandIndex > 0)
- token->setOperandID(operandOrder[operandIndex - 1]);
- }
-
- tokens.push_back(token);
- }
-
- // Free any parsed operands.
- for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
- delete parsedOperands[i];
-
- return 0;
-}
-
-int EDToken::getString(const char*& buf) {
- if (PermStr.length() == 0) {
- PermStr = Str.str();
- }
- buf = PermStr.c_str();
- return 0;
-}
diff --git a/lib/MC/MCDisassembler/EDToken.h b/lib/MC/MCDisassembler/EDToken.h
deleted file mode 100644
index 384079b72e..0000000000
--- a/lib/MC/MCDisassembler/EDToken.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===-EDToken.h - LLVM Enhanced Disassembler --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the interface for the Enhanced Disassembly library's token
-// class. The token is responsible for vending information about the token,
-// such as its type and logical value.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EDTOKEN_H
-#define LLVM_EDTOKEN_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/DataTypes.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-
-struct EDDisassembler;
-
-/// EDToken - Encapsulates a single token, which can provide a string
-/// representation of itself or interpret itself in various ways, depending
-/// on the token type.
-struct EDToken {
- enum tokenType {
- kTokenWhitespace,
- kTokenOpcode,
- kTokenLiteral,
- kTokenRegister,
- kTokenPunctuation
- };
-
- /// The parent disassembler
- EDDisassembler &Disassembler;
-
- /// The token's string representation
- llvm::StringRef Str;
- /// The token's string representation, but in a form suitable for export
- std::string PermStr;
- /// The type of the token, as exposed through the external API
- enum tokenType Type;
- /// The type of the token, as recorded by the syntax-specific tokenizer
- uint64_t LocalType;
- /// The operand corresponding to the token, or (unsigned int)-1 if not
- /// part of an operand.
- int OperandID;
-
- /// The sign if the token is a literal (1 if negative, 0 otherwise)
- bool LiteralSign;
- /// The absolute value if the token is a literal
- uint64_t LiteralAbsoluteValue;
- /// The LLVM register ID if the token is a register name
- unsigned RegisterID;
-
- /// Constructor - Initializes an EDToken with the information common to all
- /// tokens
- ///
- /// @arg str - The string corresponding to the token
- /// @arg type - The token's type as exposed through the public API
- /// @arg localType - The token's type as recorded by the tokenizer
- /// @arg disassembler - The disassembler responsible for the token
- EDToken(llvm::StringRef str,
- enum tokenType type,
- uint64_t localType,
- EDDisassembler &disassembler);
-
- /// makeLiteral - Adds the information specific to a literal
- /// @arg sign - The sign of the literal (1 if negative, 0
- /// otherwise)
- ///
- /// @arg absoluteValue - The absolute value of the literal
- void makeLiteral(bool sign, uint64_t absoluteValue);
- /// makeRegister - Adds the information specific to a register
- ///
- /// @arg registerID - The LLVM register ID
- void makeRegister(unsigned registerID);
-
- /// setOperandID - Links the token to a numbered operand
- ///
- /// @arg operandID - The operand ID to link to
- void setOperandID(int operandID);
-
- ~EDToken();
-
- /// type - Returns the public type of the token
- enum tokenType type() const;
- /// localType - Returns the tokenizer-specific type of the token
- uint64_t localType() const;
- /// string - Returns the string representation of the token
- llvm::StringRef string() const;
- /// operandID - Returns the operand ID of the token
- int operandID() const;
-
- /// literalSign - Returns the sign of the token
- /// (1 if negative, 0 if positive or unsigned, -1 if it is not a literal)
- int literalSign() const;
- /// literalAbsoluteValue - Retrieves the absolute value of the token, and
- /// returns -1 if the token is not a literal
- /// @arg value - A reference to a value that is filled in with the absolute
- /// value, if it is valid
- int literalAbsoluteValue(uint64_t &value) const;
- /// registerID - Retrieves the register ID of the token, and returns -1 if the
- /// token is not a register
- ///
- /// @arg registerID - A reference to a value that is filled in with the
- /// register ID, if it is valid
- int registerID(unsigned &registerID) const;
-
- /// tokenize - Tokenizes a string using the platform- and syntax-specific
- /// tokenizer, and returns 0 on success (-1 on failure)
- ///
- /// @arg tokens - A vector that will be filled in with pointers to
- /// allocated tokens
- /// @arg str - The string, as outputted by the AsmPrinter
- /// @arg operandOrder - The order of the operands from the operandFlags array
- /// as they appear in str
- /// @arg disassembler - The disassembler for the desired target and
- // assembly syntax
- static int tokenize(std::vector<EDToken*> &tokens,
- std::string &str,
- const signed char *operandOrder,
- EDDisassembler &disassembler);
-
- /// getString - Directs a character pointer to the string, returning 0 on
- /// success (-1 on failure)
- /// @arg buf - A reference to a pointer that is set to point to the string.
- /// The string is still owned by the token.
- int getString(const char*& buf);
-};
-
-} // end namespace llvm
-#endif
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 597ee1d691..c81abe952a 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -101,7 +101,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
}
// Add the line entry to this section's entries.
- LineSection->addLineEntry(LineEntry);
+ LineSection->addLineEntry(LineEntry,
+ MCOS->getContext().getDwarfCompileUnitID());
}
//
@@ -131,7 +132,12 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
//
static inline void EmitDwarfLineTable(MCStreamer *MCOS,
const MCSection *Section,
- const MCLineSection *LineSection) {
+ const MCLineSection *LineSection,
+ unsigned CUID) {
+ // This LineSection does not contain any LineEntry for the given Compile Unit.
+ if (!LineSection->containEntriesForID(CUID))
+ return;
+
unsigned FileNum = 1;
unsigned LastLine = 1;
unsigned Column = 0;
@@ -141,8 +147,8 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
// Loop through each MCLineEntry and encode the dwarf line number table.
for (MCLineSection::const_iterator
- it = LineSection->getMCLineEntries()->begin(),
- ie = LineSection->getMCLineEntries()->end(); it != ie; ++it) {
+ it = LineSection->getMCLineEntries(CUID).begin(),
+ ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) {
if (FileNum != it->getFileNum()) {
FileNum = it->getFileNum();
@@ -215,9 +221,36 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// Switch to the section where the table will be emitted into.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
- // Create a symbol at the beginning of this section.
- MCSymbol *LineStartSym = context.CreateTempSymbol();
- // Set the value of the symbol, as we are at the start of the section.
+ const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
+ MCOS->getContext().getMCLineTableSymbols();
+ // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
+ // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
+ // Handle Compile Unit 0, the line table start symbol is the section symbol.
+ const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
+ // Handle the rest of the Compile Units.
+ for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
+ EmitCU(MCOS, Is);
+
+ // Now delete the MCLineSections that were created in MCLineEntry::Make()
+ // and used to emit the line table.
+ const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
+ MCOS->getContext().getMCLineSections();
+ for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it =
+ MCLineSections.begin(), ie = MCLineSections.end(); it != ie;
+ ++it)
+ delete it->second;
+
+ return LineStartSym;
+}
+
+const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
+ MCContext &context = MCOS->getContext();
+
+ // Create a symbol at the beginning of the line table.
+ MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
+ if (!LineStartSym)
+ LineStartSym = context.CreateTempSymbol();
+ // Set the value of the symbol, as we are at the start of the line table.
MCOS->EmitLabel(LineStartSym);
// Create a symbol for the end of the section (to be set when we get there).
@@ -239,8 +272,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// total length, the 2 bytes for the version, and these 4 bytes for the
// length of the prologue.
MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
- (4 + 2 + 4)),
- 4, 0);
+ (4 + 2 + 4)), 4, 0);
// Parameters of the state machine, are next.
MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);
@@ -267,19 +299,19 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// First the directory table.
const std::vector<StringRef> &MCDwarfDirs =
- context.getMCDwarfDirs();
+ context.getMCDwarfDirs(CUID);
for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
- MCOS->EmitBytes(MCDwarfDirs[i], 0); // the DirectoryName
- MCOS->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
+ MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
+ MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
}
MCOS->EmitIntValue(0, 1); // Terminate the directory list
// Second the file table.
const std::vector<MCDwarfFile *> &MCDwarfFiles =
- MCOS->getContext().getMCDwarfFiles();
+ MCOS->getContext().getMCDwarfFiles(CUID);
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
- MCOS->EmitBytes(MCDwarfFiles[i]->getName(), 0); // FileName
- MCOS->EmitBytes(StringRef("\0", 1), 0); // the null term. of the string
+ MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
+ MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
// the Directory num
MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
@@ -301,11 +333,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
++it) {
const MCSection *Sec = *it;
const MCLineSection *Line = MCLineSections.lookup(Sec);
- EmitDwarfLineTable(MCOS, Sec, Line);
-
- // Now delete the MCLineSections that were created in MCLineEntry::Make()
- // and used to emit the line table.
- delete Line;
+ EmitDwarfLineTable(MCOS, Sec, Line, CUID);
}
if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
@@ -342,7 +370,7 @@ void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta,
SmallString<256> Tmp;
raw_svector_ostream OS(Tmp);
MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
- MCOS->EmitBytes(OS.str(), /*AddrSpace=*/0);
+ MCOS->EmitBytes(OS.str());
}
/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
@@ -618,30 +646,35 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
const std::vector<StringRef> &MCDwarfDirs =
context.getMCDwarfDirs();
if (MCDwarfDirs.size() > 0) {
- MCOS->EmitBytes(MCDwarfDirs[0], 0);
- MCOS->EmitBytes("/", 0);
+ MCOS->EmitBytes(MCDwarfDirs[0]);
+ MCOS->EmitBytes("/");
}
const std::vector<MCDwarfFile *> &MCDwarfFiles =
MCOS->getContext().getMCDwarfFiles();
- MCOS->EmitBytes(MCDwarfFiles[1]->getName(), 0);
+ MCOS->EmitBytes(MCDwarfFiles[1]->getName());
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_comp_dir, the working directory the assembly was done in.
- llvm::sys::Path CWD = llvm::sys::Path::GetCurrentDirectory();
- MCOS->EmitBytes(StringRef(CWD.c_str()), 0);
+ MCOS->EmitBytes(context.getCompilationDir());
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_APPLE_flags, the command line arguments of the assembler tool.
StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
if (!DwarfDebugFlags.empty()){
- MCOS->EmitBytes(DwarfDebugFlags, 0);
+ MCOS->EmitBytes(DwarfDebugFlags);
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
}
// AT_producer, the version of the assembler tool.
- MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "), 0);
- MCOS->EmitBytes(StringRef(PACKAGE_VERSION), 0);
- MCOS->EmitBytes(StringRef(")"), 0);
+ StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
+ if (!DwarfDebugProducer.empty()){
+ MCOS->EmitBytes(DwarfDebugProducer);
+ }
+ else {
+ MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
+ MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
+ MCOS->EmitBytes(StringRef(")"));
+ }
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
@@ -662,7 +695,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
MCOS->EmitULEB128IntValue(2);
// AT_name, of the label without any leading underbar.
- MCOS->EmitBytes(Entry->getName(), 0);
+ MCOS->EmitBytes(Entry->getName());
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_decl_file, index into the file table.
@@ -787,7 +820,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
static int getDataAlignmentFactor(MCStreamer &streamer) {
MCContext &context = streamer.getContext();
const MCAsmInfo &asmInfo = context.getAsmInfo();
- int size = asmInfo.getPointerSize();
+ int size = asmInfo.getCalleeSaveStackSlotSize();
if (asmInfo.isStackGrowthDirectionUp())
return size;
else
@@ -1072,7 +1105,7 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
}
case MCCFIInstruction::OpEscape:
if (VerboseAsm) Streamer.AddComment("Escape bytes");
- Streamer.EmitBytes(Instr.getValues(), 0);
+ Streamer.EmitBytes(Instr.getValues());
return;
}
llvm_unreachable("Unhandled case in switch");
@@ -1230,7 +1263,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
Augmentation += "R";
if (IsSignalFrame)
Augmentation += "S";
- streamer.EmitBytes(Augmentation.str(), 0);
+ streamer.EmitBytes(Augmentation.str());
}
streamer.EmitIntValue(0, 1);
@@ -1494,7 +1527,7 @@ void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
SmallString<256> Tmp;
raw_svector_ostream OS(Tmp);
MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS);
- Streamer.EmitBytes(OS.str(), /*AddrSpace=*/0);
+ Streamer.EmitBytes(OS.str());
}
void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta,
diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp
index 4db2846bc3..560cdbc6ab 100644
--- a/lib/MC/MCELF.cpp
+++ b/lib/MC/MCELF.cpp
@@ -52,6 +52,8 @@ unsigned MCELF::GetType(const MCSymbolData &SD) {
return Type;
}
+// Visibility is stored in the first two bits of st_other
+// st_other values are stored in the second byte of get/setFlags
void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
@@ -68,4 +70,17 @@ unsigned MCELF::GetVisibility(MCSymbolData &SD) {
return Visibility;
}
+// Other is stored in the last six bits of st_other
+// st_other values are stored in the second byte of get/setFlags
+void MCELF::setOther(MCSymbolData &SD, unsigned Other) {
+ uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_Other_Shift);
+ SD.setFlags(OtherFlags | (Other << ELF_Other_Shift));
+}
+
+unsigned MCELF::getOther(MCSymbolData &SD) {
+ unsigned Other =
+ (SD.getFlags() & (0x3f << ELF_Other_Shift)) >> ELF_Other_Shift;
+ return Other;
+}
+
}
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index 74cd042a0f..4cac84d666 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -24,11 +24,6 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
IsN64(IsN64_){
}
-/// Default e_flags = 0
-unsigned MCELFObjectTargetWriter::getEFlags() const {
- return 0;
-}
-
const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 8b9bdb14a0..7f5f1b63e5 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -1,4 +1,4 @@
-//===- lib/MC/MCELFStreamer.cpp - ELF Object Output ------------===//
+//===- lib/MC/MCELFStreamer.cpp - ELF Object Output -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -65,6 +65,10 @@ inline void MCELFStreamer::SetSectionBss() {
MCELFStreamer::~MCELFStreamer() {
}
+void MCELFStreamer::InitToTextSection() {
+ SetSectionText();
+}
+
void MCELFStreamer::InitSections() {
// This emulates the same behavior of GNU as. This makes it easier
// to compare the output as the major sections are in the same order.
@@ -86,6 +90,10 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) {
MCELF::SetType(SD, ELF::STT_TLS);
}
+void MCELFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
+
void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
switch (Flag) {
case MCAF_SyntaxUnified: return; // no-op here.
@@ -101,6 +109,9 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
}
void MCELFStreamer::ChangeSection(const MCSection *Section) {
+ MCSectionData *CurSection = getCurrentSectionData();
+ if (CurSection && CurSection->isBundleLocked())
+ report_fatal_error("Unterminated .bundle_lock when changing a section");
const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
if (Grp)
getAssembler().getOrCreateSymbolData(*Grp);
@@ -258,10 +269,22 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace) {
+ if (getCurrentSectionData()->isBundleLocked())
+ report_fatal_error("Emitting values inside a locked bundle is forbidden");
fixSymbolsInTLSFixups(Value);
MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace);
}
+void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
+ int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ if (getCurrentSectionData()->isBundleLocked())
+ report_fatal_error("Emitting values inside a locked bundle is forbidden");
+ MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value,
+ ValueSize, MaxBytesToEmit);
+}
+
// Add a symbol for the file name of this module. This is the second
// entry in the module's symbol table (the first being the null symbol).
@@ -277,7 +300,9 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) {
void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
switch (expr->getKind()) {
- case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
+ case MCExpr::Target:
+ cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
+ break;
case MCExpr::Constant:
break;
@@ -309,6 +334,19 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_Mips_GOTTPREL:
case MCSymbolRefExpr::VK_Mips_TPREL_HI:
case MCSymbolRefExpr::VK_Mips_TPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_TPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_TPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_DTPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLS:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLSGD:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLSLD:
break;
}
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());
@@ -324,32 +362,116 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
this->MCObjectStreamer::EmitInstToFragment(Inst);
- MCInstFragment &F = *cast<MCInstFragment>(getCurrentFragment());
+ MCRelaxableFragment &F = *cast<MCRelaxableFragment>(getCurrentFragment());
for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i)
fixSymbolsInTLSFixups(F.getFixups()[i].getValue());
}
void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
- MCDataFragment *DF = getOrCreateDataFragment();
-
+ MCAssembler &Assembler = getAssembler();
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
- getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
VecOS.flush();
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
fixSymbolsInTLSFixups(Fixups[i].getValue());
+ // There are several possibilities here:
+ //
+ // If bundling is disabled, append the encoded instruction to the current data
+ // fragment (or create a new such fragment if the current fragment is not a
+ // data fragment).
+ //
+ // If bundling is enabled:
+ // - If we're not in a bundle-locked group, emit the instruction into a
+ // fragment of its own. If there are no fixups registered for the
+ // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a
+ // MCDataFragment.
+ // - If we're in a bundle-locked group, append the instruction to the current
+ // data fragment because we want all the instructions in a group to get into
+ // the same fragment. Be careful not to do that for the first instruction in
+ // the group, though.
+ MCDataFragment *DF;
+
+ if (Assembler.isBundlingEnabled()) {
+ MCSectionData *SD = getCurrentSectionData();
+ if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
+ // If we are bundle-locked, we re-use the current fragment.
+ // The bundle-locking directive ensures this is a new data fragment.
+ DF = cast<MCDataFragment>(getCurrentFragment());
+ else if (!SD->isBundleLocked() && Fixups.size() == 0) {
+ // Optimize memory usage by emitting the instruction to a
+ // MCCompactEncodedInstFragment when not in a bundle-locked group and
+ // there are no fixups registered.
+ MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(SD);
+ CEIF->getContents().append(Code.begin(), Code.end());
+ return;
+ } else {
+ DF = new MCDataFragment(SD);
+ if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {
+ // If this is a new fragment created for a bundle-locked group, and the
+ // group was marked as "align_to_end", set a flag in the fragment.
+ DF->setAlignToBundleEnd(true);
+ }
+ }
+
+ // We're now emitting an instruction in a bundle group, so this flag has
+ // to be turned off.
+ SD->setBundleGroupBeforeFirstInst(false);
+ } else {
+ DF = getOrCreateDataFragment();
+ }
+
// Add the fixups and data.
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
DF->getFixups().push_back(Fixups[i]);
}
+ DF->setHasInstructions(true);
DF->getContents().append(Code.begin(), Code.end());
}
+void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
+ assert(AlignPow2 <= 30 && "Invalid bundle alignment");
+ MCAssembler &Assembler = getAssembler();
+ if (Assembler.getBundleAlignSize() == 0 && AlignPow2 > 0)
+ Assembler.setBundleAlignSize(1 << AlignPow2);
+ else
+ report_fatal_error(".bundle_align_mode should be only set once per file");
+}
+
+void MCELFStreamer::EmitBundleLock(bool AlignToEnd) {
+ MCSectionData *SD = getCurrentSectionData();
+
+ // Sanity checks
+ //
+ if (!getAssembler().isBundlingEnabled())
+ report_fatal_error(".bundle_lock forbidden when bundling is disabled");
+ else if (SD->isBundleLocked())
+ report_fatal_error("Nesting of .bundle_lock is forbidden");
+
+ SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd :
+ MCSectionData::BundleLocked);
+ SD->setBundleGroupBeforeFirstInst(true);
+}
+
+void MCELFStreamer::EmitBundleUnlock() {
+ MCSectionData *SD = getCurrentSectionData();
+
+ // Sanity checks
+ if (!getAssembler().isBundlingEnabled())
+ report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
+ else if (!SD->isBundleLocked())
+ report_fatal_error(".bundle_unlock without matching lock");
+ else if (SD->isBundleGroupBeforeFirstInst())
+ report_fatal_error("Empty bundle-locked group is forbidden");
+
+ SD->setBundleLockState(MCSectionData::NotBundleLocked);
+}
+
void MCELFStreamer::FinishImpl() {
EmitFrames(true);
@@ -377,7 +499,7 @@ void MCELFStreamer::FinishImpl() {
}
void MCELFStreamer::EmitTCEntry(const MCSymbol &S) {
// Creates a R_PPC64_TOC relocation
- MCObjectStreamer::EmitSymbolValue(&S, 8, 0);
+ MCObjectStreamer::EmitSymbolValue(&S, 8);
}
MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB,
@@ -395,6 +517,10 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("Generic ELF doesn't support this directive");
}
+MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+ return getAssembler().getOrCreateSymbolData(*Symbol);
+}
+
void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("ELF doesn't support this directive");
}
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index 7a63bace6c..1a53934fef 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -54,14 +54,16 @@ void MCExpr::print(raw_ostream &OS) const {
else
OS << Sym;
- if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT ||
+ if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_NONE ||
+ SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT ||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_TLSGD ||
SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT ||
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_TARGET2)
+ SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
+ SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
else if (SRE.getKind() != MCSymbolRefExpr::VK_None &&
SRE.getKind() != MCSymbolRefExpr::VK_PPC_DARWIN_HA16 &&
@@ -193,6 +195,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_DTPOFF: return "DTPOFF";
case VK_TLVP: return "TLVP";
case VK_SECREL: return "SECREL";
+ case VK_ARM_NONE: return "(NONE)";
case VK_ARM_PLT: return "(PLT)";
case VK_ARM_GOT: return "(GOT)";
case VK_ARM_GOTOFF: return "(GOTOFF)";
@@ -201,6 +204,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_ARM_TLSGD: return "(tlsgd)";
case VK_ARM_TARGET1: return "(target1)";
case VK_ARM_TARGET2: return "(target2)";
+ case VK_ARM_PREL31: return "(prel31)";
case VK_PPC_TOC: return "tocbase";
case VK_PPC_TOC_ENTRY: return "toc";
case VK_PPC_DARWIN_HA16: return "ha16";
@@ -209,10 +213,19 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_PPC_GAS_LO16: return "l";
case VK_PPC_TPREL16_HA: return "tprel@ha";
case VK_PPC_TPREL16_LO: return "tprel@l";
+ case VK_PPC_DTPREL16_HA: return "dtprel@ha";
+ case VK_PPC_DTPREL16_LO: return "dtprel@l";
case VK_PPC_TOC16_HA: return "toc@ha";
case VK_PPC_TOC16_LO: return "toc@l";
- case VK_PPC_GOT_TPREL16_DS: return "got@tprel";
+ case VK_PPC_GOT_TPREL16_HA: return "got@tprel@ha";
+ case VK_PPC_GOT_TPREL16_LO: return "got@tprel@l";
case VK_PPC_TLS: return "tls";
+ case VK_PPC_GOT_TLSGD16_HA: return "got@tlsgd@ha";
+ case VK_PPC_GOT_TLSGD16_LO: return "got@tlsgd@l";
+ case VK_PPC_GOT_TLSLD16_HA: return "got@tlsld@ha";
+ case VK_PPC_GOT_TLSLD16_LO: return "got@tlsld@l";
+ case VK_PPC_TLSGD: return "tlsgd";
+ case VK_PPC_TLSLD: return "tlsld";
case VK_Mips_GPREL: return "GPREL";
case VK_Mips_GOT_CALL: return "GOT_CALL";
case VK_Mips_GOT16: return "GOT16";
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index f279e74e38..7d08d0ecd5 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -34,18 +34,21 @@ private:
void EmitDataRegion(DataRegionData::KindTy Kind);
void EmitDataRegionEnd();
public:
- MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
- raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, MAB, OS, Emitter) {}
+ MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_MachOStreamer, Context, MAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
virtual void InitSections();
+ virtual void InitToTextSection();
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
@@ -84,15 +87,23 @@ public:
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_MachOStreamer;
+ }
};
} // end anonymous namespace.
void MCMachOStreamer::InitSections() {
- SwitchSection(getContext().getMachOSection("__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind::getText()));
+ InitToTextSection();
+}
+void MCMachOStreamer::InitToTextSection() {
+ SwitchSection(getContext().getMachOSection(
+ "__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0,
+ SectionKind::getText()));
}
void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
@@ -130,6 +141,9 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask);
}
+void MCMachOStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) {
if (!getAssembler().getBackend().hasDataInCodeSupport())
return;
@@ -169,6 +183,10 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
}
}
+void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
+ getAssembler().getLinkerOptions().push_back(Options);
+}
+
void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
switch (Kind) {
case MCDR_DataRegion:
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index f5ece10dc4..c872b2203f 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -19,11 +19,14 @@ namespace {
class MCNullStreamer : public MCStreamer {
public:
- MCNullStreamer(MCContext &Context) : MCStreamer(Context) {}
+ MCNullStreamer(MCContext &Context) : MCStreamer(SK_NullStreamer, Context) {}
/// @name MCStreamer Interface
/// @{
+ virtual void InitToTextSection() {
+ }
+
virtual void InitSections() {
}
@@ -35,7 +38,9 @@ namespace {
assert(getCurrentSection() && "Cannot emit before setting section!");
Symbol->setSection(*getCurrentSection());
}
-
+ virtual void EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+ }
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {}
virtual void EmitThumbFunc(MCSymbol *Func) {}
@@ -84,7 +89,7 @@ namespace {
virtual void EmitFileDirective(StringRef Filename) {}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename) {
+ StringRef Filename, unsigned CUID = 0) {
return false;
}
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -93,6 +98,10 @@ namespace {
StringRef FileName) {}
virtual void EmitInstruction(const MCInst &Inst) {}
+ virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
+ virtual void EmitBundleLock(bool AlignToEnd) {}
+ virtual void EmitBundleUnlock() {}
+
virtual void FinishImpl() {}
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
@@ -100,6 +109,11 @@ namespace {
}
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_NullStreamer;
+ }
+
};
}
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index d57e0c5b4a..2e1a045569 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -186,6 +186,10 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
Ctx->getMachOSection("__DWARF", "__debug_frame",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getMachOSection("__DWARF", "__debug_pubnames",
+ MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getMachOSection("__DWARF", "__debug_pubtypes",
MCSectionMachO::S_ATTR_DEBUG,
@@ -256,6 +260,33 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
TTypeEncoding = (CMModel == CodeModel::Small)
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
}
+ } else if (T.getArch() == Triple::aarch64) {
+ FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ // The small model guarantees static code/data size < 4GB, but not where it
+ // will be in memory. Most of these could end up >2GB away so even a signed
+ // pc-relative 32-bit address is insufficient, theoretically.
+ if (RelocM == Reloc::PIC_) {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ } else {
+ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
+ LSDAEncoding = dwarf::DW_EH_PE_absptr;
+ FDEEncoding = dwarf::DW_EH_PE_udata4;
+ TTypeEncoding = dwarf::DW_EH_PE_absptr;
+ }
+ } else if (T.getArch() == Triple::ppc64) {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_udata8;
+ FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
+ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_udata8;
}
// Solaris requires different flags for .eh_frame to seemingly every other
@@ -373,6 +404,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfFrameSection =
Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
@@ -426,6 +460,12 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfLocDWOSection =
Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfStrOffDWOSection =
+ Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
+ DwarfAddrSection =
+ Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
}
@@ -510,6 +550,11 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getCOFFSection(".debug_pubnames",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getCOFFSection(".debug_pubtypes",
COFF::IMAGE_SCN_MEM_DISCARDABLE |
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index c2171ffaa5..0d2ce83a8a 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -20,22 +20,19 @@
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
-MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter_)
- : MCStreamer(Context),
- Assembler(new MCAssembler(Context, TAB,
- *Emitter_, *TAB.createObjectWriter(OS),
- OS)),
- CurSectionData(0)
-{
-}
-
-MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter_,
+MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter_)
+ : MCStreamer(Kind, Context),
+ Assembler(new MCAssembler(Context, TAB, *Emitter_,
+ *TAB.createObjectWriter(OS), OS)),
+ CurSectionData(0) {}
+
+MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter_,
MCAssembler *_Assembler)
- : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
-{
-}
+ : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();
@@ -44,6 +41,13 @@ MCObjectStreamer::~MCObjectStreamer() {
delete Assembler;
}
+void MCObjectStreamer::reset() {
+ if (Assembler)
+ Assembler->reset();
+ CurSectionData = 0;
+ MCStreamer::reset();
+}
+
MCFragment *MCObjectStreamer::getCurrentFragment() const {
assert(getCurrentSectionData() && "No current section!");
@@ -55,7 +59,9 @@ MCFragment *MCObjectStreamer::getCurrentFragment() const {
MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
- if (!F)
+ // When bundling is enabled, we don't want to add data to a fragment that
+ // already has instructions (see MCELFStreamer::EmitInstToData for details)
+ if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions()))
F = new MCDataFragment(getCurrentSectionData());
return F;
}
@@ -128,6 +134,10 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setOffset(F->getContents().size());
}
+void MCObjectStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
+
void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
@@ -170,21 +180,27 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
if (Inst.getOperand(i).isExpr())
AddValueSymbols(Inst.getOperand(i).getExpr());
- getCurrentSectionData()->setHasInstructions(true);
+ MCSectionData *SD = getCurrentSectionData();
+ SD->setHasInstructions(true);
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
MCLineEntry::Make(this, getCurrentSection());
// If this instruction doesn't need relaxation, just emit it as data.
- if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) {
+ MCAssembler &Assembler = getAssembler();
+ if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
EmitInstToData(Inst);
return;
}
- // Otherwise, if we are relaxing everything, relax the instruction as much as
- // possible and emit it as data.
- if (getAssembler().getRelaxAll()) {
+ // Otherwise, relax and emit it as data if either:
+ // - The RelaxAll flag was passed
+ // - Bundling is enabled and this instruction is inside a bundle-locked
+ // group. We want to emit all such instructions into the same data
+ // fragment.
+ if (Assembler.getRelaxAll() ||
+ (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
MCInst Relaxed;
getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
@@ -198,7 +214,10 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
}
void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
- MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
+ // Always create a new, separate fragment here, because its size can change
+ // during relaxation.
+ MCRelaxableFragment *IF =
+ new MCRelaxableFragment(Inst, getCurrentSectionData());
SmallString<128> Code;
raw_svector_ostream VecOS(Code);
@@ -207,6 +226,23 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
IF->getContents().append(Code.begin(), Code.end());
}
+#ifndef NDEBUG
+static const char *BundlingNotImplementedMsg =
+ "Aligned bundling is not implemented for this object format";
+#endif
+
+void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
+ llvm_unreachable(BundlingNotImplementedMsg);
+}
+
+void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
+ llvm_unreachable(BundlingNotImplementedMsg);
+}
+
+void MCObjectStreamer::EmitBundleUnlock() {
+ llvm_unreachable(BundlingNotImplementedMsg);
+}
+
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
@@ -280,7 +316,7 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
return true;
- EmitFill(Res, Value, 0);
+ EmitFill(Res, Value);
return false;
}
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index d0492fd16c..c1c594a746 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -156,10 +156,36 @@ AsmToken AsmLexer::LexLineComment() {
}
static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
- if (CurPtr[0] == 'L' && CurPtr[1] == 'L')
- CurPtr += 2;
- if (CurPtr[0] == 'U' && CurPtr[1] == 'L' && CurPtr[2] == 'L')
- CurPtr += 3;
+ // Skip ULL, UL, U, L and LL suffices.
+ if (CurPtr[0] == 'U')
+ ++CurPtr;
+ if (CurPtr[0] == 'L')
+ ++CurPtr;
+ if (CurPtr[0] == 'L')
+ ++CurPtr;
+}
+
+// Look ahead to search for first non-hex digit, if it's [hH], then we treat the
+// integer as a hexadecimal, possibly with leading zeroes.
+static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
+ const char *FirstHex = 0;
+ const char *LookAhead = CurPtr;
+ while (1) {
+ if (isdigit(*LookAhead)) {
+ ++LookAhead;
+ } else if (isxdigit(*LookAhead)) {
+ if (!FirstHex)
+ FirstHex = LookAhead;
+ ++LookAhead;
+ } else {
+ break;
+ }
+ }
+ bool isHex = *LookAhead == 'h' || *LookAhead == 'H';
+ CurPtr = isHex || !FirstHex ? LookAhead : FirstHex;
+ if (isHex)
+ return 16;
+ return DefaultRadix;
}
/// LexDigit: First character is [0-9].
@@ -167,16 +193,15 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
/// Forward/Backward Label: [0-9][fb]
/// Binary integer: 0b[01]+
/// Octal integer: 0[0-7]+
-/// Hex integer: 0x[0-9a-fA-F]+
+/// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH]
/// Decimal integer: [1-9][0-9]*
AsmToken AsmLexer::LexDigit() {
// Decimal integer: [1-9][0-9]*
if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
- while (isdigit(*CurPtr))
- ++CurPtr;
-
+ unsigned Radix = doLookAhead(CurPtr, 10);
+ bool isHex = Radix == 16;
// Check for floating point literals.
- if (*CurPtr == '.' || *CurPtr == 'e') {
+ if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) {
++CurPtr;
return LexFloatLiteral();
}
@@ -184,17 +209,22 @@ AsmToken AsmLexer::LexDigit() {
StringRef Result(TokStart, CurPtr - TokStart);
long long Value;
- if (Result.getAsInteger(10, Value)) {
+ if (Result.getAsInteger(Radix, Value)) {
// Allow positive values that are too large to fit into a signed 64-bit
// integer, but that do fit in an unsigned one, we just convert them over.
unsigned long long UValue;
- if (Result.getAsInteger(10, UValue))
- return ReturnError(TokStart, "invalid decimal number");
+ if (Result.getAsInteger(Radix, UValue))
+ return ReturnError(TokStart, !isHex ? "invalid decimal number" :
+ "invalid hexdecimal number");
Value = (long long)UValue;
}
- // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
- // suffixes on integer literals.
+ // Consume the [bB][hH].
+ if (Radix == 2 || Radix == 16)
+ ++CurPtr;
+
+ // The darwin/x86 (and x86-64) assembler accepts and ignores type
+ // suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
return AsmToken(AsmToken::Integer, Result, Value);
@@ -243,6 +273,10 @@ AsmToken AsmLexer::LexDigit() {
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "invalid hexadecimal number");
+ // Consume the optional [hH].
+ if (*CurPtr == 'h' || *CurPtr == 'H')
+ ++CurPtr;
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
@@ -251,14 +285,18 @@ AsmToken AsmLexer::LexDigit() {
(int64_t)Result);
}
- // Must be an octal number, it starts with 0.
- while (*CurPtr >= '0' && *CurPtr <= '9')
- ++CurPtr;
-
- StringRef Result(TokStart, CurPtr - TokStart);
+ // Either octal or hexadecimal.
long long Value;
- if (Result.getAsInteger(8, Value))
- return ReturnError(TokStart, "invalid octal number");
+ unsigned Radix = doLookAhead(CurPtr, 8);
+ bool isHex = Radix == 16;
+ StringRef Result(TokStart, CurPtr - TokStart);
+ if (Result.getAsInteger(Radix, Value))
+ return ReturnError(TokStart, !isHex ? "invalid octal number" :
+ "invalid hexdecimal number");
+
+ // Consume the [hH].
+ if (Radix == 16)
+ ++CurPtr;
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 2c06604be2..6ab49ec92c 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -46,31 +47,34 @@ static cl::opt<bool>
FatalAssemblerWarnings("fatal-assembler-warnings",
cl::desc("Consider warnings as error"));
-MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
+MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
-/// \brief Helper class for tracking macro definitions.
-typedef std::vector<AsmToken> MacroArgument;
-typedef std::vector<MacroArgument> MacroArguments;
-typedef std::pair<StringRef, MacroArgument> MacroParameter;
-typedef std::vector<MacroParameter> MacroParameters;
+/// \brief Helper types for tracking macro definitions.
+typedef std::vector<AsmToken> MCAsmMacroArgument;
+typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
+typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter;
+typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
-struct Macro {
+struct MCAsmMacro {
StringRef Name;
StringRef Body;
- MacroParameters Parameters;
+ MCAsmMacroParameters Parameters;
public:
- Macro(StringRef N, StringRef B, const MacroParameters &P) :
+ MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) :
Name(N), Body(B), Parameters(P) {}
+
+ MCAsmMacro(const MCAsmMacro& Other)
+ : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {}
};
/// \brief Helper class for storing information about an active macro
/// instantiation.
struct MacroInstantiation {
/// The macro being instantiated.
- const Macro *TheMacro;
+ const MCAsmMacro *TheMacro;
/// The macro instantiation with substitutions.
MemoryBuffer *Instantiation;
@@ -85,11 +89,10 @@ struct MacroInstantiation {
SMLoc ExitLoc;
public:
- MacroInstantiation(const Macro *M, SMLoc IL, int EB, SMLoc EL,
+ MacroInstantiation(const MCAsmMacro *M, SMLoc IL, int EB, SMLoc EL,
MemoryBuffer *I);
};
-//struct AsmRewrite;
struct ParseStatementInfo {
/// ParsedOperands - The parsed operands from the last parsed statement.
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
@@ -97,11 +100,14 @@ struct ParseStatementInfo {
/// Opcode - The opcode from the last parsed instruction.
unsigned Opcode;
+ /// Error - Was there an error parsing the inline assembly?
+ bool ParseError;
+
SmallVectorImpl<AsmRewrite> *AsmRewrites;
- ParseStatementInfo() : Opcode(~0U), AsmRewrites(0) {}
+ ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(0) {}
ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites)
- : Opcode(~0), AsmRewrites(rewrites) {}
+ : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {}
~ParseStatementInfo() {
// Free any parsed operands.
@@ -113,8 +119,6 @@ struct ParseStatementInfo {
/// \brief The concrete assembly parser instance.
class AsmParser : public MCAsmParser {
- friend class GenericAsmParser;
-
AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION;
void operator=(const AsmParser &) LLVM_DELETED_FUNCTION;
private:
@@ -125,7 +129,6 @@ private:
SourceMgr &SrcMgr;
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
- MCAsmParserExtension *GenericParser;
MCAsmParserExtension *PlatformParser;
/// This is the current buffer index we're lexing from as managed by the
@@ -135,20 +138,19 @@ private:
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;
- /// DirectiveMap - This is a table handlers for directives. Each handler is
- /// invoked after the directive identifier is read and is responsible for
- /// parsing and validating the rest of the directive. The handler is passed
- /// in the directive name and the location of the directive keyword.
- StringMap<std::pair<MCAsmParserExtension*, DirectiveHandler> > DirectiveMap;
+ /// ExtensionDirectiveMap - maps directive names to handler methods in parser
+ /// extensions. Extensions register themselves in this map by calling
+ /// addDirectiveHandler.
+ StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
/// MacroMap - Map of currently defined macros.
- StringMap<Macro*> MacroMap;
+ StringMap<MCAsmMacro*> MacroMap;
/// ActiveMacros - Stack of active macro instantiations.
std::vector<MacroInstantiation*> ActiveMacros;
/// Boolean tracking whether macro substitution is enabled.
- unsigned MacrosEnabled : 1;
+ unsigned MacrosEnabledFlag : 1;
/// Flag tracking whether any errors have been encountered.
unsigned HadError : 1;
@@ -175,10 +177,9 @@ public:
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
- virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
- StringRef Directive,
- DirectiveHandler Handler) {
- DirectiveMap[Directive] = std::make_pair(Object, Handler);
+ virtual void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) {
+ ExtensionDirectiveMap[Directive] = Handler;
}
public:
@@ -189,9 +190,9 @@ public:
virtual MCAsmLexer &getLexer() { return Lexer; }
virtual MCContext &getContext() { return Ctx; }
virtual MCStreamer &getStreamer() { return Out; }
- virtual unsigned getAssemblerDialect() {
+ virtual unsigned getAssemblerDialect() {
if (AssemblerDialect == ~0U)
- return MAI.getAssemblerDialect();
+ return MAI.getAssemblerDialect();
else
return AssemblerDialect;
}
@@ -209,7 +210,7 @@ public:
void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; }
bool isParsingInlineAsm() { return ParsingInlineAsm; }
- bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *,bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
@@ -218,27 +219,70 @@ public:
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI);
- bool ParseExpression(const MCExpr *&Res);
- virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseAbsoluteExpression(int64_t &Res);
+ bool parseExpression(const MCExpr *&Res);
+ virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool parseAbsoluteExpression(int64_t &Res);
+
+ /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// and set \p Res to the identifier contents.
+ virtual bool parseIdentifier(StringRef &Res);
+ virtual void eatToEndOfStatement();
+ virtual void checkForValidSection();
/// }
private:
- void CheckForValidSection();
bool ParseStatement(ParseStatementInfo &Info);
void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L);
- bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
+ void CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
+ MCAsmMacroParameters Parameters);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MacroParameters &Parameters,
- const MacroArguments &A,
+ const MCAsmMacroParameters &Parameters,
+ const MCAsmMacroArguments &A,
const SMLoc &L);
+
+ /// \brief Are macros enabled in the parser?
+ bool MacrosEnabled() {return MacrosEnabledFlag;}
+
+ /// \brief Control a flag in the parser that enables or disables macros.
+ void SetMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
+
+ /// \brief Lookup a previously defined macro.
+ /// \param Name Macro name.
+ /// \returns Pointer to macro. NULL if no such macro was defined.
+ const MCAsmMacro* LookupMacro(StringRef Name);
+
+ /// \brief Define a new macro with the given name and information.
+ void DefineMacro(StringRef Name, const MCAsmMacro& Macro);
+
+ /// \brief Undefine a macro. If no such macro was defined, it's a no-op.
+ void UndefineMacro(StringRef Name);
+
+ /// \brief Are we inside a macro instantiation?
+ bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
+
+ /// \brief Handle entry to macro instantiation.
+ ///
+ /// \param M The macro.
+ /// \param NameLoc Instantiation location.
+ bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
+
+ /// \brief Handle exit from macro instantiation.
void HandleMacroExit();
+ /// \brief Extract AsmTokens for a macro argument. If the argument delimiter
+ /// is initially unknown, set it to AsmToken::Eof. It will be set to the
+ /// correct delimiter by the method.
+ bool ParseMacroArgument(MCAsmMacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter);
+
+ /// \brief Parse all macro arguments for a given macro.
+ bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
+
void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const {
@@ -260,16 +304,10 @@ private:
/// location.
void JumpToLoc(SMLoc Loc, int InBuffer=-1);
- virtual void EatToEndOfStatement();
-
- 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.
- virtual 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.
@@ -283,24 +321,95 @@ private:
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \p Res to the identifier contents.
- virtual bool ParseIdentifier(StringRef &Res);
-
- // Directive Parsing.
+ bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
- // ".ascii", ".asciiz", ".string"
+ // Generic (target and platform independent) directive parsing.
+ enum DirectiveKind {
+ DK_NO_DIRECTIVE, // Placeholder
+ DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT,
+ DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_SINGLE,
+ DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
+ DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
+ DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
+ DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_INDIRECT_SYMBOL,
+ DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
+ DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
+ DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
+ DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC,
+ DK_IF, DK_IFB, DK_IFNB, DK_IFC, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF,
+ DK_ELSEIF, DK_ELSE, DK_ENDIF,
+ DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS,
+ DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA,
+ DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER,
+ DK_CFI_OFFSET, DK_CFI_REL_OFFSET, DK_CFI_PERSONALITY, DK_CFI_LSDA,
+ DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
+ DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
+ DK_CFI_REGISTER,
+ DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
+ DK_SLEB128, DK_ULEB128
+ };
+
+ /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for
+ /// directives parsed by this class.
+ StringMap<DirectiveKind> DirectiveKindMap;
+
+ // ".ascii", ".asciz", ".string"
bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
bool ParseDirectiveRealValue(const fltSemantics &); // ".single", ...
bool ParseDirectiveFill(); // ".fill"
- bool ParseDirectiveSpace(); // ".space"
bool ParseDirectiveZero(); // ".zero"
- bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv"
+ // ".set", ".equ", ".equiv"
+ bool ParseDirectiveSet(StringRef IDVal, bool allow_redef);
bool ParseDirectiveOrg(); // ".org"
// ".align{,32}", ".p2align{,w,l}"
bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
+ // ".file", ".line", ".loc", ".stabs"
+ bool ParseDirectiveFile(SMLoc DirectiveLoc);
+ bool ParseDirectiveLine();
+ bool ParseDirectiveLoc();
+ bool ParseDirectiveStabs();
+
+ // .cfi directives
+ bool ParseDirectiveCFIRegister(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFISections();
+ bool ParseDirectiveCFIStartProc();
+ bool ParseDirectiveCFIEndProc();
+ bool ParseDirectiveCFIDefCfaOffset();
+ bool ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIAdjustCfaOffset();
+ bool ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIOffset(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality);
+ bool ParseDirectiveCFIRememberState();
+ bool ParseDirectiveCFIRestoreState();
+ bool ParseDirectiveCFISameValue(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIRestore(SMLoc DirectiveLoc);
+ bool ParseDirectiveCFIEscape();
+ bool ParseDirectiveCFISignalFrame();
+ bool ParseDirectiveCFIUndefined(SMLoc DirectiveLoc);
+
+ // macro directives
+ bool ParseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool ParseDirectiveEndMacro(StringRef Directive);
+ bool ParseDirectiveMacro(SMLoc DirectiveLoc);
+ bool ParseDirectiveMacrosOnOff(StringRef Directive);
+
+ // ".bundle_align_mode"
+ bool ParseDirectiveBundleAlignMode();
+ // ".bundle_lock"
+ bool ParseDirectiveBundleLock();
+ // ".bundle_unlock"
+ bool ParseDirectiveBundleUnlock();
+
+ // ".space", ".skip"
+ bool ParseDirectiveSpace(StringRef IDVal);
+
+ // .sleb128 (Signed=true) and .uleb128 (Signed=false)
+ bool ParseDirectiveLEB128(bool Signed);
+
/// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
/// accepts a single symbol (which should be a label or an external).
bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
@@ -321,139 +430,29 @@ private:
bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
-
- /// ParseEscapedString - Parse the current token as a string which may include
- /// escaped characters and return the string contents.
- bool ParseEscapedString(std::string &Data);
+ virtual bool parseEscapedString(std::string &Data);
const MCExpr *ApplyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
// Macro-like directives
- Macro *ParseMacroLikeBody(SMLoc DirectiveLoc);
- void InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
+ MCAsmMacro *ParseMacroLikeBody(SMLoc DirectiveLoc);
+ void InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS);
bool ParseDirectiveRept(SMLoc DirectiveLoc); // ".rept"
bool ParseDirectiveIrp(SMLoc DirectiveLoc); // ".irp"
bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
- // "_emit"
- bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info);
-};
+ // "_emit" or "__emit"
+ bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
+ size_t Len);
-/// \brief Generic implementations of directive handling, etc. which is shared
-/// (or the default, at least) for all assembler parser.
-class GenericAsmParser : public MCAsmParserExtension {
- template<bool (GenericAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<GenericAsmParser, Handler>);
- }
-public:
- GenericAsmParser() {}
-
- AsmParser &getParser() {
- return (AsmParser&) this->MCAsmParserExtension::getParser();
- }
-
- virtual void Initialize(MCAsmParser &Parser) {
- // Call the base implementation.
- this->MCAsmParserExtension::Initialize(Parser);
-
- // Debugging directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveFile>(".file");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLine>(".line");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLoc>(".loc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveStabs>(".stabs");
-
- // CFI directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFISections>(
- ".cfi_sections");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIStartProc>(
- ".cfi_startproc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
- ".cfi_endproc");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
- ".cfi_def_cfa");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
- ".cfi_def_cfa_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset>(
- ".cfi_adjust_cfa_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
- ".cfi_def_cfa_register");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIOffset>(
- ".cfi_offset");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIRelOffset>(
- ".cfi_rel_offset");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_personality");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda>(".cfi_lsda");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRememberState>(".cfi_remember_state");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRestoreState>(".cfi_restore_state");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFISameValue>(".cfi_same_value");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIUndefined>(".cfi_undefined");
- AddDirectiveHandler<
- &GenericAsmParser::ParseDirectiveCFIRegister>(".cfi_register");
-
- // Macro directives.
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
- ".macros_on");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
- ".macros_off");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectivePurgeMacro>(".purgem");
-
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128");
- }
-
- bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
+ // "align"
+ bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
- bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISections(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIAdjustCfaOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRelOffset(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIPersonalityOrLsda(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRememberState(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRestoreState(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIUndefined(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveCFIRegister(StringRef, SMLoc DirectiveLoc);
-
- bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectivePurgeMacro(StringRef, SMLoc DirectiveLoc);
-
- bool ParseDirectiveLEB128(StringRef, SMLoc);
+ void initializeDirectiveKindMap();
};
-
}
namespace llvm {
@@ -469,8 +468,8 @@ enum { DEFAULT_ADDRSPACE = 0 };
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),
+ PlatformParser(0),
+ CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
@@ -479,9 +478,6 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
SrcMgr.setDiagHandler(DiagHandler, this);
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
- // Initialize the generic parser.
- GenericParser->Initialize(*this);
-
// Initialize the platform / file format parser.
//
// FIXME: This is a hack, we need to (majorly) cleanup how these objects are
@@ -497,18 +493,19 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
PlatformParser = createELFAsmParser();
PlatformParser->Initialize(*this);
}
+
+ initializeDirectiveKindMap();
}
AsmParser::~AsmParser() {
assert(ActiveMacros.empty() && "Unexpected active macro instantiation!");
// Destroy any macros.
- for (StringMap<Macro*>::iterator it = MacroMap.begin(),
+ for (StringMap<MCAsmMacro*>::iterator it = MacroMap.begin(),
ie = MacroMap.end(); it != ie; ++it)
delete it->getValue();
delete PlatformParser;
- delete GenericParser;
}
void AsmParser::PrintMacroInstantiations() {
@@ -609,7 +606,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
getStreamer().EmitLabel(SectionStartSym);
getContext().setGenDwarfSectionStartSym(SectionStartSym);
getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(),
- StringRef(), SrcMgr.getMemoryBuffer(CurBuffer)->getBufferIdentifier());
+ StringRef(),
+ getContext().getMainFileName());
}
// While we have input, parse each statement.
@@ -620,7 +618,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
assert(HadError && "Parse statement returned an error, but none emitted!");
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
if (TheCondState.TheCond != StartingCondState.TheCond ||
@@ -667,18 +665,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
return HadError;
}
-void AsmParser::CheckForValidSection() {
+void AsmParser::checkForValidSection() {
if (!ParsingInlineAsm && !getStreamer().getCurrentSection()) {
TokError("expected section directive before assembly directive");
- Out.SwitchSection(Ctx.getMachOSection(
- "__TEXT", "__text",
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 0, SectionKind::getText()));
+ Out.InitToTextSection();
}
}
-/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
-void AsmParser::EatToEndOfStatement() {
+/// eatToEndOfStatement - Throw away the rest of the line for testing purposes.
+void AsmParser::eatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Eof))
Lex();
@@ -688,7 +683,7 @@ void AsmParser::EatToEndOfStatement() {
Lex();
}
-StringRef AsmParser::ParseStringToEndOfStatement() {
+StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) &&
@@ -717,10 +712,10 @@ StringRef AsmParser::ParseStringToComma() {
/// parenexpr ::= expr)
///
bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseExpression(Res)) return true;
+ if (parseExpression(Res)) return true;
if (Lexer.isNot(AsmToken::RParen))
return TokError("expected ')' in parentheses expression");
- EndLoc = Lexer.getLoc();
+ EndLoc = Lexer.getTok().getEndLoc();
Lex();
return false;
}
@@ -731,10 +726,10 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// bracketexpr ::= expr]
///
bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseExpression(Res)) return true;
+ if (parseExpression(Res)) return true;
if (Lexer.isNot(AsmToken::RBrac))
return TokError("expected ']' in brackets expression");
- EndLoc = Lexer.getLoc();
+ EndLoc = Lexer.getTok().getEndLoc();
Lex();
return false;
}
@@ -746,7 +741,9 @@ bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,- primaryexpr
bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- switch (Lexer.getKind()) {
+ SMLoc FirstTokenLoc = getLexer().getLoc();
+ AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
+ switch (FirstTokenKind) {
default:
return TokError("unknown token in expression");
// If we have an error assume that we've already handled it.
@@ -761,11 +758,14 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
case AsmToken::Dollar:
case AsmToken::String:
case AsmToken::Identifier: {
- EndLoc = Lexer.getLoc();
-
StringRef Identifier;
- if (ParseIdentifier(Identifier))
+ if (parseIdentifier(Identifier)) {
+ if (FirstTokenKind == AsmToken::Dollar)
+ return Error(FirstTokenLoc, "invalid token in expression");
return true;
+ }
+
+ EndLoc = SMLoc::getFromPointer(Identifier.end());
// This is a symbol reference.
std::pair<StringRef, StringRef> Split = Identifier.split('@');
@@ -799,7 +799,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
SMLoc Loc = getTok().getLoc();
int64_t IntVal = getTok().getIntVal();
Res = MCConstantExpr::Create(IntVal, getContext());
- EndLoc = Lexer.getLoc();
+ EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat token.
// Look for 'b' or 'f' following an Integer as a directional label
if (Lexer.getKind() == AsmToken::Identifier) {
@@ -811,7 +811,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
getContext());
if (IDVal == "b" && Sym->isUndefined())
return Error(Loc, "invalid reference to undefined symbol");
- EndLoc = Lexer.getLoc();
+ EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
}
}
@@ -821,6 +821,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
APFloat RealVal(APFloat::IEEEdouble, getTok().getString());
uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
Res = MCConstantExpr::Create(IntVal, getContext());
+ EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat token.
return false;
}
@@ -830,7 +831,7 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
MCSymbol *Sym = Ctx.CreateTempSymbol();
Out.EmitLabel(Sym);
Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
- EndLoc = Lexer.getLoc();
+ EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
return false;
}
@@ -863,9 +864,9 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
}
-bool AsmParser::ParseExpression(const MCExpr *&Res) {
+bool AsmParser::parseExpression(const MCExpr *&Res) {
SMLoc EndLoc;
- return ParseExpression(Res, EndLoc);
+ return parseExpression(Res, EndLoc);
}
const MCExpr *
@@ -916,7 +917,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
llvm_unreachable("Invalid expression kind!");
}
-/// ParseExpression - Parse an expression and return it.
+/// parseExpression - Parse an expression and return it.
///
/// expr ::= expr &&,|| expr -> lowest.
/// expr ::= expr |,^,&,! expr
@@ -926,7 +927,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
/// expr ::= expr *,/,% expr -> highest.
/// expr ::= primaryexpr
///
-bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
// Parse the expression.
Res = 0;
if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
@@ -964,17 +965,17 @@ bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
-bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
Res = 0;
return ParseParenExpr(Res, EndLoc) ||
ParseBinOpRHS(1, Res, EndLoc);
}
-bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
+bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
const MCExpr *Expr;
SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Expr))
+ if (parseExpression(Expr))
return true;
if (!Expr->EvaluateAsAbsolute(Res))
@@ -1121,8 +1122,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
IDVal = "";
- }
- else {
+ } else {
IDVal = getTok().getString();
Lex(); // Consume the integer token to be used as an identifier token.
if (Lexer.getKind() != AsmToken::Colon) {
@@ -1130,46 +1130,54 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return TokError("unexpected token at start of statement");
}
}
-
} else if (Lexer.is(AsmToken::Dot)) {
// Treat '.' as a valid identifier in this context.
Lex();
IDVal = ".";
-
- } else if (ParseIdentifier(IDVal)) {
+ } else if (parseIdentifier(IDVal)) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
IDVal = "";
}
-
// Handle conditional assembly here before checking for skipping. We
// have to do this so that .endif isn't skipped in a ".if 0" block for
// example.
- if (IDVal == ".if")
- return ParseDirectiveIf(IDLoc);
- if (IDVal == ".ifb")
- return ParseDirectiveIfb(IDLoc, true);
- if (IDVal == ".ifnb")
- return ParseDirectiveIfb(IDLoc, false);
- if (IDVal == ".ifc")
- return ParseDirectiveIfc(IDLoc, true);
- if (IDVal == ".ifnc")
- return ParseDirectiveIfc(IDLoc, false);
- if (IDVal == ".ifdef")
- return ParseDirectiveIfdef(IDLoc, true);
- if (IDVal == ".ifndef" || IDVal == ".ifnotdef")
- return ParseDirectiveIfdef(IDLoc, false);
- if (IDVal == ".elseif")
- return ParseDirectiveElseIf(IDLoc);
- if (IDVal == ".else")
- return ParseDirectiveElse(IDLoc);
- if (IDVal == ".endif")
- return ParseDirectiveEndIf(IDLoc);
-
- // If we are in a ".if 0" block, ignore this statement.
+ StringMap<DirectiveKind>::const_iterator DirKindIt =
+ DirectiveKindMap.find(IDVal);
+ DirectiveKind DirKind =
+ (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE :
+ DirKindIt->getValue();
+ switch (DirKind) {
+ default:
+ break;
+ case DK_IF:
+ return ParseDirectiveIf(IDLoc);
+ case DK_IFB:
+ return ParseDirectiveIfb(IDLoc, true);
+ case DK_IFNB:
+ return ParseDirectiveIfb(IDLoc, false);
+ case DK_IFC:
+ return ParseDirectiveIfc(IDLoc, true);
+ case DK_IFNC:
+ return ParseDirectiveIfc(IDLoc, false);
+ case DK_IFDEF:
+ return ParseDirectiveIfdef(IDLoc, true);
+ case DK_IFNDEF:
+ case DK_IFNOTDEF:
+ return ParseDirectiveIfdef(IDLoc, false);
+ case DK_ELSEIF:
+ return ParseDirectiveElseIf(IDLoc);
+ case DK_ELSE:
+ return ParseDirectiveElse(IDLoc);
+ case DK_ENDIF:
+ return ParseDirectiveEndIf(IDLoc);
+ }
+
+ // Ignore the statement if in the middle of inactive conditional
+ // (e.g. ".if 0").
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
return false;
}
@@ -1178,7 +1186,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// See what kind of statement we have.
switch (Lexer.getKind()) {
case AsmToken::Colon: {
- CheckForValidSection();
+ checkForValidSection();
// identifier ':' -> Label.
Lex();
@@ -1201,7 +1209,8 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return Error(IDLoc, "invalid symbol redefinition");
// Emit the label.
- Out.EmitLabel(Sym);
+ if (!ParsingInlineAsm)
+ Out.EmitLabel(Sym);
// If we are generating dwarf for assembly source files then gather the
// info to make a dwarf label entry for this label if needed.
@@ -1231,160 +1240,234 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
}
// If macros are enabled, check to see if this is a macro instantiation.
- if (MacrosEnabled)
- if (const Macro *M = MacroMap.lookup(IDVal))
- return HandleMacroEntry(IDVal, IDLoc, M);
+ if (MacrosEnabled())
+ if (const MCAsmMacro *M = LookupMacro(IDVal)) {
+ return HandleMacroEntry(M, IDLoc);
+ }
// Otherwise, we have a normal instruction or directive.
+
+ // Directives start with "."
if (IDVal[0] == '.' && IDVal != ".") {
-
- // Target hook for parsing target specific directives.
+ // There are several entities interested in parsing directives:
+ //
+ // 1. The target-specific assembly parser. Some directives are target
+ // specific or may potentially behave differently on certain targets.
+ // 2. Asm parser extensions. For example, platform-specific parsers
+ // (like the ELF parser) register themselves as extensions.
+ // 3. The generic directive parser implemented by this class. These are
+ // all the directives that behave in a target and platform independent
+ // manner, or at least have a default behavior that's shared between
+ // all targets and platforms.
+
+ // First query the target-specific parser. It will return 'true' if it
+ // isn't interested in this directive.
if (!getTargetParser().ParseDirective(ID))
return false;
- // Assembler features
- if (IDVal == ".set" || IDVal == ".equ")
- return ParseDirectiveSet(IDVal, true);
- if (IDVal == ".equiv")
- return ParseDirectiveSet(IDVal, false);
-
- // Data directives
-
- if (IDVal == ".ascii")
- return ParseDirectiveAscii(IDVal, false);
- if (IDVal == ".asciz" || IDVal == ".string")
- return ParseDirectiveAscii(IDVal, true);
-
- if (IDVal == ".byte")
- return ParseDirectiveValue(1);
- if (IDVal == ".short")
- return ParseDirectiveValue(2);
- if (IDVal == ".value")
- return ParseDirectiveValue(2);
- if (IDVal == ".2byte")
- return ParseDirectiveValue(2);
- if (IDVal == ".long")
- return ParseDirectiveValue(4);
- if (IDVal == ".int")
- return ParseDirectiveValue(4);
- if (IDVal == ".4byte")
- return ParseDirectiveValue(4);
- if (IDVal == ".quad")
- return ParseDirectiveValue(8);
- if (IDVal == ".8byte")
- return ParseDirectiveValue(8);
- if (IDVal == ".single" || IDVal == ".float")
- return ParseDirectiveRealValue(APFloat::IEEEsingle);
- if (IDVal == ".double")
- return ParseDirectiveRealValue(APFloat::IEEEdouble);
-
- if (IDVal == ".align") {
- bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
- return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1);
- }
- if (IDVal == ".align32") {
- bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
- return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4);
- }
- if (IDVal == ".balign")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
- if (IDVal == ".balignw")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
- if (IDVal == ".balignl")
- return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
- if (IDVal == ".p2align")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
- if (IDVal == ".p2alignw")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
- if (IDVal == ".p2alignl")
- return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
-
- if (IDVal == ".org")
- return ParseDirectiveOrg();
-
- if (IDVal == ".fill")
- return ParseDirectiveFill();
- if (IDVal == ".space" || IDVal == ".skip")
- return ParseDirectiveSpace();
- if (IDVal == ".zero")
- return ParseDirectiveZero();
-
- // Symbol attribute directives
-
- if (IDVal == ".extern") {
- EatToEndOfStatement(); // .extern is the default, ignore it.
- return false;
- }
- if (IDVal == ".globl" || IDVal == ".global")
- return ParseDirectiveSymbolAttribute(MCSA_Global);
- if (IDVal == ".indirect_symbol")
- return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
- if (IDVal == ".lazy_reference")
- return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
- if (IDVal == ".no_dead_strip")
- return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
- if (IDVal == ".symbol_resolver")
- return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
- if (IDVal == ".private_extern")
- return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
- if (IDVal == ".reference")
- return ParseDirectiveSymbolAttribute(MCSA_Reference);
- if (IDVal == ".weak_definition")
- return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
- if (IDVal == ".weak_reference")
- return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
- if (IDVal == ".weak_def_can_be_hidden")
- return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
-
- if (IDVal == ".comm" || IDVal == ".common")
- return ParseDirectiveComm(/*IsLocal=*/false);
- if (IDVal == ".lcomm")
- return ParseDirectiveComm(/*IsLocal=*/true);
-
- if (IDVal == ".abort")
- return ParseDirectiveAbort();
- if (IDVal == ".include")
- return ParseDirectiveInclude();
- if (IDVal == ".incbin")
- return ParseDirectiveIncbin();
-
- if (IDVal == ".code16" || IDVal == ".code16gcc")
- return TokError(Twine(IDVal) + " not supported yet");
-
- // Macro-like directives
- if (IDVal == ".rept")
- return ParseDirectiveRept(IDLoc);
- if (IDVal == ".irp")
- return ParseDirectiveIrp(IDLoc);
- if (IDVal == ".irpc")
- return ParseDirectiveIrpc(IDLoc);
- if (IDVal == ".endr")
- return ParseDirectiveEndr(IDLoc);
-
- // Look up the handler in the handler table.
+ // Next, check the extention directive map to see if any extension has
+ // registered itself to parse this directive.
std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
- DirectiveMap.lookup(IDVal);
+ ExtensionDirectiveMap.lookup(IDVal);
if (Handler.first)
return (*Handler.second)(Handler.first, IDVal, IDLoc);
+ // Finally, if no one else is interested in this directive, it must be
+ // generic and familiar to this class.
+ switch (DirKind) {
+ default:
+ break;
+ case DK_SET:
+ case DK_EQU:
+ return ParseDirectiveSet(IDVal, true);
+ case DK_EQUIV:
+ return ParseDirectiveSet(IDVal, false);
+ case DK_ASCII:
+ return ParseDirectiveAscii(IDVal, false);
+ case DK_ASCIZ:
+ case DK_STRING:
+ return ParseDirectiveAscii(IDVal, true);
+ case DK_BYTE:
+ return ParseDirectiveValue(1);
+ case DK_SHORT:
+ case DK_VALUE:
+ case DK_2BYTE:
+ return ParseDirectiveValue(2);
+ case DK_LONG:
+ case DK_INT:
+ case DK_4BYTE:
+ return ParseDirectiveValue(4);
+ case DK_QUAD:
+ case DK_8BYTE:
+ return ParseDirectiveValue(8);
+ case DK_SINGLE:
+ case DK_FLOAT:
+ return ParseDirectiveRealValue(APFloat::IEEEsingle);
+ case DK_DOUBLE:
+ return ParseDirectiveRealValue(APFloat::IEEEdouble);
+ case DK_ALIGN: {
+ bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
+ return ParseDirectiveAlign(IsPow2, /*ExprSize=*/1);
+ }
+ case DK_ALIGN32: {
+ bool IsPow2 = !getContext().getAsmInfo().getAlignmentIsInBytes();
+ return ParseDirectiveAlign(IsPow2, /*ExprSize=*/4);
+ }
+ case DK_BALIGN:
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
+ case DK_BALIGNW:
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
+ case DK_BALIGNL:
+ return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
+ case DK_P2ALIGN:
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
+ case DK_P2ALIGNW:
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
+ case DK_P2ALIGNL:
+ return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
+ case DK_ORG:
+ return ParseDirectiveOrg();
+ case DK_FILL:
+ return ParseDirectiveFill();
+ case DK_ZERO:
+ return ParseDirectiveZero();
+ case DK_EXTERN:
+ eatToEndOfStatement(); // .extern is the default, ignore it.
+ return false;
+ case DK_GLOBL:
+ case DK_GLOBAL:
+ return ParseDirectiveSymbolAttribute(MCSA_Global);
+ case DK_INDIRECT_SYMBOL:
+ return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
+ case DK_LAZY_REFERENCE:
+ return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
+ case DK_NO_DEAD_STRIP:
+ return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
+ case DK_SYMBOL_RESOLVER:
+ return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver);
+ case DK_PRIVATE_EXTERN:
+ return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
+ case DK_REFERENCE:
+ return ParseDirectiveSymbolAttribute(MCSA_Reference);
+ case DK_WEAK_DEFINITION:
+ return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
+ case DK_WEAK_REFERENCE:
+ return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
+ case DK_WEAK_DEF_CAN_BE_HIDDEN:
+ return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
+ case DK_COMM:
+ case DK_COMMON:
+ return ParseDirectiveComm(/*IsLocal=*/false);
+ case DK_LCOMM:
+ return ParseDirectiveComm(/*IsLocal=*/true);
+ case DK_ABORT:
+ return ParseDirectiveAbort();
+ case DK_INCLUDE:
+ return ParseDirectiveInclude();
+ case DK_INCBIN:
+ return ParseDirectiveIncbin();
+ case DK_CODE16:
+ case DK_CODE16GCC:
+ return TokError(Twine(IDVal) + " not supported yet");
+ case DK_REPT:
+ return ParseDirectiveRept(IDLoc);
+ case DK_IRP:
+ return ParseDirectiveIrp(IDLoc);
+ case DK_IRPC:
+ return ParseDirectiveIrpc(IDLoc);
+ case DK_ENDR:
+ return ParseDirectiveEndr(IDLoc);
+ case DK_BUNDLE_ALIGN_MODE:
+ return ParseDirectiveBundleAlignMode();
+ case DK_BUNDLE_LOCK:
+ return ParseDirectiveBundleLock();
+ case DK_BUNDLE_UNLOCK:
+ return ParseDirectiveBundleUnlock();
+ case DK_SLEB128:
+ return ParseDirectiveLEB128(true);
+ case DK_ULEB128:
+ return ParseDirectiveLEB128(false);
+ case DK_SPACE:
+ case DK_SKIP:
+ return ParseDirectiveSpace(IDVal);
+ case DK_FILE:
+ return ParseDirectiveFile(IDLoc);
+ case DK_LINE:
+ return ParseDirectiveLine();
+ case DK_LOC:
+ return ParseDirectiveLoc();
+ case DK_STABS:
+ return ParseDirectiveStabs();
+ case DK_CFI_SECTIONS:
+ return ParseDirectiveCFISections();
+ case DK_CFI_STARTPROC:
+ return ParseDirectiveCFIStartProc();
+ case DK_CFI_ENDPROC:
+ return ParseDirectiveCFIEndProc();
+ case DK_CFI_DEF_CFA:
+ return ParseDirectiveCFIDefCfa(IDLoc);
+ case DK_CFI_DEF_CFA_OFFSET:
+ return ParseDirectiveCFIDefCfaOffset();
+ case DK_CFI_ADJUST_CFA_OFFSET:
+ return ParseDirectiveCFIAdjustCfaOffset();
+ case DK_CFI_DEF_CFA_REGISTER:
+ return ParseDirectiveCFIDefCfaRegister(IDLoc);
+ case DK_CFI_OFFSET:
+ return ParseDirectiveCFIOffset(IDLoc);
+ case DK_CFI_REL_OFFSET:
+ return ParseDirectiveCFIRelOffset(IDLoc);
+ case DK_CFI_PERSONALITY:
+ return ParseDirectiveCFIPersonalityOrLsda(true);
+ case DK_CFI_LSDA:
+ return ParseDirectiveCFIPersonalityOrLsda(false);
+ case DK_CFI_REMEMBER_STATE:
+ return ParseDirectiveCFIRememberState();
+ case DK_CFI_RESTORE_STATE:
+ return ParseDirectiveCFIRestoreState();
+ case DK_CFI_SAME_VALUE:
+ return ParseDirectiveCFISameValue(IDLoc);
+ case DK_CFI_RESTORE:
+ return ParseDirectiveCFIRestore(IDLoc);
+ case DK_CFI_ESCAPE:
+ return ParseDirectiveCFIEscape();
+ case DK_CFI_SIGNAL_FRAME:
+ return ParseDirectiveCFISignalFrame();
+ case DK_CFI_UNDEFINED:
+ return ParseDirectiveCFIUndefined(IDLoc);
+ case DK_CFI_REGISTER:
+ return ParseDirectiveCFIRegister(IDLoc);
+ case DK_MACROS_ON:
+ case DK_MACROS_OFF:
+ return ParseDirectiveMacrosOnOff(IDVal);
+ case DK_MACRO:
+ return ParseDirectiveMacro(IDLoc);
+ case DK_ENDM:
+ case DK_ENDMACRO:
+ return ParseDirectiveEndMacro(IDVal);
+ case DK_PURGEM:
+ return ParseDirectivePurgeMacro(IDLoc);
+ }
return Error(IDLoc, "unknown directive");
}
- // _emit
- if (ParsingInlineAsm && IDVal == "_emit")
- return ParseDirectiveEmit(IDLoc, Info);
+ // __asm _emit or __asm __emit
+ if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
+ IDVal == "_EMIT" || IDVal == "__EMIT"))
+ return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size());
- CheckForValidSection();
+ // __asm align
+ if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
+ return ParseDirectiveMSAlign(IDLoc, Info);
- // Canonicalize the opcode to lower case.
- SmallString<128> OpcodeStr;
- for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
- OpcodeStr.push_back(tolower(IDVal[i]));
+ checkForValidSection();
+ // Canonicalize the opcode to lower case.
+ std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr.str(),
- IDLoc,Info.ParsedOperands);
+ bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
+ IDLoc, Info.ParsedOperands);
+ Info.ParseError = HadError;
// Dump the parsed representation, if requested.
if (getShowParsedOperands()) {
@@ -1405,24 +1488,24 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// section is the initial text section then generate a .loc directive for
// the instruction.
if (!HadError && getContext().getGenDwarfForAssembly() &&
- getContext().getGenDwarfSection() == getStreamer().getCurrentSection() ) {
+ getContext().getGenDwarfSection() == getStreamer().getCurrentSection()) {
- unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
+ 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() !=
+ // 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);
+ getStreamer().EmitDwarfFileDirective(
+ getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename);
unsigned CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc,CppHashBuf);
Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
- }
+ }
getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(),
Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ?
@@ -1508,7 +1591,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
}
- // If we have not parsed a cpp hash line filename comment or the source
+ // If we have not parsed a cpp hash line filename comment or the source
// manager changed or buffer changed (like in a nested include) then just
// print the normal diagnostic using its Filename and LineNo.
if (!Parser->CppHashLineNumber ||
@@ -1521,7 +1604,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
return;
}
- // Use the CppHashFilename and calculate a line number based on the
+ // Use the CppHashFilename and calculate a line number based on the
// CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
// the diagnostic.
const std::string Filename = Parser->CppHashFilename;
@@ -1548,12 +1631,13 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// 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 == '.';
+ return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
+ c == '.';
}
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MacroParameters &Parameters,
- const MacroArguments &A,
+ const MCAsmMacroParameters &Parameters,
+ const MCAsmMacroArguments &A,
const SMLoc &L) {
unsigned NParameters = Parameters.size();
if (NParameters != 0 && NParameters != A.size())
@@ -1572,7 +1656,8 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
continue;
char Next = Body[Pos + 1];
- if (Next == '$' || Next == 'n' || isdigit(Next))
+ if (Next == '$' || Next == 'n' ||
+ isdigit(static_cast<unsigned char>(Next)))
break;
} else {
// This macro has parameters, look for \foo, \bar, etc.
@@ -1608,7 +1693,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
break;
// Otherwise substitute with the token values, with spaces eliminated.
- for (MacroArgument::const_iterator it = A[Index].begin(),
+ for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
ie = A[Index].end(); it != ie; ++it)
OS << it->getString();
break;
@@ -1635,7 +1720,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
Pos = I;
}
} else {
- for (MacroArgument::const_iterator it = A[Index].begin(),
+ for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
ie = A[Index].end(); it != ie; ++it)
if (it->getKind() == AsmToken::String)
OS << it->getStringContents();
@@ -1652,7 +1737,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
return false;
}
-MacroInstantiation::MacroInstantiation(const Macro *M, SMLoc IL,
+MacroInstantiation::MacroInstantiation(const MCAsmMacro *M, SMLoc IL,
int EB, SMLoc EL,
MemoryBuffer *I)
: TheMacro(M), Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB),
@@ -1693,10 +1778,7 @@ static bool IsOperator(AsmToken::TokenKind kind)
}
}
-/// 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(MCAsmMacroArgument &MA,
AsmToken::TokenKind &ArgumentDelimiter) {
unsigned ParenLevel = 0;
unsigned AddTokens = 0;
@@ -1733,7 +1815,7 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA,
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;
+ const char *NextChar = getTok().getEndLoc().getPointer();
if (*NextChar == ' ')
AddTokens = 2;
}
@@ -1772,7 +1854,7 @@ bool AsmParser::ParseMacroArgument(MacroArgument &MA,
}
// Parse the macro instantiation arguments.
-bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
+bool AsmParser::ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A) {
const unsigned NParameters = M ? M->Parameters.size() : 0;
// Argument delimiter is initially unknown. It will be set by
// ParseMacroArgument()
@@ -1783,7 +1865,7 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
// - macros defined with parameters accept at most that many of them
for (unsigned Parameter = 0; !NParameters || Parameter < NParameters;
++Parameter) {
- MacroArgument MA;
+ MCAsmMacroArgument MA;
if (ParseMacroArgument(MA, ArgumentDelimiter))
return true;
@@ -1816,14 +1898,30 @@ bool AsmParser::ParseMacroArguments(const Macro *M, MacroArguments &A) {
return TokError("Too many arguments");
}
-bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
- const Macro *M) {
+const MCAsmMacro* AsmParser::LookupMacro(StringRef Name) {
+ StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+ return (I == MacroMap.end()) ? NULL : I->getValue();
+}
+
+void AsmParser::DefineMacro(StringRef Name, const MCAsmMacro& Macro) {
+ MacroMap[Name] = new MCAsmMacro(Macro);
+}
+
+void AsmParser::UndefineMacro(StringRef Name) {
+ StringMap<MCAsmMacro*>::iterator I = MacroMap.find(Name);
+ if (I != MacroMap.end()) {
+ delete I->getValue();
+ MacroMap.erase(I);
+ }
+}
+
+bool AsmParser::HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
// Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
// this, although we should protect against infinite loops.
if (ActiveMacros.size() == 20)
return TokError("macros cannot be nested more than 20 levels deep");
- MacroArguments A;
+ MCAsmMacroArguments A;
if (ParseMacroArguments(M, A))
return true;
@@ -1842,7 +1940,7 @@ bool AsmParser::HandleMacroEntry(StringRef Name, SMLoc NameLoc,
if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc()))
return true;
- // We include the .endmacro in the buffer as our queue to exit the macro
+ // We include the .endmacro in the buffer as our cue to exit the macro
// instantiation.
OS << ".endmacro\n";
@@ -1904,7 +2002,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
SMLoc EqualLoc = Lexer.getLoc();
const MCExpr *Value;
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// Note: we don't count b as used in "a = b". This is to allow
@@ -1961,10 +2059,10 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
return false;
}
-/// ParseIdentifier:
+/// parseIdentifier:
/// ::= identifier
/// ::= string
-bool AsmParser::ParseIdentifier(StringRef &Res) {
+bool AsmParser::parseIdentifier(StringRef &Res) {
// The assembler has relaxed rules for accepting identifiers, in particular we
// allow things like '.globl $foo', which would normally be separate
// tokens. At this level, we have already lexed so we cannot (currently)
@@ -2007,7 +2105,7 @@ bool AsmParser::ParseIdentifier(StringRef &Res) {
bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier after '" + Twine(IDVal) + "'");
if (getLexer().isNot(AsmToken::Comma))
@@ -2017,7 +2115,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
return ParseAssignment(Name, allow_redef, true);
}
-bool AsmParser::ParseEscapedString(std::string &Data) {
+bool AsmParser::parseEscapedString(std::string &Data) {
assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
Data = "";
@@ -2079,14 +2177,14 @@ bool AsmParser::ParseEscapedString(std::string &Data) {
/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in '" + Twine(IDVal) + "' directive");
std::string Data;
- if (ParseEscapedString(Data))
+ if (parseEscapedString(Data))
return true;
getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
@@ -2112,12 +2210,12 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
bool AsmParser::ParseDirectiveValue(unsigned Size) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// Special case constant expressions to match code generator.
@@ -2148,7 +2246,7 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
/// ::= (.single | .double) [ expression (, expression)* ]
bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
// We don't truly support arithmetic on floating point expressions, so we
@@ -2202,52 +2300,19 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
return false;
}
-/// ParseDirectiveSpace
-/// ::= .space expression [ , expression ]
-bool AsmParser::ParseDirectiveSpace() {
- CheckForValidSection();
-
- int64_t NumBytes;
- if (ParseAbsoluteExpression(NumBytes))
- return true;
-
- int64_t FillExpr = 0;
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.space' directive");
- Lex();
-
- if (ParseAbsoluteExpression(FillExpr))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.space' directive");
- }
-
- Lex();
-
- if (NumBytes <= 0)
- return TokError("invalid number of bytes in '.space' directive");
-
- // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
-
- return false;
-}
-
/// ParseDirectiveZero
/// ::= .zero expression
bool AsmParser::ParseDirectiveZero() {
- CheckForValidSection();
+ checkForValidSection();
int64_t NumBytes;
- if (ParseAbsoluteExpression(NumBytes))
+ if (parseAbsoluteExpression(NumBytes))
return true;
int64_t Val = 0;
if (getLexer().is(AsmToken::Comma)) {
Lex();
- if (ParseAbsoluteExpression(Val))
+ if (parseAbsoluteExpression(Val))
return true;
}
@@ -2264,10 +2329,10 @@ bool AsmParser::ParseDirectiveZero() {
/// ParseDirectiveFill
/// ::= .fill expression , expression , expression
bool AsmParser::ParseDirectiveFill() {
- CheckForValidSection();
+ checkForValidSection();
int64_t NumValues;
- if (ParseAbsoluteExpression(NumValues))
+ if (parseAbsoluteExpression(NumValues))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2275,7 +2340,7 @@ bool AsmParser::ParseDirectiveFill() {
Lex();
int64_t FillSize;
- if (ParseAbsoluteExpression(FillSize))
+ if (parseAbsoluteExpression(FillSize))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2283,7 +2348,7 @@ bool AsmParser::ParseDirectiveFill() {
Lex();
int64_t FillExpr;
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2303,11 +2368,11 @@ bool AsmParser::ParseDirectiveFill() {
/// ParseDirectiveOrg
/// ::= .org expression [ , expression ]
bool AsmParser::ParseDirectiveOrg() {
- CheckForValidSection();
+ checkForValidSection();
const MCExpr *Offset;
SMLoc Loc = getTok().getLoc();
- if (ParseExpression(Offset))
+ if (parseExpression(Offset))
return true;
// Parse optional fill expression.
@@ -2317,7 +2382,7 @@ bool AsmParser::ParseDirectiveOrg() {
return TokError("unexpected token in '.org' directive");
Lex();
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2338,11 +2403,11 @@ bool AsmParser::ParseDirectiveOrg() {
/// ParseDirectiveAlign
/// ::= {.align, ...} expression [ , expression [ , expression ]]
bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
- CheckForValidSection();
+ checkForValidSection();
SMLoc AlignmentLoc = getLexer().getLoc();
int64_t Alignment;
- if (ParseAbsoluteExpression(Alignment))
+ if (parseAbsoluteExpression(Alignment))
return true;
SMLoc MaxBytesLoc;
@@ -2359,7 +2424,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
// .align 3,,4
if (getLexer().isNot(AsmToken::Comma)) {
HasFillExpr = true;
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
}
@@ -2369,7 +2434,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
Lex();
MaxBytesLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(MaxBytesToFill))
+ if (parseAbsoluteExpression(MaxBytesToFill))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2391,6 +2456,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
Alignment = 1ULL << Alignment;
+ } else {
+ // Reject alignments that aren't a power of two, for gas compatibility.
+ if (!isPowerOf2_64(Alignment))
+ Error(AlignmentLoc, "alignment must be a power of 2");
}
// Diagnose non-sensical max bytes to align.
@@ -2423,368 +2492,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
return false;
}
-/// ParseDirectiveSymbolAttribute
-/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
-bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
- if (getLexer().isNot(AsmToken::EndOfStatement)) {
- for (;;) {
- StringRef Name;
- SMLoc Loc = getTok().getLoc();
-
- if (ParseIdentifier(Name))
- return Error(Loc, "expected identifier in directive");
-
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
-
- // Assembler local symbols don't make any sense here. Complain loudly.
- if (Sym->isTemporary())
- return Error(Loc, "non-local symbol required in directive");
-
- getStreamer().EmitSymbolAttribute(Sym, Attr);
-
- if (getLexer().is(AsmToken::EndOfStatement))
- break;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
- }
- }
-
- Lex();
- return false;
-}
-
-/// ParseDirectiveComm
-/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
-bool AsmParser::ParseDirectiveComm(bool IsLocal) {
- CheckForValidSection();
-
- SMLoc IDLoc = getLexer().getLoc();
- StringRef Name;
- if (ParseIdentifier(Name))
- return TokError("expected identifier in directive");
-
- // Handle the identifier as the key symbol.
- MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Size;
- SMLoc SizeLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(Size))
- return true;
-
- int64_t Pow2Alignment = 0;
- SMLoc Pow2AlignmentLoc;
- if (getLexer().is(AsmToken::Comma)) {
- Lex();
- Pow2AlignmentLoc = getLexer().getLoc();
- 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 ((!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);
- }
- }
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.comm' or '.lcomm' directive");
-
- Lex();
-
- // NOTE: a size of zero for a .comm should create a undefined symbol
- // but a size of .lcomm creates a bss symbol of size zero.
- if (Size < 0)
- return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
- "be less than zero");
-
- // NOTE: The alignment in the directive is a power of 2 value, the assembler
- // may internally end up wanting an alignment in bytes.
- // FIXME: Diagnose overflow.
- if (Pow2Alignment < 0)
- return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
- "alignment, can't be less than zero");
-
- if (!Sym->isUndefined())
- return Error(IDLoc, "invalid symbol redefinition");
-
- // Create the Symbol as a common or local common with Size and Pow2Alignment
- if (IsLocal) {
- getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
- }
-
- getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
- return false;
-}
-
-/// ParseDirectiveAbort
-/// ::= .abort [... message ...]
-bool AsmParser::ParseDirectiveAbort() {
- // FIXME: Use loc from directive.
- SMLoc Loc = getLexer().getLoc();
-
- StringRef Str = ParseStringToEndOfStatement();
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.abort' directive");
-
- Lex();
-
- if (Str.empty())
- Error(Loc, ".abort detected. Assembly stopping.");
- else
- Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
- // FIXME: Actually abort assembly here.
-
- return false;
-}
-
-/// ParseDirectiveInclude
-/// ::= .include "filename"
-bool AsmParser::ParseDirectiveInclude() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.include' directive");
-
- std::string Filename = getTok().getString();
- SMLoc IncludeLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.include' directive");
-
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
- // Attempt to switch the lexer to the included file before consuming the end
- // of statement to avoid losing it when we switch.
- if (EnterIncludeFile(Filename)) {
- Error(IncludeLoc, "Could not find include file '" + Filename + "'");
- return true;
- }
-
- return false;
-}
-
-/// ParseDirectiveIncbin
-/// ::= .incbin "filename"
-bool AsmParser::ParseDirectiveIncbin() {
- if (getLexer().isNot(AsmToken::String))
- return TokError("expected string in '.incbin' directive");
-
- std::string Filename = getTok().getString();
- SMLoc IncbinLoc = getLexer().getLoc();
- Lex();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.incbin' directive");
-
- // Strip the quotes.
- Filename = Filename.substr(1, Filename.size()-2);
-
- // Attempt to process the included file.
- if (ProcessIncbinFile(Filename)) {
- Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
- return true;
- }
-
- return false;
-}
-
-/// ParseDirectiveIf
-/// ::= .if expression
-bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.if' directive");
-
- Lex();
-
- TheCondState.CondMet = ExprValue;
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfb
-/// ::= .ifb string
-bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- StringRef Str = ParseStringToEndOfStatement();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifb' directive");
-
- Lex();
-
- TheCondState.CondMet = ExpectBlank == Str.empty();
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfc
-/// ::= .ifc string1, string2
-bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- StringRef Str1 = ParseStringToComma();
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
-
- StringRef Str2 = ParseStringToEndOfStatement();
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.ifc' directive");
-
- Lex();
-
- TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveIfdef
-/// ::= .ifdef symbol
-bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
- StringRef Name;
- TheCondStack.push_back(TheCondState);
- TheCondState.TheCond = AsmCond::IfCond;
-
- if (TheCondState.Ignore) {
- EatToEndOfStatement();
- } else {
- if (ParseIdentifier(Name))
- return TokError("expected identifier after '.ifdef'");
-
- Lex();
-
- MCSymbol *Sym = getContext().LookupSymbol(Name);
-
- if (expect_defined)
- TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
- else
- TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveElseIf
-/// ::= .elseif expression
-bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
- if (TheCondState.TheCond != AsmCond::IfCond &&
- TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
- " an .elseif");
- TheCondState.TheCond = AsmCond::ElseIfCond;
-
- bool LastIgnoreState = false;
- if (!TheCondStack.empty())
- LastIgnoreState = TheCondStack.back().Ignore;
- if (LastIgnoreState || TheCondState.CondMet) {
- TheCondState.Ignore = true;
- EatToEndOfStatement();
- }
- else {
- int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
- return true;
-
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.elseif' directive");
-
- Lex();
- TheCondState.CondMet = ExprValue;
- TheCondState.Ignore = !TheCondState.CondMet;
- }
-
- return false;
-}
-
-/// ParseDirectiveElse
-/// ::= .else
-bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.else' directive");
-
- Lex();
-
- if (TheCondState.TheCond != AsmCond::IfCond &&
- TheCondState.TheCond != AsmCond::ElseIfCond)
- Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
- ".elseif");
- TheCondState.TheCond = AsmCond::ElseCond;
- bool LastIgnoreState = false;
- if (!TheCondStack.empty())
- LastIgnoreState = TheCondStack.back().Ignore;
- if (LastIgnoreState || TheCondState.CondMet)
- TheCondState.Ignore = true;
- else
- TheCondState.Ignore = false;
-
- return false;
-}
-
-/// ParseDirectiveEndIf
-/// ::= .endif
-bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
- if (getLexer().isNot(AsmToken::EndOfStatement))
- return TokError("unexpected token in '.endif' directive");
-
- Lex();
-
- if ((TheCondState.TheCond == AsmCond::NoCond) ||
- TheCondStack.empty())
- Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
- ".else");
- if (!TheCondStack.empty()) {
- TheCondState = TheCondStack.back();
- TheCondStack.pop_back();
- }
-
- return false;
-}
-
/// ParseDirectiveFile
/// ::= .file [number] filename
/// ::= .file number directory filename
-bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveFile(SMLoc DirectiveLoc) {
// FIXME: I'm not sure what this is.
int64_t FileNumber = -1;
SMLoc FileNumberLoc = getLexer().getLoc();
@@ -2836,7 +2547,7 @@ bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
/// ParseDirectiveLine
/// ::= .line [number]
-bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveLine() {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
if (getLexer().isNot(AsmToken::Integer))
return TokError("unexpected token in '.line' directive");
@@ -2854,7 +2565,6 @@ bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
return false;
}
-
/// ParseDirectiveLoc
/// ::= .loc FileNumber [LineNumber] [ColumnPos] [basic_block] [prologue_end]
/// [epilogue_begin] [is_stmt VALUE] [isa VALUE]
@@ -2862,8 +2572,7 @@ bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
/// a .file directive, the second number is the line number and optionally the
/// third number is a column position (zero if not specified). The remaining
/// optional items are .loc sub-directives.
-bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
-
+bool AsmParser::ParseDirectiveLoc() {
if (getLexer().isNot(AsmToken::Integer))
return TokError("unexpected token in '.loc' directive");
int64_t FileNumber = getTok().getIntVal();
@@ -2899,7 +2608,7 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
StringRef Name;
SMLoc Loc = getTok().getLoc();
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("unexpected token in '.loc' directive");
if (Name == "basic_block")
@@ -2909,9 +2618,9 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
else if (Name == "epilogue_begin")
Flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
else if (Name == "is_stmt") {
- SMLoc Loc = getTok().getLoc();
+ Loc = getTok().getLoc();
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// The expression must be the constant 0 or 1.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
@@ -2928,9 +2637,9 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
}
}
else if (Name == "isa") {
- SMLoc Loc = getTok().getLoc();
+ Loc = getTok().getLoc();
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// The expression must be a constant greater or equal to 0.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
@@ -2944,7 +2653,7 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
}
}
else if (Name == "discriminator") {
- if (getParser().ParseAbsoluteExpression(Discriminator))
+ if (parseAbsoluteExpression(Discriminator))
return true;
}
else {
@@ -2964,20 +2673,18 @@ bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
/// ParseDirectiveStabs
/// ::= .stabs string, number, number, number
-bool GenericAsmParser::ParseDirectiveStabs(StringRef Directive,
- SMLoc DirectiveLoc) {
- return TokError("unsupported directive '" + Directive + "'");
+bool AsmParser::ParseDirectiveStabs() {
+ return TokError("unsupported directive '.stabs'");
}
/// ParseDirectiveCFISections
/// ::= .cfi_sections section [, section]
-bool GenericAsmParser::ParseDirectiveCFISections(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFISections() {
StringRef Name;
bool EH = false;
bool Debug = false;
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("Expected an identifier");
if (Name == ".eh_frame")
@@ -2988,7 +2695,7 @@ bool GenericAsmParser::ParseDirectiveCFISections(StringRef,
if (getLexer().is(AsmToken::Comma)) {
Lex();
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("Expected an identifier");
if (Name == ".eh_frame")
@@ -2998,45 +2705,41 @@ bool GenericAsmParser::ParseDirectiveCFISections(StringRef,
}
getStreamer().EmitCFISections(EH, Debug);
-
return false;
}
/// ParseDirectiveCFIStartProc
/// ::= .cfi_startproc
-bool GenericAsmParser::ParseDirectiveCFIStartProc(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIStartProc() {
getStreamer().EmitCFIStartProc();
return false;
}
/// ParseDirectiveCFIEndProc
/// ::= .cfi_endproc
-bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIEndProc() {
getStreamer().EmitCFIEndProc();
return false;
}
/// ParseRegisterOrRegisterNumber - parse register name or number.
-bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
+ SMLoc DirectiveLoc) {
unsigned RegNo;
if (getLexer().isNot(AsmToken::Integer)) {
- if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc,
- DirectiveLoc))
+ if (getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc))
return true;
Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true);
} else
- return getParser().ParseAbsoluteExpression(Register);
+ return parseAbsoluteExpression(Register);
return false;
}
/// ParseDirectiveCFIDefCfa
/// ::= .cfi_def_cfa register, offset
-bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
@@ -3046,7 +2749,7 @@ bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
Lex();
int64_t Offset = 0;
- if (getParser().ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfa(Register, Offset);
@@ -3055,22 +2758,39 @@ bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
/// ParseDirectiveCFIDefCfaOffset
/// ::= .cfi_def_cfa_offset offset
-bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIDefCfaOffset() {
int64_t Offset = 0;
- if (getParser().ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfaOffset(Offset);
return false;
}
+/// ParseDirectiveCFIRegister
+/// ::= .cfi_register register, register
+bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) {
+ int64_t Register1 = 0;
+ if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc))
+ return true;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Register2 = 0;
+ if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc))
+ return true;
+
+ getStreamer().EmitCFIRegister(Register1, Register2);
+ return false;
+}
+
/// ParseDirectiveCFIAdjustCfaOffset
/// ::= .cfi_adjust_cfa_offset adjustment
-bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() {
int64_t Adjustment = 0;
- if (getParser().ParseAbsoluteExpression(Adjustment))
+ if (parseAbsoluteExpression(Adjustment))
return true;
getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
@@ -3079,8 +2799,7 @@ bool GenericAsmParser::ParseDirectiveCFIAdjustCfaOffset(StringRef,
/// ParseDirectiveCFIDefCfaRegister
/// ::= .cfi_def_cfa_register register
-bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIDefCfaRegister(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
@@ -3091,7 +2810,7 @@ bool GenericAsmParser::ParseDirectiveCFIDefCfaRegister(StringRef,
/// ParseDirectiveCFIOffset
/// ::= .cfi_offset register, offset
-bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
int64_t Offset = 0;
@@ -3102,7 +2821,7 @@ bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
return TokError("unexpected token in directive");
Lex();
- if (getParser().ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIOffset(Register, Offset);
@@ -3111,8 +2830,7 @@ bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) {
/// ParseDirectiveCFIRelOffset
/// ::= .cfi_rel_offset register, offset
-bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
@@ -3123,7 +2841,7 @@ bool GenericAsmParser::ParseDirectiveCFIRelOffset(StringRef,
Lex();
int64_t Offset = 0;
- if (getParser().ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIRelOffset(Register, Offset);
@@ -3153,12 +2871,12 @@ static bool isValidEncoding(int64_t Encoding) {
}
/// ParseDirectiveCFIPersonalityOrLsda
+/// IsPersonality true for cfi_personality, false for cfi_lsda
/// ::= .cfi_personality encoding, [symbol_name]
/// ::= .cfi_lsda encoding, [symbol_name]
-bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
int64_t Encoding = 0;
- if (getParser().ParseAbsoluteExpression(Encoding))
+ if (parseAbsoluteExpression(Encoding))
return true;
if (Encoding == dwarf::DW_EH_PE_omit)
return false;
@@ -3171,70 +2889,61 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal,
Lex();
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
- if (IDVal == ".cfi_personality")
+ if (IsPersonality)
getStreamer().EmitCFIPersonality(Sym, Encoding);
- else {
- assert(IDVal == ".cfi_lsda");
+ else
getStreamer().EmitCFILsda(Sym, Encoding);
- }
return false;
}
/// ParseDirectiveCFIRememberState
/// ::= .cfi_remember_state
-bool GenericAsmParser::ParseDirectiveCFIRememberState(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIRememberState() {
getStreamer().EmitCFIRememberState();
return false;
}
/// ParseDirectiveCFIRestoreState
/// ::= .cfi_remember_state
-bool GenericAsmParser::ParseDirectiveCFIRestoreState(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIRestoreState() {
getStreamer().EmitCFIRestoreState();
return false;
}
/// ParseDirectiveCFISameValue
/// ::= .cfi_same_value register
-bool GenericAsmParser::ParseDirectiveCFISameValue(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFISameValue(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFISameValue(Register);
-
return false;
}
/// ParseDirectiveCFIRestore
/// ::= .cfi_restore register
-bool GenericAsmParser::ParseDirectiveCFIRestore(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIRestore(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFIRestore(Register);
-
return false;
}
/// ParseDirectiveCFIEscape
/// ::= .cfi_escape expression[,...]
-bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIEscape() {
std::string Values;
int64_t CurrValue;
- if (getParser().ParseAbsoluteExpression(CurrValue))
+ if (parseAbsoluteExpression(CurrValue))
return true;
Values.push_back((uint8_t)CurrValue);
@@ -3242,7 +2951,7 @@ bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
while (getLexer().is(AsmToken::Comma)) {
Lex();
- if (getParser().ParseAbsoluteExpression(CurrValue))
+ if (parseAbsoluteExpression(CurrValue))
return true;
Values.push_back((uint8_t)CurrValue);
@@ -3254,89 +2963,59 @@ bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
/// ParseDirectiveCFISignalFrame
/// ::= .cfi_signal_frame
-bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFISignalFrame() {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(getLexer().getLoc(),
- "unexpected token in '" + Directive + "' directive");
+ "unexpected token in '.cfi_signal_frame'");
getStreamer().EmitCFISignalFrame();
-
return false;
}
/// ParseDirectiveCFIUndefined
/// ::= .cfi_undefined register
-bool GenericAsmParser::ParseDirectiveCFIUndefined(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveCFIUndefined(SMLoc DirectiveLoc) {
int64_t Register = 0;
if (ParseRegisterOrRegisterNumber(Register, DirectiveLoc))
return true;
getStreamer().EmitCFIUndefined(Register);
-
- return false;
-}
-
-/// ParseDirectiveCFIRegister
-/// ::= .cfi_register register, register
-bool GenericAsmParser::ParseDirectiveCFIRegister(StringRef Directive,
- SMLoc DirectiveLoc) {
- int64_t Register1 = 0;
-
- if (ParseRegisterOrRegisterNumber(Register1, DirectiveLoc))
- return true;
-
- if (getLexer().isNot(AsmToken::Comma))
- return TokError("unexpected token in directive");
- Lex();
-
- int64_t Register2 = 0;
-
- if (ParseRegisterOrRegisterNumber(Register2, DirectiveLoc))
- return true;
-
- getStreamer().EmitCFIRegister(Register1, Register2);
-
return false;
}
/// ParseDirectiveMacrosOnOff
/// ::= .macros_on
/// ::= .macros_off
-bool GenericAsmParser::ParseDirectiveMacrosOnOff(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveMacrosOnOff(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(getLexer().getLoc(),
"unexpected token in '" + Directive + "' directive");
- getParser().MacrosEnabled = Directive == ".macros_on";
-
+ SetMacrosEnabled(Directive == ".macros_on");
return false;
}
/// ParseDirectiveMacro
/// ::= .macro name [parameters]
-bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in '.macro' directive");
- MacroParameters Parameters;
+ MCAsmMacroParameters Parameters;
// Argument delimiter is initially unknown. It will be set by
// ParseMacroArgument()
AsmToken::TokenKind ArgumentDelimiter = AsmToken::Eof;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
- MacroParameter Parameter;
- if (getParser().ParseIdentifier(Parameter.first))
+ MCAsmMacroParameter Parameter;
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.macro' directive");
if (getLexer().is(AsmToken::Equal)) {
Lex();
- if (getParser().ParseMacroArgument(Parameter.second, ArgumentDelimiter))
+ if (ParseMacroArgument(Parameter.second, ArgumentDelimiter))
return true;
}
@@ -3373,32 +3052,134 @@ bool GenericAsmParser::ParseDirectiveMacro(StringRef Directive,
}
// Otherwise, scan til the end of the statement.
- getParser().EatToEndOfStatement();
+ eatToEndOfStatement();
}
- if (getParser().MacroMap.lookup(Name)) {
+ if (LookupMacro(Name)) {
return Error(DirectiveLoc, "macro '" + Name + "' is already defined");
}
const char *BodyStart = StartToken.getLoc().getPointer();
const char *BodyEnd = EndToken.getLoc().getPointer();
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
- getParser().MacroMap[Name] = new Macro(Name, Body, Parameters);
+ CheckForBadMacro(DirectiveLoc, Name, Body, Parameters);
+ DefineMacro(Name, MCAsmMacro(Name, Body, Parameters));
return false;
}
+/// CheckForBadMacro
+///
+/// With the support added for named parameters there may be code out there that
+/// is transitioning from positional parameters. In versions of gas that did
+/// not support named parameters they would be ignored on the macro defintion.
+/// But to support both styles of parameters this is not possible so if a macro
+/// defintion has named parameters but does not use them and has what appears
+/// to be positional parameters, strings like $1, $2, ... and $n, then issue a
+/// warning that the positional parameter found in body which have no effect.
+/// Hoping the developer will either remove the named parameters from the macro
+/// definiton so the positional parameters get used if that was what was
+/// intended or change the macro to use the named parameters. It is possible
+/// this warning will trigger when the none of the named parameters are used
+/// and the strings like $1 are infact to simply to be passed trough unchanged.
+void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
+ StringRef Body,
+ MCAsmMacroParameters Parameters) {
+ // If this macro is not defined with named parameters the warning we are
+ // checking for here doesn't apply.
+ unsigned NParameters = Parameters.size();
+ if (NParameters == 0)
+ return;
+
+ bool NamedParametersFound = false;
+ bool PositionalParametersFound = false;
+
+ // Look at the body of the macro for use of both the named parameters and what
+ // are likely to be positional parameters. This is what expandMacro() is
+ // doing when it finds the parameters in the body.
+ while (!Body.empty()) {
+ // Scan for the next possible parameter.
+ std::size_t End = Body.size(), Pos = 0;
+ for (; Pos != End; ++Pos) {
+ // Check for a substitution or escape.
+ // This macro is defined with parameters, look for \foo, \bar, etc.
+ if (Body[Pos] == '\\' && Pos + 1 != End)
+ break;
+
+ // This macro should have parameters, but look for $0, $1, ..., $n too.
+ if (Body[Pos] != '$' || Pos + 1 == End)
+ continue;
+ char Next = Body[Pos + 1];
+ if (Next == '$' || Next == 'n' ||
+ isdigit(static_cast<unsigned char>(Next)))
+ break;
+ }
+
+ // Check if we reached the end.
+ if (Pos == End)
+ break;
+
+ if (Body[Pos] == '$') {
+ switch (Body[Pos+1]) {
+ // $$ => $
+ case '$':
+ break;
+
+ // $n => number of arguments
+ case 'n':
+ PositionalParametersFound = true;
+ break;
+
+ // $[0-9] => argument
+ default: {
+ PositionalParametersFound = true;
+ break;
+ }
+ }
+ Pos += 2;
+ } else {
+ unsigned I = Pos + 1;
+ 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].first == Argument)
+ break;
+
+ if (Index == NParameters) {
+ if (Body[Pos+1] == '(' && Body[Pos+2] == ')')
+ Pos += 3;
+ else {
+ Pos = I;
+ }
+ } else {
+ NamedParametersFound = true;
+ Pos += 1 + Argument.size();
+ }
+ }
+ // Update the scan point.
+ Body = Body.substr(Pos);
+ }
+
+ if (!NamedParametersFound && PositionalParametersFound)
+ Warning(DirectiveLoc, "macro defined with named parameters which are not "
+ "used in macro body, possible positional parameter "
+ "found in body which will have no effect");
+}
+
/// ParseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
-bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectiveEndMacro(StringRef Directive) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '" + Directive + "' directive");
// If we are inside a macro instantiation, terminate the current
// instantiation.
- if (!getParser().ActiveMacros.empty()) {
- getParser().HandleMacroExit();
+ if (InsideMacroInstantiation()) {
+ HandleMacroExit();
return false;
}
@@ -3410,37 +3191,136 @@ bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive,
/// ParseDirectivePurgeMacro
/// ::= .purgem
-bool GenericAsmParser::ParseDirectivePurgeMacro(StringRef Directive,
- SMLoc DirectiveLoc) {
+bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in '.purgem' directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.purgem' directive");
- StringMap<Macro*>::iterator I = getParser().MacroMap.find(Name);
- if (I == getParser().MacroMap.end())
+ if (!LookupMacro(Name))
return Error(DirectiveLoc, "macro '" + Name + "' is not defined");
- // Undefine the macro.
- delete I->getValue();
- getParser().MacroMap.erase(I);
+ UndefineMacro(Name);
return false;
}
-bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
- getParser().CheckForValidSection();
+/// ParseDirectiveBundleAlignMode
+/// ::= {.bundle_align_mode} expression
+bool AsmParser::ParseDirectiveBundleAlignMode() {
+ checkForValidSection();
+
+ // Expect a single argument: an expression that evaluates to a constant
+ // in the inclusive range 0-30.
+ SMLoc ExprLoc = getLexer().getLoc();
+ int64_t AlignSizePow2;
+ if (parseAbsoluteExpression(AlignSizePow2))
+ return true;
+ else if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token after expression in"
+ " '.bundle_align_mode' directive");
+ else if (AlignSizePow2 < 0 || AlignSizePow2 > 30)
+ return Error(ExprLoc,
+ "invalid bundle alignment size (expected between 0 and 30)");
+ Lex();
+
+ // Because of AlignSizePow2's verified range we can safely truncate it to
+ // unsigned.
+ getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
+ return false;
+}
+
+/// ParseDirectiveBundleLock
+/// ::= {.bundle_lock} [align_to_end]
+bool AsmParser::ParseDirectiveBundleLock() {
+ checkForValidSection();
+ bool AlignToEnd = false;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ StringRef Option;
+ SMLoc Loc = getTok().getLoc();
+ const char *kInvalidOptionError =
+ "invalid option for '.bundle_lock' directive";
+
+ if (parseIdentifier(Option))
+ return Error(Loc, kInvalidOptionError);
+
+ if (Option != "align_to_end")
+ return Error(Loc, kInvalidOptionError);
+ else if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(Loc,
+ "unexpected token after '.bundle_lock' directive option");
+ AlignToEnd = true;
+ }
+
+ Lex();
+
+ getStreamer().EmitBundleLock(AlignToEnd);
+ return false;
+}
+
+/// ParseDirectiveBundleLock
+/// ::= {.bundle_lock}
+bool AsmParser::ParseDirectiveBundleUnlock() {
+ checkForValidSection();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.bundle_unlock' directive");
+ Lex();
+
+ getStreamer().EmitBundleUnlock();
+ return false;
+}
+
+/// ParseDirectiveSpace
+/// ::= (.skip | .space) expression [ , expression ]
+bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
+ checkForValidSection();
+
+ int64_t NumBytes;
+ if (parseAbsoluteExpression(NumBytes))
+ return true;
+
+ int64_t FillExpr = 0;
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ Lex();
+
+ if (parseAbsoluteExpression(FillExpr))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ }
+
+ Lex();
+
+ if (NumBytes <= 0)
+ return TokError("invalid number of bytes in '" +
+ Twine(IDVal) + "' directive");
+
+ // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
+ getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
+
+ return false;
+}
+
+/// ParseDirectiveLEB128
+/// ::= (.sleb128 | .uleb128) expression
+bool AsmParser::ParseDirectiveLEB128(bool Signed) {
+ checkForValidSection();
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (parseExpression(Value))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");
- if (DirName[1] == 's')
+ if (Signed)
getStreamer().EmitSLEB128Value(Value);
else
getStreamer().EmitULEB128Value(Value);
@@ -3448,7 +3328,469 @@ bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) {
return false;
}
-Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
+/// ParseDirectiveSymbolAttribute
+/// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
+bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
+ if (getLexer().isNot(AsmToken::EndOfStatement)) {
+ for (;;) {
+ StringRef Name;
+ SMLoc Loc = getTok().getLoc();
+
+ if (parseIdentifier(Name))
+ return Error(Loc, "expected identifier in directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ // Assembler local symbols don't make any sense here. Complain loudly.
+ if (Sym->isTemporary())
+ return Error(Loc, "non-local symbol required in directive");
+
+ getStreamer().EmitSymbolAttribute(Sym, Attr);
+
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ }
+ }
+
+ Lex();
+ return false;
+}
+
+/// ParseDirectiveComm
+/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
+bool AsmParser::ParseDirectiveComm(bool IsLocal) {
+ checkForValidSection();
+
+ SMLoc IDLoc = getLexer().getLoc();
+ StringRef Name;
+ if (parseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ // Handle the identifier as the key symbol.
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+
+ int64_t Size;
+ SMLoc SizeLoc = getLexer().getLoc();
+ if (parseAbsoluteExpression(Size))
+ return true;
+
+ int64_t Pow2Alignment = 0;
+ SMLoc Pow2AlignmentLoc;
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+ Pow2AlignmentLoc = getLexer().getLoc();
+ 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 ((!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);
+ }
+ }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.comm' or '.lcomm' directive");
+
+ Lex();
+
+ // NOTE: a size of zero for a .comm should create a undefined symbol
+ // but a size of .lcomm creates a bss symbol of size zero.
+ if (Size < 0)
+ return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
+ "be less than zero");
+
+ // NOTE: The alignment in the directive is a power of 2 value, the assembler
+ // may internally end up wanting an alignment in bytes.
+ // FIXME: Diagnose overflow.
+ if (Pow2Alignment < 0)
+ return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
+ "alignment, can't be less than zero");
+
+ if (!Sym->isUndefined())
+ return Error(IDLoc, "invalid symbol redefinition");
+
+ // Create the Symbol as a common or local common with Size and Pow2Alignment
+ if (IsLocal) {
+ getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment);
+ return false;
+ }
+
+ getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
+ return false;
+}
+
+/// ParseDirectiveAbort
+/// ::= .abort [... message ...]
+bool AsmParser::ParseDirectiveAbort() {
+ // FIXME: Use loc from directive.
+ SMLoc Loc = getLexer().getLoc();
+
+ StringRef Str = parseStringToEndOfStatement();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.abort' directive");
+
+ Lex();
+
+ if (Str.empty())
+ Error(Loc, ".abort detected. Assembly stopping.");
+ else
+ Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
+ // FIXME: Actually abort assembly here.
+
+ return false;
+}
+
+/// ParseDirectiveInclude
+/// ::= .include "filename"
+bool AsmParser::ParseDirectiveInclude() {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '.include' directive");
+
+ std::string Filename = getTok().getString();
+ SMLoc IncludeLoc = getLexer().getLoc();
+ Lex();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.include' directive");
+
+ // Strip the quotes.
+ Filename = Filename.substr(1, Filename.size()-2);
+
+ // Attempt to switch the lexer to the included file before consuming the end
+ // of statement to avoid losing it when we switch.
+ if (EnterIncludeFile(Filename)) {
+ Error(IncludeLoc, "Could not find include file '" + Filename + "'");
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIncbin
+/// ::= .incbin "filename"
+bool AsmParser::ParseDirectiveIncbin() {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '.incbin' directive");
+
+ std::string Filename = getTok().getString();
+ SMLoc IncbinLoc = getLexer().getLoc();
+ Lex();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.incbin' directive");
+
+ // Strip the quotes.
+ Filename = Filename.substr(1, Filename.size()-2);
+
+ // Attempt to process the included file.
+ if (ProcessIncbinFile(Filename)) {
+ Error(IncbinLoc, "Could not find incbin file '" + Filename + "'");
+ return true;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIf
+/// ::= .if expression
+bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+ if (TheCondState.Ignore) {
+ eatToEndOfStatement();
+ } else {
+ int64_t ExprValue;
+ if (parseAbsoluteExpression(ExprValue))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.if' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExprValue;
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIfb
+/// ::= .ifb string
+bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ eatToEndOfStatement();
+ } else {
+ StringRef Str = parseStringToEndOfStatement();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifb' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExpectBlank == Str.empty();
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIfc
+/// ::= .ifc string1, string2
+bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ eatToEndOfStatement();
+ } else {
+ StringRef Str1 = ParseStringToComma();
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
+
+ StringRef Str2 = parseStringToEndOfStatement();
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.ifc' directive");
+
+ Lex();
+
+ TheCondState.CondMet = ExpectEqual == (Str1 == Str2);
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveIfdef
+/// ::= .ifdef symbol
+bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
+ StringRef Name;
+ TheCondStack.push_back(TheCondState);
+ TheCondState.TheCond = AsmCond::IfCond;
+
+ if (TheCondState.Ignore) {
+ eatToEndOfStatement();
+ } else {
+ if (parseIdentifier(Name))
+ return TokError("expected identifier after '.ifdef'");
+
+ Lex();
+
+ MCSymbol *Sym = getContext().LookupSymbol(Name);
+
+ if (expect_defined)
+ TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined());
+ else
+ TheCondState.CondMet = (Sym == NULL || Sym->isUndefined());
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveElseIf
+/// ::= .elseif expression
+bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
+ if (TheCondState.TheCond != AsmCond::IfCond &&
+ TheCondState.TheCond != AsmCond::ElseIfCond)
+ Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
+ " an .elseif");
+ TheCondState.TheCond = AsmCond::ElseIfCond;
+
+ bool LastIgnoreState = false;
+ if (!TheCondStack.empty())
+ LastIgnoreState = TheCondStack.back().Ignore;
+ if (LastIgnoreState || TheCondState.CondMet) {
+ TheCondState.Ignore = true;
+ eatToEndOfStatement();
+ }
+ else {
+ int64_t ExprValue;
+ if (parseAbsoluteExpression(ExprValue))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.elseif' directive");
+
+ Lex();
+ TheCondState.CondMet = ExprValue;
+ TheCondState.Ignore = !TheCondState.CondMet;
+ }
+
+ return false;
+}
+
+/// ParseDirectiveElse
+/// ::= .else
+bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.else' directive");
+
+ Lex();
+
+ if (TheCondState.TheCond != AsmCond::IfCond &&
+ TheCondState.TheCond != AsmCond::ElseIfCond)
+ Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
+ ".elseif");
+ TheCondState.TheCond = AsmCond::ElseCond;
+ bool LastIgnoreState = false;
+ if (!TheCondStack.empty())
+ LastIgnoreState = TheCondStack.back().Ignore;
+ if (LastIgnoreState || TheCondState.CondMet)
+ TheCondState.Ignore = true;
+ else
+ TheCondState.Ignore = false;
+
+ return false;
+}
+
+/// ParseDirectiveEndIf
+/// ::= .endif
+bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.endif' directive");
+
+ Lex();
+
+ if ((TheCondState.TheCond == AsmCond::NoCond) ||
+ TheCondStack.empty())
+ Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
+ ".else");
+ if (!TheCondStack.empty()) {
+ TheCondState = TheCondStack.back();
+ TheCondStack.pop_back();
+ }
+
+ return false;
+}
+
+void AsmParser::initializeDirectiveKindMap() {
+ DirectiveKindMap[".set"] = DK_SET;
+ DirectiveKindMap[".equ"] = DK_EQU;
+ DirectiveKindMap[".equiv"] = DK_EQUIV;
+ DirectiveKindMap[".ascii"] = DK_ASCII;
+ DirectiveKindMap[".asciz"] = DK_ASCIZ;
+ DirectiveKindMap[".string"] = DK_STRING;
+ DirectiveKindMap[".byte"] = DK_BYTE;
+ DirectiveKindMap[".short"] = DK_SHORT;
+ DirectiveKindMap[".value"] = DK_VALUE;
+ DirectiveKindMap[".2byte"] = DK_2BYTE;
+ DirectiveKindMap[".long"] = DK_LONG;
+ DirectiveKindMap[".int"] = DK_INT;
+ DirectiveKindMap[".4byte"] = DK_4BYTE;
+ DirectiveKindMap[".quad"] = DK_QUAD;
+ DirectiveKindMap[".8byte"] = DK_8BYTE;
+ DirectiveKindMap[".single"] = DK_SINGLE;
+ DirectiveKindMap[".float"] = DK_FLOAT;
+ DirectiveKindMap[".double"] = DK_DOUBLE;
+ DirectiveKindMap[".align"] = DK_ALIGN;
+ DirectiveKindMap[".align32"] = DK_ALIGN32;
+ DirectiveKindMap[".balign"] = DK_BALIGN;
+ DirectiveKindMap[".balignw"] = DK_BALIGNW;
+ DirectiveKindMap[".balignl"] = DK_BALIGNL;
+ DirectiveKindMap[".p2align"] = DK_P2ALIGN;
+ DirectiveKindMap[".p2alignw"] = DK_P2ALIGNW;
+ DirectiveKindMap[".p2alignl"] = DK_P2ALIGNL;
+ DirectiveKindMap[".org"] = DK_ORG;
+ DirectiveKindMap[".fill"] = DK_FILL;
+ DirectiveKindMap[".zero"] = DK_ZERO;
+ DirectiveKindMap[".extern"] = DK_EXTERN;
+ DirectiveKindMap[".globl"] = DK_GLOBL;
+ DirectiveKindMap[".global"] = DK_GLOBAL;
+ DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL;
+ DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
+ DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
+ DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
+ DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN;
+ DirectiveKindMap[".reference"] = DK_REFERENCE;
+ DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION;
+ DirectiveKindMap[".weak_reference"] = DK_WEAK_REFERENCE;
+ DirectiveKindMap[".weak_def_can_be_hidden"] = DK_WEAK_DEF_CAN_BE_HIDDEN;
+ DirectiveKindMap[".comm"] = DK_COMM;
+ DirectiveKindMap[".common"] = DK_COMMON;
+ DirectiveKindMap[".lcomm"] = DK_LCOMM;
+ DirectiveKindMap[".abort"] = DK_ABORT;
+ DirectiveKindMap[".include"] = DK_INCLUDE;
+ DirectiveKindMap[".incbin"] = DK_INCBIN;
+ DirectiveKindMap[".code16"] = DK_CODE16;
+ DirectiveKindMap[".code16gcc"] = DK_CODE16GCC;
+ DirectiveKindMap[".rept"] = DK_REPT;
+ DirectiveKindMap[".irp"] = DK_IRP;
+ DirectiveKindMap[".irpc"] = DK_IRPC;
+ DirectiveKindMap[".endr"] = DK_ENDR;
+ DirectiveKindMap[".bundle_align_mode"] = DK_BUNDLE_ALIGN_MODE;
+ DirectiveKindMap[".bundle_lock"] = DK_BUNDLE_LOCK;
+ DirectiveKindMap[".bundle_unlock"] = DK_BUNDLE_UNLOCK;
+ DirectiveKindMap[".if"] = DK_IF;
+ DirectiveKindMap[".ifb"] = DK_IFB;
+ DirectiveKindMap[".ifnb"] = DK_IFNB;
+ DirectiveKindMap[".ifc"] = DK_IFC;
+ DirectiveKindMap[".ifnc"] = DK_IFNC;
+ DirectiveKindMap[".ifdef"] = DK_IFDEF;
+ DirectiveKindMap[".ifndef"] = DK_IFNDEF;
+ DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF;
+ DirectiveKindMap[".elseif"] = DK_ELSEIF;
+ DirectiveKindMap[".else"] = DK_ELSE;
+ DirectiveKindMap[".endif"] = DK_ENDIF;
+ DirectiveKindMap[".skip"] = DK_SKIP;
+ DirectiveKindMap[".space"] = DK_SPACE;
+ DirectiveKindMap[".file"] = DK_FILE;
+ DirectiveKindMap[".line"] = DK_LINE;
+ DirectiveKindMap[".loc"] = DK_LOC;
+ DirectiveKindMap[".stabs"] = DK_STABS;
+ DirectiveKindMap[".sleb128"] = DK_SLEB128;
+ DirectiveKindMap[".uleb128"] = DK_ULEB128;
+ DirectiveKindMap[".cfi_sections"] = DK_CFI_SECTIONS;
+ DirectiveKindMap[".cfi_startproc"] = DK_CFI_STARTPROC;
+ DirectiveKindMap[".cfi_endproc"] = DK_CFI_ENDPROC;
+ DirectiveKindMap[".cfi_def_cfa"] = DK_CFI_DEF_CFA;
+ DirectiveKindMap[".cfi_def_cfa_offset"] = DK_CFI_DEF_CFA_OFFSET;
+ DirectiveKindMap[".cfi_adjust_cfa_offset"] = DK_CFI_ADJUST_CFA_OFFSET;
+ DirectiveKindMap[".cfi_def_cfa_register"] = DK_CFI_DEF_CFA_REGISTER;
+ DirectiveKindMap[".cfi_offset"] = DK_CFI_OFFSET;
+ DirectiveKindMap[".cfi_rel_offset"] = DK_CFI_REL_OFFSET;
+ DirectiveKindMap[".cfi_personality"] = DK_CFI_PERSONALITY;
+ DirectiveKindMap[".cfi_lsda"] = DK_CFI_LSDA;
+ DirectiveKindMap[".cfi_remember_state"] = DK_CFI_REMEMBER_STATE;
+ DirectiveKindMap[".cfi_restore_state"] = DK_CFI_RESTORE_STATE;
+ DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
+ DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
+ DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
+ DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
+ DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
+ DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
+ DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
+ DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
+ DirectiveKindMap[".macro"] = DK_MACRO;
+ DirectiveKindMap[".endm"] = DK_ENDM;
+ DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
+ DirectiveKindMap[".purgem"] = DK_PURGEM;
+}
+
+
+MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
AsmToken EndToken, StartToken = getTok();
unsigned NestLevel = 0;
@@ -3480,7 +3822,7 @@ Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
}
// Otherwise, scan till the end of the statement.
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
const char *BodyStart = StartToken.getLoc().getPointer();
@@ -3489,11 +3831,11 @@ Macro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
// We Are Anonymous.
StringRef Name;
- MacroParameters Parameters;
- return new Macro(Name, Body, Parameters);
+ MCAsmMacroParameters Parameters;
+ return new MCAsmMacro(Name, Body, Parameters);
}
-void AsmParser::InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
+void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
raw_svector_ostream &OS) {
OS << ".endr\n";
@@ -3516,7 +3858,7 @@ void AsmParser::InstantiateMacroLikeBody(Macro *M, SMLoc DirectiveLoc,
bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
int64_t Count;
- if (ParseAbsoluteExpression(Count))
+ if (parseAbsoluteExpression(Count))
return TokError("unexpected token in '.rept' directive");
if (Count < 0)
@@ -3529,15 +3871,15 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
Lex();
// Lex the rept definition.
- Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
// Macro instantiation is lexical, unfortunately. We construct a new buffer
// to hold the macro body with substitutions.
SmallString<256> Buf;
- MacroParameters Parameters;
- MacroArguments A;
+ MCAsmMacroParameters Parameters;
+ MCAsmMacroArguments A;
raw_svector_ostream OS(Buf);
while (Count--) {
if (expandMacro(OS, M->Body, Parameters, A, getTok().getLoc()))
@@ -3551,10 +3893,10 @@ bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
/// ParseDirectiveIrp
/// ::= .irp symbol,values
bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
- MacroParameters Parameters;
- MacroParameter Parameter;
+ MCAsmMacroParameters Parameters;
+ MCAsmMacroParameter Parameter;
- if (ParseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.irp' directive");
Parameters.push_back(Parameter);
@@ -3564,7 +3906,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
Lex();
- MacroArguments A;
+ MCAsmMacroArguments A;
if (ParseMacroArguments(0, A))
return true;
@@ -3572,7 +3914,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
Lex();
// Lex the irp definition.
- Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -3581,8 +3923,8 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
SmallString<256> Buf;
raw_svector_ostream OS(Buf);
- for (MacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
- MacroArguments Args;
+ for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
+ MCAsmMacroArguments Args;
Args.push_back(*i);
if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
@@ -3597,10 +3939,10 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
/// ParseDirectiveIrpc
/// ::= .irpc symbol,values
bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
- MacroParameters Parameters;
- MacroParameter Parameter;
+ MCAsmMacroParameters Parameters;
+ MCAsmMacroParameter Parameter;
- if (ParseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.irpc' directive");
Parameters.push_back(Parameter);
@@ -3610,7 +3952,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
Lex();
- MacroArguments A;
+ MCAsmMacroArguments A;
if (ParseMacroArguments(0, A))
return true;
@@ -3621,7 +3963,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
Lex();
// Lex the irpc definition.
- Macro *M = ParseMacroLikeBody(DirectiveLoc);
+ MCAsmMacro *M = ParseMacroLikeBody(DirectiveLoc);
if (!M)
return true;
@@ -3633,10 +3975,10 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
StringRef Values = A.front().front().getString();
std::size_t I, End = Values.size();
for (I = 0; I < End; ++I) {
- MacroArgument Arg;
+ MCAsmMacroArgument Arg;
Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I+1)));
- MacroArguments Args;
+ MCAsmMacroArguments Args;
Args.push_back(Arg);
if (expandMacro(OS, M->Body, Parameters, Args, getTok().getLoc()))
@@ -3660,10 +4002,11 @@ bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
return false;
}
-bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) {
+bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
+ size_t Len) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
if (!MCE)
@@ -3672,27 +4015,71 @@ bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) {
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));
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len));
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) {
+bool AsmParser::ParseDirectiveMSAlign(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 align");
+ uint64_t IntValue = MCE->getValue();
+ if (!isPowerOf2_64(IntValue))
+ return Error(ExprLoc, "literal value not a power of two greater then zero");
+
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5,
+ Log2_64(IntValue)));
+ return false;
+}
+
+// We are comparing pointers, but the pointers are relative to a single string.
+// Thus, this should always be deterministic.
+static int RewritesSort(const void *A, const void *B) {
+ const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A);
+ const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B);
+ if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
+ return -1;
+ if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
+ return 1;
+
+ // It's possible to have a SizeDirective rewrite and an Input/Output rewrite
+ // to the same location. Make sure the SizeDirective rewrite is performed
+ // first. This also ensure the sort algorithm is stable.
+ if (AsmRewriteA->Kind == AOK_SizeDirective) {
+ assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
+ "Expected an Input/Output rewrite!");
+ return -1;
+ }
+ if (AsmRewriteB->Kind == AOK_SizeDirective) {
+ assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
+ "Expected an Input/Output rewrite!");
+ return 1;
+ }
+ llvm_unreachable ("Unstable rewrite sort.");
+}
+
+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<bool, 4> InputDeclsAddressOf;
+ SmallVector<bool, 4> OutputDeclsAddressOf;
SmallVector<std::string, 4> InputConstraints;
SmallVector<std::string, 4> OutputConstraints;
- std::set<std::string> ClobberRegs;
+ SmallVector<unsigned, 4> ClobberRegs;
- SmallVector<struct AsmRewrite, 4> AsmStrRewrites;
+ SmallVector<AsmRewrite, 4> AsmStrRewrites;
// Prime the lexer.
Lex();
@@ -3705,64 +4092,63 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
if (ParseStatement(Info))
return true;
- if (Info.Opcode != ~0U) {
- const MCInstrDesc &Desc = MII->get(Info.Opcode);
+ if (Info.ParseError)
+ return true;
- // Build the list of clobbers, outputs and inputs.
- for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
- MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
+ if (Info.Opcode == ~0U)
+ continue;
- // Immediate.
- if (Operand->isImm()) {
- if (Operand->needAsmRewrite())
- AsmStrRewrites.push_back(AsmRewrite(AOK_ImmPrefix,
- Operand->getStartLoc()));
- continue;
- }
+ const MCInstrDesc &Desc = MII->get(Info.Opcode);
- // 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;
- }
+ // Build the list of clobbers, outputs and inputs.
+ for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
+ MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
- // 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()));
- }
- }
+ // Immediate.
+ if (Operand->isImm()) {
+ if (Operand->needAsmRewrite())
+ AsmStrRewrites.push_back(AsmRewrite(AOK_ImmPrefix,
+ Operand->getStartLoc()));
+ continue;
+ }
+
+ // Register operand.
+ if (Operand->isReg() && !Operand->needAddressOf()) {
+ unsigned NumDefs = Desc.getNumDefs();
+ // Clobber.
+ if (NumDefs && Operand->getMCOperandNum() < NumDefs)
+ ClobberRegs.push_back(Operand->getReg());
+ continue;
+ }
+
+ // Expr/Input or Output.
+ bool IsVarDecl;
+ unsigned Length, Size, Type;
+ void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc,
+ Length, Size, Type,
+ IsVarDecl);
+ if (!OpDecl)
+ continue;
+
+ bool isOutput = (i == 1) && Desc.mayStore();
+ if (Operand->isMem() && Operand->needSizeDirective())
+ AsmStrRewrites.push_back(AsmRewrite(AOK_SizeDirective,
+ Operand->getStartLoc(), /*Len*/0,
+ Operand->getMemSize()));
+
+ if (isOutput) {
+ ++InputIdx;
+ OutputDecls.push_back(OpDecl);
+ OutputDeclsAddressOf.push_back(Operand->needAddressOf());
+ OutputConstraints.push_back('=' + Operand->getConstraint().str());
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Operand->getStartLoc(),
+ Operand->getNameLen()));
+ } else {
+ InputDecls.push_back(OpDecl);
+ InputDeclsAddressOf.push_back(Operand->needAddressOf());
+ InputConstraints.push_back(Operand->getConstraint().str());
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Operand->getStartLoc(),
+ Operand->getNameLen()));
}
}
}
@@ -3772,24 +4158,27 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
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);
+ array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
+ ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
+ ClobberRegs.end());
+ Clobbers.assign(ClobberRegs.size(), std::string());
+ for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
+ raw_string_ostream OS(Clobbers[I]);
+ IP->printRegName(OS, ClobberRegs[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];
+ OpDecls[i] = std::make_pair(OutputDecls[i], OutputDeclsAddressOf[i]);
+ Constraints[i] = 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];
+ OpDecls[j] = std::make_pair(InputDecls[i], InputDeclsAddressOf[i]);
+ Constraints[j] = InputConstraints[i];
}
}
@@ -3798,10 +4187,14 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
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) {
+ array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), RewritesSort);
+ for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(),
+ E = AsmStrRewrites.end();
+ I != E; ++I) {
const char *Loc = (*I).Loc.getPointer();
+ assert(Loc >= Start && "Expected Loc to be after Start!");
+ unsigned AdditionalSkip = 0;
AsmRewriteKind Kind = (*I).Kind;
// Emit everything up to the immediate/expression. If the previous rewrite
@@ -3820,22 +4213,19 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
switch (Kind) {
default: break;
case AOK_Imm:
- OS << Twine("$$");
- OS << (*I).Val;
+ OS << "$$" << (*I).Val;
break;
case AOK_ImmPrefix:
- OS << Twine("$$");
+ OS << "$$";
break;
case AOK_Input:
- OS << '$';
- OS << InputIdx++;
+ OS << '$' << InputIdx++;
break;
case AOK_Output:
- OS << '$';
- OS << OutputIdx++;
+ OS << '$' << OutputIdx++;
break;
case AOK_SizeDirective:
- switch((*I).Val) {
+ switch ((*I).Val) {
default: break;
case 8: OS << "byte ptr "; break;
case 16: OS << "word ptr "; break;
@@ -3849,6 +4239,15 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
case AOK_Emit:
OS << ".byte";
break;
+ case AOK_Align: {
+ unsigned Val = (*I).Val;
+ OS << ".align " << Val;
+
+ // Skip the original immediate.
+ assert(Val < 10 && "Expected alignment less then 2^10.");
+ AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
+ break;
+ }
case AOK_DotOperator:
OS << (*I).Val;
break;
@@ -3856,7 +4255,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
// Skip the original expression.
if (Kind != AOK_SizeDirective)
- Start = Loc + (*I).Len;
+ Start = Loc + (*I).Len + AdditionalSkip;
}
// Emit the remainder of the asm string.
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index e7c564a243..a50eab217d 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -24,10 +24,11 @@ using namespace llvm;
namespace {
class COFFAsmParser : public MCAsmParserExtension {
- template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<COFFAsmParser, Handler>);
+ template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<COFFAsmParser, HandlerMethod>);
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(StringRef Section,
@@ -38,43 +39,43 @@ class COFFAsmParser : public MCAsmParserExtension {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
// Win64 EH directives.
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
".seh_proc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
".seh_endproc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
".seh_startchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
".seh_endchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
".seh_handler");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
".seh_handlerdata");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
".seh_pushreg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
".seh_setframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
".seh_stackalloc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
".seh_savereg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
".seh_savexmm");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
".seh_pushframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
".seh_endprologue");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
}
bool ParseSectionDirectiveText(StringRef, SMLoc) {
@@ -140,7 +141,7 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
for (;;) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -176,7 +177,7 @@ bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
StringRef SymbolName;
- if (getParser().ParseIdentifier(SymbolName))
+ if (getParser().parseIdentifier(SymbolName))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
@@ -189,7 +190,7 @@ bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
int64_t SymbolStorageClass;
- if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
+ if (getParser().parseAbsoluteExpression(SymbolStorageClass))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -202,7 +203,7 @@ bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
int64_t Type;
- if (getParser().ParseAbsoluteExpression(Type))
+ if (getParser().parseAbsoluteExpression(Type))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -221,7 +222,7 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -236,7 +237,7 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -269,7 +270,7 @@ bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -322,7 +323,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 0x0F)
@@ -339,7 +340,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
int64_t Size;
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
if (Size & 7)
@@ -363,7 +364,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 7)
@@ -390,7 +391,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -411,7 +412,7 @@ bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
if (getLexer().is(AsmToken::At)) {
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (!getParser().ParseIdentifier(CodeID)) {
+ if (!getParser().parseIdentifier(CodeID)) {
if (CodeID != "code")
return Error(startLoc, "expected @code");
Code = true;
@@ -438,7 +439,7 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
return TokError("a handler attribute must begin with '@'");
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (getParser().ParseIdentifier(identifier))
+ if (getParser().parseIdentifier(identifier))
return Error(startLoc, "expected @unwind or @except");
if (identifier == "unwind")
unwind = true;
@@ -479,7 +480,7 @@ bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
}
else {
int64_t n;
- if (getParser().ParseAbsoluteExpression(n))
+ if (getParser().parseAbsoluteExpression(n))
return true;
if (n > 15)
return Error(startLoc, "register number is too high");
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 20c949dbda..6d6409fb69 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -26,10 +26,11 @@ namespace {
/// \brief Implementation of directive handling which is shared across all
/// Darwin targets.
class DarwinAsmParser : public MCAsmParserExtension {
- template<bool (DarwinAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<DarwinAsmParser, Handler>);
+ template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<DarwinAsmParser, HandlerMethod>);
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(const char *Segment, const char *Section,
@@ -43,77 +44,128 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
".subsections_via_symbols");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
+ ".pushsection");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
+ ".popsection");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
".secure_log_unique");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
".secure_log_reset");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
+ ".data_region");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
+ ".end_data_region");
// Special section directives.
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
-
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
+ ".const_data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
+ ".constructor");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
+ ".cstring");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
+ ".destructor");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
+ ".fvmlib_init0");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
+ ".fvmlib_init1");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
+ ".lazy_symbol_pointer");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
+ ".linker_option");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
+ ".literal16");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
+ ".literal4");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
+ ".literal8");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
+ ".mod_init_func");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
+ ".mod_term_func");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
+ ".non_lazy_symbol_pointer");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
+ ".objc_cat_cls_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
+ ".objc_cat_inst_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
+ ".objc_category");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
+ ".objc_class");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
+ ".objc_class_names");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
+ ".objc_class_vars");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
+ ".objc_cls_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
+ ".objc_cls_refs");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
+ ".objc_inst_meth");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
+ ".objc_instance_vars");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
+ ".objc_message_refs");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
+ ".objc_meta_class");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
+ ".objc_meth_var_names");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
+ ".objc_meth_var_types");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
+ ".objc_module_info");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
+ ".objc_protocol");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
+ ".objc_selector_strs");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
+ ".objc_string_object");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
+ ".objc_symbols");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
+ ".picsymbol_stub");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
+ ".static_const");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
+ ".static_data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
+ ".symbol_stub");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
+ ".thread_init_func");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
+
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
}
bool ParseDirectiveDesc(StringRef, SMLoc);
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
+ bool ParseDirectiveLinkerOption(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc);
bool ParseDirectivePushSection(StringRef, SMLoc);
bool ParseDirectivePopSection(StringRef, SMLoc);
@@ -293,7 +345,7 @@ public:
}
bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
// Darwin silently ignores the .ident directive.
- getParser().EatToEndOfStatement();
+ getParser().eatToEndOfStatement();
return false;
}
bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
@@ -314,7 +366,7 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
Lex();
// FIXME: Arch specific.
- bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack.
+ bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
getStreamer().SwitchSection(getContext().getMachOSection(
Segment, Section, TAA, StubSize,
isText ? SectionKind::getText()
@@ -338,7 +390,7 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
/// ::= .desc identifier , expression
bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -349,7 +401,7 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
Lex();
int64_t DescValue;
- if (getParser().ParseAbsoluteExpression(DescValue))
+ if (getParser().parseAbsoluteExpression(DescValue))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -386,11 +438,38 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
return Warning(IDLoc, "ignoring directive .load for now");
}
+/// ParseDirectiveLinkerOption
+/// ::= .linker_option "string" ( , "string" )*
+bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
+ SmallVector<std::string, 4> Args;
+ for (;;) {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '" + Twine(IDVal) + "' directive");
+
+ std::string Data;
+ if (getParser().parseEscapedString(Data))
+ return true;
+
+ Args.push_back(Data);
+
+ Lex();
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ Lex();
+ }
+
+ getStreamer().EmitLinkerOptions(Args);
+ return false;
+}
+
/// ParseDirectiveLsym
/// ::= .lsym identifier , expression
bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -401,7 +480,7 @@ bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
Lex();
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (getParser().parseExpression(Value))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -422,7 +501,7 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
SMLoc Loc = getLexer().getLoc();
StringRef SectionName;
- if (getParser().ParseIdentifier(SectionName))
+ if (getParser().parseIdentifier(SectionName))
return Error(Loc, "expected identifier after '.section' directive");
// Verify there is a following comma.
@@ -497,7 +576,7 @@ bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
/// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ...
bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
- StringRef LogMessage = getParser().ParseStringToEndOfStatement();
+ StringRef LogMessage = getParser().parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.secure_log_unique' directive");
@@ -565,7 +644,7 @@ bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
SMLoc IDLoc = getLexer().getLoc();
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -577,7 +656,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
int64_t Pow2Alignment = 0;
@@ -585,7 +664,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
Pow2AlignmentLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Pow2Alignment))
+ if (getParser().parseAbsoluteExpression(Pow2Alignment))
return true;
}
@@ -620,7 +699,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
/// , align_expression ]]
bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
StringRef Segment;
- if (getParser().ParseIdentifier(Segment))
+ if (getParser().parseIdentifier(Segment))
return TokError("expected segment name after '.zerofill' directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -628,7 +707,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
Lex();
StringRef Section;
- if (getParser().ParseIdentifier(Section))
+ if (getParser().parseIdentifier(Section))
return TokError("expected section name after comma in '.zerofill' "
"directive");
@@ -648,7 +727,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
SMLoc IDLoc = getLexer().getLoc();
StringRef IDStr;
- if (getParser().ParseIdentifier(IDStr))
+ if (getParser().parseIdentifier(IDStr))
return TokError("expected identifier in directive");
// handle the identifier as the key symbol.
@@ -660,7 +739,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
int64_t Pow2Alignment = 0;
@@ -668,7 +747,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
Pow2AlignmentLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Pow2Alignment))
+ if (getParser().parseAbsoluteExpression(Pow2Alignment))
return true;
}
@@ -712,7 +791,7 @@ bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
}
StringRef RegionType;
SMLoc Loc = getParser().getTok().getLoc();
- if (getParser().ParseIdentifier(RegionType))
+ if (getParser().parseIdentifier(RegionType))
return TokError("expected region type after '.data_region' directive");
int Kind = StringSwitch<int>(RegionType)
.Case("jt8", MCDR_DataRegionJT8)
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index d55de1f3fb..4c45e08744 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -22,10 +22,12 @@ using namespace llvm;
namespace {
class ELFAsmParser : public MCAsmParserExtension {
- template<bool (ELFAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<ELFAsmParser, Handler>);
+ template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<ELFAsmParser, HandlerMethod>);
+
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(StringRef Section, unsigned Type,
@@ -41,38 +43,38 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectivePushSection>(".pushsection");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
}
@@ -167,7 +169,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
for (;;) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -201,7 +203,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -210,7 +212,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
Lex();
const MCExpr *Expr;
- if (getParser().ParseExpression(Expr))
+ if (getParser().parseExpression(Expr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -222,7 +224,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
// A section name can contain -, so we cannot just use
- // ParseIdentifier.
+ // parseIdentifier.
SMLoc FirstLoc = getLexer().getLoc();
unsigned Size = 0;
@@ -375,14 +377,14 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return TokError("expected '@' or '%' before type");
Lex();
- if (getParser().ParseIdentifier(TypeName))
+ if (getParser().parseIdentifier(TypeName))
return TokError("expected identifier in directive");
if (Mergeable) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("expected the entry size");
Lex();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
if (Size <= 0)
return TokError("entry size must be positive");
@@ -392,12 +394,12 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("expected group name");
Lex();
- if (getParser().ParseIdentifier(GroupName))
+ if (getParser().parseIdentifier(GroupName))
return true;
if (getLexer().is(AsmToken::Comma)) {
Lex();
StringRef Linkage;
- if (getParser().ParseIdentifier(Linkage))
+ if (getParser().parseIdentifier(Linkage))
return true;
if (Linkage != "comdat")
return TokError("Linkage must be 'comdat'");
@@ -411,7 +413,16 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
unsigned Type = ELF::SHT_PROGBITS;
- if (!TypeName.empty()) {
+ if (TypeName.empty()) {
+ if (SectionName.startswith(".note"))
+ Type = ELF::SHT_NOTE;
+ else if (SectionName == ".init_array")
+ Type = ELF::SHT_INIT_ARRAY;
+ else if (SectionName == ".fini_array")
+ Type = ELF::SHT_FINI_ARRAY;
+ else if (SectionName == ".preinit_array")
+ Type = ELF::SHT_PREINIT_ARRAY;
+ } else {
if (TypeName == "init_array")
Type = ELF::SHT_INIT_ARRAY;
else if (TypeName == "fini_array")
@@ -450,7 +461,7 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
/// ::= .type identifier , @attribute
bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -468,7 +479,7 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
SMLoc TypeLoc;
TypeLoc = getLexer().getLoc();
- if (getParser().ParseIdentifier(Type))
+ if (getParser().parseIdentifier(Type))
return TokError("expected symbol type in directive");
MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
@@ -517,7 +528,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
getStreamer().EmitIntValue(0, 1);
SeenIdent = true;
}
- getStreamer().EmitBytes(Data, 0);
+ getStreamer().EmitBytes(Data);
getStreamer().EmitIntValue(0, 1);
getStreamer().PopSection();
return false;
@@ -527,7 +538,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
/// ::= .symver foo, bar2@zed
bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -536,7 +547,7 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
Lex();
StringRef AliasName;
- if (getParser().ParseIdentifier(AliasName))
+ if (getParser().parseIdentifier(AliasName))
return TokError("expected identifier in directive");
if (AliasName.find('@') == StringRef::npos)
@@ -569,7 +580,7 @@ bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
getStreamer().EmitIntValue(Data.size()+1, 4); // namesz.
getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description).
getStreamer().EmitIntValue(1, 4); // type = NT_VERSION.
- getStreamer().EmitBytes(Data, 0); // name.
+ getStreamer().EmitBytes(Data); // name.
getStreamer().EmitIntValue(0, 1); // terminate the string.
getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment.
getStreamer().PopSection();
@@ -582,7 +593,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
// FIXME: Share code with the other alias building directives.
StringRef AliasName;
- if (getParser().ParseIdentifier(AliasName))
+ if (getParser().parseIdentifier(AliasName))
return TokError("expected identifier in directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -591,7 +602,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
Lex();
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp
index 384b341bc7..3867691107 100644
--- a/lib/MC/MCParser/MCAsmLexer.cpp
+++ b/lib/MC/MCParser/MCAsmLexer.cpp
@@ -28,5 +28,5 @@ SMLoc AsmToken::getLoc() const {
}
SMLoc AsmToken::getEndLoc() const {
- return SMLoc::getFromPointer(Str.data() + Str.size() - 1);
+ return SMLoc::getFromPointer(Str.data() + Str.size());
}
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index a8b00cd84a..6e1ebad36c 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -38,9 +38,9 @@ bool MCAsmParser::TokError(const Twine &Msg, ArrayRef<SMRange> Ranges) {
return true;
}
-bool MCAsmParser::ParseExpression(const MCExpr *&Res) {
+bool MCAsmParser::parseExpression(const MCExpr *&Res) {
SMLoc L;
- return ParseExpression(Res, L);
+ return parseExpression(Res, L);
}
void MCParsedAsmOperand::dump() const {
diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
index 1563bdd107..0e04c5537a 100644
--- a/lib/MC/MCPureStreamer.cpp
+++ b/lib/MC/MCPureStreamer.cpp
@@ -28,15 +28,17 @@ private:
virtual void EmitInstToData(const MCInst &Inst);
public:
- MCPureStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+ MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_PureStreamer, Context, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
virtual void InitSections();
+ virtual void InitToTextSection();
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
uint64_t Size = 0, unsigned ByteAlignment = 0);
virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
@@ -93,21 +95,28 @@ public:
report_fatal_error("unsupported directive in pure streamer");
}
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename) {
+ StringRef Filename, unsigned CUID = 0) {
report_fatal_error("unsupported directive in pure streamer");
}
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_PureStreamer;
+ }
};
} // end anonymous namespace.
void MCPureStreamer::InitSections() {
+ InitToTextSection();
+}
+
+void MCPureStreamer::InitToTextSection() {
// FIMXE: To what!?
SwitchSection(getContext().getMachOSection("__TEXT", "__text",
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
0, SectionKind::getText()));
-
}
void MCPureStreamer::EmitLabel(MCSymbol *Symbol) {
@@ -134,6 +143,11 @@ void MCPureStreamer::EmitLabel(MCSymbol *Symbol) {
SD.setOffset(F->getContents().size());
}
+
+void MCPureStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
+
void MCPureStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
report_fatal_error("not yet implemented in pure streamer");
@@ -182,7 +196,8 @@ bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset,
}
void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) {
- MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
+ MCRelaxableFragment *IF =
+ new MCRelaxableFragment(Inst, getCurrentSectionData());
// Add the fixups and data.
//
diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp
index e771556262..fc323155be 100644
--- a/lib/MC/MCSectionMachO.cpp
+++ b/lib/MC/MCSectionMachO.cpp
@@ -165,9 +165,9 @@ bool MCSectionMachO::isVirtualSection() const {
/// StripSpaces - This removes leading and trailing spaces from the StringRef.
static void StripSpaces(StringRef &Str) {
- while (!Str.empty() && isspace(Str[0]))
+ while (!Str.empty() && isspace(static_cast<unsigned char>(Str[0])))
Str = Str.substr(1);
- while (!Str.empty() && isspace(Str.back()))
+ while (!Str.empty() && isspace(static_cast<unsigned char>(Str.back())))
Str = Str.substr(0, Str.size()-1);
}
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 96d6d691d2..51ef415542 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -21,10 +21,9 @@
#include <cstdlib>
using namespace llvm;
-MCStreamer::MCStreamer(MCContext &Ctx)
- : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
- CurrentW64UnwindInfo(0), LastSymbol(0),
- AutoInitSections(false) {
+MCStreamer::MCStreamer(StreamerKind Kind, MCContext &Ctx)
+ : Kind(Kind), Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
+ CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) {
const MCSection *section = NULL;
SectionStack.push_back(std::make_pair(section, section));
}
@@ -34,6 +33,18 @@ MCStreamer::~MCStreamer() {
delete W64UnwindInfos[i];
}
+void MCStreamer::reset() {
+ for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i)
+ delete W64UnwindInfos[i];
+ EmitEHFrame = true;
+ EmitDebugFrame = false;
+ CurrentW64UnwindInfo = 0;
+ LastSymbol = 0;
+ const MCSection *section = NULL;
+ SectionStack.clear();
+ SectionStack.push_back(std::make_pair(section, section));
+}
+
const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
const MCSymbol *A,
const MCSymbol *B) {
@@ -92,8 +103,8 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
-void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace,
- unsigned Padding) {
+void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding,
+ unsigned AddrSpace) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
encodeULEB128(Value, OSE, Padding);
@@ -146,8 +157,8 @@ void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue,
bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
StringRef Directory,
- StringRef Filename) {
- return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0;
+ StringRef Filename, unsigned CUID) {
+ return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0;
}
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
@@ -182,6 +193,13 @@ void MCStreamer::EmitLabel(MCSymbol *Symbol) {
LastSymbol = Symbol;
}
+void MCStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
+ assert(getCurrentSection() && "Cannot emit before setting section!");
+ Symbol->setSection(*getCurrentSection());
+ LastSymbol = Symbol;
+}
+
void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) {
EnsureValidFrame();
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
@@ -602,3 +620,8 @@ void MCStreamer::Finish() {
FinishImpl();
}
+
+MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+ report_fatal_error("Not supported!");
+ return *(static_cast<MCSymbolData*> (NULL));
+}
diff --git a/lib/MC/MCTargetAsmLexer.cpp b/lib/MC/MCTargetAsmLexer.cpp
deleted file mode 100644
index c01c914cec..0000000000
--- a/lib/MC/MCTargetAsmLexer.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- llvm/MC/MCTargetAsmLexer.cpp - Target Assembly Lexer --------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCTargetAsmLexer.h"
-using namespace llvm;
-
-MCTargetAsmLexer::MCTargetAsmLexer(const Target &T)
- : TheTarget(T), Lexer(NULL) {
-}
-MCTargetAsmLexer::~MCTargetAsmLexer() {}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index cc8d2fb477..a5ba3c3653 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -27,6 +27,16 @@
using namespace llvm;
using namespace llvm::object;
+void MachObjectWriter::reset() {
+ Relocations.clear();
+ IndirectSymBase.clear();
+ StringTable.clear();
+ LocalSymbolData.clear();
+ ExternalSymbolData.clear();
+ UndefinedSymbolData.clear();
+ MCObjectWriter::reset();
+}
+
bool MachObjectWriter::
doesSymbolRequireExternRelocation(const MCSymbolData *SD) {
// Undefined symbols are always extern.
@@ -366,6 +376,39 @@ void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
}
+static unsigned ComputeLinkerOptionsLoadCommandSize(
+ const std::vector<std::string> &Options, bool is64Bit)
+{
+ unsigned Size = sizeof(macho::LinkerOptionsLoadCommand);
+ for (unsigned i = 0, e = Options.size(); i != e; ++i)
+ Size += Options[i].size() + 1;
+ return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
+}
+
+void MachObjectWriter::WriteLinkerOptionsLoadCommand(
+ const std::vector<std::string> &Options)
+{
+ unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
+ uint64_t Start = OS.tell();
+ (void) Start;
+
+ Write32(macho::LCT_LinkerOptions);
+ Write32(Size);
+ Write32(Options.size());
+ uint64_t BytesWritten = sizeof(macho::LinkerOptionsLoadCommand);
+ for (unsigned i = 0, e = Options.size(); i != e; ++i) {
+ // Write each string, including the null byte.
+ const std::string &Option = Options[i];
+ WriteBytes(Option.c_str(), Option.size() + 1);
+ BytesWritten += Option.size() + 1;
+ }
+
+ // Pad to a multiple of the pointer size.
+ WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
+
+ assert(OS.tell() - Start == Size);
+}
+
void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
@@ -683,6 +726,13 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
+ // Add the data-in-code load command size, if used.
+ unsigned NumDataRegions = Asm.getDataRegions().size();
+ if (NumDataRegions) {
+ ++NumLoadCommands;
+ LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ }
+
// Add the symbol table load command sizes, if used.
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
UndefinedSymbolData.size();
@@ -692,13 +742,15 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
macho::DysymtabLoadCommandSize);
}
- // Add the data-in-code load command size, if used.
- unsigned NumDataRegions = Asm.getDataRegions().size();
- if (NumDataRegions) {
+ // Add the linker option load commands sizes.
+ const std::vector<std::vector<std::string> > &LinkerOptions =
+ Asm.getLinkerOptions();
+ for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
++NumLoadCommands;
- LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i],
+ is64Bit());
}
-
+
// Compute the total size of the section data, as well as its file size and vm
// size.
uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
@@ -789,6 +841,11 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
IndirectSymbolOffset, NumIndirectSymbols);
}
+ // Write the linker options load commands.
+ for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
+ WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
+ }
+
// Write the actual section data.
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 01860c5d7f..6dffed73df 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -36,7 +36,7 @@
using namespace llvm;
namespace {
-typedef llvm::SmallString<COFF::NameSize> name;
+typedef SmallString<COFF::NameSize> name;
enum AuxiliaryType {
ATFunctionDefinition,
@@ -58,7 +58,7 @@ class COFFSymbol {
public:
COFF::symbol Data;
- typedef llvm::SmallVector<AuxSymbol, 1> AuxiliarySymbols;
+ typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols;
name Name;
int Index;
@@ -69,7 +69,7 @@ public:
MCSymbolData const *MCData;
- COFFSymbol(llvm::StringRef name);
+ COFFSymbol(StringRef name);
size_t size() const;
void set_name_offset(uint32_t Offset);
@@ -97,13 +97,13 @@ public:
COFFSymbol *Symbol;
relocations Relocations;
- COFFSection(llvm::StringRef name);
+ COFFSection(StringRef name);
static size_t size();
};
// This class holds the COFF string table.
class StringTable {
- typedef llvm::StringMap<size_t> map;
+ typedef StringMap<size_t> map;
map Map;
void update_length();
@@ -112,7 +112,7 @@ public:
StringTable();
size_t size() const;
- size_t insert(llvm::StringRef String);
+ size_t insert(StringRef String);
};
class WinCOFFObjectWriter : public MCObjectWriter {
@@ -144,10 +144,12 @@ public:
COFFSection *createSection(StringRef Name);
template <typename object_t, typename list_t>
- object_t *createCOFFEntity(llvm::StringRef Name, list_t &List);
+ object_t *createCOFFEntity(StringRef Name, list_t &List);
void DefineSection(MCSectionData const &SectionData);
- void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler);
+ void DefineSymbol(MCSymbol const &Symbol,
+ MCSymbolData const &SymbolData,
+ MCAssembler &Assembler);
void MakeSymbolReal(COFFSymbol &S, size_t Index);
void MakeSectionReal(COFFSection &S, size_t Number);
@@ -202,7 +204,7 @@ static inline void write_uint8_le(void *Data, uint8_t const &Value) {
//------------------------------------------------------------------------------
// Symbol class implementation
-COFFSymbol::COFFSymbol(llvm::StringRef name)
+COFFSymbol::COFFSymbol(StringRef name)
: Name(name.begin(), name.end())
, Other(NULL)
, Section(NULL)
@@ -254,7 +256,7 @@ bool COFFSymbol::should_keep() const {
//------------------------------------------------------------------------------
// Section class implementation
-COFFSection::COFFSection(llvm::StringRef name)
+COFFSection::COFFSection(StringRef name)
: Name(name)
, MCData(NULL)
, Symbol(NULL) {
@@ -287,7 +289,7 @@ size_t StringTable::size() const {
/// Add String to the table iff it is not already there.
/// @returns the index into the string table where the string is now located.
-size_t StringTable::insert(llvm::StringRef String) {
+size_t StringTable::insert(StringRef String) {
map::iterator i = Map.find(String);
if (i != Map.end())
@@ -341,14 +343,14 @@ COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){
return RetSymbol;
}
-COFFSection *WinCOFFObjectWriter::createSection(llvm::StringRef Name) {
+COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
return createCOFFEntity<COFFSection>(Name, Sections);
}
/// A template used to lookup or create a symbol/section, and initialize it if
/// needed.
template <typename object_t, typename list_t>
-object_t *WinCOFFObjectWriter::createCOFFEntity(llvm::StringRef Name,
+object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name,
list_t &List) {
object_t *Object = new object_t(Name);
@@ -408,9 +410,10 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
/// This function takes a section data object from the assembler
/// and creates the associated COFF symbol staging object.
-void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
+void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol,
+ MCSymbolData const &SymbolData,
MCAssembler &Assembler) {
- COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol());
+ COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0;
coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
@@ -418,20 +421,17 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- if (SymbolData.getSymbol().isVariable()) {
+ if (Symbol.isVariable()) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- const MCExpr *Value = SymbolData.getSymbol().getVariableValue();
// FIXME: This assert message isn't very good.
- assert(Value->getKind() == MCExpr::SymbolRef &&
+ assert(Symbol.getVariableValue()->getKind() == MCExpr::SymbolRef &&
"Value must be a SymbolRef!");
- const MCSymbolRefExpr *SymbolRef =
- static_cast<const MCSymbolRefExpr *>(Value);
- coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol());
+ coff_symbol->Other = GetOrCreateCOFFSymbol(&Symbol);
} else {
std::string WeakName = std::string(".weak.")
- + SymbolData.getSymbol().getName().str()
+ + Symbol.getName().str()
+ ".default";
COFFSymbol *WeakDefault = createSymbol(WeakName);
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
@@ -464,7 +464,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
// Bind internal COFF symbol to MC symbol.
coff_symbol->MCData = &SymbolData;
- SymbolMap[&SymbolData.getSymbol()] = coff_symbol;
+ SymbolMap[&Symbol] = coff_symbol;
}
/// making a section real involves assigned it a number and putting
@@ -619,8 +619,11 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
e = Asm.symbol_end(); i != e; i++) {
- if (ExportSymbol(*i, Asm))
- DefineSymbol(*i, Asm);
+ if (ExportSymbol(*i, Asm)) {
+ const MCSymbol &Alias = i->getSymbol();
+ const MCSymbol &Symbol = Alias.AliasedSymbol();
+ DefineSymbol(Alias, Asm.getSymbolData(Symbol), Asm);
+ }
}
}
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index 359b388618..75f343c421 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -50,10 +50,11 @@ public:
// MCStreamer interface
virtual void InitSections();
+ virtual void InitToTextSection();
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
@@ -71,16 +72,29 @@ public:
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment);
virtual void EmitFileDirective(StringRef Filename);
- virtual void EmitInstruction(const MCInst &Instruction);
virtual void EmitWin64EHHandlerData();
virtual void FinishImpl();
-private:
- virtual void EmitInstToFragment(const MCInst &Inst) {
- llvm_unreachable("Not used by WinCOFF.");
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_WinCOFFStreamer;
}
+
+private:
virtual void EmitInstToData(const MCInst &Inst) {
- llvm_unreachable("Not used by WinCOFF.");
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ VecOS.flush();
+
+ // Add the fixups and data.
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+ DF->getFixups().push_back(Fixups[i]);
+ }
+ DF->getContents().append(Code.begin(), Code.end());
}
void SetSection(StringRef Section,
@@ -115,17 +129,13 @@ private:
SectionKind::getBSS());
EmitCodeAlignment(4, 0);
}
-
};
} // end anonymous namespace.
-WinCOFFStreamer::WinCOFFStreamer(MCContext &Context,
- MCAsmBackend &MAB,
- MCCodeEmitter &CE,
- raw_ostream &OS)
- : MCObjectStreamer(Context, MAB, OS, &CE)
- , CurSymbol(NULL) {
-}
+WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ MCCodeEmitter &CE, raw_ostream &OS)
+ : MCObjectStreamer(SK_WinCOFFStreamer, Context, MAB, OS, &CE),
+ CurSymbol(NULL) {}
void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, bool External) {
@@ -164,6 +174,10 @@ void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
// MCStreamer interface
+void WinCOFFStreamer::InitToTextSection() {
+ SetSectionText();
+}
+
void WinCOFFStreamer::InitSections() {
SetSectionText();
SetSectionData();
@@ -176,6 +190,9 @@ void WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) {
MCObjectStreamer::EmitLabel(Symbol);
}
+void WinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) {
+ EmitLabel(Symbol);
+}
void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
llvm_unreachable("not implemented");
}
@@ -184,44 +201,6 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
- // FIXME: This is all very ugly and depressing. What needs to happen here
- // depends on quite a few things that are all part of relaxation, which we
- // don't really even do.
-
- if (Value->getKind() != MCExpr::SymbolRef) {
- MCObjectStreamer::EmitAssignment(Symbol, Value);
- } else {
- // FIXME: This is a horrible way to do this :(. This should really be
- // handled after we are done with the MC* objects and immediately before
- // writing out the object file when we know exactly what the symbol should
- // look like in the coff symbol table. I'm not doing that now because the
- // COFF object writer doesn't have a clearly defined separation between MC
- // data structures, the object writers data structures, and the raw, POD,
- // data structures that get written to disk.
-
- // Copy over the aliased data.
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- const MCSymbolData &RealSD = getAssembler().getOrCreateSymbolData(
- dyn_cast<const MCSymbolRefExpr>(Value)->getSymbol());
-
- // FIXME: This is particularly nasty because it breaks as soon as any data
- // members of MCSymbolData change.
- SD.CommonAlign = RealSD.CommonAlign;
- SD.CommonSize = RealSD.CommonSize;
- SD.Flags = RealSD.Flags;
- SD.Fragment = RealSD.Fragment;
- SD.Index = RealSD.Index;
- SD.IsExternal = RealSD.IsExternal;
- SD.IsPrivateExtern = RealSD.IsPrivateExtern;
- SD.Offset = RealSD.Offset;
- SD.SymbolSize = RealSD.SymbolSize;
- }
-}
-
void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
assert(Symbol && "Symbol must be non-null!");
@@ -330,22 +309,6 @@ void WinCOFFStreamer::EmitFileDirective(StringRef Filename) {
// info will be a much large effort.
}
-void WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) {
- for (unsigned i = 0, e = Instruction.getNumOperands(); i != e; ++i)
- if (Instruction.getOperand(i).isExpr())
- AddValueSymbols(Instruction.getOperand(i).getExpr());
-
- getCurrentSectionData()->setHasInstructions(true);
-
- MCInstFragment *Fragment =
- new MCInstFragment(Instruction, getCurrentSectionData());
-
- raw_svector_ostream VecOS(Fragment->getContents());
-
- getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS,
- Fragment->getFixups());
-}
-
void WinCOFFStreamer::EmitWin64EHHandlerData() {
MCStreamer::EmitWin64EHHandlerData();