forked from OSchip/llvm-project
Add support for parsing the writeback ("!") token.
llvm-svn: 119761
This commit is contained in:
parent
5a97bd873e
commit
2063b84297
|
@ -50,10 +50,10 @@ class ARMAsmParser : public TargetAsmParser {
|
||||||
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
|
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
|
||||||
|
|
||||||
int TryParseRegister();
|
int TryParseRegister();
|
||||||
ARMOperand *TryParseRegisterWithWriteBack();
|
bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
ARMOperand *ParseRegisterList();
|
bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
ARMOperand *ParseMemory();
|
bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
ARMOperand *ParseOperand();
|
bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &);
|
||||||
|
|
||||||
bool ParseMemoryOffsetReg(bool &Negative,
|
bool ParseMemoryOffsetReg(bool &Negative,
|
||||||
bool &OffsetRegShifted,
|
bool &OffsetRegShifted,
|
||||||
|
@ -127,7 +127,6 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned RegNum;
|
unsigned RegNum;
|
||||||
bool Writeback;
|
|
||||||
} Reg;
|
} Reg;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -142,11 +141,11 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||||
const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
|
const MCExpr *ShiftAmount; // used when OffsetRegShifted is true
|
||||||
enum ShiftType ShiftType; // used when OffsetRegShifted is true
|
enum ShiftType ShiftType; // used when OffsetRegShifted is true
|
||||||
unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
|
unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
|
||||||
unsigned Preindexed : 1;
|
unsigned Preindexed : 1;
|
||||||
unsigned Postindexed : 1;
|
unsigned Postindexed : 1;
|
||||||
unsigned OffsetIsReg : 1;
|
unsigned OffsetIsReg : 1;
|
||||||
unsigned Negative : 1; // only used when OffsetIsReg is true
|
unsigned Negative : 1; // only used when OffsetIsReg is true
|
||||||
unsigned Writeback : 1;
|
unsigned Writeback : 1;
|
||||||
} Mem;
|
} Mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -322,11 +321,9 @@ public:
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARMOperand *CreateReg(unsigned RegNum, bool Writeback, SMLoc S,
|
static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
|
||||||
SMLoc E) {
|
|
||||||
ARMOperand *Op = new ARMOperand(Register);
|
ARMOperand *Op = new ARMOperand(Register);
|
||||||
Op->Reg.RegNum = RegNum;
|
Op->Reg.RegNum = RegNum;
|
||||||
Op->Reg.Writeback = Writeback;
|
|
||||||
Op->StartLoc = S;
|
Op->StartLoc = S;
|
||||||
Op->EndLoc = E;
|
Op->EndLoc = E;
|
||||||
return Op;
|
return Op;
|
||||||
|
@ -396,10 +393,10 @@ void ARMOperand::dump(raw_ostream &OS) const {
|
||||||
getImm()->print(OS);
|
getImm()->print(OS);
|
||||||
break;
|
break;
|
||||||
case Memory:
|
case Memory:
|
||||||
OS << "<memory" << (!Mem.Writeback ? ">" : "!>");
|
OS << "<memory>";
|
||||||
break;
|
break;
|
||||||
case Register:
|
case Register:
|
||||||
OS << "<register " << getReg() << (!Reg.Writeback ? ">" : "!>");
|
OS << "<register " << getReg() << ">";
|
||||||
break;
|
break;
|
||||||
case RegisterList:
|
case RegisterList:
|
||||||
case DPRRegisterList:
|
case DPRRegisterList:
|
||||||
|
@ -447,34 +444,35 @@ int ARMAsmParser::TryParseRegister() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Try to parse a register name. The token must be an Identifier when called,
|
/// 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
|
/// If it's a register, an AsmOperand is created. Another AsmOperand is created
|
||||||
/// returned. Otherwise return -1.
|
/// 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
|
/// TODO this is likely to change to allow different register types and or to
|
||||||
/// parse for a specific register type.
|
/// parse for a specific register type.
|
||||||
ARMOperand *ARMAsmParser::TryParseRegisterWithWriteBack() {
|
bool ARMAsmParser::
|
||||||
|
TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
SMLoc S = Parser.getTok().getLoc();
|
SMLoc S = Parser.getTok().getLoc();
|
||||||
int RegNo = TryParseRegister();
|
int RegNo = TryParseRegister();
|
||||||
if (RegNo == -1)
|
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();
|
const AsmToken &ExclaimTok = Parser.getTok();
|
||||||
if (ExclaimTok.is(AsmToken::Exclaim)) {
|
if (ExclaimTok.is(AsmToken::Exclaim)) {
|
||||||
E = ExclaimTok.getLoc();
|
Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
|
||||||
Writeback = true;
|
ExclaimTok.getLoc()));
|
||||||
Parser.Lex(); // Eat exclaim token
|
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
|
/// Parse a register list, return it if successful else return null. The first
|
||||||
/// token must be a '{' when called.
|
/// token must be a '{' when called.
|
||||||
ARMOperand *ARMAsmParser::ParseRegisterList() {
|
bool ARMAsmParser::
|
||||||
|
ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
assert(Parser.getTok().is(AsmToken::LCurly) &&
|
assert(Parser.getTok().is(AsmToken::LCurly) &&
|
||||||
"Token is not a Left Curly Brace");
|
"Token is not a Left Curly Brace");
|
||||||
SMLoc S = Parser.getTok().getLoc();
|
SMLoc S = Parser.getTok().getLoc();
|
||||||
|
@ -491,13 +489,13 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
|
||||||
SMLoc RegLoc = RegTok.getLoc();
|
SMLoc RegLoc = RegTok.getLoc();
|
||||||
if (RegTok.isNot(AsmToken::Identifier)) {
|
if (RegTok.isNot(AsmToken::Identifier)) {
|
||||||
Error(RegLoc, "register expected");
|
Error(RegLoc, "register expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegNum = TryParseRegister();
|
int RegNum = TryParseRegister();
|
||||||
if (RegNum == -1) {
|
if (RegNum == -1) {
|
||||||
Error(RegLoc, "register expected");
|
Error(RegLoc, "register expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsRange) {
|
if (IsRange) {
|
||||||
|
@ -518,7 +516,7 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
|
||||||
const AsmToken &RCurlyTok = Parser.getTok();
|
const AsmToken &RCurlyTok = Parser.getTok();
|
||||||
if (RCurlyTok.isNot(AsmToken::RCurly)) {
|
if (RCurlyTok.isNot(AsmToken::RCurly)) {
|
||||||
Error(RCurlyTok.getLoc(), "'}' expected");
|
Error(RCurlyTok.getLoc(), "'}' expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMLoc E = RCurlyTok.getLoc();
|
SMLoc E = RCurlyTok.getLoc();
|
||||||
|
@ -540,7 +538,7 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
|
||||||
|
|
||||||
if (RegMap[Reg]) {
|
if (RegMap[Reg]) {
|
||||||
Error(RegInfo.second, "register duplicated in register list");
|
Error(RegInfo.second, "register duplicated in register list");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EmittedWarning && Reg < HighRegNum)
|
if (!EmittedWarning && Reg < HighRegNum)
|
||||||
|
@ -551,14 +549,17 @@ ARMOperand *ARMAsmParser::ParseRegisterList() {
|
||||||
HighRegNum = std::max(Reg, HighRegNum);
|
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
|
/// Parse an ARM memory expression, return false if successful else return true
|
||||||
/// or an error. The first token must be a '[' when called.
|
/// or an error. The first token must be a '[' when called.
|
||||||
|
///
|
||||||
/// TODO Only preindexing and postindexing addressing are started, unindexed
|
/// TODO Only preindexing and postindexing addressing are started, unindexed
|
||||||
/// with option, etc are still to do.
|
/// with option, etc are still to do.
|
||||||
ARMOperand *ARMAsmParser::ParseMemory() {
|
bool ARMAsmParser::
|
||||||
|
ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
SMLoc S, E;
|
SMLoc S, E;
|
||||||
assert(Parser.getTok().is(AsmToken::LBrac) &&
|
assert(Parser.getTok().is(AsmToken::LBrac) &&
|
||||||
"Token is not a Left Bracket");
|
"Token is not a Left Bracket");
|
||||||
|
@ -568,12 +569,12 @@ ARMOperand *ARMAsmParser::ParseMemory() {
|
||||||
const AsmToken &BaseRegTok = Parser.getTok();
|
const AsmToken &BaseRegTok = Parser.getTok();
|
||||||
if (BaseRegTok.isNot(AsmToken::Identifier)) {
|
if (BaseRegTok.isNot(AsmToken::Identifier)) {
|
||||||
Error(BaseRegTok.getLoc(), "register expected");
|
Error(BaseRegTok.getLoc(), "register expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
int BaseRegNum = TryParseRegister();
|
int BaseRegNum = TryParseRegister();
|
||||||
if (BaseRegNum == -1) {
|
if (BaseRegNum == -1) {
|
||||||
Error(BaseRegTok.getLoc(), "register expected");
|
Error(BaseRegTok.getLoc(), "register expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Preindexed = false;
|
bool Preindexed = false;
|
||||||
|
@ -595,25 +596,34 @@ ARMOperand *ARMAsmParser::ParseMemory() {
|
||||||
const MCExpr *Offset;
|
const MCExpr *Offset;
|
||||||
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
|
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
|
||||||
Offset, OffsetIsReg, OffsetRegNum, E))
|
Offset, OffsetIsReg, OffsetRegNum, E))
|
||||||
return 0;
|
return true;
|
||||||
const AsmToken &RBracTok = Parser.getTok();
|
const AsmToken &RBracTok = Parser.getTok();
|
||||||
if (RBracTok.isNot(AsmToken::RBrac)) {
|
if (RBracTok.isNot(AsmToken::RBrac)) {
|
||||||
Error(RBracTok.getLoc(), "']' expected");
|
Error(RBracTok.getLoc(), "']' expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
E = RBracTok.getLoc();
|
E = RBracTok.getLoc();
|
||||||
Parser.Lex(); // Eat right bracket token.
|
Parser.Lex(); // Eat right bracket token.
|
||||||
|
|
||||||
|
|
||||||
const AsmToken &ExclaimTok = Parser.getTok();
|
const AsmToken &ExclaimTok = Parser.getTok();
|
||||||
|
ARMOperand *WBOp = 0;
|
||||||
if (ExclaimTok.is(AsmToken::Exclaim)) {
|
if (ExclaimTok.is(AsmToken::Exclaim)) {
|
||||||
E = ExclaimTok.getLoc();
|
WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
|
||||||
|
ExclaimTok.getLoc());
|
||||||
Writeback = true;
|
Writeback = true;
|
||||||
Parser.Lex(); // Eat exclaim token
|
Parser.Lex(); // Eat exclaim token
|
||||||
}
|
}
|
||||||
return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
|
|
||||||
OffsetRegShifted, ShiftType, ShiftAmount,
|
Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
|
||||||
Preindexed, Postindexed, Negative, Writeback,
|
OffsetRegNum, OffsetRegShifted,
|
||||||
S, E);
|
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.
|
// The "[Rn" we have so far was not followed by a comma.
|
||||||
else if (Tok.is(AsmToken::RBrac)) {
|
else if (Tok.is(AsmToken::RBrac)) {
|
||||||
|
@ -629,27 +639,33 @@ ARMOperand *ARMAsmParser::ParseMemory() {
|
||||||
const MCExpr *Offset = 0;
|
const MCExpr *Offset = 0;
|
||||||
|
|
||||||
const AsmToken &NextTok = Parser.getTok();
|
const AsmToken &NextTok = Parser.getTok();
|
||||||
|
|
||||||
if (NextTok.isNot(AsmToken::EndOfStatement)) {
|
if (NextTok.isNot(AsmToken::EndOfStatement)) {
|
||||||
Postindexed = true;
|
Postindexed = true;
|
||||||
Writeback = true;
|
Writeback = true;
|
||||||
|
|
||||||
if (NextTok.isNot(AsmToken::Comma)) {
|
if (NextTok.isNot(AsmToken::Comma)) {
|
||||||
Error(NextTok.getLoc(), "',' expected");
|
Error(NextTok.getLoc(), "',' expected");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser.Lex(); // Eat comma token.
|
Parser.Lex(); // Eat comma token.
|
||||||
|
|
||||||
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
|
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
|
||||||
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
|
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
|
||||||
E))
|
E))
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
|
Operands.push_back(ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset,
|
||||||
OffsetRegShifted, ShiftType, ShiftAmount,
|
OffsetRegNum, OffsetRegShifted,
|
||||||
Preindexed, Postindexed, Negative, Writeback,
|
ShiftType, ShiftAmount, Preindexed,
|
||||||
S, E);
|
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],"
|
/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
|
||||||
|
@ -760,28 +776,30 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount,
|
||||||
|
|
||||||
/// Parse a arm instruction operand. For now this parses the operand regardless
|
/// Parse a arm instruction operand. For now this parses the operand regardless
|
||||||
/// of the mnemonic.
|
/// of the mnemonic.
|
||||||
ARMOperand *ARMAsmParser::ParseOperand() {
|
bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands){
|
||||||
SMLoc S, E;
|
SMLoc S, E;
|
||||||
switch (getLexer().getKind()) {
|
switch (getLexer().getKind()) {
|
||||||
default:
|
default:
|
||||||
Error(Parser.getTok().getLoc(), "unexpected token in operand");
|
Error(Parser.getTok().getLoc(), "unexpected token in operand");
|
||||||
return 0;
|
return true;
|
||||||
case AsmToken::Identifier:
|
case AsmToken::Identifier: {
|
||||||
if (ARMOperand *Op = TryParseRegisterWithWriteBack())
|
if (!TryParseRegisterWithWriteBack(Operands))
|
||||||
return Op;
|
return false;
|
||||||
|
|
||||||
// This was not a register so parse other operands that start with an
|
// This was not a register so parse other operands that start with an
|
||||||
// identifier (like labels) as expressions and create them as immediates.
|
// identifier (like labels) as expressions and create them as immediates.
|
||||||
const MCExpr *IdVal;
|
const MCExpr *IdVal;
|
||||||
S = Parser.getTok().getLoc();
|
S = Parser.getTok().getLoc();
|
||||||
if (getParser().ParseExpression(IdVal))
|
if (getParser().ParseExpression(IdVal))
|
||||||
return 0;
|
return true;
|
||||||
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
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:
|
case AsmToken::LBrac:
|
||||||
return ParseMemory();
|
return ParseMemory(Operands);
|
||||||
case AsmToken::LCurly:
|
case AsmToken::LCurly:
|
||||||
return ParseRegisterList();
|
return ParseRegisterList(Operands);
|
||||||
case AsmToken::Hash:
|
case AsmToken::Hash:
|
||||||
// #42 -> immediate.
|
// #42 -> immediate.
|
||||||
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
|
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
|
||||||
|
@ -789,9 +807,10 @@ ARMOperand *ARMAsmParser::ParseOperand() {
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
const MCExpr *ImmVal;
|
const MCExpr *ImmVal;
|
||||||
if (getParser().ParseExpression(ImmVal))
|
if (getParser().ParseExpression(ImmVal))
|
||||||
return 0;
|
return true;
|
||||||
E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
|
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 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
|
||||||
// Read the remaining operands.
|
// Read the remaining operands.
|
||||||
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
if (getLexer().isNot(AsmToken::EndOfStatement)) {
|
||||||
// Read the first operand.
|
// Read the first operand.
|
||||||
if (ARMOperand *Op = ParseOperand())
|
if (ParseOperand(Operands)) {
|
||||||
Operands.push_back(Op);
|
|
||||||
else {
|
|
||||||
Parser.EatToEndOfStatement();
|
Parser.EatToEndOfStatement();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -864,9 +881,7 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
|
||||||
Parser.Lex(); // Eat the comma.
|
Parser.Lex(); // Eat the comma.
|
||||||
|
|
||||||
// Parse and remember the operand.
|
// Parse and remember the operand.
|
||||||
if (ARMOperand *Op = ParseOperand())
|
if (ParseOperand(Operands)) {
|
||||||
Operands.push_back(Op);
|
|
||||||
else {
|
|
||||||
Parser.EatToEndOfStatement();
|
Parser.EatToEndOfStatement();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,3 +33,21 @@
|
||||||
stmib r2, {r1,r3-r6,sp}
|
stmib r2, {r1,r3-r6,sp}
|
||||||
stmda r2, {r1,r3-r6,sp}
|
stmda r2, {r1,r3-r6,sp}
|
||||||
stmdb 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}
|
||||||
|
|
Loading…
Reference in New Issue