Skip to content

Commit b0f52cd

Browse files
committed
[ARM] Auto-decode vpred_n/vpred_r operands
Make the operands auto-decodable by adding `bits<0>` fields.
1 parent 492b609 commit b0f52cd

File tree

3 files changed

+47
-56
lines changed

3 files changed

+47
-56
lines changed

llvm/lib/Target/ARM/ARMInstrCDE.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ class CDE_Vec_Instr<bit acc, dag oops, dag iops, string asm, string cstr,
268268
!con(iops, (ins vpred:$vp)), asm,
269269
!strconcat(cstr, vpred.vpred_constraint)>,
270270
CDE_RequiresQReg {
271+
bits<0> vp;
271272
}
272273

273274

llvm/lib/Target/ARM/ARMInstrMVE.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ class MVE_p<dag oops, dag iops, InstrItinClass itin, string iname,
409409
!strconcat(iname, "${vp}",
410410
!if(!eq(suffix, ""), "", !strconcat(".", suffix))),
411411
ops, !strconcat(cstr, vpred.vpred_constraint), vecsize, pattern> {
412+
bits<0> vp;
412413
let Inst{31-29} = 0b111;
413414
let Inst{27-26} = 0b11;
414415
}

llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp

Lines changed: 45 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,43 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
645645
return MCDisassembler::Success;
646646
}
647647

648+
static DecodeStatus DecodeVpredNOperand(MCInst &Inst,
649+
const MCDisassembler *Decoder) {
650+
const auto *D = static_cast<const ARMDisassembler *>(Decoder);
651+
unsigned VCC = D->VPTBlock.getVPTPred();
652+
MCRegister CondReg = VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0;
653+
654+
Inst.addOperand(MCOperand::createImm(VCC)); // $cond
655+
Inst.addOperand(MCOperand::createReg(CondReg)); // $cond_reg
656+
Inst.addOperand(MCOperand::createReg(ARM::NoRegister)); // $tp_reg
657+
658+
return MCDisassembler::Success;
659+
}
660+
661+
static DecodeStatus DecodeVpredROperand(MCInst &Inst,
662+
const MCDisassembler *Decoder) {
663+
const auto *D = static_cast<const ARMDisassembler *>(Decoder);
664+
unsigned VCC = D->VPTBlock.getVPTPred();
665+
MCRegister CondReg = VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0;
666+
667+
Inst.addOperand(MCOperand::createImm(VCC)); // $cond
668+
Inst.addOperand(MCOperand::createReg(CondReg)); // $cond_reg
669+
Inst.addOperand(MCOperand::createReg(ARM::NoRegister)); // $tp_reg
670+
671+
// The last sub-operand ($inactive) is tied to an output operand.
672+
// The output operand has already been decoded, so just copy it.
673+
const MCInstrDesc &MCID = D->MCII->get(Inst.getOpcode());
674+
unsigned InactiveOpIdx = Inst.getNumOperands();
675+
int TiedOpIdx = MCID.getOperandConstraint(InactiveOpIdx, MCOI::TIED_TO);
676+
assert(TiedOpIdx >= 0 &&
677+
"Inactive register in vpred_r is not tied to an output!");
678+
679+
// Make a copy of the operand to ensure it is not invalidated when MI grows.
680+
Inst.addOperand(MCOperand(Inst.getOperand(TiedOpIdx))); // $inactive
681+
682+
return MCDisassembler::Success;
683+
}
684+
648685
static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
649686
uint64_t Address,
650687
const MCDisassembler *Decoder) {
@@ -2783,6 +2820,7 @@ static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
27832820

27842821
Inst.addOperand(MCOperand::createImm(imm));
27852822

2823+
Check(S, DecodeVpredROperand(Inst, Decoder));
27862824
return S;
27872825
}
27882826

@@ -2808,6 +2846,7 @@ static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
28082846
if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
28092847
Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
28102848

2849+
Check(S, DecodeVpredROperand(Inst, Decoder));
28112850
return S;
28122851
}
28132852

@@ -5472,30 +5511,6 @@ static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
54725511
return S;
54735512
}
54745513

5475-
static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
5476-
uint64_t Address,
5477-
const MCDisassembler *Decoder) {
5478-
// The vpred_r operand type includes an MQPR register field derived
5479-
// from the encoding. But we don't actually want to add an operand
5480-
// to the MCInst at this stage, because AddThumbPredicate will do it
5481-
// later, and will infer the register number from the TIED_TO
5482-
// constraint. So this is a deliberately empty decoder method that
5483-
// will inhibit the auto-generated disassembly code from adding an
5484-
// operand at all.
5485-
return MCDisassembler::Success;
5486-
}
5487-
5488-
[[maybe_unused]] static DecodeStatus
5489-
DecodeVpredNOperand(MCInst &Inst, unsigned RegNo, uint64_t Address,
5490-
const MCDisassembler *Decoder) {
5491-
// Similar to above, we want to ensure that no operands are added for the
5492-
// vpred operands. (This is marked "maybe_unused" for the moment; because
5493-
// DecoderEmitter currently (wrongly) omits operands with no instruction bits,
5494-
// the decoder doesn't actually call it yet. That will be addressed in a
5495-
// future change.)
5496-
return MCDisassembler::Success;
5497-
}
5498-
54995514
static DecodeStatus
55005515
DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
55015516
const MCDisassembler *Decoder) {
@@ -5674,6 +5689,7 @@ DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
56745689
if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
56755690
return MCDisassembler::Fail;
56765691

5692+
Check(S, DecodeVpredNOperand(Inst, Decoder));
56775693
return S;
56785694
}
56795695

@@ -5877,7 +5893,7 @@ static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
58775893
return MCDisassembler::Fail;
58785894
if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
58795895
return MCDisassembler::Fail;
5880-
5896+
Check(S, DecodeVpredROperand(Inst, Decoder));
58815897
return S;
58825898
}
58835899

@@ -5912,6 +5928,7 @@ static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
59125928
if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
59135929
return MCDisassembler::Fail;
59145930

5931+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59155932
return S;
59165933
}
59175934

@@ -5922,6 +5939,7 @@ static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
59225939
unsigned Rn = fieldFromInstruction(Insn, 16, 4);
59235940
if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59245941
return MCDisassembler::Fail;
5942+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59255943
return S;
59265944
}
59275945

@@ -5931,6 +5949,7 @@ static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
59315949
DecodeStatus S = MCDisassembler::Success;
59325950
Inst.addOperand(MCOperand::createReg(ARM::VPR));
59335951
Inst.addOperand(MCOperand::createReg(ARM::VPR));
5952+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59345953
return S;
59355954
}
59365955

@@ -6205,15 +6224,13 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
62056224
(isVectorPredicable(MI) && ITBlock.instrInITBlock()))
62066225
S = SoftFail;
62076226

6208-
// If we're in an IT/VPT block, base the predicate on that. Otherwise,
6227+
// If we're in an IT block, base the predicate on that. Otherwise,
62096228
// assume a predicate of AL.
62106229
unsigned CC = ARMCC::AL;
6211-
unsigned VCC = ARMVCC::None;
62126230
if (ITBlock.instrInITBlock()) {
62136231
CC = ITBlock.getITCC();
62146232
ITBlock.advanceITState();
62156233
} else if (VPTBlock.instrInVPTBlock()) {
6216-
VCC = VPTBlock.getVPTPred();
62176234
VPTBlock.advanceVPTState();
62186235
}
62196236

@@ -6236,34 +6253,6 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
62366253
Check(S, SoftFail);
62376254
}
62386255

6239-
MCInst::iterator VCCI = MI.begin();
6240-
unsigned VCCPos;
6241-
for (VCCPos = 0; VCCPos < MCID.NumOperands; ++VCCPos, ++VCCI) {
6242-
if (ARM::isVpred(MCID.operands()[VCCPos].OperandType) || VCCI == MI.end())
6243-
break;
6244-
}
6245-
6246-
if (isVectorPredicable(MI)) {
6247-
VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
6248-
++VCCI;
6249-
if (VCC == ARMVCC::None)
6250-
VCCI = MI.insert(VCCI, MCOperand::createReg(0));
6251-
else
6252-
VCCI = MI.insert(VCCI, MCOperand::createReg(ARM::P0));
6253-
++VCCI;
6254-
VCCI = MI.insert(VCCI, MCOperand::createReg(0));
6255-
++VCCI;
6256-
if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
6257-
int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
6258-
assert(TiedOp >= 0 &&
6259-
"Inactive register in vpred_r is not tied to an output!");
6260-
// Copy the operand to ensure it's not invalidated when MI grows.
6261-
MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
6262-
}
6263-
} else if (VCC != ARMVCC::None) {
6264-
Check(S, SoftFail);
6265-
}
6266-
62676256
return S;
62686257
}
62696258

0 commit comments

Comments
 (0)