[llvm] [PowerPC][NFC] Refactor Register class and operand definitons (PR #185647)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 06:27:13 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-powerpc

Author: Lei Huang (lei137)

<details>
<summary>Changes</summary>

Main change is to add a multiclass to generate RegisterOperands and it's required AsmOperand to reduce code
duplication.

Asissted by AI.

---

Patch is 36.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/185647.diff


6 Files Affected:

- (modified) llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp (+4-4) 
- (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+1) 
- (added) llvm/lib/Target/PowerPC/PPCRegisterClasses.td (+101) 
- (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.td (+124-308) 
- (modified) llvm/lib/Target/PowerPC/PPCRegisterInfoDMR.td (+26-23) 
- (modified) llvm/lib/Target/PowerPC/PPCRegisterInfoMMA.td (+45-40) 


``````````diff
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index b07f95018ca90..7b07c0881d453 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -458,7 +458,7 @@ struct PPCOperand : public MCParsedAsmOperand {
     Inst.addOperand(MCOperand::createReg(RRegs[getRegNum()]));
   }
 
-  void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
+  void addRegGPRC_NOR0Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::createReg(RRegsNoR0[getRegNum()]));
   }
@@ -468,7 +468,7 @@ struct PPCOperand : public MCParsedAsmOperand {
     Inst.addOperand(MCOperand::createReg(XRegs[getRegNum()]));
   }
 
-  void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
+  void addRegG8RC_NOX0Operands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::createReg(XRegsNoX0[getRegNum()]));
   }
@@ -487,9 +487,9 @@ struct PPCOperand : public MCParsedAsmOperand {
 
   void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
     if (isPPC64())
-      addRegG8RCNoX0Operands(Inst, N);
+      addRegG8RC_NOX0Operands(Inst, N);
     else
-      addRegGPRCNoR0Operands(Inst, N);
+      addRegGPRC_NOR0Operands(Inst, N);
   }
 
   void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index cc5b7d90fd189..3271e4d279f56 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -733,6 +733,7 @@ def nzFPImmExactInti5 : PatLeaf<(fpimm), [{
   return IsExact && IntResult <= 15 && IntResult >= -16 && !FloatValue.isZero();
 }]>;
 
+// Floating point zero immediates (positive and negative)
 def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
 def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;
 
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterClasses.td b/llvm/lib/Target/PowerPC/PPCRegisterClasses.td
new file mode 100644
index 0000000000000..53697ac89dd1b
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/PPCRegisterClasses.td
@@ -0,0 +1,101 @@
+//===-- PPCRegisterClasses.td - PPC Register Class Definitions -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines base classes for PowerPC register classes to reduce
+// repetition and make it easier to define new register classes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Base Register Class Definitions
+//===----------------------------------------------------------------------===//
+
+// Base class for all PPC register classes - sets namespace to "PPC"
+class PPCRegisterClass<list<ValueType> regTypes, int alignment, dag regList>
+  : RegisterClass<"PPC", regTypes, alignment, regList>;
+
+//===----------------------------------------------------------------------===//
+// Variant Register Class Definitions
+//===----------------------------------------------------------------------===//
+
+// Register class that is not allocatable
+class PPCNonAllocatableRegisterClass<list<ValueType> regTypes, int alignment,
+                                     dag regList>
+  : PPCRegisterClass<regTypes, alignment, regList> {
+  let isAllocatable = 0;
+}
+
+// Register class with explicit size
+class PPCRegisterClassWithSize<list<ValueType> regTypes, int alignment,
+                               dag regList, int size>
+  : PPCRegisterClass<regTypes, alignment, regList> {
+  let Size = size;
+}
+
+// Register class with allocation priority and size
+class PPCRegisterClassWithPriority<list<ValueType> regTypes, int alignment,
+                                   dag regList, int allocPriority,
+                                   bit globalPriority, int size>
+  : PPCRegisterClass<regTypes, alignment, regList> {
+  let AllocationPriority = allocPriority;
+  let GlobalPriority = globalPriority;
+  let Size = size;
+}
+
+// GPR-style register class with alternative orders for different ABIs
+// Merged PPCRegisterClassWithAltOrders into this class since it was only used here
+class PPCGPRRegisterClass<list<ValueType> regTypes, int alignment, dag regList,
+                          dag altOrder1, dag altOrder2>
+  : PPCRegisterClass<regTypes, alignment, regList> {
+  let AltOrders = [altOrder1, altOrder2];
+  let AltOrderSelect = [{
+    return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx();
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// Classes for Generating RegisterOperand for Existing RegisterClass
+//===----------------------------------------------------------------------===//
+
+// Base class that creates a RegisterOperand for an already-defined RegisterClass,
+// assuming the AsmOperandClass already exists with the standard naming convention
+// (PPCReg<regClassName>AsmOperand).
+//
+// Usage: def spe4rc : PPCRegOperandOnly<"GPRC">;
+//   Creates: spe4rc RegisterOperand wrapping GPRC, using PPCRegGPRCAsmOperand
+class PPCRegOperandOnly<string regClassName>
+  : RegisterOperand<!cast<RegisterClass>(regClassName)> {
+  let ParserMatchClass = !cast<AsmOperandClass>(!strconcat("PPCReg", regClassName, "AsmOperand"));
+}
+
+// Multiclass that generates both the AsmOperandClass and RegisterOperand for an
+// already-defined RegisterClass. This eliminates the repetitive pattern of
+// manually defining these for each register class.
+//
+// Usage examples:
+//   defm GPRC : PPCRegOperand<"isRegNumber">;
+//     Creates: PPCRegGPRCAsmOperand and gprc (lowercase of GPRC)
+//   defm FpRC : PPCRegOperand<"isEvenRegNumber", "fpairrc">;
+//     Creates: PPCRegFpRCAsmOperand and fpairrc (custom name)
+//
+// The NAME in the defm statement  match the RegisterClass name.
+
+multiclass PPCRegOperand<string predicate, string operandName = ""> {
+  // Define the AsmOperandClass
+  def "PPCReg"#NAME#"AsmOperand" : AsmOperandClass {
+    let Name = "Reg"#NAME;
+    let PredicateMethod = predicate;
+  }
+  
+  // Define the RegisterOperand
+  // Use custom name if provided, otherwise use lowercase of NAME
+  def !if(!eq(operandName, ""), !tolower(NAME), operandName)
+    : RegisterOperand<!cast<RegisterClass>(NAME)> {
+    let ParserMatchClass = !cast<AsmOperandClass>("PPCReg"#NAME#"AsmOperand");
+  }
+}
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
index 28cfbc9991c3c..78352f9f75014 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -10,6 +10,7 @@
 //===----------------------------------------------------------------------===//
 
 include "PPCOperands.td"
+include "PPCRegisterClasses.td"
 
 let Namespace = "PPC" in {
   def sub_lt : SubRegIndex<1>;
@@ -167,9 +168,13 @@ let isArtificial = 1 in {
   }
 }
 
-let isAllocatable = 0, CopyCost = -1 in {
-  def VFHRC : RegisterClass<"PPC", [f64], 64, (sequence "VFH%u", 0, 31)>;
-  def FHRC : RegisterClass<"PPC", [f64], 64, (sequence "FH%u", 0, 31)>;
+def VFHRC : PPCNonAllocatableRegisterClass<[f64], 64,
+              (sequence "VFH%u", 0, 31)> {
+  let CopyCost = -1;
+}
+def FHRC : PPCNonAllocatableRegisterClass<[f64], 64,
+             (sequence "FH%u", 0, 31)> {
+  let CopyCost = -1;
 }
 
 // Floating-point pair registers
@@ -296,71 +301,60 @@ def CARRY: SPR<1, "xer">, DwarfRegNum<[76]> {
 // that do nothing but change RM will not get deleted.
 def RM: PPCReg<"**ROUNDING MODE**">;
 
-let isAllocatable = 0 in
-def GPRC32 : RegisterClass<"PPC", [i32,f32], 32, (add (sequence "H%u", 2, 12),
-                                                      (sequence "H%u", 30, 13),
-                                                      H31, H0, H1)>;
+def GPRC32 : PPCNonAllocatableRegisterClass<[i32,f32], 32,
+               (add (sequence "H%u", 2, 12),
+                    (sequence "H%u", 30, 13),
+                    H31, H0, H1)>;
 
 /// Register classes
 // Allocate volatiles first
 // then nonvolatiles in reverse order since stmw/lmw save from rN to r31
-def GPRC : RegisterClass<"PPC", [i32,f32], 32, (add (sequence "R%u", 2, 12),
-                                                    (sequence "R%u", 30, 13),
-                                                    R31, R0, R1, FP, BP)> {
-  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
-  // put it at the end of the list.
-  // On AIX, CSRs are allocated starting from R31 according to:
-  // https://www.ibm.com/docs/en/ssw_aix_72/assembler/assembler_pdf.pdf.
-  // This also helps setting the correct `NumOfGPRsSaved' in traceback table.
-  let AltOrders = [(add (sub GPRC, R2), R2),
-                   (add (sequence "R%u", 2, 12),
-                        (sequence "R%u", 31, 13), R0, R1, FP, BP)];
-  let AltOrderSelect = [{
-    return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx();
-  }];
-}
-
-def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12),
-                                                (sequence "X%u", 30, 14),
-                                                X31, X13, X0, X1, FP8, BP8)> {
-  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
-  // put it at the end of the list.
-  let AltOrders = [(add (sub G8RC, X2), X2),
-                   (add (sequence "X%u", 2, 12),
-                        (sequence "X%u", 31, 13), X0, X1, FP8, BP8)];
-  let AltOrderSelect = [{
-    return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx();
-  }];
-}
+def GPRC : PPCGPRRegisterClass<[i32,f32], 32,
+             (add (sequence "R%u", 2, 12),
+                  (sequence "R%u", 30, 13),
+                  R31, R0, R1, FP, BP),
+             // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+             // put it at the end of the list.
+             (add (sub GPRC, R2), R2),
+             // On AIX, CSRs are allocated starting from R31 according to:
+             // https://www.ibm.com/docs/en/ssw_aix_72/assembler/assembler_pdf.pdf.
+             // This also helps setting the correct `NumOfGPRsSaved' in traceback table.
+             (add (sequence "R%u", 2, 12),
+                  (sequence "R%u", 31, 13), R0, R1, FP, BP)>;
+
+def G8RC : PPCGPRRegisterClass<[i64], 64,
+             (add (sequence "X%u", 2, 12),
+                  (sequence "X%u", 30, 14),
+                  X31, X13, X0, X1, FP8, BP8),
+             // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+             // put it at the end of the list.
+             (add (sub G8RC, X2), X2),
+             (add (sequence "X%u", 2, 12),
+                  (sequence "X%u", 31, 13), X0, X1, FP8, BP8)>;
 
 // For some instructions r0 is special (representing the value 0 instead of
 // the value in the r0 register), and we use these register subclasses to
 // prevent r0 from being allocated for use by those instructions.
-def GPRC_NOR0 : RegisterClass<"PPC", [i32,f32], 32, (add (sub GPRC, R0), ZERO)> {
-  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
-  // put it at the end of the list.
-  let AltOrders = [(add (sub GPRC_NOR0, R2), R2),
-                   (add (sequence "R%u", 2, 12),
-                        (sequence "R%u", 31, 13), R1, FP, BP, ZERO)];
-  let AltOrderSelect = [{
-    return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx();
-  }];
-}
-
-def G8RC_NOX0 : RegisterClass<"PPC", [i64], 64, (add (sub G8RC, X0), ZERO8)> {
-  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
-  // put it at the end of the list.
-  let AltOrders = [(add (sub G8RC_NOX0, X2), X2),
-                   (add (sequence "X%u", 2, 12),
-                        (sequence "X%u", 31, 13), X1, FP8, BP8, ZERO8)];
-  let AltOrderSelect = [{
-    return MF.getSubtarget<PPCSubtarget>().getGPRAllocationOrderIdx();
-  }];
-}
-
-def SPERC : RegisterClass<"PPC", [f64], 64, (add (sequence "S%u", 2, 12),
-                                                (sequence "S%u", 30, 13),
-                                                S31, S0, S1)>;
+def GPRC_NOR0 : PPCGPRRegisterClass<[i32,f32], 32,
+                  (add (sub GPRC, R0), ZERO),
+                  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+                  // put it at the end of the list.
+                  (add (sub GPRC_NOR0, R2), R2),
+                  (add (sequence "R%u", 2, 12),
+                       (sequence "R%u", 31, 13), R1, FP, BP, ZERO)>;
+
+def G8RC_NOX0 : PPCGPRRegisterClass<[i64], 64,
+                  (add (sub G8RC, X0), ZERO8),
+                  // On non-Darwin PPC64 systems, R2 can be allocated, but must be restored, so
+                  // put it at the end of the list.
+                  (add (sub G8RC_NOX0, X2), X2),
+                  (add (sequence "X%u", 2, 12),
+                       (sequence "X%u", 31, 13), X1, FP8, BP8, ZERO8)>;
+
+def SPERC : PPCRegisterClass<[f64], 64,
+              (add (sequence "S%u", 2, 12),
+                   (sequence "S%u", 30, 13),
+                   S31, S0, S1)>;
 
 // Allocate volatiles first, then non-volatiles in reverse order. With the SVR4
 // ABI the size of the Floating-point register save area is determined by the
@@ -369,9 +363,11 @@ def SPERC : RegisterClass<"PPC", [f64], 64, (add (sequence "S%u", 2, 12),
 // previous stack frame. By allocating non-volatiles in reverse order we make
 // sure that the Floating-point register save area is always as small as
 // possible because there aren't any unused spill slots.
-def F8RC : RegisterClass<"PPC", [f64], 64, (add (sequence "F%u", 0, 13),
-                                                (sequence "F%u", 31, 14))>;
-def F4RC : RegisterClass<"PPC", [f32], 32, (add F8RC)>;
+def F8RC : PPCRegisterClass<[f64], 64,
+             (add (sequence "F%u", 0, 13),
+                  (sequence "F%u", 31, 14))>;
+
+def F4RC : PPCRegisterClass<[f32], 32, (add F8RC)>;
 
 // Floating point pair registers.
 // Note that the type used for this register class is ppcf128. This is not
@@ -380,47 +376,46 @@ def F4RC : RegisterClass<"PPC", [f32], 32, (add F8RC)>;
 // scheduling any of these instructions it should be safe to do this.
 // The reason we didn't use the correct type (Decimal Floating Point) is that
 // at the time of this implementation the correct type was not available.
-def FpRC :
-  RegisterClass<"PPC", [ppcf128], 128,
-                (add Fpair0, Fpair2, Fpair4, Fpair6, Fpair8, Fpair10, Fpair12,
-                     Fpair14, Fpair16, Fpair18, Fpair20, Fpair22, Fpair24,
-                     Fpair26, Fpair28, Fpair30)> {
-  let Size = 128;
-}
+def FpRC : PPCRegisterClassWithSize<[ppcf128], 128,
+             (add Fpair0, Fpair2, Fpair4, Fpair6, Fpair8, Fpair10, Fpair12,
+                  Fpair14, Fpair16, Fpair18, Fpair20, Fpair22, Fpair24,
+                  Fpair26, Fpair28, Fpair30), 128>;
 
-def VRRC : RegisterClass<"PPC",
-                         [v16i8,v8i16,v4i32,v2i64,v1i128,v4f32,v2f64, f128],
-                         128,
-                         (add V2, V3, V4, V5, V0, V1, V6, V7, V8, V9, V10, V11,
-                             V12, V13, V14, V15, V16, V17, V18, V19, V31, V30,
-                             V29, V28, V27, V26, V25, V24, V23, V22, V21, V20)>;
+def VRRC : PPCRegisterClassWithSize<[v16i8,v8i16,v4i32,v2i64,v1i128,v4f32,v2f64, f128],
+             128,
+             (add V2, V3, V4, V5, V0, V1, V6, V7, V8, V9, V10, V11,
+                  V12, V13, V14, V15, V16, V17, V18, V19, V31, V30,
+                  V29, V28, V27, V26, V25, V24, V23, V22, V21, V20), 128>;
 
 // VSX register classes (the allocation order mirrors that of the corresponding
 // subregister classes).
-def VSLRC : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128,
-                          (add (sequence "VSL%u", 0, 13),
-                               (sequence "VSL%u", 31, 14))>;
-def VSRC  : RegisterClass<"PPC", [v4i32,v4f32,v2f64,v2i64], 128,
-                          (add VSLRC, VRRC)>;
+def VSLRC : PPCRegisterClassWithSize<[v4i32,v4f32,v2f64,v2i64], 128,
+              (add (sequence "VSL%u", 0, 13),
+                   (sequence "VSL%u", 31, 14)), 128>;
+
+def VSRC  : PPCRegisterClassWithSize<[v4i32,v4f32,v2f64,v2i64], 128,
+              (add VSLRC, VRRC), 128>;
 
 // Register classes for the 64-bit "scalar" VSX subregisters.
-def VFRC :  RegisterClass<"PPC", [f64], 64,
-                          (add VF2, VF3, VF4, VF5, VF0, VF1, VF6, VF7,
-                               VF8, VF9, VF10, VF11, VF12, VF13, VF14,
-                               VF15, VF16, VF17, VF18, VF19, VF31, VF30,
-                               VF29, VF28, VF27, VF26, VF25, VF24, VF23,
-                               VF22, VF21, VF20)>;
-def VSFRC : RegisterClass<"PPC", [f64], 64, (add F8RC, VFRC)>;
+def VFRC :  PPCRegisterClass<[f64], 64,
+              (add VF2, VF3, VF4, VF5, VF0, VF1, VF6, VF7,
+                   VF8, VF9, VF10, VF11, VF12, VF13, VF14,
+                   VF15, VF16, VF17, VF18, VF19, VF31, VF30,
+                   VF29, VF28, VF27, VF26, VF25, VF24, VF23,
+                   VF22, VF21, VF20)>;
+
+def VSFRC : PPCRegisterClass<[f64], 64, (add F8RC, VFRC)>;
 
 // Allow spilling GPR's into caller-saved VSR's.
-def SPILLTOVSRRC : RegisterClass<"PPC", [i64, f64], 64, (add G8RC, (sub VSFRC,
-				(sequence "VF%u", 31, 20),
-				(sequence "F%u", 31, 14)))>;
+def SPILLTOVSRRC : PPCRegisterClass<[i64, f64], 64,
+                     (add G8RC, (sub VSFRC,
+                          (sequence "VF%u", 31, 20),
+                          (sequence "F%u", 31, 14)))>;
 
 // Register class for single precision scalars in VSX registers
-def VSSRC : RegisterClass<"PPC", [f32], 32, (add VSFRC)>;
+def VSSRC : PPCRegisterClass<[f32], 32, (add VSFRC)>;
 
-def CRBITRC : RegisterClass<"PPC", [i1], 32,
+def CRBITRC : PPCRegisterClassWithSize<[i1], 32,
   (add CR2LT, CR2GT, CR2EQ, CR2UN,
        CR3LT, CR3GT, CR3EQ, CR3UN,
        CR4LT, CR4GT, CR4EQ, CR4UN,
@@ -428,8 +423,7 @@ def CRBITRC : RegisterClass<"PPC", [i1], 32,
        CR6LT, CR6GT, CR6EQ, CR6UN,
        CR7LT, CR7GT, CR7EQ, CR7UN,
        CR1LT, CR1GT, CR1EQ, CR1UN,
-       CR0LT, CR0GT, CR0EQ, CR0UN)> {
-  let Size = 32;
+       CR0LT, CR0GT, CR0EQ, CR0UN), 32> {
   let AltOrders = [(sub CRBITRC, CR2LT, CR2GT, CR2EQ, CR2UN, CR3LT, CR3GT,
                         CR3EQ, CR3UN, CR4LT, CR4GT, CR4EQ, CR4UN)];
   let AltOrderSelect = [{
@@ -438,7 +432,7 @@ def CRBITRC : RegisterClass<"PPC", [i1], 32,
   }];
 }
 
-def CRRC : RegisterClass<"PPC", [i32], 32,
+def CRRC : PPCRegisterClass<[i32], 32,
   (add CR0, CR1, CR5, CR6,
        CR7, CR2, CR3, CR4)> {
   let AltOrders = [(sub CRRC, CR2, CR3, CR4)];
@@ -447,47 +441,34 @@ def CRRC : RegisterClass<"PPC", [i32], 32,
            MF.getInfo<PPCFunctionInfo>()->isNonVolatileCRDisabled();
   }];
 }
+
 // The CTR registers are not allocatable because they're used by the
 // decrement-and-branch instructions, and thus need to stay live across
 // multiple basic blocks.
-def CTRRC : RegisterClass<"PPC", [i32], 32, (add CTR)> {
-  let isAllocatable = 0;
-}
-def CTRRC8 : RegisterClass<"PPC", [i64], 64, (add CTR8)> {
-  let isAllocatable = 0;
-}
+def CTRRC : PPCNonAllocatableRegisterClass<[i32], 32, (add CTR)>;
+def CTRRC8 : PPCNonAllocatableRegisterClass<[i64], 64, (add CTR8)>;
 
-def LRRC : RegisterClass<"PPC", [i32], 32, (add LR)> {
-  let isAllocatable = 0;
-}
-def LR8RC : RegisterClass<"PPC", [i64], 64, (add LR8)> {
-  let isAllocatable = 0;
-}
+def LRRC : PPCNonAllocatableRegisterClass<[i32], 32, (add LR)>;
+def LR8RC : PPCNonAllocatableRegisterClass<[i64], 64, (add LR8)>;
 
-def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>;
-def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY, XER)> {
+def VRSAVERC : PPCRegisterClass<[i32], 32, (add VRSAVE)>;
+def CARRYRC : PPCNonAllocatableRegisterClass<[i32], 32, (add CARRY, XER)> {
   let CopyCost = -1;
-  l...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list