Skip to content

Commit dd053e6

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

File tree

3 files changed

+45
-56
lines changed

3 files changed

+45
-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: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,41 @@ 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+
const MCInstrDesc &MCID = D->MCII->get(Inst.getOpcode());
672+
unsigned InactiveOpIdx = Inst.getNumOperands();
673+
int TiedOpIdx = MCID.getOperandConstraint(InactiveOpIdx, MCOI::TIED_TO);
674+
assert(TiedOpIdx >= 0 &&
675+
"Inactive register in vpred_r is not tied to an output!");
676+
677+
// Copy the operand to ensure it's not invalidated when MI grows.
678+
Inst.addOperand(MCOperand(Inst.getOperand(TiedOpIdx))); // $inactive
679+
680+
return MCDisassembler::Success;
681+
}
682+
648683
static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
649684
uint64_t Address,
650685
const MCDisassembler *Decoder) {
@@ -2783,6 +2818,7 @@ static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
27832818

27842819
Inst.addOperand(MCOperand::createImm(imm));
27852820

2821+
Check(S, DecodeVpredROperand(Inst, Decoder));
27862822
return S;
27872823
}
27882824

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

2847+
Check(S, DecodeVpredROperand(Inst, Decoder));
28112848
return S;
28122849
}
28132850

@@ -5472,30 +5509,6 @@ static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
54725509
return S;
54735510
}
54745511

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-
54995512
static DecodeStatus
55005513
DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
55015514
const MCDisassembler *Decoder) {
@@ -5674,6 +5687,7 @@ DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
56745687
if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
56755688
return MCDisassembler::Fail;
56765689

5690+
Check(S, DecodeVpredNOperand(Inst, Decoder));
56775691
return S;
56785692
}
56795693

@@ -5877,7 +5891,7 @@ static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
58775891
return MCDisassembler::Fail;
58785892
if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
58795893
return MCDisassembler::Fail;
5880-
5894+
Check(S, DecodeVpredROperand(Inst, Decoder));
58815895
return S;
58825896
}
58835897

@@ -5912,6 +5926,7 @@ static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
59125926
if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
59135927
return MCDisassembler::Fail;
59145928

5929+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59155930
return S;
59165931
}
59175932

@@ -5922,6 +5937,7 @@ static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
59225937
unsigned Rn = fieldFromInstruction(Insn, 16, 4);
59235938
if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
59245939
return MCDisassembler::Fail;
5940+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59255941
return S;
59265942
}
59275943

@@ -5931,6 +5947,7 @@ static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
59315947
DecodeStatus S = MCDisassembler::Success;
59325948
Inst.addOperand(MCOperand::createReg(ARM::VPR));
59335949
Inst.addOperand(MCOperand::createReg(ARM::VPR));
5950+
Check(S, DecodeVpredNOperand(Inst, Decoder));
59345951
return S;
59355952
}
59365953

@@ -6205,15 +6222,13 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
62056222
(isVectorPredicable(MI) && ITBlock.instrInITBlock()))
62066223
S = SoftFail;
62076224

6208-
// If we're in an IT/VPT block, base the predicate on that. Otherwise,
6225+
// If we're in an IT block, base the predicate on that. Otherwise,
62096226
// assume a predicate of AL.
62106227
unsigned CC = ARMCC::AL;
6211-
unsigned VCC = ARMVCC::None;
62126228
if (ITBlock.instrInITBlock()) {
62136229
CC = ITBlock.getITCC();
62146230
ITBlock.advanceITState();
62156231
} else if (VPTBlock.instrInVPTBlock()) {
6216-
VCC = VPTBlock.getVPTPred();
62176232
VPTBlock.advanceVPTState();
62186233
}
62196234

@@ -6236,34 +6251,6 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
62366251
Check(S, SoftFail);
62376252
}
62386253

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-
62676254
return S;
62686255
}
62696256

0 commit comments

Comments
 (0)