@@ -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+
648685static 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-
54995514static DecodeStatus
55005515DecodeRestrictedIPredicateOperand (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