@@ -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+
648683static 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-
54995512static DecodeStatus
55005513DecodeRestrictedIPredicateOperand (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