[llvm] r235862 - [MC] [IAS] Add support for the \@ .macro pseudo-variable.

Toma Tabacu toma.tabacu at imgtec.com
Mon Apr 27 03:50:29 PDT 2015


Author: tomatabacu
Date: Mon Apr 27 05:50:29 2015
New Revision: 235862

URL: http://llvm.org/viewvc/llvm-project?rev=235862&view=rev
Log:
[MC] [IAS] Add support for the \@ .macro pseudo-variable.

Summary:
When used, it is substituted with the number of .macro instantiations we've done up to that point in time.
So if this is the 1st time we've instantiated a .macro (any .macro, regardless of name), \@ will instantiate to 0, if it's the 2nd .macro instantiation, it will instantiate to 1 etc.

It can only be used inside a .macro definition, an .irp definition or an .irpc definition (those last 2 uses are undocumented).

Reviewers: echristo, rafael

Reviewed By: rafael

Subscribers: dsanders, llvm-commits

Differential Revision: http://reviews.llvm.org/D9197

Added:
    llvm/trunk/test/MC/AsmParser/at-pseudo-variable-bad.s
    llvm/trunk/test/MC/AsmParser/at-pseudo-variable.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=235862&r1=235861&r2=235862&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Apr 27 05:50:29 2015
@@ -147,6 +147,9 @@ private:
   /// Boolean tracking whether macro substitution is enabled.
   unsigned MacrosEnabledFlag : 1;
 
+  /// \brief Keeps track of how many .macro's have been instantiated.
+  unsigned NumOfMacroInstantiations;
+
   /// Flag tracking whether any errors have been encountered.
   unsigned HadError : 1;
 
@@ -251,7 +254,7 @@ private:
                         ArrayRef<MCAsmMacroParameter> Parameters);
   bool expandMacro(raw_svector_ostream &OS, StringRef Body,
                    ArrayRef<MCAsmMacroParameter> Parameters,
-                   ArrayRef<MCAsmMacroArgument> A,
+                   ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable,
                    const SMLoc &L);
 
   /// \brief Are macros enabled in the parser?
@@ -519,6 +522,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCCo
 
   PlatformParser->Initialize(*this);
   initializeDirectiveKindMap();
+
+  NumOfMacroInstantiations = 0;
 }
 
 AsmParser::~AsmParser() {
@@ -1764,7 +1769,8 @@ static bool isIdentifierChar(char c) {
 
 bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
                             ArrayRef<MCAsmMacroParameter> Parameters,
-                            ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) {
+                            ArrayRef<MCAsmMacroArgument> A,
+                            bool EnableAtPseudoVariable, const SMLoc &L) {
   unsigned NParameters = Parameters.size();
   bool HasVararg = NParameters ? Parameters.back().Vararg : false;
   if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
@@ -1830,36 +1836,47 @@ bool AsmParser::expandMacro(raw_svector_
       Pos += 2;
     } else {
       unsigned I = Pos + 1;
-      while (isIdentifierChar(Body[I]) && I + 1 != End)
+
+      // Check for the \@ pseudo-variable.
+      if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
         ++I;
+      else
+        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].Name == Argument)
-          break;
 
-      if (Index == NParameters) {
-        if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
-          Pos += 3;
-        else {
-          OS << '\\' << Argument;
-          Pos = I;
-        }
+      if (Argument == "@") {
+        OS << NumOfMacroInstantiations;
+        Pos += 2;
       } else {
-        bool VarargParameter = HasVararg && Index == (NParameters - 1);
-        for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
-                                                ie = A[Index].end();
-             it != ie; ++it)
-          // We expect no quotes around the string's contents when
-          // parsing for varargs.
-          if (it->getKind() != AsmToken::String || VarargParameter)
-            OS << it->getString();
-          else
-            OS << it->getStringContents();
+        for (; Index < NParameters; ++Index)
+          if (Parameters[Index].Name == Argument)
+            break;
+
+        if (Index == NParameters) {
+          if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')')
+            Pos += 3;
+          else {
+            OS << '\\' << Argument;
+            Pos = I;
+          }
+        } else {
+          bool VarargParameter = HasVararg && Index == (NParameters - 1);
+          for (MCAsmMacroArgument::const_iterator it = A[Index].begin(),
+                                                  ie = A[Index].end();
+               it != ie; ++it)
+            // We expect no quotes around the string's contents when
+            // parsing for varargs.
+            if (it->getKind() != AsmToken::String || VarargParameter)
+              OS << it->getString();
+            else
+              OS << it->getStringContents();
 
-        Pos += 1 + Argument.size();
+          Pos += 1 + Argument.size();
+        }
       }
     }
     // Update the scan point.
@@ -2117,7 +2134,7 @@ bool AsmParser::handleMacroEntry(const M
   StringRef Body = M->Body;
   raw_svector_ostream OS(Buf);
 
-  if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc()))
+  if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc()))
     return true;
 
   // We include the .endmacro in the buffer as our cue to exit the macro
@@ -2133,6 +2150,8 @@ bool AsmParser::handleMacroEntry(const M
       NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
   ActiveMacros.push_back(MI);
 
+  ++NumOfMacroInstantiations;
+
   // Jump to the macro instantiation and prime the lexer.
   CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
@@ -4378,7 +4397,8 @@ bool AsmParser::parseDirectiveRept(SMLoc
   SmallString<256> Buf;
   raw_svector_ostream OS(Buf);
   while (Count--) {
-    if (expandMacro(OS, M->Body, None, None, getTok().getLoc()))
+    // Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
+    if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
       return true;
   }
   instantiateMacroLikeBody(M, DirectiveLoc, OS);
@@ -4417,7 +4437,9 @@ bool AsmParser::parseDirectiveIrp(SMLoc
   raw_svector_ostream OS(Buf);
 
   for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
-    if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc()))
+    // Note that the AtPseudoVariable is enabled for instantiations of .irp.
+    // This is undocumented, but GAS seems to support it.
+    if (expandMacro(OS, M->Body, Parameter, *i, true, getTok().getLoc()))
       return true;
   }
 
@@ -4464,7 +4486,9 @@ bool AsmParser::parseDirectiveIrpc(SMLoc
     MCAsmMacroArgument Arg;
     Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1)));
 
-    if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc()))
+    // Note that the AtPseudoVariable is enabled for instantiations of .irpc.
+    // This is undocumented, but GAS seems to support it.
+    if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
       return true;
   }
 

Added: llvm/trunk/test/MC/AsmParser/at-pseudo-variable-bad.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/at-pseudo-variable-bad.s?rev=235862&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/at-pseudo-variable-bad.s (added)
+++ llvm/trunk/test/MC/AsmParser/at-pseudo-variable-bad.s Mon Apr 27 05:50:29 2015
@@ -0,0 +1,23 @@
+# RUN: not llvm-mc -triple i386-unknown-unknown < %s 2>&1 | FileCheck %s
+
+add  $1\@, %eax
+# CHECK: :[[@LINE-1]]:8: error: unexpected token in argument list
+
+.macro A @
+  mov  %eax, %eax
+.endm
+# CHECK: :[[@LINE-3]]:11: error: expected identifier in '.macro' directive
+
+.rept 2
+  addi $8, $8, \@
+.endr
+# CHECK: error: unknown token in expression
+# CHECK: :[[@LINE-4]]:1: note: while in macro instantiation
+# CHECK-NEXT: .rept 2
+
+.rep 3
+  addi $9, $9, \@
+.endr
+# CHECK: error: unknown token in expression
+# CHECK: :[[@LINE-4]]:1: note: while in macro instantiation
+# CHECK-NEXT: .rep 3

Added: llvm/trunk/test/MC/AsmParser/at-pseudo-variable.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/at-pseudo-variable.s?rev=235862&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/at-pseudo-variable.s (added)
+++ llvm/trunk/test/MC/AsmParser/at-pseudo-variable.s Mon Apr 27 05:50:29 2015
@@ -0,0 +1,64 @@
+# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
+
+.macro A
+  add  $1\@, %eax
+.endm
+
+.macro B
+  sub  $1\@, %eax
+.endm
+
+  A
+# CHECK: addl  $10, %eax
+  A
+# CHECK: addl  $11, %eax
+  B
+# CHECK: subl  $12, %eax
+  B
+# CHECK: subl  $13, %eax
+
+# The following uses of \@ are undocumented, but valid:
+.irpc foo,234
+  add  $\foo\@, %eax
+.endr
+# CHECK: addl  $24, %eax
+# CHECK: addl  $34, %eax
+# CHECK: addl  $44, %eax
+
+.irp reg,%eax,%ebx
+  sub  $2\@, \reg
+.endr
+# CHECK: subl  $24, %eax
+# CHECK: subl  $24, %ebx
+
+# Test that .irp(c) and .rep(t) do not increase \@.
+# Only the use of A should increase \@, so we can test that it increases by 1
+# each time.
+
+.irpc foo,123
+  sub  $\foo, %eax
+.endr
+
+  A
+# CHECK: addl  $14, %eax
+
+.irp reg,%eax,%ebx
+  sub  $4, \reg
+.endr
+
+  A
+# CHECK: addl  $15, %eax
+
+.rept 2
+  sub  $5, %eax
+.endr
+
+  A
+# CHECK: addl  $16, %eax
+
+.rep 3
+  sub  $6, %eax
+.endr
+
+  A
+# CHECK: addl  $17, %eax





More information about the llvm-commits mailing list