[llvm] b857481 - [AArch64][llvm] Rewrite the TLBI multiclass to be clearer (NFC) (#186451)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 06:49:15 PDT 2026


Author: Jonathan Thackray
Date: 2026-03-30T14:49:10+01:00
New Revision: b857481e6b2554a76062288cfed06a0ed9951263

URL: https://github.com/llvm/llvm-project/commit/b857481e6b2554a76062288cfed06a0ed9951263
DIFF: https://github.com/llvm/llvm-project/commit/b857481e6b2554a76062288cfed06a0ed9951263.diff

LOG: [AArch64][llvm] Rewrite the TLBI multiclass to be clearer (NFC) (#186451)

The `tlbi` multiclass is really doing four jobs at once: base TLBI,
synthesized nXS, optional TLBIP, and synthesized TLBIP nXS. Also,
`needsreg` and `optreg` are really just a 3-state operand policy in
disguise. Likewise, the PLBI multiclass has this same issue.

Change `needsreg` and `optreg` into a combined enum-alike, so it's
clearer whether the instruction takes no register operand, a required
register operand or an optional register operand.

This improves on my original change 66e8270e8. Further work to
improve this code is in #187400.

Added: 
    

Modified: 
    llvm/lib/Target/AArch64/AArch64SystemOperands.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
    llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 004bff92c082d..8129dde0658cf 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -856,34 +856,44 @@ def : TIndex<"nb", 0b1>;
 // TLBI (translation lookaside buffer invalidate) instruction options.
 //===----------------------------------------------------------------------===//
 
+def SysAliasRegUse : GenericEnum {
+  let FilterClass = "RegValue";
+}
+
+class RegValue;
+
+def REG_NONE     : RegValue;
+def REG_OPTIONAL : RegValue;
+def REG_REQUIRED : RegValue;
+
 class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, bit needsreg, bit optionalreg> {
+                 bits<3> op2, RegValue reguse> {
   string Name = name;
   bits<14> Encoding;
+  RegValue RegUse = reguse;
   let Encoding{13-11} = op1;
   let Encoding{10-7} = crn;
   let Encoding{6-3} = crm;
   let Encoding{2-0} = op2;
-  bit NeedsReg = needsreg;
-  bit OptionalReg = optionalreg;
   list<string> Requires = [];
   list<string> ExtraRequires = [];
   code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }];
 }
 
 class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                bits<3> op2, bit needsreg, bit optionalreg>
-  : TLBICommon<name, op1, crn, crm, op2, needsreg, optionalreg>;
+                bits<3> op2, RegValue reguse>
+  : TLBICommon<name, op1, crn, crm, op2, reguse>;
 
 class TLBIPEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, bit needsreg, bit optionalreg>
-  : TLBICommon<name, op1, crn, crm, op2, needsreg, optionalreg>;
+                 bits<3> op2, RegValue reguse>
+  : TLBICommon<name, op1, crn, crm, op2, reguse>;
 
 multiclass TLBITableBase {
   def NAME # Table : GenericTable {
     let FilterClass = NAME # "Entry";
     let CppTypeName = NAME;
-    let Fields = ["Name", "Encoding", "NeedsReg", "OptionalReg", "RequiresStr"];
+    let Fields = ["Name", "Encoding", "RegUse", "RequiresStr"];
+    string TypeOf_RegUse = "SysAliasRegUse";
     let PrimaryKey = ["Encoding"];
     let PrimaryKeyName = "lookup" # NAME # "ByEncoding";
   }
@@ -897,127 +907,127 @@ defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
 multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn, bits<4> crm,
-             bits<3> op2, bit needsreg = 1, bit optionalreg = 0> {
-  def : TLBIEntry<name, op1, crn, crm, op2, needsreg, optionalreg>;
-  def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg, optionalreg> {
+             bits<3> op2, RegValue reguse> {
+  def : TLBIEntry<name, op1, crn, crm, op2, reguse>;
+  def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
     let Encoding{7} = 1;
     let ExtraRequires = ["AArch64::FeatureXS"];
   }
   if !eq(hasTLBIP, true) then {
-    def : TLBIPEntry<name, op1, crn, crm, op2, needsreg, optionalreg> {
+    def : TLBIPEntry<name, op1, crn, crm, op2, reguse> {
       let ExtraRequires = ["AArch64::FeatureD128"];
     }
-    def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg, optionalreg> {
+    def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
       let Encoding{7} = 1;
       let ExtraRequires = ["AArch64::FeatureD128"];
     }
   }
 }
 
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg, optreg
-defm : TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001>;
-defm : TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101>;
-defm : TLBI<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, 0, 1>;
-defm : TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, 0, 1>;
-defm : TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, 0, 1>;
-defm : TLBI<"VAE1IS",       1, 0b000, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"VAE2IS",       1, 0b100, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"VAE3IS",       1, 0b110, 0b1000, 0b0011, 0b001>;
-defm : TLBI<"ASIDE1IS",     0, 0b000, 0b1000, 0b0011, 0b010>;
-defm : TLBI<"VAAE1IS",      1, 0b000, 0b1000, 0b0011, 0b011>;
-defm : TLBI<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, 0, 1>;
-defm : TLBI<"VALE1IS",      1, 0b000, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VALE2IS",      1, 0b100, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VALE3IS",      1, 0b110, 0b1000, 0b0011, 0b101>;
-defm : TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, 0, 1>;
-defm : TLBI<"VAALE1IS",     1, 0b000, 0b1000, 0b0011, 0b111>;
-defm : TLBI<"IPAS2E1",      1, 0b100, 0b1000, 0b0100, 0b001>;
-defm : TLBI<"IPAS2LE1",     1, 0b100, 0b1000, 0b0100, 0b101>;
-defm : TLBI<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, 0, 0>;
-defm : TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, 0, 0>;
-defm : TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, 0, 0>;
-defm : TLBI<"VAE1",         1, 0b000, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"VAE2",         1, 0b100, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"VAE3",         1, 0b110, 0b1000, 0b0111, 0b001>;
-defm : TLBI<"ASIDE1",       0, 0b000, 0b1000, 0b0111, 0b010>;
-defm : TLBI<"VAAE1",        1, 0b000, 0b1000, 0b0111, 0b011>;
-defm : TLBI<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, 0, 0>;
-defm : TLBI<"VALE1",        1, 0b000, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VALE2",        1, 0b100, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101>;
-defm : TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, 0, 0>;
-defm : TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>;
+defm : TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>;
+defm : TLBI<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+defm : TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+defm : TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+defm : TLBI<"VAE1IS",       1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+defm : TLBI<"VAE2IS",       1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+defm : TLBI<"VAE3IS",       1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+defm : TLBI<"ASIDE1IS",     0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>;
+defm : TLBI<"VAAE1IS",      1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>;
+defm : TLBI<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>;
+defm : TLBI<"VALE1IS",      1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+defm : TLBI<"VALE2IS",      1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+defm : TLBI<"VALE3IS",      1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+defm : TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>;
+defm : TLBI<"VAALE1IS",     1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>;
+defm : TLBI<"IPAS2E1",      1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>;
+defm : TLBI<"IPAS2LE1",     1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>;
+defm : TLBI<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>;
+defm : TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>;
+defm : TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>;
+defm : TLBI<"VAE1",         1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+defm : TLBI<"VAE2",         1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+defm : TLBI<"VAE3",         1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+defm : TLBI<"ASIDE1",       0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>;
+defm : TLBI<"VAAE1",        1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>;
+defm : TLBI<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>;
+defm : TLBI<"VALE1",        1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+defm : TLBI<"VALE2",        1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+defm : TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+defm : TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
+defm : TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
 
 // Armv8.4-A Translation Lookaside Buffer Instructions (TLBI)
 let Requires = ["AArch64::FeatureTLB_RMI"] in {
 // Armv8.4-A Outer Sharable TLB Maintenance instructions:
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg, optreg
-defm : TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, 0, 1>;
-defm : TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010>;
-defm : TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011>;
-defm : TLBI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111>;
-defm : TLBI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000>;
-defm : TLBI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100>;
-defm : TLBI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, 0, 1>;
-defm : TLBI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001>;
-defm : TLBI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101>;
-defm : TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, 0, 1>;
-defm : TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, 0, 1>;
-defm : TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, 0, 1>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+defm : TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
+defm : TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
+defm : TLBI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
+defm : TLBI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
+defm : TLBI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
+defm : TLBI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
+defm : TLBI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+defm : TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
+defm : TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
 
 // Armv8.4-A TLB Range Maintenance instructions:
 //                   hasTLBIP  op1    CRn     CRm     op2
-defm : TLBI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011>;
-defm : TLBI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111>;
-defm : TLBI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011>;
-defm : TLBI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111>;
-defm : TLBI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011>;
-defm : TLBI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101>;
-defm : TLBI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111>;
-defm : TLBI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010>;
-defm : TLBI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110>;
-defm : TLBI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010>;
-defm : TLBI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110>;
-defm : TLBI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011>;
-defm : TLBI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111>;
-defm : TLBI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101>;
-defm : TLBI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001>;
-defm : TLBI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101>;
-defm : TLBI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001>;
-defm : TLBI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101>;
-defm : TLBI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001>;
-defm : TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101>;
+defm : TLBI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
+defm : TLBI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
+defm : TLBI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
+defm : TLBI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
+defm : TLBI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
+defm : TLBI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
+defm : TLBI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
+defm : TLBI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
+defm : TLBI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
+defm : TLBI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
+defm : TLBI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+defm : TLBI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+defm : TLBI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
 } //FeatureTLB_RMI
 
 // Armv9-A Realm Management Extension TLBI Instructions
 let Requires = ["AArch64::FeatureRME"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg
-defm : TLBI<"RPAOS",        0, 0b110, 0b1000, 0b0100, 0b011>;
-defm : TLBI<"RPALOS",       0, 0b110, 0b1000, 0b0100, 0b111>;
-defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, 0, 0>;
-defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, 0, 0>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"RPAOS",        0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+defm : TLBI<"RPALOS",       0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
+defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
 let Requires = ["AArch64::FeatureTLBIW"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg, optreg
-defm : TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, 0, 0>;
-defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, 0, 1>;
-defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, 0, 1>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
+defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
+defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -2827,22 +2837,22 @@ foreach n = 0-1 in {
 }
 
 class PLBIEntry<bits<3> op1, bits<4> crn, bits<4> crm, bits<3> op2, string name,
-                bit needsreg, bit optionalreg> {
+                RegValue reguse> {
   string Name = name;
   bits<14> Encoding;
+  RegValue RegUse = reguse;
   let Encoding{13-11} = op1;
   let Encoding{10-7} = crn;
   let Encoding{6-3} = crm;
   let Encoding{2-0} = op2;
-  bit NeedsReg = needsreg;
-  bit OptionalReg = optionalreg;
   string RequiresStr = [{ {AArch64::FeatureS1POE2} }];
 }
 
 def PLBITable : GenericTable {
   let FilterClass = "PLBIEntry";
   let CppTypeName = "PLBI";
-  let Fields = ["Name", "Encoding", "NeedsReg", "OptionalReg", "RequiresStr"];
+  let Fields = ["Name", "Encoding", "RegUse", "RequiresStr"];
+  string TypeOf_RegUse = "SysAliasRegUse";
 
   let PrimaryKey = ["Encoding"];
   let PrimaryKeyName = "lookupPLBIByEncoding";
@@ -2854,24 +2864,25 @@ def lookupPLBIByName : SearchIndex {
 }
 
 multiclass PLBI<string name, bits<3> op1, bits<4> crn, bits<3> op2,
-                bit needsreg, bit optreg> {
+                RegValue reguse, bit optionalIS = 0> {
   // Entries containing "IS" or "OS" allow optional regs when +tlbid enabled
-  def : PLBIEntry<op1, crn, 0b0111, op2, name,         needsreg, 0>;
-  def : PLBIEntry<op1, crn, 0b0011, op2, name#"IS",    needsreg, optreg>;
-  def : PLBIEntry<op1, crn, 0b0001, op2, name#"OS",    needsreg, optreg>;
-  def : PLBIEntry<op1, crn, 0b1111, op2, name#"NXS",   needsreg, 0>;
-  def : PLBIEntry<op1, crn, 0b1011, op2, name#"ISNXS", needsreg, optreg>;
-  def : PLBIEntry<op1, crn, 0b1001, op2, name#"OSNXS", needsreg, optreg>;
+  defvar ISOSRegUse = !if(optionalIS, REG_OPTIONAL, reguse);
+  def : PLBIEntry<op1, crn, 0b0111, op2, name,         reguse>;
+  def : PLBIEntry<op1, crn, 0b0011, op2, name#"IS",    ISOSRegUse>;
+  def : PLBIEntry<op1, crn, 0b0001, op2, name#"OS",    ISOSRegUse>;
+  def : PLBIEntry<op1, crn, 0b1111, op2, name#"NXS",   reguse>;
+  def : PLBIEntry<op1, crn, 0b1011, op2, name#"ISNXS", ISOSRegUse>;
+  def : PLBIEntry<op1, crn, 0b1001, op2, name#"OSNXS", ISOSRegUse>;
 }
 
 // CRm defines above six variants of each instruction. It is omitted here.
-//                     Op1    CRn     Op2    nr optreg
-defm : PLBI<"ALLE3",   0b110, 0b1010, 0b000, 0, 0>;
-defm : PLBI<"ALLE2",   0b100, 0b1010, 0b000, 0, 1>;
-defm : PLBI<"ALLE1",   0b100, 0b1010, 0b100, 0, 1>;
-defm : PLBI<"VMALLE1", 0b000, 0b1010, 0b000, 0, 1>;
-defm : PLBI<"ASIDE1",  0b000, 0b1010, 0b010, 1, 0>;
-defm : PLBI<"PERME3",  0b110, 0b1010, 0b001, 1, 0>;
-defm : PLBI<"PERME2",  0b100, 0b1010, 0b001, 1, 0>;
-defm : PLBI<"PERME1",  0b000, 0b1010, 0b001, 1, 0>;
-defm : PLBI<"PERMAE1", 0b000, 0b1010, 0b011, 1, 0>;
+//                     Op1    CRn     Op2    reguse    optionalIS
+defm : PLBI<"ALLE3",   0b110, 0b1010, 0b000, REG_NONE>;
+defm : PLBI<"ALLE2",   0b100, 0b1010, 0b000, REG_NONE, 1>;
+defm : PLBI<"ALLE1",   0b100, 0b1010, 0b100, REG_NONE, 1>;
+defm : PLBI<"VMALLE1", 0b000, 0b1010, 0b000, REG_NONE, 1>;
+defm : PLBI<"ASIDE1",  0b000, 0b1010, 0b010, REG_REQUIRED>;
+defm : PLBI<"PERME3",  0b110, 0b1010, 0b001, REG_REQUIRED>;
+defm : PLBI<"PERME2",  0b100, 0b1010, 0b001, REG_REQUIRED>;
+defm : PLBI<"PERME1",  0b000, 0b1010, 0b001, REG_REQUIRED>;
+defm : PLBI<"PERMAE1", 0b000, 0b1010, 0b011, REG_REQUIRED>;

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index cdfb9ee46634a..9cfccaf8fcaba 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -4092,11 +4092,9 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
       setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
       return TokError(Str);
     }
-    ExpectRegister = TLBI->NeedsReg;
-    bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
-    if (hasAll || hasTLBID) {
-      OptionalRegister = TLBI->OptionalReg;
-    }
+    ExpectRegister = TLBI->RegUse == REG_REQUIRED;
+    if (hasAll || hasTLBID)
+      OptionalRegister = TLBI->RegUse == REG_OPTIONAL;
     createSysAlias(TLBI->Encoding, Operands, S);
   } else if (Mnemonic == "mlbi") {
     const AArch64MLBI::MLBI *MLBI = AArch64MLBI::lookupMLBIByName(Op);
@@ -4140,10 +4138,9 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
       setRequiredFeatureString(PLBI->getRequiredFeatures(), Str);
       return TokError(Str);
     }
-    ExpectRegister = PLBI->NeedsReg;
-    if (hasAll || hasTLBID) {
-      OptionalRegister = PLBI->OptionalReg;
-    }
+    ExpectRegister = PLBI->RegUse == REG_REQUIRED;
+    if (hasAll || hasTLBID)
+      OptionalRegister = PLBI->RegUse == REG_OPTIONAL;
     createSysAlias(PLBI->Encoding, Operands, S);
   } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" ||
              Mnemonic == "cosp") {

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 2fe162f930fdf..2f4b3fa016336 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1021,10 +1021,10 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
     if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))
       return false;
 
-    NeedsReg = TLBI->NeedsReg;
+    NeedsReg = TLBI->RegUse == REG_REQUIRED;
     if (STI.hasFeature(AArch64::FeatureAll) ||
         STI.hasFeature(AArch64::FeatureTLBID))
-      OptionalReg = TLBI->OptionalReg;
+      OptionalReg = TLBI->RegUse == REG_OPTIONAL;
     Ins = "tlbi\t";
     Name = std::string(TLBI->Name);
   } else if (CnVal == 12) {
@@ -1053,10 +1053,10 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
     if (!PLBI || !PLBI->haveFeatures(STI.getFeatureBits()))
       return false;
 
-    NeedsReg = PLBI->NeedsReg;
+    NeedsReg = PLBI->RegUse == REG_REQUIRED;
     if (STI.hasFeature(AArch64::FeatureAll) ||
         STI.hasFeature(AArch64::FeatureTLBID))
-      OptionalReg = PLBI->OptionalReg;
+      OptionalReg = PLBI->RegUse == REG_OPTIONAL;
     Ins = "plbi\t";
     Name = std::string(PLBI->Name);
   } else

diff  --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 97777dec45863..38b2b3ec1e8dc 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -435,6 +435,9 @@ struct SysAlias {
   FeatureBitset getRequiredFeatures() const { return FeaturesRequired; }
 };
 
+#define GET_SysAliasRegUse_DECL
+#include "AArch64GenSystemOperands.inc"
+
 struct SysAliasReg : SysAlias {
   bool NeedsReg;
   constexpr SysAliasReg(const char *N, uint16_t E, bool R)
@@ -444,13 +447,12 @@ struct SysAliasReg : SysAlias {
 };
 
 struct SysAliasOptionalReg : SysAlias {
-  bool NeedsReg;
-  bool OptionalReg;
-  constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O)
-      : SysAlias(N, E), NeedsReg(R), OptionalReg(O) {}
-  constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O,
+  SysAliasRegUse RegUse;
+  constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R)
+      : SysAlias(N, E), RegUse(R) {}
+  constexpr SysAliasOptionalReg(const char *N, uint16_t E, SysAliasRegUse R,
                                 FeatureBitset F)
-      : SysAlias(N, E, F), NeedsReg(R), OptionalReg(O) {}
+      : SysAlias(N, E, F), RegUse(R) {}
 };
 
 struct SysAliasImm : SysAlias {


        


More information about the llvm-commits mailing list