aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAssembler.cpp58
-rw-r--r--lib/MC/MCELFStreamer.cpp14
-rw-r--r--lib/MC/MCParser/AsmParser.cpp1731
3 files changed, 936 insertions, 867 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 5fdc57ad30..e5d4995e16 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -38,6 +38,8 @@ 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,
@@ -222,6 +224,11 @@ MCEncodedFragment::~MCEncodedFragment() {
/* *** */
+MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
+}
+
+/* *** */
+
MCSectionData::MCSectionData() : Section(0) {}
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
@@ -388,6 +395,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
switch (F.getKind()) {
case MCFragment::FT_Data:
case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
return cast<MCEncodedFragment>(F).getContents().size();
case MCFragment::FT_Fill:
return cast<MCFillFragment>(F).getSize();
@@ -458,7 +466,7 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
//
//
// BundlePadding
- // |||
+ // |||
// -------------------------------------
// Prev |##########| F |
// -------------------------------------
@@ -497,6 +505,9 @@ 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) {
@@ -505,6 +516,22 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
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");
@@ -517,8 +544,6 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
++stats::EmittedFragments;
- // FIXME: Embed in fragments instead?
- uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
switch (F.getKind()) {
case MCFragment::FT_Align: {
++stats::EmittedAlignFragments;
@@ -570,6 +595,11 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
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);
@@ -742,9 +772,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);
@@ -954,6 +985,8 @@ 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_Relaxable: OS << "MCRelaxableFragment"; break;
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
@@ -1001,6 +1034,19 @@ 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()
@@ -1094,7 +1140,9 @@ void MCAssembler::dump() {
// anchors for MC*Fragment vtables
void MCEncodedFragment::anchor() { }
+void MCEncodedFragmentWithFixups::anchor() { }
void MCDataFragment::anchor() { }
+void MCCompactEncodedInstFragment::anchor() { }
void MCRelaxableFragment::anchor() { }
void MCAlignFragment::anchor() { }
void MCFillFragment::anchor() { }
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index cae73be298..e5b749e28b 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -371,8 +371,10 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
// data fragment).
//
// If bundling is enabled:
- // - If we're not in a bundle-locked group, emit the instruction into a data
- // fragment of its own.
+ // - 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
@@ -383,6 +385,14 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
MCSectionData *SD = getCurrentSectionData();
if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
DF = getOrCreateDataFragment();
+ 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) {
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 45aaa2ec75..43c872b809 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -50,26 +50,11 @@ MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
-/// \brief Helper class for tracking macro definitions.
-typedef std::vector<MCAsmMacroArgument> MacroArguments;
-typedef std::pair<StringRef, MCAsmMacroArgument> MacroParameter;
-typedef std::vector<MacroParameter> MacroParameters;
-
-struct Macro {
- StringRef Name;
- StringRef Body;
- MacroParameters Parameters;
-
-public:
- Macro(StringRef N, StringRef B, const MacroParameters &P) :
- Name(N), Body(B), Parameters(P) {}
-};
-
/// \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;
@@ -84,7 +69,7 @@ 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);
};
@@ -115,8 +100,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:
@@ -127,7 +110,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
@@ -137,14 +119,15 @@ 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.
+ typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
+ ExtensionDirectiveHandler;
+ 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;
@@ -180,7 +163,7 @@ public:
virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
StringRef Directive,
DirectiveHandler Handler) {
- DirectiveMap[Directive] = std::make_pair(Object, Handler);
+ ExtensionDirectiveMap[Directive] = std::make_pair(Object, Handler);
}
public:
@@ -225,6 +208,9 @@ public:
virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
virtual bool ParseAbsoluteExpression(int64_t &Res);
+ bool ParseMacroArgument(MCAsmMacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter);
+
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
virtual bool ParseIdentifier(StringRef &Res);
@@ -233,6 +219,14 @@ public:
virtual bool MacrosEnabled() {return MacrosEnabledFlag;}
virtual void SetMacrosEnabled(bool flag) {MacrosEnabledFlag = flag;}
+ virtual const MCAsmMacro* LookupMacro(StringRef Name);
+ virtual void DefineMacro(StringRef Name, const MCAsmMacro& Macro);
+ virtual void UndefineMacro(StringRef Name);
+
+ virtual bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
+ virtual bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
+ void HandleMacroExit();
+
virtual void CheckForValidSection();
/// }
@@ -242,12 +236,10 @@ private:
void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L);
- bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
- const MacroParameters &Parameters,
- const MacroArguments &A,
+ const MCAsmMacroParameters &Parameters,
+ const MCAsmMacroArguments &A,
const SMLoc &L);
- void HandleMacroExit();
void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
@@ -270,9 +262,7 @@ private:
/// location.
void JumpToLoc(SMLoc Loc, int InBuffer=-1);
- bool ParseMacroArgument(MCAsmMacroArgument &MA,
- AsmToken::TokenKind &ArgumentDelimiter);
- bool ParseMacroArguments(const Macro *M, MacroArguments &A);
+ bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &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
@@ -291,8 +281,9 @@ private:
bool ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc);
- // Directive Parsing.
+ bool ParseRegisterOrRegisterNumber(int64_t &Register, SMLoc DirectiveLoc);
+ // 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,
@@ -306,10 +297,21 @@ private:
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_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
};
- StringMap<DirectiveKind> DirectiveKindMapping;
+ /// DirectiveKindMap - Maps directive name --> DirectiveKind enum, for
+ /// directives parsed by this class.
+ StringMap<DirectiveKind> DirectiveKindMap;
// ".ascii", ".asciz", ".string"
bool ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
@@ -323,6 +325,38 @@ private:
// ".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"
@@ -330,6 +364,12 @@ private:
// ".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);
@@ -359,8 +399,8 @@ private:
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"
@@ -370,125 +410,8 @@ private:
// "_emit"
bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info);
- void initializeDirectiveKindMapping();
-};
-
-/// \brief Generic implementation of directive handling, etc. which is shared
-/// (or the default, at least) for all assembler parsers.
-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");
-
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveSpace>(".space");
- AddDirectiveHandler<&GenericAsmParser::ParseDirectiveSpace>(".skip");
-
- // 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);
-
- bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
- bool ParseDirectiveSpace(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 {
@@ -504,7 +427,7 @@ 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),
+ PlatformParser(0),
CurBuffer(0), MacrosEnabledFlag(true), CppHashLineNumber(0),
AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) {
// Save the old handler.
@@ -514,9 +437,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
@@ -533,19 +453,18 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx,
PlatformParser->Initialize(*this);
}
- initializeDirectiveKindMapping();
+ 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() {
@@ -1182,10 +1101,10 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// have to do this so that .endif isn't skipped in a ".if 0" block for
// example.
StringMap<DirectiveKind>::const_iterator DirKindIt =
- DirectiveKindMapping.find(IDVal);
+ DirectiveKindMap.find(IDVal);
DirectiveKind DirKind =
- (DirKindIt == DirectiveKindMapping.end()) ? DK_NO_DIRECTIVE :
- DirKindIt->getValue();
+ (DirKindIt == DirectiveKindMap.end()) ? DK_NO_DIRECTIVE :
+ DirKindIt->getValue();
switch (DirKind) {
default:
break;
@@ -1278,16 +1197,39 @@ 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 (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;
+ // Next, check the extention directive map to see if any extension has
+ // registered itself to parse this directive.
+ std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
+ 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;
@@ -1397,14 +1339,71 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
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);
}
- // Look up the handler in the extension handler table.
- std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
- DirectiveMap.lookup(IDVal);
- if (Handler.first)
- return (*Handler.second)(Handler.first, IDVal, IDLoc);
-
return Error(IDLoc, "unknown directive");
}
@@ -1590,8 +1589,8 @@ static bool isIdentifierChar(char 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())
@@ -1690,7 +1689,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),
@@ -1807,7 +1806,7 @@ bool AsmParser::ParseMacroArgument(MCAsmMacroArgument &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()
@@ -1851,14 +1850,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;
@@ -1877,7 +1892,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";
@@ -2425,507 +2440,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
return false;
}
-
-/// 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;
-}
-
-/// 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"