mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
ARM indexed load assembly parsing and encoding.
More parsing support for indexed loads. Fix pre-indexed with writeback parsing for register offsets and handle basic post-indexed offsets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f39031b360
commit
f4fa3d6e46
@ -665,11 +665,17 @@ def addrmode2 : Operand<i32>,
|
|||||||
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def PostIdxRegShiftedAsmOperand : AsmOperandClass {
|
||||||
|
let Name = "PostIdxRegShifted";
|
||||||
|
let ParserMethod = "parsePostIdxReg";
|
||||||
|
}
|
||||||
def am2offset_reg : Operand<i32>,
|
def am2offset_reg : Operand<i32>,
|
||||||
ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
|
ComplexPattern<i32, 2, "SelectAddrMode2OffsetReg",
|
||||||
[], [SDNPWantRoot]> {
|
[], [SDNPWantRoot]> {
|
||||||
let EncoderMethod = "getAddrMode2OffsetOpValue";
|
let EncoderMethod = "getAddrMode2OffsetOpValue";
|
||||||
let PrintMethod = "printAddrMode2OffsetOperand";
|
let PrintMethod = "printAddrMode2OffsetOperand";
|
||||||
|
// When using this for assembly, it's always as a post-index offset.
|
||||||
|
let ParserMatchClass = PostIdxRegShiftedAsmOperand;
|
||||||
let MIOperandInfo = (ops GPR, i32imm);
|
let MIOperandInfo = (ops GPR, i32imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,9 @@ class ARMOperand : public MCParsedAsmOperand {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned RegNum;
|
unsigned RegNum;
|
||||||
unsigned Imm;
|
bool isAdd;
|
||||||
|
ARM_AM::ShiftOpc ShiftTy;
|
||||||
|
unsigned ShiftImm;
|
||||||
} PostIdxReg;
|
} PostIdxReg;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -498,12 +500,15 @@ public:
|
|||||||
bool isToken() const { return Kind == Token; }
|
bool isToken() const { return Kind == Token; }
|
||||||
bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
|
bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
|
||||||
bool isMemory() const { return Kind == Memory; }
|
bool isMemory() const { return Kind == Memory; }
|
||||||
bool isPostIdxReg() const { return Kind == PostIndexRegister; }
|
|
||||||
bool isShifterImm() const { return Kind == ShifterImmediate; }
|
bool isShifterImm() const { return Kind == ShifterImmediate; }
|
||||||
bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
|
bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
|
||||||
bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
|
bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
|
||||||
bool isRotImm() const { return Kind == RotateImmediate; }
|
bool isRotImm() const { return Kind == RotateImmediate; }
|
||||||
bool isBitfield() const { return Kind == BitfieldDescriptor; }
|
bool isBitfield() const { return Kind == BitfieldDescriptor; }
|
||||||
|
bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; }
|
||||||
|
bool isPostIdxReg() const {
|
||||||
|
return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
|
||||||
|
}
|
||||||
bool isMemNoOffset() const {
|
bool isMemNoOffset() const {
|
||||||
if (Kind != Memory)
|
if (Kind != Memory)
|
||||||
return false;
|
return false;
|
||||||
@ -858,7 +863,18 @@ public:
|
|||||||
void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
|
void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 2 && "Invalid number of operands!");
|
assert(N == 2 && "Invalid number of operands!");
|
||||||
Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
|
Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
|
||||||
Inst.addOperand(MCOperand::CreateImm(PostIdxReg.Imm));
|
Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 2 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
|
||||||
|
// The sign, shift type, and shift amount are encoded in a single operand
|
||||||
|
// using the AM2 encoding helpers.
|
||||||
|
ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
|
||||||
|
unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
|
||||||
|
PostIdxReg.ShiftTy);
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(Imm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
|
void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
|
||||||
@ -1027,11 +1043,15 @@ public:
|
|||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARMOperand *CreatePostIdxReg(unsigned RegNum, unsigned Imm,
|
static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
|
||||||
|
ARM_AM::ShiftOpc ShiftTy,
|
||||||
|
unsigned ShiftImm,
|
||||||
SMLoc S, SMLoc E) {
|
SMLoc S, SMLoc E) {
|
||||||
ARMOperand *Op = new ARMOperand(PostIndexRegister);
|
ARMOperand *Op = new ARMOperand(PostIndexRegister);
|
||||||
Op->PostIdxReg.RegNum = RegNum;
|
Op->PostIdxReg.RegNum = RegNum;
|
||||||
Op->PostIdxReg.Imm = Imm;
|
Op->PostIdxReg.isAdd = isAdd;
|
||||||
|
Op->PostIdxReg.ShiftTy = ShiftTy;
|
||||||
|
Op->PostIdxReg.ShiftImm = ShiftImm;
|
||||||
Op->StartLoc = S;
|
Op->StartLoc = S;
|
||||||
Op->EndLoc = E;
|
Op->EndLoc = E;
|
||||||
return Op;
|
return Op;
|
||||||
@ -1093,9 +1113,12 @@ void ARMOperand::print(raw_ostream &OS) const {
|
|||||||
OS << ">";
|
OS << ">";
|
||||||
break;
|
break;
|
||||||
case PostIndexRegister:
|
case PostIndexRegister:
|
||||||
OS << "post-idx register " << (PostIdxReg.Imm ? "" : "-")
|
OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
|
||||||
<< PostIdxReg.RegNum
|
<< PostIdxReg.RegNum;
|
||||||
<< ">";
|
if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
|
||||||
|
OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
|
||||||
|
<< PostIdxReg.ShiftImm;
|
||||||
|
OS << ">";
|
||||||
break;
|
break;
|
||||||
case ProcIFlags: {
|
case ProcIFlags: {
|
||||||
OS << "<ARM_PROC::";
|
OS << "<ARM_PROC::";
|
||||||
@ -1861,9 +1884,9 @@ parseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
|||||||
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
||||||
parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
// Check for a post-index addressing register operand. Specifically:
|
// Check for a post-index addressing register operand. Specifically:
|
||||||
// postidx_reg := '+' register
|
// postidx_reg := '+' register {, shift}
|
||||||
// | '-' register
|
// | '-' register {, shift}
|
||||||
// | register
|
// | register {, shift}
|
||||||
|
|
||||||
// This method must return MatchOperand_NoMatch without consuming any tokens
|
// This method must return MatchOperand_NoMatch without consuming any tokens
|
||||||
// in the case where there is no match, as other alternatives take other
|
// in the case where there is no match, as other alternatives take other
|
||||||
@ -1891,7 +1914,11 @@ parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
|||||||
}
|
}
|
||||||
SMLoc E = Parser.getTok().getLoc();
|
SMLoc E = Parser.getTok().getLoc();
|
||||||
|
|
||||||
Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, S, E));
|
ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
|
||||||
|
unsigned ShiftImm = 0;
|
||||||
|
|
||||||
|
Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
|
||||||
|
ShiftImm, S, E));
|
||||||
|
|
||||||
return MatchOperand_Success;
|
return MatchOperand_Success;
|
||||||
}
|
}
|
||||||
@ -2107,7 +2134,12 @@ parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
|||||||
ShiftType, ShiftValue, isNegative,
|
ShiftType, ShiftValue, isNegative,
|
||||||
S, E));
|
S, E));
|
||||||
|
|
||||||
|
// If there's a pre-indexing writeback marker, '!', just add it as a token
|
||||||
|
// operand.
|
||||||
|
if (Parser.getTok().is(AsmToken::Exclaim)) {
|
||||||
|
Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
|
||||||
|
Parser.Lex(); // Eat the '!'.
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -24,3 +24,19 @@ _func:
|
|||||||
@ CHECK: ldr r3, [r1], #-30 @ encoding: [0x1e,0x30,0x11,0xe4]
|
@ CHECK: ldr r3, [r1], #-30 @ encoding: [0x1e,0x30,0x11,0xe4]
|
||||||
|
|
||||||
|
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
@ LDR (register)
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
ldr r3, [r8, r1]
|
||||||
|
ldr r2, [r5, -r3]
|
||||||
|
ldr r1, [r5, r9]!
|
||||||
|
ldr r6, [r7, -r8]!
|
||||||
|
ldr r5, [r9], r2
|
||||||
|
ldr r4, [r3], -r6
|
||||||
|
|
||||||
|
@ CHECK: ldr r3, [r8, r1] @ encoding: [0x01,0x30,0x98,0xe7]
|
||||||
|
@ CHECK: ldr r2, [r5, -r3] @ encoding: [0x03,0x20,0x15,0xe7]
|
||||||
|
@ CHECK: ldr r1, [r5, r9]! @ encoding: [0x09,0x10,0xb5,0xe7]
|
||||||
|
@ CHECK: ldr r6, [r7, -r8]! @ encoding: [0x08,0x60,0x37,0xe7]
|
||||||
|
@ CHECK: ldr r5, [r9], r2 @ encoding: [0x02,0x50,0x99,0xe6]
|
||||||
|
@ CHECK: ldr r4, [r3], -r6 @ encoding: [0x06,0x40,0x13,0xe6]
|
||||||
|
Loading…
Reference in New Issue
Block a user