https://github.com/s-barannikov updated 
https://github.com/llvm/llvm-project/pull/156540

>From 8e6e8dd7ff743523e55c7d3bb60c0f521980d6d0 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <baranniko...@gmail.com>
Date: Tue, 2 Sep 2025 10:26:16 +0300
Subject: [PATCH] [ARM] Remove most post-decoding instruction adjustments

---
 llvm/lib/Target/ARM/ARMInstrCDE.td            |   4 +
 llvm/lib/Target/ARM/ARMInstrFormats.td        |   9 +-
 llvm/lib/Target/ARM/ARMInstrMVE.td            |   1 +
 llvm/lib/Target/ARM/ARMInstrThumb.td          |  10 +
 llvm/lib/Target/ARM/ARMInstrThumb2.td         |  23 +-
 llvm/lib/Target/ARM/CMakeLists.txt            |   3 +-
 .../ARM/Disassembler/ARMDisassembler.cpp      | 370 +++++++++++-------
 llvm/test/MC/Disassembler/ARM/arm-tests.txt   |   2 +-
 8 files changed, 269 insertions(+), 153 deletions(-)

diff --git a/llvm/lib/Target/ARM/ARMInstrCDE.td 
b/llvm/lib/Target/ARM/ARMInstrCDE.td
index 54e27a6be5583..5d4e3acf5b581 100644
--- a/llvm/lib/Target/ARM/ARMInstrCDE.td
+++ b/llvm/lib/Target/ARM/ARMInstrCDE.td
@@ -115,6 +115,7 @@ class CDE_CX1_Instr<string iname, CX_Params params>
                   !con(params.Iops1, (ins imm_13b:$imm), params.PredOp),
                   !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $imm"),
                   params.Cstr> {
+  bits<0> p;
   bits<13> imm;
   bits<4> Rd;
 
@@ -131,6 +132,7 @@ class CDE_CX2_Instr<string iname, CX_Params params>
                   !con(params.Iops2, (ins imm_9b:$imm), params.PredOp),
                   !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $imm"),
                   params.Cstr> {
+  bits<0> p;
   bits<9> imm;
   bits<4> Rd;
   bits<4> Rn;
@@ -149,6 +151,7 @@ class CDE_CX3_Instr<string iname, CX_Params params>
                   !con(params.Iops3, (ins imm_6b:$imm), params.PredOp),
                   !strconcat(iname, params.PAsm, "\t$coproc, $Rd, $Rn, $Rm, 
$imm"),
                   params.Cstr> {
+  bits<0> p;
   bits<6> imm;
   bits<4> Rd;
   bits<4> Rn;
@@ -268,6 +271,7 @@ class CDE_Vec_Instr<bit acc, dag oops, dag iops, string 
asm, string cstr,
                      !con(iops, (ins vpred:$vp)), asm,
                      !strconcat(cstr, vpred.vpred_constraint)>,
     CDE_RequiresQReg {
+  bits<0> vp;
 }
 
 
diff --git a/llvm/lib/Target/ARM/ARMInstrFormats.td 
b/llvm/lib/Target/ARM/ARMInstrFormats.td
index e50740f7d57c5..dc815e1124fa5 100644
--- a/llvm/lib/Target/ARM/ARMInstrFormats.td
+++ b/llvm/lib/Target/ARM/ARMInstrFormats.td
@@ -1219,6 +1219,8 @@ class Thumb1sI<dag oops, dag iops, AddrMode am, int sz,
                InstrItinClass itin,
                string opc, string asm, string cstr, list<dag> pattern>
   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+  bits<0> s;
+  bits<0> p;
   let OutOperandList = !con(oops, (outs s_cc_out:$s));
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${s}${p}", asm);
@@ -1243,6 +1245,7 @@ class Thumb1pI<dag oops, dag iops, AddrMode am, int sz,
                InstrItinClass itin,
                string opc, string asm, string cstr, list<dag> pattern>
   : InstThumb<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+  bits<0> p;
   let OutOperandList = oops;
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${p}", asm);
@@ -1341,7 +1344,8 @@ class T1Misc<bits<7> opcode> : Encoding16 {
 class Thumb2I<dag oops, dag iops, AddrMode am, int sz,
               InstrItinClass itin,
               string opc, string asm, string cstr, list<dag> pattern>
-  : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+    : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+  bits<0> p;
   let OutOperandList = oops;
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${p}", asm);
@@ -1360,6 +1364,7 @@ class Thumb2sI<dag oops, dag iops, AddrMode am, int sz,
                InstrItinClass itin,
                string opc, string asm, string cstr, list<dag> pattern>
   : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+  bits<0> p;
   bits<1> s; // condition-code set flag ('1' if the insn should set the flags)
   let Inst{20} = s;
 
@@ -2220,6 +2225,7 @@ class NeonI<dag oops, dag iops, AddrMode am, IndexMode 
im, Format f,
             InstrItinClass itin, string opc, string dt, string asm, string 
cstr,
             list<dag> pattern>
   : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
+  bits<0> p;
   let OutOperandList = oops;
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${p}", ".", dt, "\t", asm);
@@ -2233,6 +2239,7 @@ class NeonXI<dag oops, dag iops, AddrMode am, IndexMode 
im, Format f,
              InstrItinClass itin, string opc, string asm, string cstr,
              list<dag> pattern>
   : InstARM<am, 4, im, f, NeonDomain, cstr, itin> {
+  bits<0> p;
   let OutOperandList = oops;
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${p}", "\t", asm);
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td 
b/llvm/lib/Target/ARM/ARMInstrMVE.td
index 9dffd945d5baa..e24413465799f 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -409,6 +409,7 @@ class MVE_p<dag oops, dag iops, InstrItinClass itin, string 
iname,
            !strconcat(iname, "${vp}",
                       !if(!eq(suffix, ""), "", !strconcat(".", suffix))),
            ops, !strconcat(cstr, vpred.vpred_constraint), vecsize, pattern> {
+  bits<0> vp;
   let Inst{31-29} = 0b111;
   let Inst{27-26} = 0b11;
 }
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td 
b/llvm/lib/Target/ARM/ARMInstrThumb.td
index 0c5ea3e0fa8d5..bc1b34c691e39 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -483,6 +483,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, 
isIndirectBranch = 1 in {
   def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>,
             T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
     // A6.2.3 & A8.6.25
+    bits<0> p;
     bits<4> Rm;
     let Inst{6-3} = Rm;
     let Inst{2-0} = 0b000;
@@ -491,6 +492,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, 
isIndirectBranch = 1 in {
   def tBXNS : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bxns${p}\t$Rm", []>,
               Requires<[IsThumb, Has8MSecExt]>,
               T1Special<{1,1,0,?}>, Sched<[WriteBr]> {
+    bits<0> p;
     bits<4> Rm;
     let Inst{6-3} = Rm;
     let Inst{2-0} = 0b100;
@@ -523,6 +525,7 @@ let isCall = 1,
                   "bl${p}\t$func",
                   [(ARMcall tglobaladdr:$func)]>,
              Requires<[IsThumb]>, Sched<[WriteBrL]> {
+    bits<0> p;
     bits<24> func;
     let Inst{26} = func{23};
     let Inst{25-16} = func{20-11};
@@ -536,6 +539,7 @@ let isCall = 1,
                  (outs), (ins pred:$p, thumb_blx_target:$func), IIC_Br,
                    "blx${p}\t$func", []>,
               Requires<[IsThumb, HasV5T, IsNotMClass]>, Sched<[WriteBrL]> {
+    bits<0> p;
     bits<24> func;
     let Inst{26} = func{23};
     let Inst{25-16} = func{20-11};
@@ -550,6 +554,7 @@ let isCall = 1,
                   "blx${p}\t$func", []>,
               Requires<[IsThumb, HasV5T]>,
               T1Special<{1,1,1,?}>, Sched<[WriteBrL]> { // A6.2.3 & A8.6.24;
+    bits<0> p;
     bits<4> func;
     let Inst{6-3} = func;
     let Inst{2-0} = 0b000;
@@ -565,6 +570,7 @@ let isCall = 1,
                    "blxns${p}\t$func", []>,
                 Requires<[IsThumb, Has8MSecExt]>,
                 T1Special<{1,1,1,?}>, Sched<[WriteBrL]> {
+    bits<0> p;
     bits<4> func;
     let Inst{6-3} = func;
     let Inst{2-0} = 0b100;
@@ -824,6 +830,7 @@ let hasSideEffects = 0 in {
 let mayLoad = 1, hasExtraDefRegAllocReq = 1, variadicOpsAreDefs = 1 in
 def tLDMIA : T1I<(outs), (ins tGPR:$Rn, pred:$p, reglist:$regs, variable_ops),
         IIC_iLoad_m, "ldm${p}\t$Rn, $regs", []>, T1Encoding<{1,1,0,0,1,?}> {
+  bits<0> p;
   bits<3> Rn;
   bits<8> regs;
   let Inst{10-8} = Rn;
@@ -854,6 +861,7 @@ def tSTMIA_UPD : Thumb1I<(outs tGPR:$wb),
                          AddrModeNone, 2, IIC_iStore_mu,
                          "stm${p}\t$Rn!, $regs", "$Rn = $wb", []>,
                      T1Encoding<{1,1,0,0,0,?}> {
+  bits<0> p;
   bits<3> Rn;
   bits<8> regs;
   let Inst{10-8} = Rn;
@@ -872,6 +880,7 @@ def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, 
variable_ops),
                IIC_iPop,
                "pop${p}\t$regs", []>,
            T1Misc<{1,1,0,?,?,?,?}>, Sched<[WriteLd]> {
+  bits<0> p;
   bits<16> regs;
   let Inst{8}   = regs{15};
   let Inst{7-0} = regs{7-0};
@@ -882,6 +891,7 @@ def tPUSH : T1I<(outs), (ins pred:$p, reglist:$regs, 
variable_ops),
                 IIC_iStore_m,
                 "push${p}\t$regs", []>,
             T1Misc<{0,1,0,?,?,?,?}>, Sched<[WriteST]> {
+  bits<0> p;
   bits<16> regs;
   let Inst{8}   = regs{14};
   let Inst{7-0} = regs{7-0};
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td 
b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index c00d616670b5a..b5485c5973e02 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -2059,6 +2059,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
   def IA :
     T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2074,6 +2075,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
   def IA_UPD :
     T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
           itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2089,6 +2091,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
   def DB :
     T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2104,6 +2107,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
   def DB_UPD :
     T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
           itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2128,6 +2132,7 @@ multiclass thumb2_st_mult<string asm, InstrItinClass itin,
   def IA :
     T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2146,6 +2151,7 @@ multiclass thumb2_st_mult<string asm, InstrItinClass itin,
   def IA_UPD :
     T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
           itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2164,6 +2170,7 @@ multiclass thumb2_st_mult<string asm, InstrItinClass itin,
   def DB :
     T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
          itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -2182,6 +2189,7 @@ multiclass thumb2_st_mult<string asm, InstrItinClass itin,
   def DB_UPD :
     T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
           itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
+    bits<0>  p;
     bits<4>  Rn;
     bits<16> regs;
 
@@ -4030,9 +4038,11 @@ def t2TBH : T2I<(outs), (ins (addrmode_tbh $Rn, 
$Rm):$addr), IIC_Br,
 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
 // a two-value operand where a dag node expects ", "two operands. :(
 let isBranch = 1, isTerminator = 1 in
-def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
-                "b", ".w\t$target",
-                [/*(ARMbrcond bb:$target, imm:$cc)*/]>, Sched<[WriteBr]> {
+def t2Bcc : Thumb2XI<(outs), (ins brtarget:$target, pred:$p),
+                     AddrModeNone, 4, IIC_Br,
+                     "b${p}.w\t$target", "",
+                     [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
+            Sched<[WriteBr]> {
   let Inst{31-27} = 0b11110;
   let Inst{15-14} = 0b10;
   let Inst{12} = 0;
@@ -5488,6 +5498,7 @@ class V8_1MI<dag oops, dag iops, AddrMode am, 
InstrItinClass itin, string asm,
 def t2CLRM : V8_1MI<(outs),
                     (ins pred:$p, reglist_with_apsr:$regs, variable_ops),
                     AddrModeNone, NoItinerary, "clrm${p}", "$regs", "", []> {
+  bits<0> p;
   bits<16> regs;
 
   let Inst{31-16} = 0b1110100010011111;
@@ -5516,6 +5527,7 @@ def t2BF_LabelPseudo
 
 def t2BFi : t2BF<(ins bflabel_u4:$b_label, bflabel_s16:$label, pred:$p),
                  !strconcat("bf", "${p}"), "$b_label, $label"> {
+  bits<0> p;
   bits<4> b_label;
   bits<16> label;
 
@@ -5547,6 +5559,7 @@ def t2BFic : t2BF<(ins bflabel_u4:$b_label, 
bflabel_s12:$label,
 
 def t2BFr : t2BF<(ins bflabel_u4:$b_label, rGPR:$Rn, pred:$p),
                  !strconcat("bfx", "${p}"), "$b_label, $Rn"> {
+  bits<0> p;
   bits<4> b_label;
   bits<4> Rn;
 
@@ -5558,6 +5571,7 @@ def t2BFr : t2BF<(ins bflabel_u4:$b_label, rGPR:$Rn, 
pred:$p),
 
 def t2BFLi : t2BF<(ins bflabel_u4:$b_label, bflabel_s18:$label, pred:$p),
                   !strconcat("bfl", "${p}"), "$b_label, $label"> {
+  bits<0> p;
   bits<4> b_label;
   bits<18> label;
 
@@ -5570,6 +5584,7 @@ def t2BFLi : t2BF<(ins bflabel_u4:$b_label, 
bflabel_s18:$label, pred:$p),
 
 def t2BFLr : t2BF<(ins bflabel_u4:$b_label, rGPR:$Rn, pred:$p),
                   !strconcat("bflx", "${p}"), "$b_label, $Rn"> {
+  bits<0> p;
   bits<4> b_label;
   bits<4> Rn;
 
@@ -5810,6 +5825,7 @@ let Predicates = [IsThumb2, HasV8_1MMainline, HasPACBTI] 
in {
 def t2PACG : V8_1MI<(outs rGPR:$Rd),
                     (ins pred:$p, GPRnopc:$Rn, GPRnopc:$Rm),
                     AddrModeNone, NoItinerary, "pacg${p}", "$Rd, $Rn, $Rm", 
"", []> {
+  bits<0> p;
   bits<4> Rd;
   bits<4> Rn;
   bits<4> Rm;
@@ -5825,6 +5841,7 @@ let hasSideEffects = 1 in {
 class PACBTIAut<dag iops, string asm, bit b>
   : V8_1MI<(outs), iops,
            AddrModeNone, NoItinerary, asm, "$Ra, $Rn, $Rm", "", []> {
+  bits<0> p;
   bits<4> Ra;
   bits<4> Rn;
   bits<4> Rm;
diff --git a/llvm/lib/Target/ARM/CMakeLists.txt 
b/llvm/lib/Target/ARM/CMakeLists.txt
index fa778cad4af8e..a39629bd8aeb0 100644
--- a/llvm/lib/Target/ARM/CMakeLists.txt
+++ b/llvm/lib/Target/ARM/CMakeLists.txt
@@ -6,8 +6,7 @@ tablegen(LLVM ARMGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM ARMGenAsmWriter.inc -gen-asm-writer)
 tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv)
 tablegen(LLVM ARMGenDAGISel.inc -gen-dag-isel)
-tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler
-              -ignore-non-decodable-operands)
+tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM ARMGenFastISel.inc -gen-fast-isel)
 tablegen(LLVM ARMGenGlobalISel.inc -gen-global-isel)
 tablegen(LLVM ARMGenInstrInfo.inc -gen-instr-info)
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp 
b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 4052593008027..df2afec29ede7 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -119,6 +119,8 @@ class VPTStatus {
 class ARMDisassembler : public MCDisassembler {
 public:
   std::unique_ptr<const MCInstrInfo> MCII;
+  mutable ITStatus ITBlock;
+  mutable VPTStatus VPTBlock;
 
   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
                   const MCInstrInfo *MCII)
@@ -146,10 +148,6 @@ class ARMDisassembler : public MCDisassembler {
                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
                                    raw_ostream &CStream) const;
 
-  mutable ITStatus ITBlock;
-  mutable VPTStatus VPTBlock;
-
-  void AddThumb1SBit(MCInst &MI, bool InITBlock) const;
   bool isVectorPredicable(const MCInst &MI) const;
   DecodeStatus AddThumbPredicate(MCInst&) const;
   void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
@@ -250,9 +248,13 @@ DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned 
RegNo, uint64_t Address,
 static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
                                            uint64_t Address,
                                            const MCDisassembler *Decoder);
+static DecodeStatus DecodePredicateOperand(MCInst &Inst,
+                                           const MCDisassembler *Decoder);
 static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder);
+static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
+                                       const MCDisassembler *Decoder);
 static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);
@@ -620,11 +622,9 @@ static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned 
Insn, uint64_t Address,
 static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
                                          uint64_t Address,
                                          const MCDisassembler *Decoder);
-static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
-                                        uint64_t Address,
+static DecodeStatus DecodeVpredROperand(MCInst &Inst,
                                         const MCDisassembler *Decoder);
-static DecodeStatus DecodeVpredNOperand(MCInst &Inst, unsigned Val,
-                                        uint64_t Address,
+static DecodeStatus DecodeVpredNOperand(MCInst &Inst,
                                         const MCDisassembler *Decoder);
 static DecodeStatus
 DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
@@ -800,9 +800,21 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, 
uint64_t &Size,
                                              ArrayRef<uint8_t> Bytes,
                                              uint64_t Address,
                                              raw_ostream &CS) const {
+  DecodeStatus S;
   if (STI.hasFeature(ARM::ModeThumb))
-    return getThumbInstruction(MI, Size, Bytes, Address, CS);
-  return getARMInstruction(MI, Size, Bytes, Address, CS);
+    S = getThumbInstruction(MI, Size, Bytes, Address, CS);
+  else
+    S = getARMInstruction(MI, Size, Bytes, Address, CS);
+  if (S != DecodeStatus::Fail) {
+    const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
+    if (!MCID.isVariadic() && MI.getNumOperands() != MCID.getNumOperands()) {
+      reportFatalInternalError(MCII->getName(MI.getOpcode()) + ": expected " +
+                               Twine(MCID.getNumOperands()) +
+                               " operands, got " + Twine(MI.getNumOperands()) +
+                               "\n");
+    }
+  }
+  return S;
 }
 
 DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
@@ -833,26 +845,17 @@ DecodeStatus ARMDisassembler::getARMInstruction(MCInst 
&MI, uint64_t &Size,
     return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
   }
 
-  struct DecodeTable {
-    const uint8_t *P;
-    bool DecodePred;
+  const uint8_t *Tables[] = {
+      DecoderTableVFP32,      DecoderTableVFPV832,
+      DecoderTableNEONData32, DecoderTableNEONLoadStore32,
+      DecoderTableNEONDup32,  DecoderTablev8NEON32,
+      DecoderTablev8Crypto32,
   };
 
-  const DecodeTable Tables[] = {
-      {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
-      {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
-      {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
-      {DecoderTablev8Crypto32, false},
-  };
-
-  for (auto Table : Tables) {
-    Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
+  for (const uint8_t *Table : Tables) {
+    Result = decodeInstruction(Table, MI, Insn, Address, this, STI);
     if (Result != MCDisassembler::Fail) {
       Size = 4;
-      // Add a fake predicate operand, because we share these instruction
-      // definitions with Thumb2 where these instructions are predicable.
-      if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
-        return MCDisassembler::Fail;
       return Result;
     }
   }
@@ -868,28 +871,6 @@ DecodeStatus ARMDisassembler::getARMInstruction(MCInst 
&MI, uint64_t &Size,
   return MCDisassembler::Fail;
 }
 
-// Thumb1 instructions don't have explicit S bits.  Rather, they
-// implicitly set CPSR.  Since it's not represented in the encoding, the
-// auto-generated decoder won't inject the CPSR operand.  We need to fix
-// that as a post-pass.
-void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
-  const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
-  MCInst::iterator I = MI.begin();
-  for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
-    if (I == MI.end()) break;
-    if (MCID.operands()[i].isOptionalDef() &&
-        MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
-      if (i > 0 && MCID.operands()[i - 1].isPredicate())
-        continue;
-      MI.insert(I,
-                MCOperand::createReg(InITBlock ? ARM::NoRegister : ARM::CPSR));
-      return;
-    }
-  }
-
-  MI.insert(I, MCOperand::createReg(InITBlock ? ARM::NoRegister : ARM::CPSR));
-}
-
 bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
   for (unsigned i = 0; i < MCID.NumOperands; ++i) {
@@ -956,64 +937,10 @@ ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
       (isVectorPredicable(MI) && ITBlock.instrInITBlock()))
     S = SoftFail;
 
-  // If we're in an IT/VPT block, base the predicate on that.  Otherwise,
-  // assume a predicate of AL.
-  unsigned CC = ARMCC::AL;
-  unsigned VCC = ARMVCC::None;
-  if (ITBlock.instrInITBlock()) {
-    CC = ITBlock.getITCC();
+  if (ITBlock.instrInITBlock())
     ITBlock.advanceITState();
-  } else if (VPTBlock.instrInVPTBlock()) {
-    VCC = VPTBlock.getVPTPred();
+  else if (VPTBlock.instrInVPTBlock())
     VPTBlock.advanceVPTState();
-  }
-
-  const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
-
-  MCInst::iterator CCI = MI.begin();
-  for (unsigned i = 0; i < MCID.NumOperands; ++i, ++CCI) {
-    if (MCID.operands()[i].isPredicate() || CCI == MI.end())
-      break;
-  }
-
-  if (MCID.isPredicable()) {
-    CCI = MI.insert(CCI, MCOperand::createImm(CC));
-    ++CCI;
-    if (CC == ARMCC::AL)
-      MI.insert(CCI, MCOperand::createReg(ARM::NoRegister));
-    else
-      MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
-  } else if (CC != ARMCC::AL) {
-    Check(S, SoftFail);
-  }
-
-  MCInst::iterator VCCI = MI.begin();
-  unsigned VCCPos;
-  for (VCCPos = 0; VCCPos < MCID.NumOperands; ++VCCPos, ++VCCI) {
-    if (ARM::isVpred(MCID.operands()[VCCPos].OperandType) || VCCI == MI.end())
-      break;
-  }
-
-  if (isVectorPredicable(MI)) {
-    VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
-    ++VCCI;
-    if (VCC == ARMVCC::None)
-      VCCI = MI.insert(VCCI, MCOperand::createReg(0));
-    else
-      VCCI = MI.insert(VCCI, MCOperand::createReg(ARM::P0));
-    ++VCCI;
-    VCCI = MI.insert(VCCI, MCOperand::createReg(0));
-    ++VCCI;
-    if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
-      int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
-      assert(TiedOp >= 0 &&
-             "Inactive register in vpred_r is not tied to an output!");
-      // Copy the operand to ensure it's not invalidated when MI grows.
-      MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
-    }
-  } else if (VCC != ARMVCC::None) {
-    Check(S, SoftFail);
-  }
 
   return S;
 }
@@ -1392,6 +1319,33 @@ static DecodeStatus DecodePredicateOperand(MCInst &Inst, 
unsigned Val,
   return S;
 }
 
+static DecodeStatus DecodePredicateOperand(MCInst &Inst,
+                                           const MCDisassembler *Decoder) {
+  const auto *D = static_cast<const ARMDisassembler *>(Decoder);
+
+  if (!D->getSubtargetInfo().hasFeature(ARM::ModeThumb)) {
+    // Add a fake predicate operand, because we share these instruction
+    // definitions with Thumb2 where these instructions are predicable.
+    Inst.addOperand(MCOperand::createImm(ARMCC::AL));
+    Inst.addOperand(MCOperand::createReg(ARM::NoRegister));
+    return MCDisassembler::Success;
+  }
+
+  ARMCC::CondCodes CC = ARMCC::AL;
+  if (D->ITBlock.instrInITBlock())
+    CC = static_cast<ARMCC::CondCodes>(D->ITBlock.getITCC());
+
+  Inst.addOperand(MCOperand::createImm(CC));
+  Inst.addOperand(
+      MCOperand::createReg(CC == ARMCC::AL ? ARM::NoRegister : ARM::CPSR));
+
+  const MCInstrDesc &MCID = D->MCII->get(Inst.getOpcode());
+  if (CC != ARMCC::AL && !MCID.isPredicable())
+    return MCDisassembler::SoftFail;
+
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
                                        uint64_t Address,
                                        const MCDisassembler *Decoder) {
@@ -1402,6 +1356,14 @@ static DecodeStatus DecodeCCOutOperand(MCInst &Inst, 
unsigned Val,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeCCOutOperand(MCInst &Inst,
+                                       const MCDisassembler *Decoder) {
+  const auto *D = static_cast<const ARMDisassembler *>(Decoder);
+  Inst.addOperand(MCOperand::createReg(
+      D->ITBlock.instrInITBlock() ? ARM::NoRegister : ARM::CPSR));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
                                           uint64_t Address,
                                           const MCDisassembler *Decoder) {
@@ -1776,7 +1738,59 @@ static DecodeStatus DecodeCopMemInstruction(MCInst 
&Inst, unsigned Insn,
       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
         return MCDisassembler::Fail;
       break;
+    case ARM::t2LDC2L_OFFSET:
+    case ARM::t2LDC2L_OPTION:
+    case ARM::t2LDC2L_POST:
+    case ARM::t2LDC2L_PRE:
+    case ARM::t2LDC2_OFFSET:
+    case ARM::t2LDC2_OPTION:
+    case ARM::t2LDC2_POST:
+    case ARM::t2LDC2_PRE:
+    case ARM::t2LDCL_OFFSET:
+    case ARM::t2LDCL_OPTION:
+    case ARM::t2LDCL_POST:
+    case ARM::t2LDCL_PRE:
+    case ARM::t2LDC_OFFSET:
+    case ARM::t2LDC_OPTION:
+    case ARM::t2LDC_POST:
+    case ARM::t2LDC_PRE:
+    case ARM::t2STC2L_OFFSET:
+    case ARM::t2STC2L_OPTION:
+    case ARM::t2STC2L_POST:
+    case ARM::t2STC2L_PRE:
+    case ARM::t2STC2_OFFSET:
+    case ARM::t2STC2_OPTION:
+    case ARM::t2STC2_POST:
+    case ARM::t2STC2_PRE:
+    case ARM::t2STCL_OFFSET:
+    case ARM::t2STCL_OPTION:
+    case ARM::t2STCL_POST:
+    case ARM::t2STCL_PRE:
+    case ARM::t2STC_OFFSET:
+    case ARM::t2STC_OPTION:
+    case ARM::t2STC_POST:
+    case ARM::t2STC_PRE:
+      DecodePredicateOperand(Inst, Decoder);
+      break;
+    case ARM::LDC2L_OFFSET:
+    case ARM::LDC2L_OPTION:
+    case ARM::LDC2L_POST:
+    case ARM::LDC2L_PRE:
+    case ARM::LDC2_OFFSET:
+    case ARM::LDC2_OPTION:
+    case ARM::LDC2_POST:
+    case ARM::LDC2_PRE:
+    case ARM::STC2L_OFFSET:
+    case ARM::STC2L_OPTION:
+    case ARM::STC2L_POST:
+    case ARM::STC2L_PRE:
+    case ARM::STC2_OFFSET:
+    case ARM::STC2_OPTION:
+    case ARM::STC2_POST:
+    case ARM::STC2_PRE:
+      break;
     default:
+      llvm_unreachable("Unexpected opcode");
       break;
   }
 
@@ -1943,6 +1957,8 @@ static DecodeStatus DecodeTSBInstruction(MCInst &Inst, 
unsigned Insn,
   // the only available operand), but LLVM expects the instruction to have one
   // operand, so we need to add the csync when decoding.
   Inst.addOperand(MCOperand::createImm(ARM_TSB::CSYNC));
+  if (Inst.getOpcode() == ARM::t2TSB)
+    DecodePredicateOperand(Inst, Decoder);
   return MCDisassembler::Success;
 }
 
@@ -2144,24 +2160,6 @@ static DecodeStatus DecodeRFEInstruction(MCInst &Inst, 
unsigned Insn,
   DecodeStatus S = MCDisassembler::Success;
 
   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
-  unsigned mode = fieldFromInstruction(Insn, 23, 2);
-
-  switch (mode) {
-    case 0:
-      mode = ARM_AM::da;
-      break;
-    case 1:
-      mode = ARM_AM::ia;
-      break;
-    case 2:
-      mode = ARM_AM::db;
-      break;
-    case 3:
-      mode = ARM_AM::ib;
-      break;
-  }
-
-  Inst.addOperand(MCOperand::createImm(mode));
   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
     return MCDisassembler::Fail;
 
@@ -2394,6 +2392,7 @@ static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, 
unsigned Insn,
     if(imm > 4) return MCDisassembler::Fail;
     Inst.setOpcode(ARM::t2HINT);
     Inst.addOperand(MCOperand::createImm(imm));
+    DecodePredicateOperand(Inst, Decoder);
   }
 
   return S;
@@ -2419,6 +2418,7 @@ DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn, 
uint64_t Address,
   Inst.setOpcode(Opcode);
   if (Opcode == ARM::t2HINT) {
     Inst.addOperand(MCOperand::createImm(imm));
+    DecodePredicateOperand(Inst, Decoder);
   }
 
   return MCDisassembler::Success;
@@ -2446,6 +2446,7 @@ static DecodeStatus DecodeT2MOVTWInstruction(MCInst 
&Inst, unsigned Insn,
   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
     Inst.addOperand(MCOperand::createImm(imm));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -2650,6 +2651,7 @@ static DecodeStatus DecodeT2BInstruction(MCInst &Inst, 
unsigned Insn,
                                 true, 4, Inst, Decoder))
     Inst.addOperand(MCOperand::createImm(imm32));
 
+  DecodePredicateOperand(Inst, Decoder);
   return Status;
 }
 
@@ -2975,6 +2977,7 @@ static DecodeStatus DecodeVLDInstruction(MCInst &Inst, 
unsigned Insn,
     break;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3301,6 +3304,7 @@ static DecodeStatus DecodeVSTInstruction(MCInst &Inst, 
unsigned Insn,
       break;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3349,6 +3353,7 @@ static DecodeStatus DecodeVLD1DupInstruction(MCInst 
&Inst, unsigned Insn,
       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3398,6 +3403,7 @@ static DecodeStatus DecodeVLD2DupInstruction(MCInst 
&Inst, unsigned Insn,
       return MCDisassembler::Fail;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3434,6 +3440,7 @@ static DecodeStatus DecodeVLD3DupInstruction(MCInst 
&Inst, unsigned Insn,
       return MCDisassembler::Fail;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3487,6 +3494,7 @@ static DecodeStatus DecodeVLD4DupInstruction(MCInst 
&Inst, unsigned Insn,
       return MCDisassembler::Fail;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3533,6 +3541,7 @@ static DecodeStatus DecodeVMOVModImmInstruction(MCInst 
&Inst, unsigned Insn,
       break;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3558,9 +3567,11 @@ static DecodeStatus DecodeMVEModImmInstruction(MCInst 
&Inst, unsigned Insn,
 
   Inst.addOperand(MCOperand::createImm(imm));
 
+  // vpred_r operand.
   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
   Inst.addOperand(MCOperand::createReg(0));
   Inst.addOperand(MCOperand::createImm(0));
+  DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder);
 
   return S;
 }
@@ -3586,8 +3597,8 @@ static DecodeStatus DecodeMVEVADCInstruction(MCInst 
&Inst, unsigned Insn,
     return MCDisassembler::Fail;
   if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
     Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
-  Inst.addOperand(MCOperand::createImm(Qd));
 
+  DecodeVpredROperand(Inst, Decoder);
   return S;
 }
 
@@ -3608,6 +3619,7 @@ static DecodeStatus DecodeVSHLMaxInstruction(MCInst 
&Inst, unsigned Insn,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(8 << size));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3673,6 +3685,7 @@ static DecodeStatus DecodeTBLInstruction(MCInst &Inst, 
unsigned Insn,
   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3698,6 +3711,7 @@ static DecodeStatus DecodeThumbAddSpecialReg(MCInst 
&Inst, uint16_t Insn,
   }
 
   Inst.addOperand(MCOperand::createImm(imm));
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3890,6 +3904,7 @@ static DecodeStatus DecodeT2LoadShift(MCInst &Inst, 
unsigned Insn,
   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -3975,6 +3990,8 @@ static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, 
unsigned Insn,
 
   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
     return MCDisassembler::Fail;
+
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4056,6 +4073,8 @@ static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, 
unsigned Insn,
 
   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
     return MCDisassembler::Fail;
+
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4095,6 +4114,8 @@ static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
     return MCDisassembler::Fail;
+
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4149,6 +4170,7 @@ static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, 
unsigned Insn,
   }
   Inst.addOperand(MCOperand::createImm(imm));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4398,6 +4420,7 @@ static DecodeStatus DecodeT2LdStPre(MCInst &Inst, 
unsigned Insn,
   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4437,6 +4460,7 @@ static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, 
uint16_t Insn,
   Inst.addOperand(MCOperand::createReg(ARM::SP));
   Inst.addOperand(MCOperand::createImm(imm));
 
+  DecodePredicateOperand(Inst, Decoder);
   return MCDisassembler::Success;
 }
 
@@ -4463,6 +4487,7 @@ static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, 
uint16_t Insn,
     return MCDisassembler::Fail;
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -4587,6 +4612,7 @@ static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, 
unsigned Insn,
     return MCDisassembler::Fail;
   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
     return MCDisassembler::Fail;
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5052,6 +5078,7 @@ static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5117,6 +5144,7 @@ static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5184,6 +5212,7 @@ static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5247,6 +5276,7 @@ static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5317,6 +5347,7 @@ static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5380,6 +5411,7 @@ static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5461,6 +5493,7 @@ static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5533,6 +5566,7 @@ static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(index));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5651,6 +5685,7 @@ static DecodeStatus DecodeT2LDRDPreInstruction(MCInst 
&Inst, unsigned Insn,
   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5686,6 +5721,7 @@ static DecodeStatus DecodeT2STRDPreInstruction(MCInst 
&Inst, unsigned Insn,
   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5712,6 +5748,7 @@ static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t 
Insn, uint64_t Address,
       Val = -Val;
   }
   Inst.addOperand(MCOperand::createImm(Val));
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5809,6 +5846,7 @@ static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(64 - imm));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -5868,6 +5906,7 @@ static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     return MCDisassembler::Fail;
   Inst.addOperand(MCOperand::createImm(64 - imm));
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -6073,8 +6112,10 @@ static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned 
Insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
   DecodeStatus S = MCDisassembler::Success;
 
-  if (Inst.getOpcode() == ARM::MVE_LCTP)
+  if (Inst.getOpcode() == ARM::MVE_LCTP) {
+    DecodePredicateOperand(Inst, Decoder);
     return S;
+  }
 
   unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
                  fieldFromInstruction(Insn, 1, 10) << 1;
@@ -6119,6 +6160,7 @@ static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned 
Insn, uint64_t Address,
         Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
 
       Inst.setOpcode(ARM::MVE_LCTP);
+      DecodePredicateOperand(Inst, Decoder);
     } else {
       Inst.addOperand(MCOperand::createReg(ARM::LR));
       if (!Check(S, DecoderGPRRegisterClass(Inst,
@@ -6295,27 +6337,55 @@ static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, 
unsigned Val,
   return S;
 }
 
-static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
-                                        uint64_t Address,
+static DecodeStatus DecodeVpredROperand(MCInst &Inst,
                                         const MCDisassembler *Decoder) {
-  // The vpred_r operand type includes an MQPR register field derived
-  // from the encoding. But we don't actually want to add an operand
-  // to the MCInst at this stage, because AddThumbPredicate will do it
-  // later, and will infer the register number from the TIED_TO
-  // constraint. So this is a deliberately empty decoder method that
-  // will inhibit the auto-generated disassembly code from adding an
-  // operand at all.
+  const auto *D = static_cast<const ARMDisassembler *>(Decoder);
+
+  ARMVCC::VPTCodes VCC = ARMVCC::None;
+  if (D->VPTBlock.instrInVPTBlock())
+    VCC = static_cast<ARMVCC::VPTCodes>(D->VPTBlock.getVPTPred());
+
+  const MCInstrDesc &MCID = D->MCII->get(Inst.getOpcode());
+  unsigned VCCPos;
+  for (VCCPos = 0; VCCPos != MCID.NumOperands; ++VCCPos) {
+    if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R)
+      break;
+  }
+  assert(VCCPos != MCID.NumOperands);
+
+  Inst.addOperand(MCOperand::createImm(VCC));
+  Inst.addOperand(
+      MCOperand::createReg(VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0));
+  Inst.addOperand(MCOperand::createReg(ARM::NoRegister));
+
+  int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
+  assert(TiedOp >= 0 &&
+         "Inactive register in vpred_r is not tied to an output!");
+  // Copy the operand to ensure it's not invalidated when MI grows.
+  Inst.addOperand(MCOperand(Inst.getOperand(TiedOp)));
+
+  if (D->ITBlock.instrInITBlock())
+    return MCDisassembler::SoftFail;
+
   return MCDisassembler::Success;
 }
 
-[[maybe_unused]] static DecodeStatus
-DecodeVpredNOperand(MCInst &Inst, unsigned RegNo, uint64_t Address,
-                    const MCDisassembler *Decoder) {
-  // Similar to above, we want to ensure that no operands are added for the
-  // vpred operands. (This is marked "maybe_unused" for the moment; because
-  // DecoderEmitter currently (wrongly) omits operands with no instruction 
bits,
-  // the decoder doesn't actually call it yet. That will be addressed in a
-  // future change.)
+static DecodeStatus DecodeVpredNOperand(MCInst &Inst,
+                                        const MCDisassembler *Decoder) {
+  const auto *D = static_cast<const ARMDisassembler *>(Decoder);
+
+  ARMVCC::VPTCodes VCC = ARMVCC::None;
+  if (D->VPTBlock.instrInVPTBlock())
+    VCC = static_cast<ARMVCC::VPTCodes>(D->VPTBlock.getVPTPred());
+
+  Inst.addOperand(MCOperand::createImm(VCC));
+  Inst.addOperand(
+      MCOperand::createReg(VCC == ARMVCC::None ? ARM::NoRegister : ARM::P0));
+  Inst.addOperand(MCOperand::createReg(ARM::NoRegister));
+
+  if (D->ITBlock.instrInITBlock())
+    return MCDisassembler::SoftFail;
+
   return MCDisassembler::Success;
 }
 
@@ -6497,6 +6567,7 @@ DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t 
Address,
   if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  DecodeVpredNOperand(Inst, Decoder);
   return S;
 }
 
@@ -6575,6 +6646,7 @@ static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, 
unsigned Insn,
   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, 
Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -6601,6 +6673,7 @@ static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, 
unsigned Insn,
   if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, 
Decoder)))
     return MCDisassembler::Fail;
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -6646,6 +6719,8 @@ DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
       return MCDisassembler::Fail;
 
+    DecodePredicateOperand(Inst, Decoder);
+
     if (fieldFromInstruction (Insn, 6, 3) != 4)
       return MCDisassembler::SoftFail;
 
@@ -6681,6 +6756,7 @@ DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned 
Insn, uint64_t Address,
     Inst.addOperand(MCOperand::createImm(Saturate));
   }
 
+  DecodePredicateOperand(Inst, Decoder);
   return S;
 }
 
@@ -6700,7 +6776,8 @@ static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, 
unsigned Insn,
     return MCDisassembler::Fail;
   if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
     return MCDisassembler::Fail;
-
+  if (!Check(S, DecodeVpredROperand(Inst, Decoder)))
+    return MCDisassembler::Fail;
   return S;
 }
 
@@ -6735,6 +6812,7 @@ static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned 
Insn, uint64_t Address,
   if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
     return MCDisassembler::Fail;
 
+  // vpred_n operand.
   Inst.addOperand(MCOperand::createImm(ARMVCC::None));
   Inst.addOperand(MCOperand::createReg(0));
   Inst.addOperand(MCOperand::createImm(0));
@@ -6749,6 +6827,7 @@ static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned 
Insn, uint64_t Address,
   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
     return MCDisassembler::Fail;
+  DecodeVpredNOperand(Inst, Decoder);
   return S;
 }
 
@@ -6758,6 +6837,7 @@ static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned 
Insn,
   DecodeStatus S = MCDisassembler::Success;
   Inst.addOperand(MCOperand::createReg(ARM::VPR));
   Inst.addOperand(MCOperand::createReg(ARM::VPR));
+  DecodeVpredNOperand(Inst, Decoder);
   return S;
 }
 
@@ -6785,10 +6865,12 @@ static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, 
unsigned Insn,
   if (TypeT3) {
     Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
     Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
+    DecodePredicateOperand(Inst, Decoder);
   } else {
     Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
     if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
       return MCDisassembler::Fail;
+    DecodePredicateOperand(Inst, Decoder);
     if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
       return MCDisassembler::Fail;
   }
@@ -6882,9 +6964,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst 
&MI, uint64_t &Size,
                              STI);
   if (Result) {
     Size = 2;
-    bool InITBlock = ITBlock.instrInITBlock();
     Check(Result, AddThumbPredicate(MI));
-    AddThumb1SBit(MI, InITBlock);
     return Result;
   }
 
@@ -6950,9 +7030,7 @@ DecodeStatus ARMDisassembler::getThumbInstruction(MCInst 
&MI, uint64_t &Size,
       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
   if (Result != MCDisassembler::Fail) {
     Size = 4;
-    bool InITBlock = ITBlock.instrInITBlock();
     Check(Result, AddThumbPredicate(MI));
-    AddThumb1SBit(MI, InITBlock);
     return Result;
   }
 
diff --git a/llvm/test/MC/Disassembler/ARM/arm-tests.txt 
b/llvm/test/MC/Disassembler/ARM/arm-tests.txt
index 008bb1154e57f..a1016cdb5c8cc 100644
--- a/llvm/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/llvm/test/MC/Disassembler/ARM/arm-tests.txt
@@ -354,7 +354,7 @@
 # CHECK:         strheq  r0, [r0, -r0]
 0xb0 0x00 0x00 0x01
 
-# CHECK: rfedb #4!
+# CHECK: rfedb r2!
 0x14 0x0 0x32 0xf9
 
 # CHECK: stc2l p0, c0, [r2], #-96

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to