mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 06:32:09 +00:00
ARM refactor am6offset usage for VLD1.
Split am6offset into fixed and register offset variants so the instruction encodings are explicit rather than relying an a magic reg0 marker. Needed to being able to parse these. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142853 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0135fe1854
commit
10b90a9bbf
@ -2401,10 +2401,14 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
|
||||
case ARM::VLD1q16:
|
||||
case ARM::VLD1q32:
|
||||
case ARM::VLD1q64:
|
||||
case ARM::VLD1q8_UPD:
|
||||
case ARM::VLD1q16_UPD:
|
||||
case ARM::VLD1q32_UPD:
|
||||
case ARM::VLD1q64_UPD:
|
||||
case ARM::VLD1q8wb_fixed:
|
||||
case ARM::VLD1q16wb_fixed:
|
||||
case ARM::VLD1q32wb_fixed:
|
||||
case ARM::VLD1q64wb_fixed:
|
||||
case ARM::VLD1q8wb_register:
|
||||
case ARM::VLD1q16wb_register:
|
||||
case ARM::VLD1q32wb_register:
|
||||
case ARM::VLD1q64wb_register:
|
||||
case ARM::VLD2d8:
|
||||
case ARM::VLD2d16:
|
||||
case ARM::VLD2d32:
|
||||
@ -2562,10 +2566,14 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
|
||||
case ARM::VLD1q16Pseudo:
|
||||
case ARM::VLD1q32Pseudo:
|
||||
case ARM::VLD1q64Pseudo:
|
||||
case ARM::VLD1q8Pseudo_UPD:
|
||||
case ARM::VLD1q16Pseudo_UPD:
|
||||
case ARM::VLD1q32Pseudo_UPD:
|
||||
case ARM::VLD1q64Pseudo_UPD:
|
||||
case ARM::VLD1q8PseudoWB_register:
|
||||
case ARM::VLD1q16PseudoWB_register:
|
||||
case ARM::VLD1q32PseudoWB_register:
|
||||
case ARM::VLD1q64PseudoWB_register:
|
||||
case ARM::VLD1q8PseudoWB_fixed:
|
||||
case ARM::VLD1q16PseudoWB_fixed:
|
||||
case ARM::VLD1q32PseudoWB_fixed:
|
||||
case ARM::VLD1q64PseudoWB_fixed:
|
||||
case ARM::VLD2d8Pseudo:
|
||||
case ARM::VLD2d16Pseudo:
|
||||
case ARM::VLD2d32Pseudo:
|
||||
|
@ -102,7 +102,7 @@ namespace {
|
||||
unsigned PseudoOpc;
|
||||
unsigned RealOpc;
|
||||
bool IsLoad;
|
||||
bool HasWriteBack;
|
||||
bool HasWritebackOperand;
|
||||
NEONRegSpacing RegSpacing;
|
||||
unsigned char NumRegs; // D registers loaded or stored
|
||||
unsigned char RegElts; // elements per D register; used for lane ops
|
||||
@ -148,13 +148,17 @@ static const NEONLdStTableEntry NEONLdStTable[] = {
|
||||
{ ARM::VLD1d64TPseudo_UPD, ARM::VLD1d64T_UPD, true, true, SingleSpc, 3, 1 ,false},
|
||||
|
||||
{ ARM::VLD1q16Pseudo, ARM::VLD1q16, true, false, SingleSpc, 2, 4 ,false},
|
||||
{ ARM::VLD1q16Pseudo_UPD, ARM::VLD1q16_UPD, true, true, SingleSpc, 2, 4 ,false},
|
||||
{ ARM::VLD1q16PseudoWB_fixed, ARM::VLD1q16wb_fixed,true,false,SingleSpc, 2, 4 ,false},
|
||||
{ ARM::VLD1q16PseudoWB_register, ARM::VLD1q16wb_register, true, true, SingleSpc, 2, 4 ,false},
|
||||
{ ARM::VLD1q32Pseudo, ARM::VLD1q32, true, false, SingleSpc, 2, 2 ,false},
|
||||
{ ARM::VLD1q32Pseudo_UPD, ARM::VLD1q32_UPD, true, true, SingleSpc, 2, 2 ,false},
|
||||
{ ARM::VLD1q32PseudoWB_fixed, ARM::VLD1q32wb_fixed,true,false,SingleSpc, 2, 2 ,false},
|
||||
{ ARM::VLD1q32PseudoWB_register, ARM::VLD1q32wb_register, true, true, SingleSpc, 2, 2 ,false},
|
||||
{ ARM::VLD1q64Pseudo, ARM::VLD1q64, true, false, SingleSpc, 2, 1 ,false},
|
||||
{ ARM::VLD1q64Pseudo_UPD, ARM::VLD1q64_UPD, true, true, SingleSpc, 2, 1 ,false},
|
||||
{ ARM::VLD1q64PseudoWB_fixed, ARM::VLD1q64wb_fixed,true,false,SingleSpc, 2, 2 ,false},
|
||||
{ ARM::VLD1q64PseudoWB_register, ARM::VLD1q64wb_register, true, true, SingleSpc, 2, 1 ,false},
|
||||
{ ARM::VLD1q8Pseudo, ARM::VLD1q8, true, false, SingleSpc, 2, 8 ,false},
|
||||
{ ARM::VLD1q8Pseudo_UPD, ARM::VLD1q8_UPD, true, true, SingleSpc, 2, 8 ,false},
|
||||
{ ARM::VLD1q8PseudoWB_fixed, ARM::VLD1q8wb_fixed,true,false, SingleSpc, 2, 8 ,false},
|
||||
{ ARM::VLD1q8PseudoWB_register, ARM::VLD1q8wb_register,true,true,SingleSpc,2,8,false},
|
||||
|
||||
{ ARM::VLD2DUPd16Pseudo, ARM::VLD2DUPd16, true, false, SingleSpc, 2, 4,true},
|
||||
{ ARM::VLD2DUPd16Pseudo_UPD, ARM::VLD2DUPd16_UPD, true, true, SingleSpc, 2, 4,true},
|
||||
@ -436,14 +440,14 @@ void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI) {
|
||||
if (NumRegs > 3 && TableEntry->copyAllListRegs)
|
||||
MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
|
||||
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
// Copy the addrmode6 operands.
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
// Copy the am6offset operand.
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
// For an instruction writing double-spaced subregs, the pseudo instruction
|
||||
@ -488,14 +492,14 @@ void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
|
||||
TII->get(TableEntry->RealOpc));
|
||||
unsigned OpIdx = 0;
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
// Copy the addrmode6 operands.
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
// Copy the am6offset operand.
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
bool SrcIsKill = MI.getOperand(OpIdx).isKill();
|
||||
@ -565,14 +569,14 @@ void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
|
||||
MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
|
||||
}
|
||||
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
// Copy the addrmode6 operands.
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
// Copy the am6offset operand.
|
||||
if (TableEntry->HasWriteBack)
|
||||
if (TableEntry->HasWritebackOperand)
|
||||
MIB.addOperand(MI.getOperand(OpIdx++));
|
||||
|
||||
// Grab the super-register source.
|
||||
@ -1068,10 +1072,14 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
|
||||
case ARM::VLD1q16Pseudo:
|
||||
case ARM::VLD1q32Pseudo:
|
||||
case ARM::VLD1q64Pseudo:
|
||||
case ARM::VLD1q8Pseudo_UPD:
|
||||
case ARM::VLD1q16Pseudo_UPD:
|
||||
case ARM::VLD1q32Pseudo_UPD:
|
||||
case ARM::VLD1q64Pseudo_UPD:
|
||||
case ARM::VLD1q8PseudoWB_register:
|
||||
case ARM::VLD1q16PseudoWB_register:
|
||||
case ARM::VLD1q32PseudoWB_register:
|
||||
case ARM::VLD1q64PseudoWB_register:
|
||||
case ARM::VLD1q8PseudoWB_fixed:
|
||||
case ARM::VLD1q16PseudoWB_fixed:
|
||||
case ARM::VLD1q32PseudoWB_fixed:
|
||||
case ARM::VLD1q64PseudoWB_fixed:
|
||||
case ARM::VLD2d8Pseudo:
|
||||
case ARM::VLD2d16Pseudo:
|
||||
case ARM::VLD2d32Pseudo:
|
||||
|
@ -1549,6 +1549,23 @@ SDValue ARMDAGToDAGISel::GetVLDSTAlign(SDValue Align, unsigned NumVecs,
|
||||
return CurDAG->getTargetConstant(Alignment, MVT::i32);
|
||||
}
|
||||
|
||||
// Get the register stride update opcode of a VLD/VST instruction that
|
||||
// is otherwise equivalent to the given fixed stride updating instruction.
|
||||
static unsigned getVLDSTRegisterUpdateOpcode(unsigned Opc) {
|
||||
switch (Opc) {
|
||||
default: break;
|
||||
case ARM::VLD1d8wb_fixed: return ARM::VLD1d8wb_register;
|
||||
case ARM::VLD1d16wb_fixed: return ARM::VLD1d16wb_register;
|
||||
case ARM::VLD1d32wb_fixed: return ARM::VLD1d32wb_register;
|
||||
case ARM::VLD1d64wb_fixed: return ARM::VLD1d64wb_register;
|
||||
case ARM::VLD1q8wb_fixed: return ARM::VLD1q8wb_register;
|
||||
case ARM::VLD1q16wb_fixed: return ARM::VLD1q16wb_register;
|
||||
case ARM::VLD1q32wb_fixed: return ARM::VLD1q32wb_register;
|
||||
case ARM::VLD1q64wb_fixed: return ARM::VLD1q64wb_register;
|
||||
}
|
||||
return Opc; // If not one we handle, return it unchanged.
|
||||
}
|
||||
|
||||
SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs,
|
||||
unsigned *DOpcodes, unsigned *QOpcodes0,
|
||||
unsigned *QOpcodes1) {
|
||||
@ -1612,7 +1629,14 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, bool isUpdating, unsigned NumVecs,
|
||||
Ops.push_back(Align);
|
||||
if (isUpdating) {
|
||||
SDValue Inc = N->getOperand(AddrOpIdx + 1);
|
||||
Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc);
|
||||
// FIXME: VLD1 fixed increment doesn't need Reg0. Remove the reg0
|
||||
// case entirely when the rest are updated to that form, too.
|
||||
// Do that before committing this change. Likewise, the opcode
|
||||
// update call will become unconditional.
|
||||
if (NumVecs == 1 && !isa<ConstantSDNode>(Inc.getNode()))
|
||||
Opc = getVLDSTRegisterUpdateOpcode(Opc);
|
||||
if (NumVecs != 1 || !isa<ConstantSDNode>(Inc.getNode()))
|
||||
Ops.push_back(isa<ConstantSDNode>(Inc.getNode()) ? Reg0 : Inc);
|
||||
}
|
||||
Ops.push_back(Pred);
|
||||
Ops.push_back(Reg0);
|
||||
@ -2750,16 +2774,18 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
|
||||
}
|
||||
|
||||
case ARMISD::VLD1_UPD: {
|
||||
unsigned DOpcodes[] = { ARM::VLD1d8_UPD, ARM::VLD1d16_UPD,
|
||||
ARM::VLD1d32_UPD, ARM::VLD1d64_UPD };
|
||||
unsigned QOpcodes[] = { ARM::VLD1q8Pseudo_UPD, ARM::VLD1q16Pseudo_UPD,
|
||||
ARM::VLD1q32Pseudo_UPD, ARM::VLD1q64Pseudo_UPD };
|
||||
unsigned DOpcodes[] = { ARM::VLD1d8wb_fixed, ARM::VLD1d16wb_fixed,
|
||||
ARM::VLD1d32wb_fixed, ARM::VLD1d64wb_fixed };
|
||||
unsigned QOpcodes[] = { ARM::VLD1q8PseudoWB_fixed,
|
||||
ARM::VLD1q16PseudoWB_fixed,
|
||||
ARM::VLD1q32PseudoWB_fixed,
|
||||
ARM::VLD1q64PseudoWB_fixed };
|
||||
return SelectVLD(N, true, 1, DOpcodes, QOpcodes, 0);
|
||||
}
|
||||
|
||||
case ARMISD::VLD2_UPD: {
|
||||
unsigned DOpcodes[] = { ARM::VLD2d8Pseudo_UPD, ARM::VLD2d16Pseudo_UPD,
|
||||
ARM::VLD2d32Pseudo_UPD, ARM::VLD1q64Pseudo_UPD };
|
||||
ARM::VLD2d32Pseudo_UPD, ARM::VLD1q64PseudoWB_fixed};
|
||||
unsigned QOpcodes[] = { ARM::VLD2q8Pseudo_UPD, ARM::VLD2q16Pseudo_UPD,
|
||||
ARM::VLD2q32Pseudo_UPD };
|
||||
return SelectVLD(N, true, 2, DOpcodes, QOpcodes, 0);
|
||||
@ -2767,7 +2793,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
|
||||
|
||||
case ARMISD::VLD3_UPD: {
|
||||
unsigned DOpcodes[] = { ARM::VLD3d8Pseudo_UPD, ARM::VLD3d16Pseudo_UPD,
|
||||
ARM::VLD3d32Pseudo_UPD, ARM::VLD1d64TPseudo_UPD };
|
||||
ARM::VLD3d32Pseudo_UPD, ARM::VLD1q64PseudoWB_fixed};
|
||||
unsigned QOpcodes0[] = { ARM::VLD3q8Pseudo_UPD,
|
||||
ARM::VLD3q16Pseudo_UPD,
|
||||
ARM::VLD3q32Pseudo_UPD };
|
||||
@ -2779,7 +2805,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
|
||||
|
||||
case ARMISD::VLD4_UPD: {
|
||||
unsigned DOpcodes[] = { ARM::VLD4d8Pseudo_UPD, ARM::VLD4d16Pseudo_UPD,
|
||||
ARM::VLD4d32Pseudo_UPD, ARM::VLD1d64QPseudo_UPD };
|
||||
ARM::VLD4d32Pseudo_UPD, ARM::VLD1q64PseudoWB_fixed};
|
||||
unsigned QOpcodes0[] = { ARM::VLD4q8Pseudo_UPD,
|
||||
ARM::VLD4q16Pseudo_UPD,
|
||||
ARM::VLD4q32Pseudo_UPD };
|
||||
|
@ -259,6 +259,14 @@ class VLDQWBPseudo<InstrItinClass itin>
|
||||
: PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
|
||||
(ins addrmode6:$addr, am6offset:$offset), itin,
|
||||
"$addr.addr = $wb">;
|
||||
class VLDQWBfixedPseudo<InstrItinClass itin>
|
||||
: PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
|
||||
(ins addrmode6:$addr), itin,
|
||||
"$addr.addr = $wb">;
|
||||
class VLDQWBregisterPseudo<InstrItinClass itin>
|
||||
: PseudoNLdSt<(outs QPR:$dst, GPR:$wb),
|
||||
(ins addrmode6:$addr, rGPR:$offset), itin,
|
||||
"$addr.addr = $wb">;
|
||||
class VLDQQPseudo<InstrItinClass itin>
|
||||
: PseudoNLdSt<(outs QQPR:$dst), (ins addrmode6:$addr), itin, "">;
|
||||
class VLDQQWBPseudo<InstrItinClass itin>
|
||||
@ -309,37 +317,58 @@ def VLD1q32Pseudo : VLDQPseudo<IIC_VLD1x2>;
|
||||
def VLD1q64Pseudo : VLDQPseudo<IIC_VLD1x2>;
|
||||
|
||||
// ...with address register writeback:
|
||||
class VLD1DWB<bits<4> op7_4, string Dt>
|
||||
: NLdSt<0,0b10,0b0111,op7_4, (outs DPR:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD1u,
|
||||
"vld1", Dt, "\\{$Vd\\}, $Rn$Rm",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Inst{4} = Rn{4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
multiclass VLD1DWB<bits<4> op7_4, string Dt> {
|
||||
def _fixed : NLdSt<0,0b10, 0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn), IIC_VLD1u,
|
||||
"vld1", Dt, "$Vd, $Rn!",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
|
||||
let Inst{4} = Rn{4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
}
|
||||
def _register : NLdSt<0,0b10,0b0111,op7_4, (outs VecListOneD:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1u,
|
||||
"vld1", Dt, "$Vd, $Rn, $Rm",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Inst{4} = Rn{4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
}
|
||||
}
|
||||
class VLD1QWB<bits<4> op7_4, string Dt>
|
||||
: NLdSt<0,0b10,0b1010,op7_4, (outs VecListTwoD:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD1x2u,
|
||||
"vld1", Dt, "$Vd, $Rn$Rm",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Inst{5-4} = Rn{5-4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
multiclass VLD1QWB<bits<4> op7_4, string Dt> {
|
||||
def _fixed : NLdSt<0,0b10,0b1010,op7_4, (outs VecListTwoD:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn), IIC_VLD1x2u,
|
||||
"vld1", Dt, "$Vd, $Rn!",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Rm = 0b1101; // NLdSt will assign to the right encoding bits.
|
||||
let Inst{5-4} = Rn{5-4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
}
|
||||
def _register : NLdSt<0,0b10,0b1010,op7_4, (outs VecListTwoD:$Vd, GPR:$wb),
|
||||
(ins addrmode6:$Rn, rGPR:$Rm), IIC_VLD1x2u,
|
||||
"vld1", Dt, "$Vd, $Rn, $Rm",
|
||||
"$Rn.addr = $wb", []> {
|
||||
let Inst{5-4} = Rn{5-4};
|
||||
let DecoderMethod = "DecodeVLDInstruction";
|
||||
}
|
||||
}
|
||||
|
||||
def VLD1d8_UPD : VLD1DWB<{0,0,0,?}, "8">;
|
||||
def VLD1d16_UPD : VLD1DWB<{0,1,0,?}, "16">;
|
||||
def VLD1d32_UPD : VLD1DWB<{1,0,0,?}, "32">;
|
||||
def VLD1d64_UPD : VLD1DWB<{1,1,0,?}, "64">;
|
||||
defm VLD1d8wb : VLD1DWB<{0,0,0,?}, "8">;
|
||||
defm VLD1d16wb : VLD1DWB<{0,1,0,?}, "16">;
|
||||
defm VLD1d32wb : VLD1DWB<{1,0,0,?}, "32">;
|
||||
defm VLD1d64wb : VLD1DWB<{1,1,0,?}, "64">;
|
||||
defm VLD1q8wb : VLD1QWB<{0,0,?,?}, "8">;
|
||||
defm VLD1q16wb : VLD1QWB<{0,1,?,?}, "16">;
|
||||
defm VLD1q32wb : VLD1QWB<{1,0,?,?}, "32">;
|
||||
defm VLD1q64wb : VLD1QWB<{1,1,?,?}, "64">;
|
||||
|
||||
def VLD1q8_UPD : VLD1QWB<{0,0,?,?}, "8">;
|
||||
def VLD1q16_UPD : VLD1QWB<{0,1,?,?}, "16">;
|
||||
def VLD1q32_UPD : VLD1QWB<{1,0,?,?}, "32">;
|
||||
def VLD1q64_UPD : VLD1QWB<{1,1,?,?}, "64">;
|
||||
|
||||
def VLD1q8Pseudo_UPD : VLDQWBPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q16Pseudo_UPD : VLDQWBPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q32Pseudo_UPD : VLDQWBPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q64Pseudo_UPD : VLDQWBPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q8PseudoWB_fixed : VLDQWBfixedPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q16PseudoWB_fixed : VLDQWBfixedPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q32PseudoWB_fixed : VLDQWBfixedPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q64PseudoWB_fixed : VLDQWBfixedPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q8PseudoWB_register : VLDQWBregisterPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q16PseudoWB_register : VLDQWBregisterPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q32PseudoWB_register : VLDQWBregisterPseudo<IIC_VLD1x2u>;
|
||||
def VLD1q64PseudoWB_register : VLDQWBregisterPseudo<IIC_VLD1x2u>;
|
||||
|
||||
// ...with 3 registers
|
||||
class VLD1D3<bits<4> op7_4, string Dt>
|
||||
|
@ -2054,14 +2054,22 @@ static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||||
|
||||
// Writeback operand
|
||||
switch (Inst.getOpcode()) {
|
||||
case ARM::VLD1d8_UPD:
|
||||
case ARM::VLD1d16_UPD:
|
||||
case ARM::VLD1d32_UPD:
|
||||
case ARM::VLD1d64_UPD:
|
||||
case ARM::VLD1q8_UPD:
|
||||
case ARM::VLD1q16_UPD:
|
||||
case ARM::VLD1q32_UPD:
|
||||
case ARM::VLD1q64_UPD:
|
||||
case ARM::VLD1d8wb_fixed:
|
||||
case ARM::VLD1d16wb_fixed:
|
||||
case ARM::VLD1d32wb_fixed:
|
||||
case ARM::VLD1d64wb_fixed:
|
||||
case ARM::VLD1d8wb_register:
|
||||
case ARM::VLD1d16wb_register:
|
||||
case ARM::VLD1d32wb_register:
|
||||
case ARM::VLD1d64wb_register:
|
||||
case ARM::VLD1q8wb_fixed:
|
||||
case ARM::VLD1q16wb_fixed:
|
||||
case ARM::VLD1q32wb_fixed:
|
||||
case ARM::VLD1q64wb_fixed:
|
||||
case ARM::VLD1q8wb_register:
|
||||
case ARM::VLD1q16wb_register:
|
||||
case ARM::VLD1q32wb_register:
|
||||
case ARM::VLD1q64wb_register:
|
||||
case ARM::VLD1d8T_UPD:
|
||||
case ARM::VLD1d16T_UPD:
|
||||
case ARM::VLD1d32T_UPD:
|
||||
@ -2103,11 +2111,42 @@ static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||||
return MCDisassembler::Fail;
|
||||
|
||||
// AddrMode6 Offset (register)
|
||||
if (Rm == 0xD)
|
||||
Inst.addOperand(MCOperand::CreateReg(0));
|
||||
else if (Rm != 0xF) {
|
||||
if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
||||
switch (Inst.getOpcode()) {
|
||||
default:
|
||||
// The below have been updated to have explicit am6offset split
|
||||
// between fixed and register offset. For those instructions not
|
||||
// yet updated, we need to add an additional reg0 operand for the
|
||||
// fixed variant.
|
||||
//
|
||||
// The fixed offset encodes as Rm == 0xd, so we check for that.
|
||||
if (Rm == 0xd) {
|
||||
Inst.addOperand(MCOperand::CreateReg(0));
|
||||
break;
|
||||
}
|
||||
// Fall through to handle the register offset variant.
|
||||
case ARM::VLD1d8wb_fixed:
|
||||
case ARM::VLD1d16wb_fixed:
|
||||
case ARM::VLD1d32wb_fixed:
|
||||
case ARM::VLD1d64wb_fixed:
|
||||
case ARM::VLD1d8wb_register:
|
||||
case ARM::VLD1d16wb_register:
|
||||
case ARM::VLD1d32wb_register:
|
||||
case ARM::VLD1d64wb_register:
|
||||
case ARM::VLD1q8wb_fixed:
|
||||
case ARM::VLD1q16wb_fixed:
|
||||
case ARM::VLD1q32wb_fixed:
|
||||
case ARM::VLD1q64wb_fixed:
|
||||
case ARM::VLD1q8wb_register:
|
||||
case ARM::VLD1q16wb_register:
|
||||
case ARM::VLD1q32wb_register:
|
||||
case ARM::VLD1q64wb_register:
|
||||
// The fixed offset post-increment encodes Rm == 0xd. The no-writeback
|
||||
// variant encodes Rm == 0xf. Anything else is a register offset post-
|
||||
// increment and we need to add the register operand to the instruction.
|
||||
if (Rm != 0xD && Rm != 0xF &&
|
||||
!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
||||
return MCDisassembler::Fail;
|
||||
break;
|
||||
}
|
||||
|
||||
return S;
|
||||
|
Loading…
x
Reference in New Issue
Block a user