[llvm-commits] [llvm] r118363 - /llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Bill Wendling isanbard at gmail.com
Sat Nov 6 15:36:58 PDT 2010


Author: void
Date: Sat Nov  6 17:36:58 2010
New Revision: 118363

URL: http://llvm.org/viewvc/llvm-project?rev=118363&view=rev
Log:
Add support for parsing register lists. We can't use a bitfield to keep track of
the registers, because the register numbers may be much greater than the number
of bits available in the machine's register.

I extracted the register list verification code out of the actual parsing of the
registers. This made checking for errors much easier. It also limits the number
of warnings that would be emitted for cascading infractions.

Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=118363&r1=118362&r2=118363&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Sat Nov  6 17:36:58 2010
@@ -82,7 +82,6 @@
 
   /// }
 
-
 public:
   ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
     : TargetAsmParser(T), Parser(_Parser), TM(_TM) {
@@ -93,7 +92,6 @@
 
   virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
                                 SmallVectorImpl<MCParsedAsmOperand*> &Operands);
-
   virtual bool ParseDirective(AsmToken DirectiveID);
 };
 } // end anonymous namespace
@@ -433,7 +431,8 @@
 ARMOperand *ARMAsmParser::TryParseRegisterWithWriteBack() {
   SMLoc S = Parser.getTok().getLoc();
   int RegNo = TryParseRegister();
-  if (RegNo == -1) return 0;
+  if (RegNo == -1)
+    return 0;
 
   SMLoc E = Parser.getTok().getLoc();
 
@@ -451,10 +450,9 @@
 /// Parse a register list, return it if successful else return null.  The first
 /// token must be a '{' when called.
 ARMOperand *ARMAsmParser::ParseRegisterList() {
-  SMLoc S, E;
   assert(Parser.getTok().is(AsmToken::LCurly) &&
          "Token is not a Left Curly Brace");
-  S = Parser.getTok().getLoc();
+  SMLoc S = Parser.getTok().getLoc();
   Parser.Lex(); // Eat left curly brace token.
 
   const AsmToken &RegTok = Parser.getTok();
@@ -463,18 +461,22 @@
     Error(RegLoc, "register expected");
     return 0;
   }
+
   int RegNum = TryParseRegister();
   if (RegNum == -1) {
     Error(RegLoc, "register expected");
     return 0;
   }
 
-  unsigned RegList = 1 << RegNum;
-
-  int HighRegNum = RegNum;
-  // TODO ranges like "{Rn-Rm}"
-  while (Parser.getTok().is(AsmToken::Comma)) {
-    Parser.Lex(); // Eat comma token.
+  unsigned PrevRegNum = RegNum;
+  std::vector<std::pair<unsigned, SMLoc> > Registers;
+  Registers.reserve(32);
+  Registers.push_back(std::make_pair(RegNum, RegLoc));
+
+  while (Parser.getTok().is(AsmToken::Comma) ||
+         Parser.getTok().is(AsmToken::Minus)) {
+    bool IsRange = Parser.getTok().is(AsmToken::Minus);
+    Parser.Lex(); // Eat comma or minus token.
 
     const AsmToken &RegTok = Parser.getTok();
     SMLoc RegLoc = RegTok.getLoc();
@@ -482,33 +484,73 @@
       Error(RegLoc, "register expected");
       return 0;
     }
+
     int RegNum = TryParseRegister();
     if (RegNum == -1) {
       Error(RegLoc, "register expected");
       return 0;
     }
 
-    if (RegList & (1 << RegNum))
-      Warning(RegLoc, "register duplicated in register list");
-    else if (RegNum <= HighRegNum)
-      Warning(RegLoc, "register not in ascending order in register list");
-    RegList |= 1 << RegNum;
-    HighRegNum = RegNum;
+    if (IsRange) {
+      int Reg = PrevRegNum;
+      do {
+        ++Reg;
+        Registers.push_back(std::make_pair(Reg, RegLoc));
+      } while (Reg != RegNum);
+    } else {
+      Registers.push_back(std::make_pair(RegNum, RegLoc));
+    }
+
+    PrevRegNum = RegNum;
   }
+
+  // Process the right curly brace of the list.
   const AsmToken &RCurlyTok = Parser.getTok();
   if (RCurlyTok.isNot(AsmToken::RCurly)) {
     Error(RCurlyTok.getLoc(), "'}' expected");
     return 0;
   }
-  E = RCurlyTok.getLoc();
-  Parser.Lex(); // Eat left curly brace token.
 
-  // FIXME: Need to return an operand!
-  Error(E, "FIXME: register list parsing not implemented");
-  return 0;
+  SMLoc E = RCurlyTok.getLoc();
+  Parser.Lex(); // Eat right curly brace token.
+ 
+  // Verify the register list.
+  std::vector<std::pair<unsigned, SMLoc> >::iterator
+    RI = Registers.begin(), RE = Registers.end();
+
+  unsigned Number = Registers.size();
+  unsigned HighRegNum = RI->first;
+  unsigned RegStart = RI->first;
+
+  DenseMap<unsigned, bool> RegMap;
+  RegMap[RI->first] = true;
+
+  for (++RI; RI != RE; ++RI) {
+    std::pair<unsigned, SMLoc> &RegInfo = *RI;
+
+    if (RegMap[RegInfo.first]) {
+      Error(RegInfo.second, "register duplicated in register list");
+      return 0;
+    }
+
+    if (RegInfo.first < HighRegNum)
+      Warning(RegInfo.second,
+              "register not in ascending order in register list");
+
+    RegMap[RegInfo.first] = true;
+    HighRegNum = std::max(RegInfo.first, HighRegNum);
+    RegStart = std::min(RegInfo.first, RegStart);
+  }
+
+  if (RegStart + Number - 1 != HighRegNum) {
+    Error(RegLoc, "non-contiguous register range");
+    return 0;
+  }
+
+  return ARMOperand::CreateRegList(RegStart, Number, S, E);
 }
 
-/// Parse an arm memory expression, return false if successful else return true
+/// Parse an ARM memory expression, return false if successful else return true
 /// or an error.  The first token must be a '[' when called.
 /// TODO Only preindexing and postindexing addressing are started, unindexed
 /// with option, etc are still to do.





More information about the llvm-commits mailing list