@@ -639,6 +639,43 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
639
639
return MCDisassembler::Success;
640
640
}
641
641
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
+
642
679
static DecodeStatus DecodeSORegImmOperand (MCInst &Inst, unsigned Val,
643
680
uint64_t Address,
644
681
const MCDisassembler *Decoder) {
@@ -2777,6 +2814,7 @@ static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
2777
2814
2778
2815
Inst.addOperand (MCOperand::createImm (imm));
2779
2816
2817
+ Check (S, DecodeVpredROperand (Inst, Decoder));
2780
2818
return S;
2781
2819
}
2782
2820
@@ -2802,6 +2840,7 @@ static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
2802
2840
if (!fieldFromInstruction (Insn, 12 , 1 )) // I bit clear => need input FPSCR
2803
2841
Inst.addOperand (MCOperand::createReg (ARM::FPSCR_NZCV));
2804
2842
2843
+ Check (S, DecodeVpredROperand (Inst, Decoder));
2805
2844
return S;
2806
2845
}
2807
2846
@@ -5466,30 +5505,6 @@ static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
5466
5505
return S;
5467
5506
}
5468
5507
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
-
5493
5508
static DecodeStatus
5494
5509
DecodeRestrictedIPredicateOperand (MCInst &Inst, unsigned Val, uint64_t Address,
5495
5510
const MCDisassembler *Decoder) {
@@ -5668,6 +5683,7 @@ DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
5668
5683
if (!Check (S, AddrDecoder (Inst, addr, Address, Decoder)))
5669
5684
return MCDisassembler::Fail;
5670
5685
5686
+ Check (S, DecodeVpredNOperand (Inst, Decoder));
5671
5687
return S;
5672
5688
}
5673
5689
@@ -5871,7 +5887,7 @@ static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
5871
5887
return MCDisassembler::Fail;
5872
5888
if (!Check (S, DecodeVCVTImmOperand (Inst, imm6, Address, Decoder)))
5873
5889
return MCDisassembler::Fail;
5874
-
5890
+ Check (S, DecodeVpredROperand (Inst, Decoder));
5875
5891
return S;
5876
5892
}
5877
5893
@@ -5906,6 +5922,7 @@ static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
5906
5922
if (!Check (S, predicate_decoder (Inst, fc, Address, Decoder)))
5907
5923
return MCDisassembler::Fail;
5908
5924
5925
+ Check (S, DecodeVpredNOperand (Inst, Decoder));
5909
5926
return S;
5910
5927
}
5911
5928
@@ -5916,6 +5933,7 @@ static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
5916
5933
unsigned Rn = fieldFromInstruction (Insn, 16 , 4 );
5917
5934
if (!Check (S, DecoderGPRRegisterClass (Inst, Rn, Address, Decoder)))
5918
5935
return MCDisassembler::Fail;
5936
+ Check (S, DecodeVpredNOperand (Inst, Decoder));
5919
5937
return S;
5920
5938
}
5921
5939
@@ -5925,6 +5943,7 @@ static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
5925
5943
DecodeStatus S = MCDisassembler::Success;
5926
5944
Inst.addOperand (MCOperand::createReg (ARM::VPR));
5927
5945
Inst.addOperand (MCOperand::createReg (ARM::VPR));
5946
+ Check (S, DecodeVpredNOperand (Inst, Decoder));
5928
5947
return S;
5929
5948
}
5930
5949
@@ -6199,15 +6218,13 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
6199
6218
(isVectorPredicable (MI) && ITBlock.instrInITBlock ()))
6200
6219
S = SoftFail;
6201
6220
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,
6203
6222
// assume a predicate of AL.
6204
6223
unsigned CC = ARMCC::AL;
6205
- unsigned VCC = ARMVCC::None;
6206
6224
if (ITBlock.instrInITBlock ()) {
6207
6225
CC = ITBlock.getITCC ();
6208
6226
ITBlock.advanceITState ();
6209
6227
} else if (VPTBlock.instrInVPTBlock ()) {
6210
- VCC = VPTBlock.getVPTPred ();
6211
6228
VPTBlock.advanceVPTState ();
6212
6229
}
6213
6230
@@ -6230,34 +6247,6 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
6230
6247
Check (S, SoftFail);
6231
6248
}
6232
6249
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
-
6261
6250
return S;
6262
6251
}
6263
6252
0 commit comments