xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
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 //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Hexagon implementation of the TargetRegisterInfo
11*9880d681SAndroid Build Coastguard Worker // class.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "HexagonRegisterInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
17*9880d681SAndroid Build Coastguard Worker #include "HexagonMachineFunctionInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "HexagonSubtarget.h"
19*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/PseudoSourceValue.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MachineLocation.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker using namespace llvm;
40*9880d681SAndroid Build Coastguard Worker 
HexagonRegisterInfo()41*9880d681SAndroid Build Coastguard Worker HexagonRegisterInfo::HexagonRegisterInfo()
42*9880d681SAndroid Build Coastguard Worker     : HexagonGenRegisterInfo(Hexagon::R31) {}
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker 
isEHReturnCalleeSaveReg(unsigned R) const45*9880d681SAndroid Build Coastguard Worker bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
46*9880d681SAndroid Build Coastguard Worker   return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
47*9880d681SAndroid Build Coastguard Worker          R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker 
isCalleeSaveReg(unsigned Reg) const50*9880d681SAndroid Build Coastguard Worker bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const {
51*9880d681SAndroid Build Coastguard Worker   return Hexagon::R16 <= Reg && Reg <= Hexagon::R27;
52*9880d681SAndroid Build Coastguard Worker }
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker const MCPhysReg *
getCallerSavedRegs(const MachineFunction * MF,const TargetRegisterClass * RC) const56*9880d681SAndroid Build Coastguard Worker HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
57*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *RC) const {
58*9880d681SAndroid Build Coastguard Worker   using namespace Hexagon;
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg Int32[] = {
61*9880d681SAndroid Build Coastguard Worker     R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
62*9880d681SAndroid Build Coastguard Worker   };
63*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg Int64[] = {
64*9880d681SAndroid Build Coastguard Worker     D0, D1, D2, D3, D4, D5, D6, D7, 0
65*9880d681SAndroid Build Coastguard Worker   };
66*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg Pred[] = {
67*9880d681SAndroid Build Coastguard Worker     P0, P1, P2, P3, 0
68*9880d681SAndroid Build Coastguard Worker   };
69*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg VecSgl[] = {
70*9880d681SAndroid Build Coastguard Worker      V0,  V1,  V2,  V3,  V4,  V5,  V6,  V7,  V8,  V9, V10, V11, V12, V13,
71*9880d681SAndroid Build Coastguard Worker     V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
72*9880d681SAndroid Build Coastguard Worker     V28, V29, V30, V31,   0
73*9880d681SAndroid Build Coastguard Worker   };
74*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg VecDbl[] = {
75*9880d681SAndroid Build Coastguard Worker     W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
76*9880d681SAndroid Build Coastguard Worker   };
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   switch (RC->getID()) {
79*9880d681SAndroid Build Coastguard Worker     case IntRegsRegClassID:
80*9880d681SAndroid Build Coastguard Worker       return Int32;
81*9880d681SAndroid Build Coastguard Worker     case DoubleRegsRegClassID:
82*9880d681SAndroid Build Coastguard Worker       return Int64;
83*9880d681SAndroid Build Coastguard Worker     case PredRegsRegClassID:
84*9880d681SAndroid Build Coastguard Worker       return Pred;
85*9880d681SAndroid Build Coastguard Worker     case VectorRegsRegClassID:
86*9880d681SAndroid Build Coastguard Worker     case VectorRegs128BRegClassID:
87*9880d681SAndroid Build Coastguard Worker       return VecSgl;
88*9880d681SAndroid Build Coastguard Worker     case VecDblRegsRegClassID:
89*9880d681SAndroid Build Coastguard Worker     case VecDblRegs128BRegClassID:
90*9880d681SAndroid Build Coastguard Worker       return VecDbl;
91*9880d681SAndroid Build Coastguard Worker     default:
92*9880d681SAndroid Build Coastguard Worker       break;
93*9880d681SAndroid Build Coastguard Worker   }
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg Empty[] = { 0 };
96*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
97*9880d681SAndroid Build Coastguard Worker   dbgs() << "Register class: " << getRegClassName(RC) << "\n";
98*9880d681SAndroid Build Coastguard Worker #endif
99*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected register class");
100*9880d681SAndroid Build Coastguard Worker   return Empty;
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const105*9880d681SAndroid Build Coastguard Worker HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
106*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg CalleeSavedRegsV3[] = {
107*9880d681SAndroid Build Coastguard Worker     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
108*9880d681SAndroid Build Coastguard Worker     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
109*9880d681SAndroid Build Coastguard Worker     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
110*9880d681SAndroid Build Coastguard Worker   };
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   // Functions that contain a call to __builtin_eh_return also save the first 4
113*9880d681SAndroid Build Coastguard Worker   // parameter registers.
114*9880d681SAndroid Build Coastguard Worker   static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
115*9880d681SAndroid Build Coastguard Worker     Hexagon::R0,    Hexagon::R1,    Hexagon::R2,    Hexagon::R3,
116*9880d681SAndroid Build Coastguard Worker     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
117*9880d681SAndroid Build Coastguard Worker     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
118*9880d681SAndroid Build Coastguard Worker     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
119*9880d681SAndroid Build Coastguard Worker   };
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn();
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker   switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
124*9880d681SAndroid Build Coastguard Worker   case HexagonSubtarget::V4:
125*9880d681SAndroid Build Coastguard Worker   case HexagonSubtarget::V5:
126*9880d681SAndroid Build Coastguard Worker   case HexagonSubtarget::V55:
127*9880d681SAndroid Build Coastguard Worker   case HexagonSubtarget::V60:
128*9880d681SAndroid Build Coastguard Worker     return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Callee saved registers requested for unknown architecture "
132*9880d681SAndroid Build Coastguard Worker                    "version");
133*9880d681SAndroid Build Coastguard Worker }
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker 
getReservedRegs(const MachineFunction & MF) const136*9880d681SAndroid Build Coastguard Worker BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
137*9880d681SAndroid Build Coastguard Worker   const {
138*9880d681SAndroid Build Coastguard Worker   BitVector Reserved(getNumRegs());
139*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::R29);
140*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::R30);
141*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::R31);
142*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::PC);
143*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::D14);
144*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::D15);
145*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::LC0);
146*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::LC1);
147*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::SA0);
148*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::SA1);
149*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::UGP);
150*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::GP);
151*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::CS0);
152*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::CS1);
153*9880d681SAndroid Build Coastguard Worker   Reserved.set(Hexagon::CS);
154*9880d681SAndroid Build Coastguard Worker   return Reserved;
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker 
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOp,RegScavenger * RS) const158*9880d681SAndroid Build Coastguard Worker void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
159*9880d681SAndroid Build Coastguard Worker                                               int SPAdj, unsigned FIOp,
160*9880d681SAndroid Build Coastguard Worker                                               RegScavenger *RS) const {
161*9880d681SAndroid Build Coastguard Worker   //
162*9880d681SAndroid Build Coastguard Worker   // Hexagon_TODO: Do we need to enforce this for Hexagon?
163*9880d681SAndroid Build Coastguard Worker   assert(SPAdj == 0 && "Unexpected");
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;
166*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MB = *MI.getParent();
167*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MB.getParent();
168*9880d681SAndroid Build Coastguard Worker   auto &HST = MF.getSubtarget<HexagonSubtarget>();
169*9880d681SAndroid Build Coastguard Worker   auto &HII = *HST.getInstrInfo();
170*9880d681SAndroid Build Coastguard Worker   auto &HFI = *HST.getFrameLowering();
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker   unsigned BP = 0;
173*9880d681SAndroid Build Coastguard Worker   int FI = MI.getOperand(FIOp).getIndex();
174*9880d681SAndroid Build Coastguard Worker   // Select the base pointer (BP) and calculate the actual offset from BP
175*9880d681SAndroid Build Coastguard Worker   // to the beginning of the object at index FI.
176*9880d681SAndroid Build Coastguard Worker   int Offset = HFI.getFrameIndexReference(MF, FI, BP);
177*9880d681SAndroid Build Coastguard Worker   // Add the offset from the instruction.
178*9880d681SAndroid Build Coastguard Worker   int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
179*9880d681SAndroid Build Coastguard Worker   bool IsKill = false;
180*9880d681SAndroid Build Coastguard Worker 
181*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI.getOpcode();
182*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
183*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFR_FIA:
184*9880d681SAndroid Build Coastguard Worker       MI.setDesc(HII.get(Hexagon::A2_addi));
185*9880d681SAndroid Build Coastguard Worker       MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
186*9880d681SAndroid Build Coastguard Worker       MI.RemoveOperand(FIOp+1);
187*9880d681SAndroid Build Coastguard Worker       return;
188*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFR_FI:
189*9880d681SAndroid Build Coastguard Worker       // Set up the instruction for updating below.
190*9880d681SAndroid Build Coastguard Worker       MI.setDesc(HII.get(Hexagon::A2_addi));
191*9880d681SAndroid Build Coastguard Worker       break;
192*9880d681SAndroid Build Coastguard Worker   }
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker   if (!HII.isValidOffset(Opc, RealOffset)) {
195*9880d681SAndroid Build Coastguard Worker     // If the offset is not valid, calculate the address in a temporary
196*9880d681SAndroid Build Coastguard Worker     // register and use it with offset 0.
197*9880d681SAndroid Build Coastguard Worker     auto &MRI = MF.getRegInfo();
198*9880d681SAndroid Build Coastguard Worker     unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
199*9880d681SAndroid Build Coastguard Worker     const DebugLoc &DL = MI.getDebugLoc();
200*9880d681SAndroid Build Coastguard Worker     BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR)
201*9880d681SAndroid Build Coastguard Worker       .addReg(BP)
202*9880d681SAndroid Build Coastguard Worker       .addImm(RealOffset);
203*9880d681SAndroid Build Coastguard Worker     BP = TmpR;
204*9880d681SAndroid Build Coastguard Worker     RealOffset = 0;
205*9880d681SAndroid Build Coastguard Worker     IsKill = true;
206*9880d681SAndroid Build Coastguard Worker   }
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker   MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill);
209*9880d681SAndroid Build Coastguard Worker   MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker 
getRARegister() const213*9880d681SAndroid Build Coastguard Worker unsigned HexagonRegisterInfo::getRARegister() const {
214*9880d681SAndroid Build Coastguard Worker   return Hexagon::R31;
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker 
getFrameRegister(const MachineFunction & MF) const218*9880d681SAndroid Build Coastguard Worker unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
219*9880d681SAndroid Build Coastguard Worker                                                &MF) const {
220*9880d681SAndroid Build Coastguard Worker   const HexagonFrameLowering *TFI = getFrameLowering(MF);
221*9880d681SAndroid Build Coastguard Worker   if (TFI->hasFP(MF))
222*9880d681SAndroid Build Coastguard Worker     return getFrameRegister();
223*9880d681SAndroid Build Coastguard Worker   return getStackRegister();
224*9880d681SAndroid Build Coastguard Worker }
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker 
getFrameRegister() const227*9880d681SAndroid Build Coastguard Worker unsigned HexagonRegisterInfo::getFrameRegister() const {
228*9880d681SAndroid Build Coastguard Worker   return Hexagon::R30;
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker 
getStackRegister() const232*9880d681SAndroid Build Coastguard Worker unsigned HexagonRegisterInfo::getStackRegister() const {
233*9880d681SAndroid Build Coastguard Worker   return Hexagon::R29;
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker 
useFPForScavengingIndex(const MachineFunction & MF) const237*9880d681SAndroid Build Coastguard Worker bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
238*9880d681SAndroid Build Coastguard Worker       const {
239*9880d681SAndroid Build Coastguard Worker   return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
240*9880d681SAndroid Build Coastguard Worker }
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker 
getFirstCallerSavedNonParamReg() const243*9880d681SAndroid Build Coastguard Worker unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
244*9880d681SAndroid Build Coastguard Worker   return Hexagon::R6;
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker #define GET_REGINFO_TARGET_DESC
249*9880d681SAndroid Build Coastguard Worker #include "HexagonGenRegisterInfo.inc"
250