@@ -639,6 +639,43 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
639639 return MCDisassembler::Success;
640640}
641641
642+ static DecodeStatus DecodeVpredNOperand (MCInst &Inst,
643+ const MCDisassembler *Decoder) {
644+ const auto *D = static_cast <const ARMDisassembler *>(Decoder);
645+ unsigned VCC = D->VPTBlock .getVPTPred ();
646+ MCRegister CondReg = VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0;
647+
648+ Inst.addOperand (MCOperand::createImm (VCC)); // $cond
649+ Inst.addOperand (MCOperand::createReg (CondReg)); // $cond_reg
650+ Inst.addOperand (MCOperand::createReg (ARM::NoRegister)); // $tp_reg
651+
652+ return MCDisassembler::Success;
653+ }
654+
655+ static DecodeStatus DecodeVpredROperand (MCInst &Inst,
656+ const MCDisassembler *Decoder) {
657+ const auto *D = static_cast <const ARMDisassembler *>(Decoder);
658+ unsigned VCC = D->VPTBlock .getVPTPred ();
659+ MCRegister CondReg = VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0;
660+
661+ Inst.addOperand (MCOperand::createImm (VCC)); // $cond
662+ Inst.addOperand (MCOperand::createReg (CondReg)); // $cond_reg
663+ Inst.addOperand (MCOperand::createReg (ARM::NoRegister)); // $tp_reg
664+
665+ // The last sub-operand ($inactive) is tied to an output operand.
666+ // The output operand has already been decoded, so just copy it.
667+ const MCInstrDesc &MCID = D->MCII ->get (Inst.getOpcode ());
668+ unsigned InactiveOpIdx = Inst.getNumOperands ();
669+ int TiedOpIdx = MCID.getOperandConstraint (InactiveOpIdx, MCOI::TIED_TO);
670+ assert (TiedOpIdx >= 0 &&
671+ " Inactive register in vpred_r is not tied to an output!" );
672+
673+ // Make a copy of the operand to ensure it is not invalidated when MI grows.
674+ Inst.addOperand (MCOperand (Inst.getOperand (TiedOpIdx))); // $inactive
675+
676+ return MCDisassembler::Success;
677+ }
678+
642679static DecodeStatus DecodeSORegImmOperand (MCInst &Inst, unsigned Val,
643680 uint64_t Address,
644681 const MCDisassembler *Decoder) {
@@ -2777,6 +2814,7 @@ static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
27772814
27782815 Inst.addOperand (MCOperand::createImm (imm));
27792816
2817+ Check (S, DecodeVpredROperand (Inst, Decoder));
27802818 return S;
27812819}
27822820
@@ -2802,6 +2840,7 @@ static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
28022840 if (!fieldFromInstruction (Insn, 12 , 1 )) // I bit clear => need input FPSCR
28032841 Inst.addOperand (MCOperand::createReg (ARM::FPSCR_NZCV));
28042842
2843+ Check (S, DecodeVpredROperand (Inst, Decoder));
28052844 return S;
28062845}
28072846
@@ -5466,30 +5505,6 @@ static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
54665505 return S;
54675506}
54685507
5469- static DecodeStatus DecodeVpredROperand (MCInst &Inst, unsigned RegNo,
5470- uint64_t Address,
5471- const MCDisassembler *Decoder) {
5472- // The vpred_r operand type includes an MQPR register field derived
5473- // from the encoding. But we don't actually want to add an operand
5474- // to the MCInst at this stage, because AddThumbPredicate will do it
5475- // later, and will infer the register number from the TIED_TO
5476- // constraint. So this is a deliberately empty decoder method that
5477- // will inhibit the auto-generated disassembly code from adding an
5478- // operand at all.
5479- return MCDisassembler::Success;
5480- }
5481-
5482- [[maybe_unused]] static DecodeStatus
5483- DecodeVpredNOperand (MCInst &Inst, unsigned RegNo, uint64_t Address,
5484- const MCDisassembler *Decoder) {
5485- // Similar to above, we want to ensure that no operands are added for the
5486- // vpred operands. (This is marked "maybe_unused" for the moment; because
5487- // DecoderEmitter currently (wrongly) omits operands with no instruction bits,
5488- // the decoder doesn't actually call it yet. That will be addressed in a
5489- // future change.)
5490- return MCDisassembler::Success;
5491- }
5492-
54935508static DecodeStatus
54945509DecodeRestrictedIPredicateOperand (MCInst &Inst, unsigned Val, uint64_t Address,
54955510 const MCDisassembler *Decoder) {
@@ -5668,6 +5683,7 @@ DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
56685683 if (!Check (S, AddrDecoder (Inst, addr, Address, Decoder)))
56695684 return MCDisassembler::Fail;
56705685
5686+ Check (S, DecodeVpredNOperand (Inst, Decoder));
56715687 return S;
56725688}
56735689
@@ -5871,7 +5887,7 @@ static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
58715887 return MCDisassembler::Fail;
58725888 if (!Check (S, DecodeVCVTImmOperand (Inst, imm6, Address, Decoder)))
58735889 return MCDisassembler::Fail;
5874-
5890+ Check (S, DecodeVpredROperand (Inst, Decoder));
58755891 return S;
58765892}
58775893
@@ -5906,6 +5922,7 @@ static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
59065922 if (!Check (S, predicate_decoder (Inst, fc, Address, Decoder)))
59075923 return MCDisassembler::Fail;
59085924
5925+ Check (S, DecodeVpredNOperand (Inst, Decoder));
59095926 return S;
59105927}
59115928
@@ -5916,6 +5933,7 @@ static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
59165933 unsigned Rn = fieldFromInstruction (Insn, 16 , 4 );
59175934 if (!Check (S, DecoderGPRRegisterClass (Inst, Rn, Address, Decoder)))
59185935 return MCDisassembler::Fail;
5936+ Check (S, DecodeVpredNOperand (Inst, Decoder));
59195937 return S;
59205938}
59215939
@@ -5925,6 +5943,7 @@ static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
59255943 DecodeStatus S = MCDisassembler::Success;
59265944 Inst.addOperand (MCOperand::createReg (ARM::VPR));
59275945 Inst.addOperand (MCOperand::createReg (ARM::VPR));
5946+ Check (S, DecodeVpredNOperand (Inst, Decoder));
59285947 return S;
59295948}
59305949
@@ -6199,15 +6218,13 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
61996218 (isVectorPredicable (MI) && ITBlock.instrInITBlock ()))
62006219 S = SoftFail;
62016220
6202- // If we're in an IT/VPT block, base the predicate on that. Otherwise,
6221+ // If we're in an IT block, base the predicate on that. Otherwise,
62036222 // assume a predicate of AL.
62046223 unsigned CC = ARMCC::AL;
6205- unsigned VCC = ARMVCC::None;
62066224 if (ITBlock.instrInITBlock ()) {
62076225 CC = ITBlock.getITCC ();
62086226 ITBlock.advanceITState ();
62096227 } else if (VPTBlock.instrInVPTBlock ()) {
6210- VCC = VPTBlock.getVPTPred ();
62116228 VPTBlock.advanceVPTState ();
62126229 }
62136230
@@ -6230,34 +6247,6 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
62306247 Check (S, SoftFail);
62316248 }
62326249
6233- MCInst::iterator VCCI = MI.begin ();
6234- unsigned VCCPos;
6235- for (VCCPos = 0 ; VCCPos < MCID.NumOperands ; ++VCCPos, ++VCCI) {
6236- if (ARM::isVpred (MCID.operands ()[VCCPos].OperandType ) || VCCI == MI.end ())
6237- break ;
6238- }
6239-
6240- if (isVectorPredicable (MI)) {
6241- VCCI = MI.insert (VCCI, MCOperand::createImm (VCC));
6242- ++VCCI;
6243- if (VCC == ARMVCC::None)
6244- VCCI = MI.insert (VCCI, MCOperand::createReg (0 ));
6245- else
6246- VCCI = MI.insert (VCCI, MCOperand::createReg (ARM::P0));
6247- ++VCCI;
6248- VCCI = MI.insert (VCCI, MCOperand::createReg (0 ));
6249- ++VCCI;
6250- if (MCID.operands ()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
6251- int TiedOp = MCID.getOperandConstraint (VCCPos + 3 , MCOI::TIED_TO);
6252- assert (TiedOp >= 0 &&
6253- " Inactive register in vpred_r is not tied to an output!" );
6254- // Copy the operand to ensure it's not invalidated when MI grows.
6255- MI.insert (VCCI, MCOperand (MI.getOperand (TiedOp)));
6256- }
6257- } else if (VCC != ARMVCC::None) {
6258- Check (S, SoftFail);
6259- }
6260-
62616250 return S;
62626251}
62636252
0 commit comments