mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-30 21:29:28 +00:00
Refactor and improve the encodings/decodings for addrmode3 loads, and make the writeback operand always the first.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136295 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5de728cfe1
commit
7b2958392c
@ -1863,7 +1863,7 @@ defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>;
|
|||||||
}
|
}
|
||||||
|
|
||||||
multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
|
multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
|
||||||
def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb),
|
def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt),
|
||||||
(ins addrmode3:$addr), IndexModePre,
|
(ins addrmode3:$addr), IndexModePre,
|
||||||
LdMiscFrm, itin,
|
LdMiscFrm, itin,
|
||||||
opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
|
opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> {
|
||||||
@ -1874,7 +1874,7 @@ multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> {
|
|||||||
let Inst{11-8} = addr{7-4}; // imm7_4/zero
|
let Inst{11-8} = addr{7-4}; // imm7_4/zero
|
||||||
let Inst{3-0} = addr{3-0}; // imm3_0/Rm
|
let Inst{3-0} = addr{3-0}; // imm3_0/Rm
|
||||||
}
|
}
|
||||||
def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb),
|
def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt),
|
||||||
(ins GPR:$Rn, am3offset:$offset), IndexModePost,
|
(ins GPR:$Rn, am3offset:$offset), IndexModePost,
|
||||||
LdMiscFrm, itin,
|
LdMiscFrm, itin,
|
||||||
opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
|
opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> {
|
||||||
@ -1893,7 +1893,7 @@ defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>;
|
|||||||
defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
|
defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>;
|
||||||
defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
|
defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>;
|
||||||
let hasExtraDefRegAllocReq = 1 in {
|
let hasExtraDefRegAllocReq = 1 in {
|
||||||
def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
|
def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2),
|
||||||
(ins addrmode3:$addr), IndexModePre,
|
(ins addrmode3:$addr), IndexModePre,
|
||||||
LdMiscFrm, IIC_iLoad_d_ru,
|
LdMiscFrm, IIC_iLoad_d_ru,
|
||||||
"ldrd", "\t$Rt, $Rt2, $addr!",
|
"ldrd", "\t$Rt, $Rt2, $addr!",
|
||||||
@ -1904,8 +1904,9 @@ def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
|
|||||||
let Inst{19-16} = addr{12-9}; // Rn
|
let Inst{19-16} = addr{12-9}; // Rn
|
||||||
let Inst{11-8} = addr{7-4}; // imm7_4/zero
|
let Inst{11-8} = addr{7-4}; // imm7_4/zero
|
||||||
let Inst{3-0} = addr{3-0}; // imm3_0/Rm
|
let Inst{3-0} = addr{3-0}; // imm3_0/Rm
|
||||||
|
let DecoderMethod = "DecodeAddrMode3Instruction";
|
||||||
}
|
}
|
||||||
def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
|
def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rn_wb, GPR:$Rt, GPR:$Rt2),
|
||||||
(ins GPR:$Rn, am3offset:$offset), IndexModePost,
|
(ins GPR:$Rn, am3offset:$offset), IndexModePost,
|
||||||
LdMiscFrm, IIC_iLoad_d_ru,
|
LdMiscFrm, IIC_iLoad_d_ru,
|
||||||
"ldrd", "\t$Rt, $Rt2, [$Rn], $offset",
|
"ldrd", "\t$Rt, $Rt2, [$Rn], $offset",
|
||||||
@ -1917,6 +1918,7 @@ def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb),
|
|||||||
let Inst{19-16} = Rn;
|
let Inst{19-16} = Rn;
|
||||||
let Inst{11-8} = offset{7-4}; // imm7_4/zero
|
let Inst{11-8} = offset{7-4}; // imm7_4/zero
|
||||||
let Inst{3-0} = offset{3-0}; // imm3_0/Rm
|
let Inst{3-0} = offset{3-0}; // imm3_0/Rm
|
||||||
|
let DecoderMethod = "DecodeAddrMode3Instruction";
|
||||||
}
|
}
|
||||||
} // hasExtraDefRegAllocReq = 1
|
} // hasExtraDefRegAllocReq = 1
|
||||||
} // mayLoad = 1, neverHasSideEffects = 1
|
} // mayLoad = 1, neverHasSideEffects = 1
|
||||||
@ -1953,17 +1955,17 @@ def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
|
|||||||
let Inst{11-0} = addr{11-0};
|
let Inst{11-0} = addr{11-0};
|
||||||
let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
|
let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2";
|
||||||
}
|
}
|
||||||
def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
|
def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
|
||||||
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
||||||
"ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
"ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
||||||
let Inst{21} = 1; // overwrite
|
let Inst{21} = 1; // overwrite
|
||||||
}
|
}
|
||||||
def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
|
def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
|
||||||
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
||||||
"ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
"ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
||||||
let Inst{21} = 1; // overwrite
|
let Inst{21} = 1; // overwrite
|
||||||
}
|
}
|
||||||
def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb),
|
def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$base_wb, GPR:$Rt),
|
||||||
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
(ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru,
|
||||||
"ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
"ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> {
|
||||||
let Inst{21} = 1; // overwrite
|
let Inst{21} = 1; // overwrite
|
||||||
@ -1981,7 +1983,10 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm,
|
|||||||
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
|
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
|
||||||
def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr),
|
def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr),
|
||||||
StMiscFrm, IIC_iStore_d_r,
|
StMiscFrm, IIC_iStore_d_r,
|
||||||
"strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>;
|
"strd", "\t$Rt, $src2, $addr", []>,
|
||||||
|
Requires<[IsARM, HasV5TE]> {
|
||||||
|
let Inst{21} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Indexed stores
|
// Indexed stores
|
||||||
def STR_PRE_REG : AI2stridx_reg<0, 1, (outs GPR:$Rn_wb),
|
def STR_PRE_REG : AI2stridx_reg<0, 1, (outs GPR:$Rn_wb),
|
||||||
@ -2070,14 +2075,38 @@ def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
|
|||||||
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
|
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
|
||||||
StMiscFrm, IIC_iStore_d_ru,
|
StMiscFrm, IIC_iStore_d_ru,
|
||||||
"strd", "\t$src1, $src2, [$base, $offset]!",
|
"strd", "\t$src1, $src2, [$base, $offset]!",
|
||||||
"$base = $base_wb", []>;
|
"$base = $base_wb", []> {
|
||||||
|
bits<4> src1;
|
||||||
|
bits<4> base;
|
||||||
|
bits<10> offset;
|
||||||
|
let Inst{23} = offset{8}; // U bit
|
||||||
|
let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
|
||||||
|
let Inst{19-16} = base;
|
||||||
|
let Inst{15-12} = src1;
|
||||||
|
let Inst{11-8} = offset{7-4};
|
||||||
|
let Inst{3-0} = offset{3-0};
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeAddrMode3Instruction";
|
||||||
|
}
|
||||||
|
|
||||||
// For disassembly only
|
// For disassembly only
|
||||||
def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
|
def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
|
||||||
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
|
(ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
|
||||||
StMiscFrm, IIC_iStore_d_ru,
|
StMiscFrm, IIC_iStore_d_ru,
|
||||||
"strd", "\t$src1, $src2, [$base], $offset",
|
"strd", "\t$src1, $src2, [$base], $offset",
|
||||||
"$base = $base_wb", []>;
|
"$base = $base_wb", []> {
|
||||||
|
bits<4> src1;
|
||||||
|
bits<4> base;
|
||||||
|
bits<10> offset;
|
||||||
|
let Inst{23} = offset{8}; // U bit
|
||||||
|
let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
|
||||||
|
let Inst{19-16} = base;
|
||||||
|
let Inst{15-12} = src1;
|
||||||
|
let Inst{11-8} = offset{7-4};
|
||||||
|
let Inst{3-0} = offset{3-0};
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeAddrMode3Instruction";
|
||||||
|
}
|
||||||
} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
|
} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
|
||||||
|
|
||||||
// STRT, STRBT, and STRHT are for disassembly only.
|
// STRT, STRBT, and STRHT are for disassembly only.
|
||||||
|
@ -1919,11 +1919,9 @@ cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
|
|||||||
bool ARMAsmParser::
|
bool ARMAsmParser::
|
||||||
cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
|
cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
|
||||||
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
|
|
||||||
|
|
||||||
// Create a writeback register dummy placeholder.
|
// Create a writeback register dummy placeholder.
|
||||||
Inst.addOperand(MCOperand::CreateImm(0));
|
Inst.addOperand(MCOperand::CreateImm(0));
|
||||||
|
((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
|
||||||
((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
|
((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
|
||||||
((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
|
((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1460,7 +1460,7 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
|
|||||||
&& "Invalid arguments");
|
&& "Invalid arguments");
|
||||||
|
|
||||||
// Operand 0 of a pre- and post-indexed store is the address base writeback.
|
// Operand 0 of a pre- and post-indexed store is the address base writeback.
|
||||||
if (isPrePost && isStore) {
|
if (isPrePost) {
|
||||||
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
|
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
|
||||||
"Reg operand expected");
|
"Reg operand expected");
|
||||||
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
|
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
|
||||||
@ -1485,15 +1485,6 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
|
|||||||
++OpIdx;
|
++OpIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After dst of a pre- and post-indexed load is the address base writeback.
|
|
||||||
if (isPrePost && !isStore) {
|
|
||||||
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
|
|
||||||
"Reg operand expected");
|
|
||||||
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
|
|
||||||
decodeRn(insn))));
|
|
||||||
++OpIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disassemble the base operand.
|
// Disassemble the base operand.
|
||||||
if (OpIdx >= NumOps)
|
if (OpIdx >= NumOps)
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user