mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-15 19:24:33 +00:00
Add parsing for the Thumb t_addrmode_s4 addressing mode. This can almost
certainly be made more generic. But it does allow us to parse something like: ldr r3, [r2, r4] correctly in Thumb mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -222,16 +222,30 @@ public:
|
||||
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;
|
||||
if (!Mem.Offset) return true;
|
||||
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
|
||||
if (!CE)
|
||||
return false;
|
||||
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);
|
||||
}
|
||||
bool isMemModeThumb() const {
|
||||
if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback)
|
||||
return false;
|
||||
|
||||
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-124.
|
||||
uint64_t Value = CE->getValue();
|
||||
return ((Value & 0x3) == 0 && Value <= 124);
|
||||
}
|
||||
|
||||
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
|
||||
// Add as immediates when possible. Null MCExpr = 0.
|
||||
@@ -302,6 +316,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void addMemModeThumbOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 3 && isMemModeThumb() && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
|
||||
|
||||
if (Mem.Offset) {
|
||||
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
|
||||
assert(CE && "Non-constant mode offset operand!");
|
||||
Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
|
||||
Inst.addOperand(MCOperand::CreateReg(0));
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::CreateImm(0));
|
||||
Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dump(raw_ostream &OS) const;
|
||||
|
||||
static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
|
||||
@@ -592,8 +621,8 @@ ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
int OffsetRegNum;
|
||||
bool OffsetRegShifted;
|
||||
enum ShiftType ShiftType;
|
||||
const MCExpr *ShiftAmount;
|
||||
const MCExpr *Offset;
|
||||
const MCExpr *ShiftAmount = 0;
|
||||
const MCExpr *Offset = 0;
|
||||
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
|
||||
Offset, OffsetIsReg, OffsetRegNum, E))
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user