s/std::vector/SmallVector/
[oota-llvm.git] / lib / Target / ARM / AsmParser / ARMAsmParser.cpp
index 0d2caa862eac9e06d16e2c3fdddddaa05ea3ea75..12225b00ed0556c03541b6c73900be24f6f1253e 100644 (file)
@@ -128,8 +128,7 @@ class ARMOperand : public MCParsedAsmOperand {
     } Reg;
 
     struct {
-      unsigned RegStart;
-      unsigned Number;
+      SmallVector<unsigned, 32> *Registers;
     } RegList;
 
     struct {
@@ -179,6 +178,10 @@ public:
       break;
     }
   }
+  ~ARMOperand() {
+    if (isRegList())
+      delete RegList.Registers;
+  }
 
   /// getStartLoc - Get the location of the first token of this operand.
   SMLoc getStartLoc() const { return StartLoc; }
@@ -196,18 +199,13 @@ public:
   }
 
   unsigned getReg() const {
-    assert((Kind == Register || Kind == RegisterList) && "Invalid access!");
-    unsigned RegNum = 0;
-    if (Kind == Register)
-      RegNum = Reg.RegNum;
-    else
-      RegNum = RegList.RegStart;
-    return RegNum;
+    assert(Kind == Register && "Invalid access!");
+    return Reg.RegNum;
   }
 
-  std::pair<unsigned, unsigned> getRegList() const {
+  const SmallVectorImpl<unsigned> &getRegList() const {
     assert(Kind == RegisterList && "Invalid access!");
-    return std::make_pair(RegList.RegStart, RegList.Number);
+    return *RegList.Registers;
   }
 
   const MCExpr *getImm() const {
@@ -217,10 +215,24 @@ public:
 
   bool isCondCode() const { return Kind == CondCode; }
   bool isImm() const { return Kind == Immediate; }
-  bool isReg() const { return Kind == Register || Kind == RegisterList; }
+  bool isReg() const { return Kind == Register; }
   bool isRegList() const { return Kind == RegisterList; }
   bool isToken() const { return Kind == Token; }
   bool isMemory() const { return Kind == Memory; }
+  bool isMemMode5() const {
+    if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
+        Mem.Writeback || Mem.Negative)
+      return false;
+    // If there is an offset expression, make sure it's valid.
+    if (!Mem.Offset)
+      return true;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+    if (!CE)
+      return false;
+    // The offset must be a multiple of 4 in the range 0-1020.
+    int64_t Value = CE->getValue();
+    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
+  }
 
   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
     // Add as immediates when possible.  Null MCExpr = 0.
@@ -244,24 +256,17 @@ public:
     Inst.addOperand(MCOperand::CreateReg(getReg()));
   }
 
-  void addImmOperands(MCInst &Inst, unsigned N) const {
+  void addRegListOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
-    addExpr(Inst, getImm());
+    const SmallVectorImpl<unsigned> &RegList = getRegList();
+    for (SmallVectorImpl<unsigned>::const_iterator
+           I = RegList.begin(), E = RegList.end(); I != E; ++I)
+      Inst.addOperand(MCOperand::CreateReg(*I));
   }
 
-  bool isMemMode5() const {
-    if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
-        Mem.Writeback || Mem.Negative)
-      return false;
-    // If there is an offset expression, make sure it's valid.
-    if (!Mem.Offset)
-      return true;
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
-    if (!CE)
-      return false;
-    // The offset must be a multiple of 4 in the range 0-1020.
-    int64_t Value = CE->getValue();
-    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
+  void addImmOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addExpr(Inst, getImm());
   }
 
   void addMemMode5Operands(MCInst &Inst, unsigned N) const {
@@ -319,11 +324,15 @@ public:
     return Op;
   }
 
-  static ARMOperand *CreateRegList(unsigned RegStart, unsigned Number,
-                                   SMLoc S, SMLoc E) {
+  static ARMOperand *
+  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
+                SMLoc S, SMLoc E) {
     ARMOperand *Op = new ARMOperand(RegisterList);
-    Op->RegList.RegStart = RegStart;
-    Op->RegList.Number = Number;
+    Op->RegList.Registers = new SmallVector<unsigned, 32>();
+    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
+           I = Regs.begin(), E = Regs.end(); I != E; ++I)
+      Op->RegList.Registers->push_back(I->first);
+    std::sort(Op->RegList.Registers->begin(), Op->RegList.Registers->end());
     Op->StartLoc = S;
     Op->EndLoc = E;
     return Op;
@@ -380,12 +389,12 @@ void ARMOperand::dump(raw_ostream &OS) const {
     break;
   case RegisterList: {
     OS << "<register_list ";
-    std::pair<unsigned, unsigned> List = getRegList();
-    unsigned RegEnd = List.first + List.second;
 
-    for (unsigned Idx = List.first; Idx < RegEnd; ) {
-      OS << Idx;
-      if (++Idx < RegEnd) OS << ", ";
+    const SmallVectorImpl<unsigned> &RegList = getRegList();
+    for (SmallVectorImpl<unsigned>::const_iterator
+           I = RegList.begin(), E = RegList.end(); I != E; ) {
+      OS << *I;
+      if (++I < E) OS << ", ";
     }
 
     OS << ">";
@@ -453,30 +462,14 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
   assert(Parser.getTok().is(AsmToken::LCurly) &&
          "Token is not a Left Curly Brace");
   SMLoc S = Parser.getTok().getLoc();
-  Parser.Lex(); // Eat left curly brace token.
 
-  const AsmToken &RegTok = Parser.getTok();
-  SMLoc RegLoc = RegTok.getLoc();
-  if (RegTok.isNot(AsmToken::Identifier)) {
-    Error(RegLoc, "register expected");
-    return 0;
-  }
-
-  int RegNum = TryParseRegister();
-  if (RegNum == -1) {
-    Error(RegLoc, "register expected");
-    return 0;
-  }
-
-  unsigned PrevRegNum = RegNum;
-  std::vector<std::pair<unsigned, SMLoc> > Registers;
-  Registers.reserve(32);
-  Registers.push_back(std::make_pair(RegNum, RegLoc));
+  // Read the rest of the registers in the list.
+  unsigned PrevRegNum = 0;
+  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
 
-  while (Parser.getTok().is(AsmToken::Comma) ||
-         Parser.getTok().is(AsmToken::Minus)) {
+  do {
     bool IsRange = Parser.getTok().is(AsmToken::Minus);
-    Parser.Lex(); // Eat comma or minus token.
+    Parser.Lex(); // Eat non-identifier token.
 
     const AsmToken &RegTok = Parser.getTok();
     SMLoc RegLoc = RegTok.getLoc();
@@ -502,7 +495,8 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
     }
 
     PrevRegNum = RegNum;
-  }
+  } while (Parser.getTok().is(AsmToken::Comma) ||
+           Parser.getTok().is(AsmToken::Minus));
 
   // Process the right curly brace of the list.
   const AsmToken &RCurlyTok = Parser.getTok();
@@ -515,18 +509,15 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
   Parser.Lex(); // Eat right curly brace token.
  
   // Verify the register list.
-  std::vector<std::pair<unsigned, SMLoc> >::iterator
+  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_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;
+    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
 
     if (RegMap[RegInfo.first]) {
       Error(RegInfo.second, "register duplicated in register list");
@@ -539,15 +530,9 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
 
     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);
+  return ARMOperand::CreateRegList(Registers, S, E);
 }
 
 /// Parse an ARM memory expression, return false if successful else return true