[llvm-commits] [llvm] r119761 - in /llvm/trunk: lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/arm_instructions.s
Bill Wendling
isanbard at gmail.com
Thu Nov 18 15:43:06 PST 2010
Author: void
Date: Thu Nov 18 17:43:05 2010
New Revision: 119761
URL: http://llvm.org/viewvc/llvm-project?rev=119761&view=rev
Log:
Add support for parsing the writeback ("!") token.
Modified:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/arm_instructions.s
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=119761&r1=119760&r2=119761&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Nov 18 17:43:05 2010
@@ -50,10 +50,10 @@
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
int TryParseRegister();
- ARMOperand *TryParseRegisterWithWriteBack();
- ARMOperand *ParseRegisterList();
- ARMOperand *ParseMemory();
- ARMOperand *ParseOperand();
+ bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
+ bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
+ bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
+ bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &);
bool ParseMemoryOffsetReg(bool &Negative,
bool &OffsetRegShifted,
@@ -127,7 +127,6 @@
struct {
unsigned RegNum;
- bool Writeback;
} Reg;
struct {
@@ -142,11 +141,11 @@
const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
enum ShiftType ShiftType; // used when OffsetRegShifted is true
unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
- unsigned Preindexed : 1;
- unsigned Postindexed : 1;
- unsigned OffsetIsReg : 1;
- unsigned Negative : 1; // only used when OffsetIsReg is true
- unsigned Writeback : 1;
+ unsigned Preindexed : 1;
+ unsigned Postindexed : 1;
+ unsigned OffsetIsReg : 1;
+ unsigned Negative : 1; // only used when OffsetIsReg is true
+ unsigned Writeback : 1;
} Mem;
};
@@ -322,11 +321,9 @@
return Op;
}
- static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S,
- SMLoc E) {
+ static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
ARMOperand *Op = new ARMOperand(Register);
Op->Reg.RegNum = RegNum;
- Op->Reg.Writeback = Writeback;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
@@ -396,10 +393,10 @@
getImm()->print(OS);
break;
case Memory:
- OS << "<memory" << (!Mem.Writeback ? ">" : "!>");
+ OS << "<memory>";
break;
case Register:
- OS << "<register " << getReg() << (!Reg.Writeback ? ">" : "!>");
+ OS << "<register " << getReg() << ">";
break;
case RegisterList:
case DPRRegisterList:
@@ -447,34 +444,35 @@
}
-/// Try to parse a register name. The token must be an Identifier when called,
-/// and if it is a register name the token is eaten and the register number is
-/// returned. Otherwise return -1.
+/// Try to parse a register name. The token must be an Identifier when called.
+/// If it's a register, an AsmOperand is created. Another AsmOperand is created
+/// if there is a "writeback". 'true' if it's not a register.
///
/// TODO this is likely to change to allow different register types and or to
/// parse for a specific register type.
-ARMOperand *ARMAsmParser::TryParseRegisterWithWriteBack() {
+bool ARMAsmParser::
+TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S = Parser.getTok().getLoc();
int RegNo = TryParseRegister();
if (RegNo == -1)
- return 0;
+ return true;
- SMLoc E = Parser.getTok().getLoc();
+ Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
- bool Writeback = false;
const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
- E = ExclaimTok.getLoc();
- Writeback = true;
+ Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
+ ExclaimTok.getLoc()));
Parser.Lex(); // Eat exclaim token
}
- return ARMOperand::CreateReg(RegNo, Writeback, S, E);
+ return false;
}
/// Parse a register list, return it if successful else return null. The first
/// token must be a '{' when called.
-ARMOperand *ARMAsmParser::ParseRegisterList() {
+bool ARMAsmParser::
+ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
assert(Parser.getTok().is(AsmToken::LCurly) &&
"Token is not a Left Curly Brace");
SMLoc S = Parser.getTok().getLoc();
@@ -491,13 +489,13 @@
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier)) {
Error(RegLoc, "register expected");
- return 0;
+ return true;
}
int RegNum = TryParseRegister();
if (RegNum == -1) {
Error(RegLoc, "register expected");
- return 0;
+ return true;
}
if (IsRange) {
@@ -518,7 +516,7 @@
const AsmToken &RCurlyTok = Parser.getTok();
if (RCurlyTok.isNot(AsmToken::RCurly)) {
Error(RCurlyTok.getLoc(), "'}' expected");
- return 0;
+ return true;
}
SMLoc E = RCurlyTok.getLoc();
@@ -540,7 +538,7 @@
if (RegMap[Reg]) {
Error(RegInfo.second, "register duplicated in register list");
- return 0;
+ return true;
}
if (!EmittedWarning && Reg < HighRegNum)
@@ -551,14 +549,17 @@
HighRegNum = std::max(Reg, HighRegNum);
}
- return ARMOperand::CreateRegList(Registers, S, E);
+ Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
+ return false;
}
/// 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.
-ARMOperand *ARMAsmParser::ParseMemory() {
+bool ARMAsmParser::
+ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
SMLoc S, E;
assert(Parser.getTok().is(AsmToken::LBrac) &&
"Token is not a Left Bracket");
@@ -568,12 +569,12 @@
const AsmToken &BaseRegTok = Parser.getTok();
if (BaseRegTok.isNot(AsmToken::Identifier)) {
Error(BaseRegTok.getLoc(), "register expected");
- return 0;
+ return true;
}
int BaseRegNum = TryParseRegister();
if (BaseRegNum == -1) {
Error(BaseRegTok.getLoc(), "register expected");
- return 0;
+ return true;
}
bool Preindexed = false;
@@ -595,25 +596,34 @@
const MCExpr *Offset;
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum, E))
- return 0;
+ return true;
const AsmToken &RBracTok = Parser.getTok();
if (RBracTok.isNot(AsmToken::RBrac)) {
Error(RBracTok.getLoc(), "']' expected");
- return 0;
+ return true;
}
E = RBracTok.getLoc();
Parser.Lex(); // Eat right bracket token.
+
const AsmToken &ExclaimTok = Parser.getTok();
+ ARMOperand *WBOp = 0;
if (ExclaimTok.is(AsmToken::Exclaim)) {
- E = ExclaimTok.getLoc();
+ WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
+ ExclaimTok.getLoc());
Writeback = true;
Parser.Lex(); // Eat exclaim token
}
- return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
- OffsetRegShifted, ShiftType, ShiftAmount,
- Preindexed, Postindexed, Negative, Writeback,
- S, E);
+
+ Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
+ OffsetRegNum, OffsetRegShifted,
+ ShiftType, ShiftAmount, Preindexed,
+ Postindexed, Negative, Writeback,
+ S, E));
+ if (WBOp)
+ Operands.push_back(WBOp);
+
+ return false;
}
// The "[Rn" we have so far was not followed by a comma.
else if (Tok.is(AsmToken::RBrac)) {
@@ -629,27 +639,33 @@
const MCExpr *Offset = 0;
const AsmToken &NextTok = Parser.getTok();
+
if (NextTok.isNot(AsmToken::EndOfStatement)) {
Postindexed = true;
Writeback = true;
+
if (NextTok.isNot(AsmToken::Comma)) {
Error(NextTok.getLoc(), "',' expected");
- return 0;
+ return true;
}
+
Parser.Lex(); // Eat comma token.
+
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
E))
- return 0;
+ return true;
}
- return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
- OffsetRegShifted, ShiftType, ShiftAmount,
- Preindexed, Postindexed, Negative, Writeback,
- S, E);
+ Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
+ OffsetRegNum, OffsetRegShifted,
+ ShiftType, ShiftAmount, Preindexed,
+ Postindexed, Negative, Writeback,
+ S, E));
+ return false;
}
- return 0;
+ return true;
}
/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
@@ -760,28 +776,30 @@
/// Parse a arm instruction operand. For now this parses the operand regardless
/// of the mnemonic.
-ARMOperand *ARMAsmParser::ParseOperand() {
+bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands){
SMLoc S, E;
switch (getLexer().getKind()) {
default:
Error(Parser.getTok().getLoc(), "unexpected token in operand");
- return 0;
- case AsmToken::Identifier:
- if (ARMOperand *Op = TryParseRegisterWithWriteBack())
- return Op;
+ return true;
+ case AsmToken::Identifier: {
+ if (!TryParseRegisterWithWriteBack(Operands))
+ return false;
// This was not a register so parse other operands that start with an
// identifier (like labels) as expressions and create them as immediates.
const MCExpr *IdVal;
S = Parser.getTok().getLoc();
if (getParser().ParseExpression(IdVal))
- return 0;
+ return true;
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- return ARMOperand::CreateImm(IdVal, S, E);
+ Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
+ return false;
+ }
case AsmToken::LBrac:
- return ParseMemory();
+ return ParseMemory(Operands);
case AsmToken::LCurly:
- return ParseRegisterList();
+ return ParseRegisterList(Operands);
case AsmToken::Hash:
// #42 -> immediate.
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
@@ -789,9 +807,10 @@
Parser.Lex();
const MCExpr *ImmVal;
if (getParser().ParseExpression(ImmVal))
- return 0;
+ return true;
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- return ARMOperand::CreateImm(ImmVal, S, E);
+ Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
+ return false;
}
}
@@ -853,9 +872,7 @@
// Read the remaining operands.
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
- if (ARMOperand *Op = ParseOperand())
- Operands.push_back(Op);
- else {
+ if (ParseOperand(Operands)) {
Parser.EatToEndOfStatement();
return true;
}
@@ -864,9 +881,7 @@
Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
- if (ARMOperand *Op = ParseOperand())
- Operands.push_back(Op);
- else {
+ if (ParseOperand(Operands)) {
Parser.EatToEndOfStatement();
return true;
}
Modified: llvm/trunk/test/MC/ARM/arm_instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/arm_instructions.s?rev=119761&r1=119760&r2=119761&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/arm_instructions.s (original)
+++ llvm/trunk/test/MC/ARM/arm_instructions.s Thu Nov 18 17:43:05 2010
@@ -33,3 +33,21 @@
stmib r2, {r1,r3-r6,sp}
stmda r2, {r1,r3-r6,sp}
stmdb r2, {r1,r3-r6,sp}
+
+@ CHECK: ldmia r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xb2,0xe8]
+@ CHECK: ldmib r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xb2,0xe9]
+@ CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe8]
+@ CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe9]
+ ldmia r2!, {r1,r3-r6,sp}
+ ldmib r2!, {r1,r3-r6,sp}
+ ldmda r2!, {r1,r3-r6,sp}
+ ldmdb r2!, {r1,r3-r6,sp}
+
+@ CHECK: stmia r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa2,0xe8]
+@ CHECK: stmib r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa2,0xe9]
+@ CHECK: stmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x22,0xe8]
+@ CHECK: stmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x22,0xe9]
+ stmia r2!, {r1,r3-r6,sp}
+ stmib r2!, {r1,r3-r6,sp}
+ stmda r2!, {r1,r3-r6,sp}
+ stmdb r2!, {r1,r3-r6,sp}
More information about the llvm-commits
mailing list