[llvm] [AArch64] Refactor predicate register class decode functions (PR #97412)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 2 05:45:47 PDT 2024


https://github.com/DevM-uk created https://github.com/llvm/llvm-project/pull/97412

In a previous PR #81716, a new decoder function was added to llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp. During code review it was suggested that, as most of the decoder functions were very similar in structure, that they be refactored into a single, templated function. I have added the refactored function, removed the definitions of the replaced functions, and replaced the references to the replaced functions in AArch64Disassembler.cpp and llvm/lib/Target/AArch64/AArch64RegisterInfo.td. To reduce the number of duplicate references in AArch64RegisterInfo.td, I have also made a small change to llvm/utils/TableGen/DecoderEmitter.cpp.

>From 2e526f87e9f9e238b9df4b1588065e22a1e52e9e Mon Sep 17 00:00:00 2001
From: Max Beck-Jones <max.beck-jones at arm.com>
Date: Mon, 1 Jul 2024 15:41:41 +0000
Subject: [PATCH] [AArch64] Refactor predicate register class decode functions

In a previous PR #81716, a new decoder function was added to llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp. During code review it was suggested that, as most of the decoder functions were very similar in structure, that they be refactored into a single, templated function. I have added the refactored function, removed the definitions of the replaced functions, and replaced the references to the replaced functions in AArch64Disassembler.cpp and llvm/lib/Target/AArch64/AArch64RegisterInfo.td. To reduce the number of duplicate references in AArch64RegisterInfo.td, I have also made a small change to llvm/utils/TableGen/DecoderEmitter.cpp.
---
 .../lib/Target/AArch64/AArch64RegisterInfo.td |  79 +-
 .../Disassembler/AArch64Disassembler.cpp      | 828 +++++-------------
 llvm/utils/TableGen/DecoderEmitter.cpp        |   3 +-
 3 files changed, 298 insertions(+), 612 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index dfaa67dd1959d..4dc33e6168cbd 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -160,25 +160,30 @@ def GPR64common : RegisterClass<"AArch64", [i64], 64,
                                 (add (sequence "X%u", 0, 28), FP, LR)> {
   let AltOrders = [(rotl GPR64common, 8)];
   let AltOrderSelect = [{ return 1; }];
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>";
 }
 // GPR register classes which exclude SP/WSP.
 def GPR32 : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WZR)> {
   let AltOrders = [(rotl GPR32, 8)];
   let AltOrderSelect = [{ return 1; }];
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>";
 }
 def GPR64 : RegisterClass<"AArch64", [i64], 64, (add GPR64common, XZR)> {
   let AltOrders = [(rotl GPR64, 8)];
   let AltOrderSelect = [{ return 1; }];
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>";
 }
 
 // GPR register classes which include SP/WSP.
 def GPR32sp : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WSP)> {
   let AltOrders = [(rotl GPR32sp, 8)];
   let AltOrderSelect = [{ return 1; }];
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>";
 }
 def GPR64sp : RegisterClass<"AArch64", [i64], 64, (add GPR64common, SP)> {
   let AltOrders = [(rotl GPR64sp, 8)];
   let AltOrderSelect = [{ return 1; }];
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID,0, 32>";
 }
 
 def GPR32sponly : RegisterClass<"AArch64", [i32], 32, (add WSP)>;
@@ -446,18 +451,24 @@ def Q31   : AArch64Reg<31, "q31", [D31], ["v31", ""]>, DwarfRegAlias<B31>;
 
 def FPR8  : RegisterClass<"AArch64", [i8], 8, (sequence "B%u", 0, 31)> {
   let Size = 8;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>";
 }
 def FPR16 : RegisterClass<"AArch64", [f16, bf16, i16], 16, (sequence "H%u", 0, 31)> {
   let Size = 16;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>";
 }
 
 def FPR16_lo : RegisterClass<"AArch64", [f16], 16, (trunc FPR16, 16)> {
   let Size = 16;
 }
-def FPR32 : RegisterClass<"AArch64", [f32, i32], 32,(sequence "S%u", 0, 31)>;
+def FPR32 : RegisterClass<"AArch64", [f32, i32], 32,(sequence "S%u", 0, 31)> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>";
+}
 def FPR64 : RegisterClass<"AArch64", [f64, i64, v2f32, v1f64, v8i8, v4i16, v2i32,
                                       v1i64, v4f16, v4bf16],
-                                     64, (sequence "D%u", 0, 31)>;
+                                     64, (sequence "D%u", 0, 31)> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>";
+}
 def FPR64_lo : RegisterClass<"AArch64",
                              [v8i8, v4i16, v2i32, v1i64, v4f16, v4bf16, v2f32,
                               v1f64],
@@ -469,21 +480,27 @@ def FPR64_lo : RegisterClass<"AArch64",
 def FPR128 : RegisterClass<"AArch64",
                            [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, f128,
                             v8f16, v8bf16],
-                           128, (sequence "Q%u", 0, 31)>;
+                           128, (sequence "Q%u", 0, 31)> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>";
+}
 
 // The lower 16 vector registers.  Some instructions can only take registers
 // in this range.
 def FPR128_lo : RegisterClass<"AArch64",
                               [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16,
                                v8bf16],
-                              128, (trunc FPR128, 16)>;
+                              128, (trunc FPR128, 16)> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 16>";
+}
 
 // The lower 8 vector registers.  Some instructions can only take registers
 // in this range.
 def FPR128_0to7 : RegisterClass<"AArch64",
                                 [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16,
                                  v8bf16],
-                                128, (trunc FPR128, 8)>;
+                                128, (trunc FPR128, 8)> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 8>";
+}
 
 // Pairs, triples, and quads of 64-bit vector registers.
 def DSeqPairs : RegisterTuples<[dsub0, dsub1], [(rotl FPR64, 0), (rotl FPR64, 1)]>;
@@ -495,12 +512,15 @@ def DSeqQuads : RegisterTuples<[dsub0, dsub1, dsub2, dsub3],
                                 (rotl FPR64, 2), (rotl FPR64, 3)]>;
 def DD   : RegisterClass<"AArch64", [untyped], 64, (add DSeqPairs)> {
   let Size = 128;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::DDRegClassID, 0, 32>";
 }
 def DDD  : RegisterClass<"AArch64", [untyped], 64, (add DSeqTriples)> {
   let Size = 192;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::DDDRegClassID, 0, 32>";
 }
 def DDDD : RegisterClass<"AArch64", [untyped], 64, (add DSeqQuads)> {
   let Size = 256;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::DDDDRegClassID, 0, 32>";
 }
 
 // Pairs, triples, and quads of 128-bit vector registers.
@@ -513,12 +533,15 @@ def QSeqQuads : RegisterTuples<[qsub0, qsub1, qsub2, qsub3],
                                 (rotl FPR128, 2), (rotl FPR128, 3)]>;
 def QQ   : RegisterClass<"AArch64", [untyped], 128, (add QSeqPairs)> {
   let Size = 256;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::QQRegClassID, 0, 32>";
 }
 def QQQ  : RegisterClass<"AArch64", [untyped], 128, (add QSeqTriples)> {
   let Size = 384;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::QQQRegClassID, 0, 32>";
 }
 def QQQQ : RegisterClass<"AArch64", [untyped], 128, (add QSeqQuads)> {
   let Size = 512;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::QQQQRegClassID, 0, 32>";
 }
 
 
@@ -904,9 +927,15 @@ class PPRClass<int firstreg, int lastreg> : RegisterClass<
   let Size = 16;
 }
 
-def PPR    : PPRClass<0, 15>;
-def PPR_3b : PPRClass<0, 7>; // Restricted 3 bit SVE predicate register class.
-def PPR_p8to15 : PPRClass<8, 15>;
+def PPR    : PPRClass<0, 15> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PPRRegClassID, 0, 16>";
+}
+def PPR_3b : PPRClass<0, 7> { // Restricted 3 bit SVE predicate register class.
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PPRRegClassID, 0, 8>";
+}
+def PPR_p8to15 : PPRClass<8, 15> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PNRRegClassID, 8, 8>";
+}
 
 class PPRAsmOperand <string name, string RegClass, int Width>: AsmOperandClass {
   let Name = "SVE" # name # "Reg";
@@ -941,7 +970,9 @@ class PNRClass<int firstreg, int lastreg> : RegisterClass<
   let Size = 16;
 }
 
-def PNR        : PNRClass<0, 15>;
+def PNR        : PNRClass<0, 15> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PNRRegClassID, 0, 16>";
+}
 def PNR_3b     : PNRClass<0, 7>;
 def PNR_p8to15 : PNRClass<8, 15>;
 
@@ -982,7 +1013,7 @@ class PNRP8to15RegOp<string Suffix, AsmOperandClass C, int Width, RegisterClass
     : SVERegOp<Suffix, C, ElementSizeNone, RC> {
   let PrintMethod   = "printPredicateAsCounter<" # Width # ">";
   let EncoderMethod = "EncodePNR_p8to15";
-  let DecoderMethod = "DecodePNR_p8to15RegisterClass";
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PNRRegClassID, 8, 8>";
 }
 
 def PNRAny_p8to15 : PNRP8to15RegOp<"",  PNRAsmAny_p8to15,  0,  PNR_p8to15>;
@@ -1013,7 +1044,9 @@ class PPRorPNRAsmOperand<string name, string RegClass, int Width>: AsmOperandCla
   let ParserMethod = "tryParseSVEPredicateOrPredicateAsCounterVector";
 }
 
-def PPRorPNR         : PPRorPNRClass;
+def PPRorPNR         : PPRorPNRClass {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PPRorPNRRegClassID, 0, 16>";
+}
 def PPRorPNRAsmOp8   : PPRorPNRAsmOperand<"PPRorPNRB", "PPRorPNR", 8>;
 def PPRorPNRAsmOpAny : PPRorPNRAsmOperand<"PPRorPNRAny", "PPRorPNR", 0>;
 def PPRorPNRAny      : PPRRegOp<"", PPRorPNRAsmOpAny, ElementSizeNone, PPRorPNR>;
@@ -1024,6 +1057,7 @@ def PSeqPairs : RegisterTuples<[psub0, psub1], [(rotl PPR, 0), (rotl PPR, 1)]>;
 
 def PPR2 : RegisterClass<"AArch64", [untyped], 16, (add PSeqPairs)> {
   let Size = 32;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::PPR2RegClassID, 0, 16>";
 }
 
 class PPRVectorList<int ElementWidth, int NumRegs> : AsmOperandClass {
@@ -1097,9 +1131,15 @@ class ZPRClass<int lastreg> : RegisterClass<"AArch64",
   let Size = 128;
 }
 
-def ZPR    : ZPRClass<31>;
-def ZPR_4b : ZPRClass<15>; // Restricted 4 bit SVE vector register class.
-def ZPR_3b : ZPRClass<7>;  // Restricted 3 bit SVE vector register class.
+def ZPR    : ZPRClass<31> {
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>";
+}
+def ZPR_4b : ZPRClass<15> { // Restricted 4 bit SVE vector register class.
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 16>";
+}
+def ZPR_3b : ZPRClass<7> {  // Restricted 3 bit SVE vector register class.
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 8>";
+}
 
 class ZPRAsmOperand<string name, int Width, string RegClassSuffix = "">
     : AsmOperandClass {
@@ -1176,12 +1216,15 @@ def ZSeqQuads   : RegisterTuples<[zsub0, zsub1, zsub2, zsub3], [(rotl ZPR, 0), (
 
 def ZPR2   : RegisterClass<"AArch64", [untyped], 128, (add ZSeqPairs)>  {
   let Size = 256;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR2RegClassID, 0, 32>";
 }
 def ZPR3  : RegisterClass<"AArch64", [untyped], 128, (add ZSeqTriples)> {
   let Size = 384;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR3RegClassID, 0, 32>";
 }
 def ZPR4 : RegisterClass<"AArch64", [untyped], 128, (add ZSeqQuads)> {
   let Size = 512;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR4RegClassID, 0, 32>";
 }
 
 class ZPRVectorList<int ElementWidth, int NumRegs> : AsmOperandClass {
@@ -1379,10 +1422,12 @@ def ZStridedQuadsHi : RegisterTuples<[zsub0, zsub1, zsub2, zsub3], [
 def ZPR2Strided : RegisterClass<"AArch64", [untyped], 128,
                                 (add ZStridedPairsLo, ZStridedPairsHi)>  {
   let Size = 256;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR2StridedRegClassID, 0, 16>";
 }
 def ZPR4Strided : RegisterClass<"AArch64", [untyped], 128,
                                 (add ZStridedQuadsLo, ZStridedQuadsHi)>  {
   let Size = 512;
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR4StridedRegClassID, 0, 8>";
 }
 
 def ZPR2StridedOrContiguous : RegisterClass<"AArch64", [untyped], 128,
@@ -1401,7 +1446,7 @@ class ZPRVectorListStrided<int ElementWidth, int NumRegs, int Stride>
 }
 
 let EncoderMethod = "EncodeZPR2StridedRegisterClass",
-    DecoderMethod = "DecodeZPR2StridedRegisterClass" in {
+    DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR2StridedRegClassID, 0, 16>" in {
   def ZZ_b_strided
       : RegisterOperand<ZPR2Strided, "printTypedVectorList<0, 'b'>"> {
     let ParserMatchClass = ZPRVectorListStrided<8, 2, 8>;
@@ -1439,7 +1484,7 @@ def ZPR4StridedOrContiguous : RegisterClass<"AArch64", [untyped], 128,
 }
 
 let EncoderMethod = "EncodeZPR4StridedRegisterClass",
-    DecoderMethod = "DecodeZPR4StridedRegisterClass" in {
+    DecoderMethod = "DecodeSimpleRegisterClass<AArch64::ZPR4StridedRegClassID, 0, 16>" in {
   def ZZZZ_b_strided
       : RegisterOperand<ZPR4Strided, "printTypedVectorList<0,'b'>"> {
     let ParserMatchClass = ZPRVectorListStrided<8, 4, 4>;
@@ -1774,9 +1819,11 @@ def MatrixTileList : MatrixTileListOperand<>;
 
 def MatrixIndexGPR32_8_11 : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 8, 11)> {
    let DiagnosticType = "InvalidMatrixIndexGPR32_8_11";
+   let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_8_11RegClassID, 0, 4>";
 }
 def MatrixIndexGPR32_12_15 : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 12, 15)> {
   let DiagnosticType = "InvalidMatrixIndexGPR32_12_15";
+  let DecoderMethod = "DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_12_15RegClassID, 0, 4>";
 }
 def MatrixIndexGPR32Op8_11 : RegisterOperand<MatrixIndexGPR32_8_11> {
   let EncoderMethod = "encodeMatrixIndexGPR32<AArch64::W8>";
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index ddb875e73ff5a..b97f00c993112 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -38,100 +38,19 @@ using DecodeStatus = MCDisassembler::DecodeStatus;
 
 // Forward declare these because the autogenerated code will reference them.
 // Definitions are further down.
-static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
+template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
+static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);
-static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                 uint64_t Address,
-                                                 const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
-                               const MCDisassembler *Decoder);
-static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Address,
-                                             const MCDisassembler *Decoder);
-static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Address,
-                                             const MCDisassembler *Decoder);
-static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Address,
-                                             const MCDisassembler *Decoder);
-static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
-                               const MCDisassembler *Decoder);
-static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Address,
-                                             const MCDisassembler *Decoder);
 static DecodeStatus
 DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
                                 const MCDisassembler *Decoder);
-static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const MCDisassembler *Decoder);
-static DecodeStatus
-DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
-                                         uint64_t Address, const void *Decoder);
-static DecodeStatus
-DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Address,
-                                          const MCDisassembler *Decoder);
-static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Address,
-                                             const MCDisassembler *Decoder);
-static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Address,
-                                               const MCDisassembler *Decoder);
-static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Address,
-                                          const MCDisassembler *Decoder);
-static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Address,
-                                          const MCDisassembler *Decoder);
-static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Address,
-                                              const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Address,
-                                              const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
-static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder);
 static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const void *Decoder);
 static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const void *Decoder);
-static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                   uint64_t Address,
-                                                   const void *Decoder);
-static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                   uint64_t Address,
-                                                   const void *Decoder);
 template <unsigned NumBitsForTile>
 static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
                                      uint64_t Address,
@@ -140,24 +59,6 @@ static DecodeStatus
 DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
                                   uint64_t Address,
                                   const MCDisassembler *Decoder);
-static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                uint64_t Addr,
-                                                const MCDisassembler *Decoder);
-static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder);
-static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Address,
-                                              const MCDisassembler *Decoder);
-static DecodeStatus
-DecodePNR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
-                              const MCDisassembler *Decoder);
-static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const void *Decoder);
 static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const void *Decoder);
@@ -314,8 +215,8 @@ static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
 #define SoftFail MCDisassembler::SoftFail
 
 static MCDisassembler *createAArch64Disassembler(const Target &T,
-                                               const MCSubtargetInfo &STI,
-                                               MCContext &Ctx) {
+                                                 const MCSubtargetInfo &STI,
+                                                 MCContext &Ctx) {
 
   return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
 }
@@ -426,103 +327,15 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler() {
                                        createAArch64ExternalSymbolizer);
 }
 
-static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Addr,
+template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
+static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
+                                              uint64_t Address,
                                               const MCDisassembler *Decoder) {
-  if (RegNo > 31)
+  if (RegNo > NumRegsInClass - 1)
     return Fail;
 
   unsigned Register =
-      AArch64MCRegisterClasses[AArch64::FPR128RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus
-DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
-                             const MCDisassembler *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-  return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
-}
-
-static DecodeStatus
-DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
-                               const MCDisassembler *Decoder) {
-  if (RegNo > 7)
-    return Fail;
-  return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
-}
-
-static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Addr,
-                                             const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::FPR64RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Addr,
-                                             const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::FPR32RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Addr,
-                                             const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::FPR16RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Addr,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::FPR8RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus
-DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
-                               const MCDisassembler *Decoder) {
-  if (RegNo > 30)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::GPR64commonRegClassID].getRegister(
-          RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Addr,
-                                             const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::GPR64RegClassID].getRegister(RegNo);
+      AArch64MCRegisterClasses[RegClassID].getRegister(RegNo + FirstReg);
   Inst.addOperand(MCOperand::createReg(Register));
   return Success;
 }
@@ -542,129 +355,6 @@ DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
   return Success;
 }
 
-static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Addr,
-                                               const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus
-DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
-                                         uint64_t Addr, const void *Decoder) {
-  if (RegNo > 3)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_8_11RegClassID]
-          .getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus
-DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Addr,
-                                          const MCDisassembler *Decoder) {
-  if (RegNo > 3)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_12_15RegClassID]
-          .getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
-                                             uint64_t Addr,
-                                             const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::GPR32RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
-                                               uint64_t Addr,
-                                               const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::GPR32spRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Address,
-                                           const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Address,
-                                              const MCDisassembler *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-  return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
-}
-
-static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Address,
-                                              const MCDisassembler *Decoder) {
-  if (RegNo > 7)
-    return Fail;
-  return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
-}
-
-static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPR3RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
 static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const void *Decoder) {
@@ -687,30 +377,6 @@ static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
   return Success;
 }
 
-static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                   uint64_t Address,
-                                                   const void *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPR2StridedRegClassID].getRegister(
-          RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                   uint64_t Address,
-                                                   const void *Decoder) {
-  if (RegNo > 7)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::ZPR4StridedRegClassID].getRegister(
-          RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
 static DecodeStatus
 DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
                                   uint64_t Address,
@@ -744,74 +410,6 @@ static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
   return Success;
 }
 
-static DecodeStatus DecodePPRorPNRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                                uint64_t Addr,
-                                                const MCDisassembler *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::PPRorPNRRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Addr,
-                                           const MCDisassembler *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::PPRRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Addr,
-                                           const MCDisassembler *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::PNRRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
-                                              uint64_t Addr,
-                                              const MCDisassembler *Decoder) {
-  if (RegNo > 7)
-    return Fail;
-
-  // Just reuse the PPR decode table
-  return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder);
-}
-
-static DecodeStatus
-DecodePNR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
-                              const MCDisassembler *Decoder) {
-  if (RegNo > 7)
-    return Fail;
-
-  // Just reuse the PPR decode table
-  return DecodePNRRegisterClass(Inst, RegNo + 8, Addr, Decoder);
-}
-
-static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Address,
-                                            const void *Decoder) {
-  if (RegNo > 15)
-    return Fail;
-
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
 static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
                                                 uint64_t Address,
                                                 const void *Decoder) {
@@ -823,72 +421,6 @@ static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
   return Success;
 }
 
-static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Addr,
-                                          const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::QQRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Addr,
-                                           const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::QQQRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Addr,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::QQQQRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                          uint64_t Addr,
-                                          const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::DDRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                           uint64_t Addr,
-                                           const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::DDDRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
-static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
-                                            uint64_t Addr,
-                                            const MCDisassembler *Decoder) {
-  if (RegNo > 31)
-    return Fail;
-  unsigned Register =
-      AArch64MCRegisterClasses[AArch64::DDDDRegClassID].getRegister(RegNo);
-  Inst.addOperand(MCOperand::createReg(Register));
-  return Success;
-}
-
 static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
                                                uint64_t Addr,
                                                const MCDisassembler *Decoder) {
@@ -938,7 +470,7 @@ static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
 static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
                                     uint64_t Address,
                                     const MCDisassembler *Decoder) {
-  Inst.addOperand(MCOperand::createImm((Imm  >> 1) & 1));
+  Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
   Inst.addOperand(MCOperand::createImm(Imm & 1));
   return Success;
 }
@@ -971,11 +503,15 @@ static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
   unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
 
   if (IsToVec) {
-    DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
+        Inst, Rd, Address, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+        Inst, Rn, Address, Decoder);
   } else {
-    DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
-    DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+        Inst, Rd, Address, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
+        Inst, Rn, Address, Decoder);
   }
 
   // Add the lane
@@ -1093,9 +629,12 @@ DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
     // if sf == '0' and imm6<5> == '1' then ReservedValue()
     if (shiftLo >> 5 == 1)
       return Fail;
-    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   }
   case AArch64::ADDXrs:
@@ -1114,9 +653,12 @@ DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
   case AArch64::ORNXrs:
   case AArch64::EORXrs:
   case AArch64::EONXrs:
-    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   }
 
@@ -1139,12 +681,14 @@ static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::MOVKWi:
     if (shift & (1U << 5))
       return Fail;
-    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
     break;
   case AArch64::MOVZXi:
   case AArch64::MOVNXi:
   case AArch64::MOVKXi:
-    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
     break;
   }
 
@@ -1179,38 +723,46 @@ DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
   case AArch64::LDRSHWui:
   case AArch64::STRWui:
   case AArch64::LDRWui:
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDRSBXui:
   case AArch64::LDRSHXui:
   case AArch64::LDRSWui:
   case AArch64::STRXui:
   case AArch64::LDRXui:
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDRQui:
   case AArch64::STRQui:
-    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                                Decoder);
     break;
   case AArch64::LDRDui:
   case AArch64::STRDui:
-    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDRSui:
   case AArch64::STRSui:
-    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDRHui:
   case AArch64::STRHui:
-    DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDRBui:
   case AArch64::STRBui:
-    DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                              Decoder);
     break;
   }
 
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
   if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
     Inst.addOperand(MCOperand::createImm(offset));
   return Success;
@@ -1278,7 +830,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRBpre:
   case AArch64::LDRBpost:
   case AArch64::STRBpost:
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
     break;
   }
 
@@ -1329,7 +882,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::LDAPURHi:
   case AArch64::LDAPURSHWi:
   case AArch64::LDAPURi:
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDURSBXi:
   case AArch64::LDURSHXi:
@@ -1356,7 +910,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::LDAPURSBXi:
   case AArch64::STLURXi:
   case AArch64::LDAPURXi:
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDURQi:
   case AArch64::STURQi:
@@ -1364,7 +919,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRQpre:
   case AArch64::LDRQpost:
   case AArch64::STRQpost:
-    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                                Decoder);
     break;
   case AArch64::LDURDi:
   case AArch64::STURDi:
@@ -1372,7 +928,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRDpre:
   case AArch64::LDRDpost:
   case AArch64::STRDpost:
-    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDURSi:
   case AArch64::STURSi:
@@ -1380,7 +937,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRSpre:
   case AArch64::LDRSpost:
   case AArch64::STRSpost:
-    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDURHi:
   case AArch64::STURHi:
@@ -1388,7 +946,8 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRHpre:
   case AArch64::LDRHpost:
   case AArch64::STRHpost:
-    DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDURBi:
   case AArch64::STURBi:
@@ -1396,11 +955,13 @@ static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STRBpre:
   case AArch64::LDRBpost:
   case AArch64::STRBpost:
-    DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                              Decoder);
     break;
   }
 
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
   Inst.addOperand(MCOperand::createImm(offset));
 
   bool IsLoad = fieldFromInstruction(insn, 22, 1);
@@ -1432,7 +993,8 @@ DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
   case AArch64::STXRW:
   case AArch64::STXRB:
   case AArch64::STXRH:
-    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
+                                                               Decoder);
     [[fallthrough]];
   case AArch64::LDARW:
   case AArch64::LDARB:
@@ -1452,11 +1014,13 @@ DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
   case AArch64::LDLARW:
   case AArch64::LDLARB:
   case AArch64::LDLARH:
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::STLXRX:
   case AArch64::STXRX:
-    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
+                                                               Decoder);
     [[fallthrough]];
   case AArch64::LDARX:
   case AArch64::LDAXRX:
@@ -1464,29 +1028,37 @@ DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
   case AArch64::STLRX:
   case AArch64::LDLARX:
   case AArch64::STLLRX:
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
     break;
   case AArch64::STLXPW:
   case AArch64::STXPW:
-    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
+                                                               Decoder);
     [[fallthrough]];
   case AArch64::LDAXPW:
   case AArch64::LDXPW:
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   case AArch64::STLXPX:
   case AArch64::STXPX:
-    DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
+                                                               Decoder);
     [[fallthrough]];
   case AArch64::LDAXPX:
   case AArch64::LDXPX:
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   }
 
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
 
   // You shouldn't load to the same register twice in an instruction...
   if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
@@ -1542,7 +1114,8 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STPSpre:
   case AArch64::STGPpre:
   case AArch64::STGPpost:
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
     break;
   }
 
@@ -1565,8 +1138,10 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STPXi:
   case AArch64::LDPSWi:
   case AArch64::STGPi:
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDPWpost:
   case AArch64::STPWpost:
@@ -1578,8 +1153,10 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STNPWi:
   case AArch64::LDPWi:
   case AArch64::STPWi:
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDNPQi:
   case AArch64::STNPQi:
@@ -1589,8 +1166,10 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STPQi:
   case AArch64::LDPQpre:
   case AArch64::STPQpre:
-    DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                                Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                                Decoder);
     break;
   case AArch64::LDNPDi:
   case AArch64::STNPDi:
@@ -1600,8 +1179,10 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STPDi:
   case AArch64::LDPDpre:
   case AArch64::STPDpre:
-    DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   case AArch64::LDNPSi:
   case AArch64::STNPSi:
@@ -1611,12 +1192,15 @@ static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
   case AArch64::STPSi:
   case AArch64::LDPSpre:
   case AArch64::STPSpre:
-    DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
-    DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
+                                                               Decoder);
     break;
   }
 
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
   Inst.addOperand(MCOperand::createImm(offset));
 
   // You shouldn't load to the same register twice in an instruction...
@@ -1645,16 +1229,18 @@ static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
     return Fail;
   case AArch64::LDRAAwriteback:
   case AArch64::LDRABwriteback:
-    DecodeGPR64spRegisterClass(Inst, Rn /* writeback register */, Addr,
-                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
+        Inst, Rn /* writeback register */, Addr, Decoder);
     break;
   case AArch64::LDRAAindexed:
   case AArch64::LDRABindexed:
     break;
   }
 
-  DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                             Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
   DecodeSImm<10>(Inst, offset, Addr, Decoder);
 
   if (writeback && Rt == Rn && Rn != 31) {
@@ -1681,39 +1267,57 @@ static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
     return Fail;
   case AArch64::ADDWrx:
   case AArch64::SUBWrx:
-    DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::ADDSWrx:
   case AArch64::SUBSWrx:
-    DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::ADDXrx:
   case AArch64::SUBXrx:
-    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::ADDSXrx:
   case AArch64::SUBSXrx:
-    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::ADDXrx64:
   case AArch64::SUBXrx64:
-    DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::SUBSXrx64:
   case AArch64::ADDSXrx64:
-    DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   }
 
@@ -1731,19 +1335,25 @@ static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
 
   if (Datasize) {
     if (Inst.getOpcode() == AArch64::ANDSXri)
-      DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
     else
-      DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
+          Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
     imm = fieldFromInstruction(insn, 10, 13);
     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
       return Fail;
   } else {
     if (Inst.getOpcode() == AArch64::ANDSWri)
-      DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
     else
-      DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
+          Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
     imm = fieldFromInstruction(insn, 10, 12);
     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
       return Fail;
@@ -1761,9 +1371,11 @@ static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
   imm |= fieldFromInstruction(insn, 5, 5);
 
   if (Inst.getOpcode() == AArch64::MOVID)
-    DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                               Decoder);
   else
-    DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                Decoder);
 
   Inst.addOperand(MCOperand::createImm(imm));
 
@@ -1800,8 +1412,10 @@ static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
   imm |= fieldFromInstruction(insn, 5, 5);
 
   // Tied operands added twice.
-  DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
-  DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                              Decoder);
+  DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                              Decoder);
 
   Inst.addOperand(MCOperand::createImm(imm));
   Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
@@ -1820,7 +1434,8 @@ static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
   if (imm & (1 << (21 - 1)))
     imm |= ~((1LL << 21) - 1);
 
-  DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                             Decoder);
   if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
     Inst.addOperand(MCOperand::createImm(imm));
 
@@ -1844,16 +1459,22 @@ static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
 
   if (Datasize) {
     if (Rd == 31 && !S)
-      DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
+          Inst, Rd, Addr, Decoder);
     else
-      DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
   } else {
     if (Rd == 31 && !S)
-      DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
+          Inst, Rd, Addr, Decoder);
     else
-      DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
-    DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
+      DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
+                                                                 Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                                 Decoder);
   }
 
   if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
@@ -1939,9 +1560,11 @@ static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
     dst |= ~((1LL << 14) - 1);
 
   if (fieldFromInstruction(insn, 31, 1) == 0)
-    DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
   else
-    DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                               Decoder);
   Inst.addOperand(MCOperand::createImm(bit));
   if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
     Inst.addOperand(MCOperand::createImm(dst));
@@ -1965,17 +1588,15 @@ DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,
 static DecodeStatus
 DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
                                   const MCDisassembler *Decoder) {
-  return DecodeGPRSeqPairsClassRegisterClass(Inst,
-                                             AArch64::WSeqPairsClassRegClassID,
-                                             RegNo, Addr, Decoder);
+  return DecodeGPRSeqPairsClassRegisterClass(
+      Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
 }
 
 static DecodeStatus
 DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
                                   const MCDisassembler *Decoder) {
-  return DecodeGPRSeqPairsClassRegisterClass(Inst,
-                                             AArch64::XSeqPairsClassRegClassID,
-                                             RegNo, Addr, Decoder);
+  return DecodeGPRSeqPairsClassRegisterClass(
+      Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
 }
 
 static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
@@ -1993,7 +1614,8 @@ static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
   Inst.addOperand(MCOperand::createImm(CRn));
   Inst.addOperand(MCOperand::createImm(CRm));
   Inst.addOperand(MCOperand::createImm(op2));
-  DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
+                                                             Decoder);
 
   return Success;
 }
@@ -2007,9 +1629,11 @@ DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
     return Fail;
 
   // The same (tied) operand is added twice to the instruction.
-  DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,
+                                                           Decoder);
   if (Inst.getOpcode() != AArch64::DUPM_ZI)
-    DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,
+                                                             Decoder);
   Inst.addOperand(MCOperand::createImm(imm));
   return Success;
 }
@@ -2018,7 +1642,7 @@ template <int Bits>
 static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
                                const MCDisassembler *Decoder) {
   if (Imm & ~((1LL << Bits) - 1))
-      return Fail;
+    return Fail;
 
   // Imm is a signed immediate, so sign extend it.
   if (Imm & (1 << (Bits - 1)))
@@ -2072,12 +1696,18 @@ static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
 
   // All three register operands are written back, so they all appear
   // twice in the operand list, once as outputs and once as inputs.
-  if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
-      !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
-      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
-      !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
-      !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
-      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder))
+  if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rd, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rs, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+          Inst, Rn, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rd, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rs, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+          Inst, Rn, Addr, Decoder))
     return MCDisassembler::Fail;
 
   return MCDisassembler::Success;
@@ -2097,11 +1727,16 @@ static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
 
   // Rd and Rn (not Rm) register operands are written back, so they appear
   // twice in the operand list, once as outputs and once as inputs.
-  if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
-      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
-      !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
-      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
-      !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder))
+  if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rd, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+          Inst, Rn, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
+          Inst, Rd, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+          Inst, Rn, Addr, Decoder) ||
+      !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
+          Inst, Rm, Addr, Decoder))
     return MCDisassembler::Fail;
 
   return MCDisassembler::Success;
@@ -2123,16 +1758,19 @@ static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
   uint64_t Rm = fieldFromInstruction(insn, 16, 5);
 
   Inst.addOperand(MCOperand::createImm(Rt));
-  DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
+  DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
+                                                               Decoder);
 
   switch (Inst.getOpcode()) {
   default:
     return Fail;
   case AArch64::PRFMroW:
-    DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   case AArch64::PRFMroX:
-    DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
+    DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
+                                                               Decoder);
     break;
   }
 
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index c303322e63b44..62f672bf351ae 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -1877,7 +1877,8 @@ static std::string findOperandDecoderMethod(Record *Record) {
   }
 
   if (Record->isSubClassOf("RegisterOperand"))
-    Record = Record->getValueAsDef("RegClass");
+    // Allows use of a DecoderMethod in referenced RegisterClass if set.
+    return findOperandDecoderMethod(Record->getValueAsDef("RegClass"));
 
   if (Record->isSubClassOf("RegisterClass")) {
     Decoder = "Decode" + Record->getName().str() + "RegisterClass";



More information about the llvm-commits mailing list