[llvm] 7d1a295 - [ms] [llvm-ml] Add support for anonymous labels (`@@`, `@B`, `@F`)

Eric Astor via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 7 07:29:37 PDT 2022


Author: Eric Astor
Date: 2022-07-07T10:29:10-04:00
New Revision: 7d1a295484e3e6fd2dddec9ad73d3e227ed4629c

URL: https://github.com/llvm/llvm-project/commit/7d1a295484e3e6fd2dddec9ad73d3e227ed4629c
DIFF: https://github.com/llvm/llvm-project/commit/7d1a295484e3e6fd2dddec9ad73d3e227ed4629c.diff

LOG: [ms] [llvm-ml] Add support for anonymous labels (`@@`, `@B`, `@F`)

ml.exe and ml64.exe support the use of anonymous labels, with @B and @F referring to the previous and next anonymous label respectively.

We add similar support to llvm-ml, with the exception that we are unable to emit an error message for an @F expression not followed by a @@ label.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D128944

Added: 
    llvm/test/tools/llvm-ml/anonymous_labels.asm
    llvm/test/tools/llvm-ml/anonymous_labels_errors.asm

Modified: 
    llvm/lib/MC/MCParser/MasmParser.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp
index 8c582d225e300..2a2741a33326d 100644
--- a/llvm/lib/MC/MCParser/MasmParser.cpp
+++ b/llvm/lib/MC/MCParser/MasmParser.cpp
@@ -1585,6 +1585,16 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
       Res = MCUnaryExpr::createNot(Res, getContext(), FirstTokenLoc);
       return false;
     }
+    // Parse directional local label references.
+    if (Identifier.equals_insensitive("@b") ||
+        Identifier.equals_insensitive("@f")) {
+      bool Before = Identifier.equals_insensitive("@b");
+      MCSymbol *Sym = getContext().getDirectionalLocalSymbol(0, Before);
+      if (Before && Sym->isUndefined())
+        return Error(FirstTokenLoc, "Expected @@ label before @B reference");
+      Res = MCSymbolRefExpr::create(Sym, getContext());
+      return false;
+    }
     // Parse symbol variant.
     std::pair<StringRef, StringRef> Split;
     if (!MAI.useParensForSymbolVariant()) {
@@ -1714,34 +1724,10 @@ bool MasmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
   case AsmToken::BigNum:
     return TokError("literal value out of range for directive");
   case AsmToken::Integer: {
-    SMLoc Loc = getTok().getLoc();
     int64_t IntVal = getTok().getIntVal();
     Res = MCConstantExpr::create(IntVal, getContext());
     EndLoc = Lexer.getTok().getEndLoc();
     Lex(); // Eat token.
-    // Look for 'b' or 'f' following an Integer as a directional label.
-    if (Lexer.getKind() == AsmToken::Identifier) {
-      StringRef IDVal = getTok().getString();
-      // Look up the symbol variant if used.
-      std::pair<StringRef, StringRef> Split = IDVal.split('@');
-      MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
-      if (Split.first.size() != IDVal.size()) {
-        Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
-        if (Variant == MCSymbolRefExpr::VK_Invalid)
-          return TokError("invalid variant '" + Split.second + "'");
-        IDVal = Split.first;
-      }
-      if (IDVal == "f" || IDVal == "b") {
-        MCSymbol *Sym =
-            Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
-        Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
-        if (IDVal == "b" && Sym->isUndefined())
-          return Error(Loc, "directional label undefined");
-        DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym));
-        EndLoc = Lexer.getTok().getEndLoc();
-        Lex(); // Eat identifier.
-      }
-    }
     return false;
   }
   case AsmToken::String: {
@@ -2110,29 +2096,9 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
   AsmToken ID = getTok();
   SMLoc IDLoc = ID.getLoc();
   StringRef IDVal;
-  int64_t LocalLabelVal = -1;
   if (Lexer.is(AsmToken::HashDirective))
     return parseCppHashLineFilenameComment(IDLoc);
-  // Allow an integer followed by a ':' as a directional local label.
-  if (Lexer.is(AsmToken::Integer)) {
-    LocalLabelVal = getTok().getIntVal();
-    if (LocalLabelVal < 0) {
-      if (!TheCondState.Ignore) {
-        Lex(); // always eat a token
-        return Error(IDLoc, "unexpected token at start of statement");
-      }
-      IDVal = "";
-    } else {
-      IDVal = getTok().getString();
-      Lex(); // Consume the integer token to be used as an identifier token.
-      if (Lexer.getKind() != AsmToken::Colon) {
-        if (!TheCondState.Ignore) {
-          Lex(); // always eat a token
-          return Error(IDLoc, "unexpected token at start of statement");
-        }
-      }
-    }
-  } else if (Lexer.is(AsmToken::Dot)) {
+  if (Lexer.is(AsmToken::Dot)) {
     // Treat '.' as a valid identifier in this context.
     Lex();
     IDVal = ".";
@@ -2257,19 +2223,22 @@ bool MasmParser::parseStatement(ParseStatementInfo &Info,
     // FIXME: This doesn't diagnose assignment to a symbol which has been
     // implicitly marked as external.
     MCSymbol *Sym;
-    if (LocalLabelVal == -1) {
-      if (ParsingMSInlineAsm && SI) {
-        StringRef RewrittenLabel =
-            SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
-        assert(!RewrittenLabel.empty() &&
-               "We should have an internal name here.");
-        Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
-                                       RewrittenLabel);
-        IDVal = RewrittenLabel;
-      }
+    if (ParsingMSInlineAsm && SI) {
+      StringRef RewrittenLabel =
+          SI->LookupInlineAsmLabel(IDVal, getSourceManager(), IDLoc, true);
+      assert(!RewrittenLabel.empty() &&
+             "We should have an internal name here.");
+      Info.AsmRewrites->emplace_back(AOK_Label, IDLoc, IDVal.size(),
+                                     RewrittenLabel);
+      IDVal = RewrittenLabel;
+    }
+    // Handle directional local labels
+    if (IDVal == "@@") {
+      Sym = Ctx.createDirectionalLocalSymbol(0);
+    } else {
       Sym = getContext().getOrCreateSymbol(IDVal);
-    } else
-      Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
+    }
+
     // End of Labels should be treated as end of line for lexing
     // purposes but that information is not available to the Lexer who
     // does not understand Labels. This may cause us to see a Hash

diff  --git a/llvm/test/tools/llvm-ml/anonymous_labels.asm b/llvm/test/tools/llvm-ml/anonymous_labels.asm
new file mode 100644
index 0000000000000..e66f78c1b20fc
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/anonymous_labels.asm
@@ -0,0 +1,42 @@
+; RUN: llvm-ml -filetype=s %s /Fo - | FileCheck %s
+
+.code
+
+t1:
+  jmp @F
+  jmp @F
+; CHECK-LABEL: t1:
+; CHECK-NEXT: jmp [[TEMP1:[[:alpha:][:digit:]]+]]
+; CHECK-NEXT: jmp [[TEMP1]]
+
+@@:
+  xor eax, eax
+; CHECK: [[TEMP1]]:
+; CHECK-NEXT: xor eax, eax
+
+t2:
+  jmp @B
+  jmp @B
+; CHECK-LABEL: t2:
+; CHECK-NEXT: jmp [[TEMP1]]
+; CHECK-NEXT: jmp [[TEMP1]]
+
+t3:
+  jmp @F
+; CHECK-LABEL: t3:
+; CHECK-NEXT: jmp [[TEMP2:[[:alpha:][:digit:]]+]]
+
+@@:
+  xor eax, eax
+; CHECK: [[TEMP2]]:
+; CHECK-NEXT: xor eax, eax
+
+@@:
+  xor eax, eax
+; CHECK: [[TEMP3:[[:alpha:][:digit:]]+]]:
+; CHECK-NEXT: xor eax, eax
+
+t4:
+  jmp @B
+; CHECK-LABEL: t4:
+; CHECK-NEXT: jmp [[TEMP3]]

diff  --git a/llvm/test/tools/llvm-ml/anonymous_labels_errors.asm b/llvm/test/tools/llvm-ml/anonymous_labels_errors.asm
new file mode 100644
index 0000000000000..8fcab381bbc03
--- /dev/null
+++ b/llvm/test/tools/llvm-ml/anonymous_labels_errors.asm
@@ -0,0 +1,16 @@
+; RUN: not llvm-ml -filetype=s %s /Fo - 2>&1 | FileCheck %s --implicit-check-not=error:
+
+.code
+
+; CHECK: :[[# @LINE + 2]]:5: error: Expected @@ label before @B reference
+; CHECK: :[[# @LINE + 1]]:7: error: Unexpected identifier!
+jmp @B
+
+@@:
+  jmp @B
+  jmp @F
+@@:
+  xor eax, eax
+
+; NOTE: a trailing @F will not fail; fixing this seems to require two passes.
+jmp @F


        


More information about the llvm-commits mailing list