[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