} Reg;
struct {
- unsigned RegStart;
- unsigned Number;
+ SmallVector<unsigned, 32> *Registers;
} RegList;
struct {
break;
}
}
+ ~ARMOperand() {
+ if (isRegList())
+ delete RegList.Registers;
+ }
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const { return StartLoc; }
}
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 {
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.
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 {
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;
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 << ">";
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();
}
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();
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");
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