X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FAsmParser%2FARMAsmParser.cpp;h=12225b00ed0556c03541b6c73900be24f6f1253e;hb=5fa22a19750c082ff161db1702ebe96dd2a787e7;hp=a456d3ce5249c6f847e78a8bb6f59c71b0d0c555;hpb=b32e7844e9f79d2bd4ff34a1d19aba347f999abc;p=oota-llvm.git diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index a456d3ce524..12225b00ed0 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -128,8 +128,7 @@ class ARMOperand : public MCParsedAsmOperand { } Reg; struct { - unsigned RegStart; - unsigned Number; + SmallVector *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 getRegList() const { + const SmallVectorImpl &getRegList() const { assert(Kind == RegisterList && "Invalid access!"); - return std::make_pair(RegList.RegStart, RegList.Number); + return *RegList.Registers; } const MCExpr *getImm() const { @@ -221,6 +219,20 @@ public: 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(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 &RegList = getRegList(); + for (SmallVectorImpl::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(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 > &Regs, + SMLoc S, SMLoc E) { ARMOperand *Op = new ARMOperand(RegisterList); - Op->RegList.RegStart = RegStart; - Op->RegList.Number = Number; + Op->RegList.Registers = new SmallVector(); + for (SmallVectorImpl >::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 << " List = getRegList(); - unsigned RegEnd = List.first + List.second; - for (unsigned Idx = List.first; Idx < RegEnd; ) { - OS << Idx; - if (++Idx < RegEnd) OS << ", "; + const SmallVectorImpl &RegList = getRegList(); + for (SmallVectorImpl::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 > 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, 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 >::iterator + SmallVectorImpl >::const_iterator RI = Registers.begin(), RE = Registers.end(); - unsigned Number = Registers.size(); unsigned HighRegNum = RI->first; - unsigned RegStart = RI->first; - DenseMap RegMap; RegMap[RI->first] = true; for (++RI; RI != RE; ++RI) { - std::pair &RegInfo = *RI; + const std::pair &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