| //===-- PPCRegisterClasses.td - 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 | |
| //===----------------------------------------------------------------------===// | |
| // 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 with 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"); | |
| } | |
| } |