[llvm] r213876 - Let the integrated assembler understand .exitm, PR20426.
Nico Weber
nicolasweber at gmx.de
Thu Jul 24 10:08:39 PDT 2014
Author: nico
Date: Thu Jul 24 12:08:39 2014
New Revision: 213876
URL: http://llvm.org/viewvc/llvm-project?rev=213876&view=rev
Log:
Let the integrated assembler understand .exitm, PR20426.
Added:
llvm/trunk/test/MC/AsmParser/macro-exitm.s
Modified:
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=213876&r1=213875&r2=213876&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Jul 24 12:08:39 2014
@@ -92,8 +92,12 @@ struct MacroInstantiation {
/// The location where parsing should resume upon instantiation completion.
SMLoc ExitLoc;
+ /// The depth of TheCondStack at the start of the instantiation.
+ size_t CondStackDepth;
+
public:
- MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I);
+ MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I,
+ size_t CondStackDepth);
};
struct ParseStatementInfo {
@@ -351,7 +355,8 @@ private:
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_CFI_WINDOW_SAVE,
- DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
+ DK_MACROS_ON, DK_MACROS_OFF,
+ DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
DK_SLEB128, DK_ULEB128,
DK_ERR, DK_ERROR, DK_WARNING,
DK_END
@@ -403,6 +408,7 @@ private:
// macro directives
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
+ bool parseDirectiveExitMacro(StringRef Directive);
bool parseDirectiveEndMacro(StringRef Directive);
bool parseDirectiveMacro(SMLoc DirectiveLoc);
bool parseDirectiveMacrosOnOff(StringRef Directive);
@@ -1541,6 +1547,8 @@ bool AsmParser::parseStatement(ParseStat
return parseDirectiveMacrosOnOff(IDVal);
case DK_MACRO:
return parseDirectiveMacro(IDLoc);
+ case DK_EXITM:
+ return parseDirectiveExitMacro(IDVal);
case DK_ENDM:
case DK_ENDMACRO:
return parseDirectiveEndMacro(IDVal);
@@ -1858,8 +1866,9 @@ bool AsmParser::expandMacro(raw_svector_
}
MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
- MemoryBuffer *I)
- : Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL) {}
+ MemoryBuffer *I, size_t CondStackDepth)
+ : Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
+ CondStackDepth(CondStackDepth) {}
static bool isOperator(AsmToken::TokenKind kind) {
switch (kind) {
@@ -2122,8 +2131,9 @@ bool AsmParser::handleMacroEntry(const M
// Create the macro instantiation object and add to the current macro
// instantiation stack.
- MacroInstantiation *MI = new MacroInstantiation(
- NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ MacroInstantiation *MI =
+ new MacroInstantiation(NameLoc, CurBuffer, getTok().getLoc(),
+ Instantiation, TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
@@ -3471,6 +3481,26 @@ void AsmParser::checkForBadMacro(SMLoc D
"found in body which will have no effect");
}
+/// parseDirectiveExitMacro
+/// ::= .exitm
+bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '" + Directive + "' directive");
+
+ if (!isInsideMacroInstantiation())
+ return TokError("unexpected '" + Directive + "' in file, "
+ "no current macro definition");
+
+ // Exit all conditionals that are active in the current macro.
+ while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
+ TheCondState = TheCondStack.back();
+ TheCondStack.pop_back();
+ }
+
+ handleMacroExit();
+ return false;
+}
+
/// parseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
@@ -4226,6 +4256,7 @@ void AsmParser::initializeDirectiveKindM
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
+ DirectiveKindMap[".exitm"] = DK_EXITM;
DirectiveKindMap[".endm"] = DK_ENDM;
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
DirectiveKindMap[".purgem"] = DK_PURGEM;
@@ -4286,8 +4317,9 @@ void AsmParser::instantiateMacroLikeBody
// Create the macro instantiation object and add to the current macro
// instantiation stack.
- MacroInstantiation *MI = new MacroInstantiation(
- DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
+ MacroInstantiation *MI =
+ new MacroInstantiation(DirectiveLoc, CurBuffer, getTok().getLoc(),
+ Instantiation, TheCondStack.size());
ActiveMacros.push_back(MI);
// Jump to the macro instantiation and prime the lexer.
Added: llvm/trunk/test/MC/AsmParser/macro-exitm.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/macro-exitm.s?rev=213876&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/macro-exitm.s (added)
+++ llvm/trunk/test/MC/AsmParser/macro-exitm.s Thu Jul 24 12:08:39 2014
@@ -0,0 +1,64 @@
+// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+// .exitm is encountered in a normal macro expansion
+.macro REP
+.rept 3
+.long 0
+.exitm
+.endr
+.endm
+REP
+// Only the output from the first rept expansion should make it through:
+// CHECK: .long 0
+// CHECK-NOT: .long 0
+
+// .exitm is in a true branch
+.macro A
+.if 1
+.long 1
+.exitm
+.endif
+.long 1
+.endm
+A
+// CHECK: .long 1
+// CHECK-NOT: .long 1
+
+// .exitm is in a false branch
+.macro B
+.if 1
+.long 2
+.else
+.exitm
+.endif
+.long 2
+.endm
+B
+// CHECK: .long 2
+// CHECK: .long 2
+
+
+// .exitm is in a false branch that is encountered prior to the true branch
+.macro C
+.if 0
+.exitm
+.else
+.long 3
+.endif
+.long 3
+.endm
+C
+// CHECK: .long 3
+// CHECK: .long 3
+
+// .exitm is in a macro that's expanded in a conditional block.
+.macro D
+.long 4
+.exitm
+.long 4
+.endm
+.if 1
+D
+.endif
+// CHECK: .long 4
+// CHECK-NOT: .long 4
More information about the llvm-commits
mailing list