mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-15 09:33:39 +00:00
Thumb2 assembly parsing and encoding for LDRBT.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139267 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
489c693f65
commit
f0eee6eca8
@ -123,6 +123,16 @@ def t2adrlabel : Operand<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// t2addrmode_posimm8 := reg + imm8
|
||||||
|
def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";}
|
||||||
|
def t2addrmode_posimm8 : Operand<i32> {
|
||||||
|
let PrintMethod = "printT2AddrModeImm8Operand";
|
||||||
|
let EncoderMethod = "getT2AddrModeImm8OpValue";
|
||||||
|
let DecoderMethod = "DecodeT2AddrModeImm8";
|
||||||
|
let ParserMatchClass = MemPosImm8OffsetAsmOperand;
|
||||||
|
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
|
||||||
|
}
|
||||||
|
|
||||||
// t2addrmode_negimm8 := reg - imm8
|
// t2addrmode_negimm8 := reg - imm8
|
||||||
def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";}
|
def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";}
|
||||||
def t2addrmode_negimm8 : Operand<i32>,
|
def t2addrmode_negimm8 : Operand<i32>,
|
||||||
@ -1291,26 +1301,24 @@ def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn),
|
|||||||
[]>;
|
[]>;
|
||||||
} // mayLoad = 1, neverHasSideEffects = 1
|
} // mayLoad = 1, neverHasSideEffects = 1
|
||||||
|
|
||||||
// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
|
// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110).
|
||||||
// for disassembly only.
|
|
||||||
// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
|
// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
|
||||||
class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
|
class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
|
||||||
: T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
|
: T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc,
|
||||||
"\t$Rt, $addr", []> {
|
"\t$Rt, $addr", []> {
|
||||||
|
bits<4> Rt;
|
||||||
|
bits<13> addr;
|
||||||
let Inst{31-27} = 0b11111;
|
let Inst{31-27} = 0b11111;
|
||||||
let Inst{26-25} = 0b00;
|
let Inst{26-25} = 0b00;
|
||||||
let Inst{24} = signed;
|
let Inst{24} = signed;
|
||||||
let Inst{23} = 0;
|
let Inst{23} = 0;
|
||||||
let Inst{22-21} = type;
|
let Inst{22-21} = type;
|
||||||
let Inst{20} = 1; // load
|
let Inst{20} = 1; // load
|
||||||
|
let Inst{19-16} = addr{12-9};
|
||||||
|
let Inst{15-12} = Rt;
|
||||||
let Inst{11} = 1;
|
let Inst{11} = 1;
|
||||||
let Inst{10-8} = 0b110; // PUW.
|
let Inst{10-8} = 0b110; // PUW.
|
||||||
|
let Inst{7-0} = addr{7-0};
|
||||||
bits<4> Rt;
|
|
||||||
bits<13> addr;
|
|
||||||
let Inst{15-12} = Rt;
|
|
||||||
let Inst{19-16} = addr{12-9};
|
|
||||||
let Inst{7-0} = addr{7-0};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
|
def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
|
||||||
|
@ -742,6 +742,14 @@ public:
|
|||||||
int64_t Val = Mem.OffsetImm->getValue();
|
int64_t Val = Mem.OffsetImm->getValue();
|
||||||
return Val > -256 && Val < 256;
|
return Val > -256 && Val < 256;
|
||||||
}
|
}
|
||||||
|
bool isMemPosImm8Offset() const {
|
||||||
|
if (Kind != Memory || Mem.OffsetRegNum != 0)
|
||||||
|
return false;
|
||||||
|
// Immediate offset in range [0, 255].
|
||||||
|
if (!Mem.OffsetImm) return true;
|
||||||
|
int64_t Val = Mem.OffsetImm->getValue();
|
||||||
|
return Val >= 0 && Val < 256;
|
||||||
|
}
|
||||||
bool isMemNegImm8Offset() const {
|
bool isMemNegImm8Offset() const {
|
||||||
if (Kind != Memory || Mem.OffsetRegNum != 0)
|
if (Kind != Memory || Mem.OffsetRegNum != 0)
|
||||||
return false;
|
return false;
|
||||||
@ -1108,11 +1116,12 @@ public:
|
|||||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
Inst.addOperand(MCOperand::CreateImm(Val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
addMemImm8OffsetOperands(Inst, N);
|
||||||
|
}
|
||||||
|
|
||||||
void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
|
void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 2 && "Invalid number of operands!");
|
addMemImm8OffsetOperands(Inst, N);
|
||||||
int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
|
|
||||||
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
|
|
||||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
|
void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
@ -591,6 +591,20 @@ _func:
|
|||||||
@ CHECK: ldrb.w r7, [sp, r2] @ encoding: [0x1d,0xf8,0x02,0x70]
|
@ CHECK: ldrb.w r7, [sp, r2] @ encoding: [0x1d,0xf8,0x02,0x70]
|
||||||
|
|
||||||
|
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
@ LDRBT
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
ldrbt r1, [r2]
|
||||||
|
ldrbt r1, [r8, #0]
|
||||||
|
ldrbt r1, [r8, #3]
|
||||||
|
ldrbt r1, [r8, #255]
|
||||||
|
|
||||||
|
@ CHECK: ldrbt r1, [r2] @ encoding: [0x12,0xf8,0x00,0x1e]
|
||||||
|
@ CHECK: ldrbt r1, [r8] @ encoding: [0x18,0xf8,0x00,0x1e]
|
||||||
|
@ CHECK: ldrbt r1, [r8, #3] @ encoding: [0x18,0xf8,0x03,0x1e]
|
||||||
|
@ CHECK: ldrbt r1, [r8, #255] @ encoding: [0x18,0xf8,0xff,0x1e]
|
||||||
|
|
||||||
|
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
@ IT
|
@ IT
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
|
@ -666,6 +666,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
|||||||
MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ...
|
MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ...
|
||||||
MISC("it_mask", "kOperandTypeThumbITMask"); // I
|
MISC("it_mask", "kOperandTypeThumbITMask"); // I
|
||||||
MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R
|
MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R
|
||||||
|
MISC("t2addrmode_posimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
|
||||||
MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
|
MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
|
||||||
MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
|
MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I
|
||||||
MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
|
MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I
|
||||||
|
Loading…
x
Reference in New Issue
Block a user