xref: /aosp_15_r20/external/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- AArch64RegisterBankInfo.cpp -------------------------------*- C++ -*-==//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker /// \file
10*9880d681SAndroid Build Coastguard Worker /// This file implements the targeting of the RegisterBankInfo class for
11*9880d681SAndroid Build Coastguard Worker /// AArch64.
12*9880d681SAndroid Build Coastguard Worker /// \todo This should be generated by TableGen.
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "AArch64RegisterBankInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "AArch64InstrInfo.h" // For XXXRegClassID.
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_BUILD_GLOBAL_ISEL
25*9880d681SAndroid Build Coastguard Worker #error "You shouldn't build this"
26*9880d681SAndroid Build Coastguard Worker #endif
27*9880d681SAndroid Build Coastguard Worker 
AArch64RegisterBankInfo(const TargetRegisterInfo & TRI)28*9880d681SAndroid Build Coastguard Worker AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
29*9880d681SAndroid Build Coastguard Worker     : RegisterBankInfo(AArch64::NumRegisterBanks) {
30*9880d681SAndroid Build Coastguard Worker   // Initialize the GPR bank.
31*9880d681SAndroid Build Coastguard Worker   createRegisterBank(AArch64::GPRRegBankID, "GPR");
32*9880d681SAndroid Build Coastguard Worker   // The GPR register bank is fully defined by all the registers in
33*9880d681SAndroid Build Coastguard Worker   // GR64all + its subclasses.
34*9880d681SAndroid Build Coastguard Worker   addRegBankCoverage(AArch64::GPRRegBankID, AArch64::GPR64allRegClassID, TRI);
35*9880d681SAndroid Build Coastguard Worker   const RegisterBank &RBGPR = getRegBank(AArch64::GPRRegBankID);
36*9880d681SAndroid Build Coastguard Worker   (void)RBGPR;
37*9880d681SAndroid Build Coastguard Worker   assert(RBGPR.covers(*TRI.getRegClass(AArch64::GPR32RegClassID)) &&
38*9880d681SAndroid Build Coastguard Worker          "Subclass not added?");
39*9880d681SAndroid Build Coastguard Worker   assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker   // Initialize the FPR bank.
42*9880d681SAndroid Build Coastguard Worker   createRegisterBank(AArch64::FPRRegBankID, "FPR");
43*9880d681SAndroid Build Coastguard Worker   // The FPR register bank is fully defined by all the registers in
44*9880d681SAndroid Build Coastguard Worker   // GR64all + its subclasses.
45*9880d681SAndroid Build Coastguard Worker   addRegBankCoverage(AArch64::FPRRegBankID, AArch64::QQQQRegClassID, TRI);
46*9880d681SAndroid Build Coastguard Worker   const RegisterBank &RBFPR = getRegBank(AArch64::FPRRegBankID);
47*9880d681SAndroid Build Coastguard Worker   (void)RBFPR;
48*9880d681SAndroid Build Coastguard Worker   assert(RBFPR.covers(*TRI.getRegClass(AArch64::QQRegClassID)) &&
49*9880d681SAndroid Build Coastguard Worker          "Subclass not added?");
50*9880d681SAndroid Build Coastguard Worker   assert(RBFPR.covers(*TRI.getRegClass(AArch64::FPR64RegClassID)) &&
51*9880d681SAndroid Build Coastguard Worker          "Subclass not added?");
52*9880d681SAndroid Build Coastguard Worker   assert(RBFPR.getSize() == 512 &&
53*9880d681SAndroid Build Coastguard Worker          "FPRs should hold up to 512-bit via QQQQ sequence");
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   // Initialize the CCR bank.
56*9880d681SAndroid Build Coastguard Worker   createRegisterBank(AArch64::CCRRegBankID, "CCR");
57*9880d681SAndroid Build Coastguard Worker   addRegBankCoverage(AArch64::CCRRegBankID, AArch64::CCRRegClassID, TRI);
58*9880d681SAndroid Build Coastguard Worker   const RegisterBank &RBCCR = getRegBank(AArch64::CCRRegBankID);
59*9880d681SAndroid Build Coastguard Worker   (void)RBCCR;
60*9880d681SAndroid Build Coastguard Worker   assert(RBCCR.covers(*TRI.getRegClass(AArch64::CCRRegClassID)) &&
61*9880d681SAndroid Build Coastguard Worker          "Class not added?");
62*9880d681SAndroid Build Coastguard Worker   assert(RBCCR.getSize() == 32 && "CCR should hold up to 32-bit");
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   assert(verify(TRI) && "Invalid register bank information");
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker 
copyCost(const RegisterBank & A,const RegisterBank & B,unsigned Size) const67*9880d681SAndroid Build Coastguard Worker unsigned AArch64RegisterBankInfo::copyCost(const RegisterBank &A,
68*9880d681SAndroid Build Coastguard Worker                                            const RegisterBank &B,
69*9880d681SAndroid Build Coastguard Worker                                            unsigned Size) const {
70*9880d681SAndroid Build Coastguard Worker   // What do we do with different size?
71*9880d681SAndroid Build Coastguard Worker   // copy are same size.
72*9880d681SAndroid Build Coastguard Worker   // Will introduce other hooks for different size:
73*9880d681SAndroid Build Coastguard Worker   // * extract cost.
74*9880d681SAndroid Build Coastguard Worker   // * build_sequence cost.
75*9880d681SAndroid Build Coastguard Worker   // TODO: Add more accurate cost for FPR to/from GPR.
76*9880d681SAndroid Build Coastguard Worker   return RegisterBankInfo::copyCost(A, B, Size);
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker 
getRegBankFromRegClass(const TargetRegisterClass & RC) const79*9880d681SAndroid Build Coastguard Worker const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
80*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass &RC) const {
81*9880d681SAndroid Build Coastguard Worker   switch (RC.getID()) {
82*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR8RegClassID:
83*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR16RegClassID:
84*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR32RegClassID:
85*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR64RegClassID:
86*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR128RegClassID:
87*9880d681SAndroid Build Coastguard Worker   case AArch64::FPR128_loRegClassID:
88*9880d681SAndroid Build Coastguard Worker   case AArch64::DDRegClassID:
89*9880d681SAndroid Build Coastguard Worker   case AArch64::DDDRegClassID:
90*9880d681SAndroid Build Coastguard Worker   case AArch64::DDDDRegClassID:
91*9880d681SAndroid Build Coastguard Worker   case AArch64::QQRegClassID:
92*9880d681SAndroid Build Coastguard Worker   case AArch64::QQQRegClassID:
93*9880d681SAndroid Build Coastguard Worker   case AArch64::QQQQRegClassID:
94*9880d681SAndroid Build Coastguard Worker     return getRegBank(AArch64::FPRRegBankID);
95*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR32commonRegClassID:
96*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR32RegClassID:
97*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR32spRegClassID:
98*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR32sponlyRegClassID:
99*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR32allRegClassID:
100*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR64commonRegClassID:
101*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR64RegClassID:
102*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR64spRegClassID:
103*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR64sponlyRegClassID:
104*9880d681SAndroid Build Coastguard Worker   case AArch64::GPR64allRegClassID:
105*9880d681SAndroid Build Coastguard Worker   case AArch64::tcGPR64RegClassID:
106*9880d681SAndroid Build Coastguard Worker   case AArch64::WSeqPairsClassRegClassID:
107*9880d681SAndroid Build Coastguard Worker   case AArch64::XSeqPairsClassRegClassID:
108*9880d681SAndroid Build Coastguard Worker     return getRegBank(AArch64::GPRRegBankID);
109*9880d681SAndroid Build Coastguard Worker   case AArch64::CCRRegClassID:
110*9880d681SAndroid Build Coastguard Worker     return getRegBank(AArch64::CCRRegBankID);
111*9880d681SAndroid Build Coastguard Worker   default:
112*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Register class not supported");
113*9880d681SAndroid Build Coastguard Worker   }
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker RegisterBankInfo::InstructionMappings
getInstrAlternativeMappings(const MachineInstr & MI) const117*9880d681SAndroid Build Coastguard Worker AArch64RegisterBankInfo::getInstrAlternativeMappings(
118*9880d681SAndroid Build Coastguard Worker     const MachineInstr &MI) const {
119*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
120*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::G_OR: {
121*9880d681SAndroid Build Coastguard Worker     // 32 and 64-bit or can be mapped on either FPR or
122*9880d681SAndroid Build Coastguard Worker     // GPR for the same cost.
123*9880d681SAndroid Build Coastguard Worker     const MachineFunction &MF = *MI.getParent()->getParent();
124*9880d681SAndroid Build Coastguard Worker     const TargetSubtargetInfo &STI = MF.getSubtarget();
125*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
126*9880d681SAndroid Build Coastguard Worker     const MachineRegisterInfo &MRI = MF.getRegInfo();
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, TRI);
129*9880d681SAndroid Build Coastguard Worker     if (Size != 32 && Size != 64)
130*9880d681SAndroid Build Coastguard Worker       break;
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker     // If the instruction has any implicit-defs or uses,
133*9880d681SAndroid Build Coastguard Worker     // do not mess with it.
134*9880d681SAndroid Build Coastguard Worker     if (MI.getNumOperands() != 3)
135*9880d681SAndroid Build Coastguard Worker       break;
136*9880d681SAndroid Build Coastguard Worker     InstructionMappings AltMappings;
137*9880d681SAndroid Build Coastguard Worker     InstructionMapping GPRMapping(/*ID*/ 1, /*Cost*/ 1, /*NumOperands*/ 3);
138*9880d681SAndroid Build Coastguard Worker     InstructionMapping FPRMapping(/*ID*/ 2, /*Cost*/ 1, /*NumOperands*/ 3);
139*9880d681SAndroid Build Coastguard Worker     for (unsigned Idx = 0; Idx != 3; ++Idx) {
140*9880d681SAndroid Build Coastguard Worker       GPRMapping.setOperandMapping(Idx, Size,
141*9880d681SAndroid Build Coastguard Worker                                    getRegBank(AArch64::GPRRegBankID));
142*9880d681SAndroid Build Coastguard Worker       FPRMapping.setOperandMapping(Idx, Size,
143*9880d681SAndroid Build Coastguard Worker                                    getRegBank(AArch64::FPRRegBankID));
144*9880d681SAndroid Build Coastguard Worker     }
145*9880d681SAndroid Build Coastguard Worker     AltMappings.emplace_back(std::move(GPRMapping));
146*9880d681SAndroid Build Coastguard Worker     AltMappings.emplace_back(std::move(FPRMapping));
147*9880d681SAndroid Build Coastguard Worker     return AltMappings;
148*9880d681SAndroid Build Coastguard Worker   }
149*9880d681SAndroid Build Coastguard Worker   default:
150*9880d681SAndroid Build Coastguard Worker     break;
151*9880d681SAndroid Build Coastguard Worker   }
152*9880d681SAndroid Build Coastguard Worker   return RegisterBankInfo::getInstrAlternativeMappings(MI);
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
applyMappingImpl(const OperandsMapper & OpdMapper) const155*9880d681SAndroid Build Coastguard Worker void AArch64RegisterBankInfo::applyMappingImpl(
156*9880d681SAndroid Build Coastguard Worker     const OperandsMapper &OpdMapper) const {
157*9880d681SAndroid Build Coastguard Worker   switch (OpdMapper.getMI().getOpcode()) {
158*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::G_OR: {
159*9880d681SAndroid Build Coastguard Worker     // Those ID must match getInstrAlternativeMappings.
160*9880d681SAndroid Build Coastguard Worker     assert((OpdMapper.getInstrMapping().getID() == 1 ||
161*9880d681SAndroid Build Coastguard Worker             OpdMapper.getInstrMapping().getID() == 2) &&
162*9880d681SAndroid Build Coastguard Worker            "Don't know how to handle that ID");
163*9880d681SAndroid Build Coastguard Worker     return applyDefaultMapping(OpdMapper);
164*9880d681SAndroid Build Coastguard Worker   }
165*9880d681SAndroid Build Coastguard Worker   default:
166*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Don't know how to handle that operation");
167*9880d681SAndroid Build Coastguard Worker   }
168*9880d681SAndroid Build Coastguard Worker }
169