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

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 13 09:59:03 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Jonathan Thackray (jthackray)

<details>
<summary>Changes</summary>

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

Split these apart so it's much more logical and easier to maintain
since we've got more updates to this code in future.

---
Full diff: https://github.com/llvm/llvm-project/pull/186451.diff


1 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64SystemOperands.td (+69-42) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 004bff92c082d..9eeb82cb7fdd2 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -856,28 +856,35 @@ def : TIndex<"nb", 0b1>;
 // TLBI (translation lookaside buffer invalidate) instruction options.
 //===----------------------------------------------------------------------===//
 
+defvar SYS_ALIAS_REG_NONE = 0;
+defvar SYS_ALIAS_REG_OPTIONAL = 1;
+defvar SYS_ALIAS_REG_REQUIRED = 2;
+
+class SysAliasRegUse<int reguse> {
+  bit NeedsReg = !eq(reguse, SYS_ALIAS_REG_REQUIRED);
+  bit OptionalReg = !eq(reguse, SYS_ALIAS_REG_OPTIONAL);
+}
+
 class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, bit needsreg, bit optionalreg> {
+                 bits<3> op2, int reguse> : SysAliasRegUse<reguse> {
   string Name = name;
   bits<14> Encoding;
   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, int 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, int reguse>
+  : TLBICommon<name, op1, crn, crm, op2, reguse>;
 
 multiclass TLBITableBase {
   def NAME # Table : GenericTable {
@@ -896,63 +903,83 @@ multiclass TLBITableBase {
 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> {
+multiclass EmitTLBI<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                    bits<3> op2, int reguse> {
+  def : TLBIEntry<name, op1, crn, crm, op2, reguse>;
+}
+
+multiclass EmitTLBINXS<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                       bits<3> op2, int reguse> {
+  def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
     let Encoding{7} = 1;
     let ExtraRequires = ["AArch64::FeatureXS"];
   }
+}
+
+multiclass EmitTLBIP<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                     bits<3> op2, int reguse> {
+  def : TLBIPEntry<name, op1, crn, crm, op2, reguse> {
+    let ExtraRequires = ["AArch64::FeatureD128"];
+  }
+}
+
+multiclass EmitTLBIPNXS<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                        bits<3> op2, int reguse> {
+  def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
+    let Encoding{7} = 1;
+    let ExtraRequires = ["AArch64::FeatureD128"];
+  }
+}
+
+multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn, bits<4> crm,
+             bits<3> op2, int reguse = SYS_ALIAS_REG_REQUIRED> {
+  defm : EmitTLBI<name, op1, crn, crm, op2, reguse>;
+  defm : EmitTLBINXS<name, op1, crn, crm, op2, reguse>;
   if !eq(hasTLBIP, true) then {
-    def : TLBIPEntry<name, op1, crn, crm, op2, needsreg, optionalreg> {
-      let ExtraRequires = ["AArch64::FeatureD128"];
-    }
-    def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg, optionalreg> {
-      let Encoding{7} = 1;
-      let ExtraRequires = ["AArch64::FeatureD128"];
-    }
+    defm : EmitTLBIP<name, op1, crn, crm, op2, reguse>;
+    defm : EmitTLBIPNXS<name, op1, crn, crm, op2, reguse>;
   }
 }
 
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg, optreg
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
 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<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, SYS_ALIAS_REG_OPTIONAL>;
+defm : TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, SYS_ALIAS_REG_OPTIONAL>;
+defm : TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, SYS_ALIAS_REG_OPTIONAL>;
 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<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, SYS_ALIAS_REG_OPTIONAL>;
 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<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, SYS_ALIAS_REG_OPTIONAL>;
 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<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, SYS_ALIAS_REG_NONE>;
+defm : TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, SYS_ALIAS_REG_NONE>;
+defm : TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, SYS_ALIAS_REG_NONE>;
 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<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, SYS_ALIAS_REG_NONE>;
 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<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, SYS_ALIAS_REG_NONE>;
 defm : TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111>;
 
 // 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>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, SYS_ALIAS_REG_OPTIONAL>;
 defm : TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001>;
 defm : TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010>;
 defm : TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011>;
@@ -962,12 +989,12 @@ 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<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, SYS_ALIAS_REG_OPTIONAL>;
 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>;
+defm : TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, SYS_ALIAS_REG_OPTIONAL>;
+defm : TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, SYS_ALIAS_REG_OPTIONAL>;
+defm : TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, SYS_ALIAS_REG_OPTIONAL>;
 
 // Armv8.4-A TLB Range Maintenance instructions:
 //                   hasTLBIP  op1    CRn     CRm     op2
@@ -1005,19 +1032,19 @@ defm : TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101>;
 
 // Armv9-A Realm Management Extension TLBI Instructions
 let Requires = ["AArch64::FeatureRME"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    needsreg
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
 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>;
+defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, SYS_ALIAS_REG_NONE>;
+defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, SYS_ALIAS_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, SYS_ALIAS_REG_NONE>;
+defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, SYS_ALIAS_REG_OPTIONAL>;
+defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, SYS_ALIAS_REG_OPTIONAL>;
 }
 
 //===----------------------------------------------------------------------===//

``````````

</details>


https://github.com/llvm/llvm-project/pull/186451


More information about the llvm-commits mailing list