xref: /aosp_15_r20/external/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PPCRegisterInfo.cpp - PowerPC 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 PowerPC 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 "PPCRegisterInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "PPC.h"
17*9880d681SAndroid Build Coastguard Worker #include "PPCFrameLowering.h"
18*9880d681SAndroid Build Coastguard Worker #include "PPCInstrBuilder.h"
19*9880d681SAndroid Build Coastguard Worker #include "PPCMachineFunctionInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "PPCSubtarget.h"
21*9880d681SAndroid Build Coastguard Worker #include "PPCTargetMachine.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallingConv.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetFrameLowering.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
43*9880d681SAndroid Build Coastguard Worker #include <cstdlib>
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker using namespace llvm;
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "reginfo"
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker #define GET_REGINFO_TARGET_DESC
50*9880d681SAndroid Build Coastguard Worker #include "PPCGenRegisterInfo.inc"
51*9880d681SAndroid Build Coastguard Worker 
52*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
53*9880d681SAndroid Build Coastguard Worker EnableBasePointer("ppc-use-base-pointer", cl::Hidden, cl::init(true),
54*9880d681SAndroid Build Coastguard Worker          cl::desc("Enable use of a base pointer for complex stack frames"));
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
57*9880d681SAndroid Build Coastguard Worker AlwaysBasePointer("ppc-always-use-base-pointer", cl::Hidden, cl::init(false),
58*9880d681SAndroid Build Coastguard Worker          cl::desc("Force the use of a base pointer in every function"));
59*9880d681SAndroid Build Coastguard Worker 
PPCRegisterInfo(const PPCTargetMachine & TM)60*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::PPCRegisterInfo(const PPCTargetMachine &TM)
61*9880d681SAndroid Build Coastguard Worker   : PPCGenRegisterInfo(TM.isPPC64() ? PPC::LR8 : PPC::LR,
62*9880d681SAndroid Build Coastguard Worker                        TM.isPPC64() ? 0 : 1,
63*9880d681SAndroid Build Coastguard Worker                        TM.isPPC64() ? 0 : 1),
64*9880d681SAndroid Build Coastguard Worker     TM(TM) {
65*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LD]   = PPC::LDX;    ImmToIdxMap[PPC::STD]  = PPC::STDX;
66*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LBZ]  = PPC::LBZX;   ImmToIdxMap[PPC::STB]  = PPC::STBX;
67*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LHZ]  = PPC::LHZX;   ImmToIdxMap[PPC::LHA]  = PPC::LHAX;
68*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LWZ]  = PPC::LWZX;   ImmToIdxMap[PPC::LWA]  = PPC::LWAX;
69*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LFS]  = PPC::LFSX;   ImmToIdxMap[PPC::LFD]  = PPC::LFDX;
70*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::STH]  = PPC::STHX;   ImmToIdxMap[PPC::STW]  = PPC::STWX;
71*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::STFS] = PPC::STFSX;  ImmToIdxMap[PPC::STFD] = PPC::STFDX;
72*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::ADDI] = PPC::ADD4;
73*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LWA_32] = PPC::LWAX_32;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   // 64-bit
76*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LHA8] = PPC::LHAX8; ImmToIdxMap[PPC::LBZ8] = PPC::LBZX8;
77*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::LHZ8] = PPC::LHZX8; ImmToIdxMap[PPC::LWZ8] = PPC::LWZX8;
78*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::STB8] = PPC::STBX8; ImmToIdxMap[PPC::STH8] = PPC::STHX8;
79*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::STW8] = PPC::STWX8; ImmToIdxMap[PPC::STDU] = PPC::STDUX;
80*9880d681SAndroid Build Coastguard Worker   ImmToIdxMap[PPC::ADDI8] = PPC::ADD8;
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker /// getPointerRegClass - Return the register class to use to hold pointers.
84*9880d681SAndroid Build Coastguard Worker /// This is used for addressing modes.
85*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const86*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
87*9880d681SAndroid Build Coastguard Worker                                                                        const {
88*9880d681SAndroid Build Coastguard Worker   // Note that PPCInstrInfo::FoldImmediate also directly uses this Kind value
89*9880d681SAndroid Build Coastguard Worker   // when it checks for ZERO folding.
90*9880d681SAndroid Build Coastguard Worker   if (Kind == 1) {
91*9880d681SAndroid Build Coastguard Worker     if (TM.isPPC64())
92*9880d681SAndroid Build Coastguard Worker       return &PPC::G8RC_NOX0RegClass;
93*9880d681SAndroid Build Coastguard Worker     return &PPC::GPRC_NOR0RegClass;
94*9880d681SAndroid Build Coastguard Worker   }
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   if (TM.isPPC64())
97*9880d681SAndroid Build Coastguard Worker     return &PPC::G8RCRegClass;
98*9880d681SAndroid Build Coastguard Worker   return &PPC::GPRCRegClass;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker const MCPhysReg*
getCalleeSavedRegs(const MachineFunction * MF) const102*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
103*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
104*9880d681SAndroid Build Coastguard Worker   if (MF->getFunction()->getCallingConv() == CallingConv::AnyReg) {
105*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasVSX())
106*9880d681SAndroid Build Coastguard Worker       return CSR_64_AllRegs_VSX_SaveList;
107*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasAltivec())
108*9880d681SAndroid Build Coastguard Worker       return CSR_64_AllRegs_Altivec_SaveList;
109*9880d681SAndroid Build Coastguard Worker     return CSR_64_AllRegs_SaveList;
110*9880d681SAndroid Build Coastguard Worker   }
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isDarwinABI())
113*9880d681SAndroid Build Coastguard Worker     return TM.isPPC64()
114*9880d681SAndroid Build Coastguard Worker                ? (Subtarget.hasAltivec() ? CSR_Darwin64_Altivec_SaveList
115*9880d681SAndroid Build Coastguard Worker                                          : CSR_Darwin64_SaveList)
116*9880d681SAndroid Build Coastguard Worker                : (Subtarget.hasAltivec() ? CSR_Darwin32_Altivec_SaveList
117*9880d681SAndroid Build Coastguard Worker                                          : CSR_Darwin32_SaveList);
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   if (TM.isPPC64() && MF->getInfo<PPCFunctionInfo>()->isSplitCSR())
120*9880d681SAndroid Build Coastguard Worker     return CSR_SRV464_TLS_PE_SaveList;
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker   // On PPC64, we might need to save r2 (but only if it is not reserved).
123*9880d681SAndroid Build Coastguard Worker   bool SaveR2 = MF->getRegInfo().isAllocatable(PPC::X2);
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   return TM.isPPC64()
126*9880d681SAndroid Build Coastguard Worker              ? (Subtarget.hasAltivec()
127*9880d681SAndroid Build Coastguard Worker                     ? (SaveR2 ? CSR_SVR464_R2_Altivec_SaveList
128*9880d681SAndroid Build Coastguard Worker                               : CSR_SVR464_Altivec_SaveList)
129*9880d681SAndroid Build Coastguard Worker                     : (SaveR2 ? CSR_SVR464_R2_SaveList : CSR_SVR464_SaveList))
130*9880d681SAndroid Build Coastguard Worker              : (Subtarget.hasAltivec() ? CSR_SVR432_Altivec_SaveList
131*9880d681SAndroid Build Coastguard Worker                                        : CSR_SVR432_SaveList);
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker const MCPhysReg *
getCalleeSavedRegsViaCopy(const MachineFunction * MF) const135*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getCalleeSavedRegsViaCopy(const MachineFunction *MF) const {
136*9880d681SAndroid Build Coastguard Worker   assert(MF && "Invalid MachineFunction pointer.");
137*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
138*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isDarwinABI())
139*9880d681SAndroid Build Coastguard Worker     return nullptr;
140*9880d681SAndroid Build Coastguard Worker   if (!TM.isPPC64())
141*9880d681SAndroid Build Coastguard Worker     return nullptr;
142*9880d681SAndroid Build Coastguard Worker   if (MF->getFunction()->getCallingConv() != CallingConv::CXX_FAST_TLS)
143*9880d681SAndroid Build Coastguard Worker     return nullptr;
144*9880d681SAndroid Build Coastguard Worker   if (!MF->getInfo<PPCFunctionInfo>()->isSplitCSR())
145*9880d681SAndroid Build Coastguard Worker     return nullptr;
146*9880d681SAndroid Build Coastguard Worker 
147*9880d681SAndroid Build Coastguard Worker   // On PPC64, we might need to save r2 (but only if it is not reserved).
148*9880d681SAndroid Build Coastguard Worker   bool SaveR2 = !getReservedRegs(*MF).test(PPC::X2);
149*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasAltivec())
150*9880d681SAndroid Build Coastguard Worker     return SaveR2
151*9880d681SAndroid Build Coastguard Worker       ? CSR_SVR464_R2_Altivec_ViaCopy_SaveList
152*9880d681SAndroid Build Coastguard Worker       : CSR_SVR464_Altivec_ViaCopy_SaveList;
153*9880d681SAndroid Build Coastguard Worker   else
154*9880d681SAndroid Build Coastguard Worker     return SaveR2
155*9880d681SAndroid Build Coastguard Worker       ? CSR_SVR464_R2_ViaCopy_SaveList
156*9880d681SAndroid Build Coastguard Worker       : CSR_SVR464_ViaCopy_SaveList;
157*9880d681SAndroid Build Coastguard Worker }
158*9880d681SAndroid Build Coastguard Worker 
159*9880d681SAndroid Build Coastguard Worker const uint32_t *
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const160*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
161*9880d681SAndroid Build Coastguard Worker                                       CallingConv::ID CC) const {
162*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
163*9880d681SAndroid Build Coastguard Worker   if (CC == CallingConv::AnyReg) {
164*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasVSX())
165*9880d681SAndroid Build Coastguard Worker       return CSR_64_AllRegs_VSX_RegMask;
166*9880d681SAndroid Build Coastguard Worker     if (Subtarget.hasAltivec())
167*9880d681SAndroid Build Coastguard Worker       return CSR_64_AllRegs_Altivec_RegMask;
168*9880d681SAndroid Build Coastguard Worker     return CSR_64_AllRegs_RegMask;
169*9880d681SAndroid Build Coastguard Worker   }
170*9880d681SAndroid Build Coastguard Worker 
171*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isDarwinABI())
172*9880d681SAndroid Build Coastguard Worker     return TM.isPPC64() ? (Subtarget.hasAltivec() ? CSR_Darwin64_Altivec_RegMask
173*9880d681SAndroid Build Coastguard Worker                                                   : CSR_Darwin64_RegMask)
174*9880d681SAndroid Build Coastguard Worker                         : (Subtarget.hasAltivec() ? CSR_Darwin32_Altivec_RegMask
175*9880d681SAndroid Build Coastguard Worker                                                   : CSR_Darwin32_RegMask);
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker   return TM.isPPC64() ? (Subtarget.hasAltivec() ? CSR_SVR464_Altivec_RegMask
178*9880d681SAndroid Build Coastguard Worker                                                 : CSR_SVR464_RegMask)
179*9880d681SAndroid Build Coastguard Worker                       : (Subtarget.hasAltivec() ? CSR_SVR432_Altivec_RegMask
180*9880d681SAndroid Build Coastguard Worker                                                 : CSR_SVR432_RegMask);
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker const uint32_t*
getNoPreservedMask() const184*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getNoPreservedMask() const {
185*9880d681SAndroid Build Coastguard Worker   return CSR_NoRegs_RegMask;
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker 
adjustStackMapLiveOutMask(uint32_t * Mask) const188*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::adjustStackMapLiveOutMask(uint32_t *Mask) const {
189*9880d681SAndroid Build Coastguard Worker   for (unsigned PseudoReg : {PPC::ZERO, PPC::ZERO8, PPC::RM})
190*9880d681SAndroid Build Coastguard Worker     Mask[PseudoReg / 32] &= ~(1u << (PseudoReg % 32));
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker 
getReservedRegs(const MachineFunction & MF) const193*9880d681SAndroid Build Coastguard Worker BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
194*9880d681SAndroid Build Coastguard Worker   BitVector Reserved(getNumRegs());
195*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
196*9880d681SAndroid Build Coastguard Worker   const PPCFrameLowering *TFI = getFrameLowering(MF);
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker   // The ZERO register is not really a register, but the representation of r0
199*9880d681SAndroid Build Coastguard Worker   // when used in instructions that treat r0 as the constant 0.
200*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::ZERO);
201*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::ZERO8);
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker   // The FP register is also not really a register, but is the representation
204*9880d681SAndroid Build Coastguard Worker   // of the frame pointer register used by ISD::FRAMEADDR.
205*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::FP);
206*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::FP8);
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker   // The BP register is also not really a register, but is the representation
209*9880d681SAndroid Build Coastguard Worker   // of the base pointer register used by setjmp.
210*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::BP);
211*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::BP8);
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   // The counter registers must be reserved so that counter-based loops can
214*9880d681SAndroid Build Coastguard Worker   // be correctly formed (and the mtctr instructions are not DCE'd).
215*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::CTR);
216*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::CTR8);
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::R1);
219*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::LR);
220*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::LR8);
221*9880d681SAndroid Build Coastguard Worker   Reserved.set(PPC::RM);
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker   if (!Subtarget.isDarwinABI() || !Subtarget.hasAltivec())
224*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::VRSAVE);
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker   // The SVR4 ABI reserves r2 and r13
227*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isSVR4ABI()) {
228*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::R2);  // System-reserved register
229*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::R13); // Small Data Area pointer register
230*9880d681SAndroid Build Coastguard Worker   }
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker   // On PPC64, r13 is the thread pointer. Never allocate this register.
233*9880d681SAndroid Build Coastguard Worker   if (TM.isPPC64()) {
234*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::R13);
235*9880d681SAndroid Build Coastguard Worker 
236*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::X1);
237*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::X13);
238*9880d681SAndroid Build Coastguard Worker 
239*9880d681SAndroid Build Coastguard Worker     if (TFI->needsFP(MF))
240*9880d681SAndroid Build Coastguard Worker       Reserved.set(PPC::X31);
241*9880d681SAndroid Build Coastguard Worker 
242*9880d681SAndroid Build Coastguard Worker     if (hasBasePointer(MF))
243*9880d681SAndroid Build Coastguard Worker       Reserved.set(PPC::X30);
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker     // The 64-bit SVR4 ABI reserves r2 for the TOC pointer.
246*9880d681SAndroid Build Coastguard Worker     if (Subtarget.isSVR4ABI()) {
247*9880d681SAndroid Build Coastguard Worker       // We only reserve r2 if we need to use the TOC pointer. If we have no
248*9880d681SAndroid Build Coastguard Worker       // explicit uses of the TOC pointer (meaning we're a leaf function with
249*9880d681SAndroid Build Coastguard Worker       // no constant-pool loads, etc.) and we have no potential uses inside an
250*9880d681SAndroid Build Coastguard Worker       // inline asm block, then we can treat r2 has an ordinary callee-saved
251*9880d681SAndroid Build Coastguard Worker       // register.
252*9880d681SAndroid Build Coastguard Worker       const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
253*9880d681SAndroid Build Coastguard Worker       if (FuncInfo->usesTOCBasePtr() || MF.hasInlineAsm())
254*9880d681SAndroid Build Coastguard Worker         Reserved.set(PPC::X2);
255*9880d681SAndroid Build Coastguard Worker       else
256*9880d681SAndroid Build Coastguard Worker         Reserved.reset(PPC::R2);
257*9880d681SAndroid Build Coastguard Worker     }
258*9880d681SAndroid Build Coastguard Worker   }
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker   if (TFI->needsFP(MF))
261*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::R31);
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker   bool IsPositionIndependent = TM.isPositionIndependent();
264*9880d681SAndroid Build Coastguard Worker   if (hasBasePointer(MF)) {
265*9880d681SAndroid Build Coastguard Worker     if (Subtarget.isSVR4ABI() && !TM.isPPC64() && IsPositionIndependent)
266*9880d681SAndroid Build Coastguard Worker       Reserved.set(PPC::R29);
267*9880d681SAndroid Build Coastguard Worker     else
268*9880d681SAndroid Build Coastguard Worker       Reserved.set(PPC::R30);
269*9880d681SAndroid Build Coastguard Worker   }
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isSVR4ABI() && !TM.isPPC64() && IsPositionIndependent)
272*9880d681SAndroid Build Coastguard Worker     Reserved.set(PPC::R30);
273*9880d681SAndroid Build Coastguard Worker 
274*9880d681SAndroid Build Coastguard Worker   // Reserve Altivec registers when Altivec is unavailable.
275*9880d681SAndroid Build Coastguard Worker   if (!Subtarget.hasAltivec())
276*9880d681SAndroid Build Coastguard Worker     for (TargetRegisterClass::iterator I = PPC::VRRCRegClass.begin(),
277*9880d681SAndroid Build Coastguard Worker          IE = PPC::VRRCRegClass.end(); I != IE; ++I)
278*9880d681SAndroid Build Coastguard Worker       Reserved.set(*I);
279*9880d681SAndroid Build Coastguard Worker 
280*9880d681SAndroid Build Coastguard Worker   return Reserved;
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker 
getRegPressureLimit(const TargetRegisterClass * RC,MachineFunction & MF) const283*9880d681SAndroid Build Coastguard Worker unsigned PPCRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
284*9880d681SAndroid Build Coastguard Worker                                               MachineFunction &MF) const {
285*9880d681SAndroid Build Coastguard Worker   const PPCFrameLowering *TFI = getFrameLowering(MF);
286*9880d681SAndroid Build Coastguard Worker   const unsigned DefaultSafety = 1;
287*9880d681SAndroid Build Coastguard Worker 
288*9880d681SAndroid Build Coastguard Worker   switch (RC->getID()) {
289*9880d681SAndroid Build Coastguard Worker   default:
290*9880d681SAndroid Build Coastguard Worker     return 0;
291*9880d681SAndroid Build Coastguard Worker   case PPC::G8RC_NOX0RegClassID:
292*9880d681SAndroid Build Coastguard Worker   case PPC::GPRC_NOR0RegClassID:
293*9880d681SAndroid Build Coastguard Worker   case PPC::G8RCRegClassID:
294*9880d681SAndroid Build Coastguard Worker   case PPC::GPRCRegClassID: {
295*9880d681SAndroid Build Coastguard Worker     unsigned FP = TFI->hasFP(MF) ? 1 : 0;
296*9880d681SAndroid Build Coastguard Worker     return 32 - FP - DefaultSafety;
297*9880d681SAndroid Build Coastguard Worker   }
298*9880d681SAndroid Build Coastguard Worker   case PPC::F8RCRegClassID:
299*9880d681SAndroid Build Coastguard Worker   case PPC::F4RCRegClassID:
300*9880d681SAndroid Build Coastguard Worker   case PPC::QFRCRegClassID:
301*9880d681SAndroid Build Coastguard Worker   case PPC::QSRCRegClassID:
302*9880d681SAndroid Build Coastguard Worker   case PPC::QBRCRegClassID:
303*9880d681SAndroid Build Coastguard Worker   case PPC::VRRCRegClassID:
304*9880d681SAndroid Build Coastguard Worker   case PPC::VFRCRegClassID:
305*9880d681SAndroid Build Coastguard Worker   case PPC::VSLRCRegClassID:
306*9880d681SAndroid Build Coastguard Worker   case PPC::VSHRCRegClassID:
307*9880d681SAndroid Build Coastguard Worker     return 32 - DefaultSafety;
308*9880d681SAndroid Build Coastguard Worker   case PPC::VSRCRegClassID:
309*9880d681SAndroid Build Coastguard Worker   case PPC::VSFRCRegClassID:
310*9880d681SAndroid Build Coastguard Worker   case PPC::VSSRCRegClassID:
311*9880d681SAndroid Build Coastguard Worker     return 64 - DefaultSafety;
312*9880d681SAndroid Build Coastguard Worker   case PPC::CRRCRegClassID:
313*9880d681SAndroid Build Coastguard Worker     return 8 - DefaultSafety;
314*9880d681SAndroid Build Coastguard Worker   }
315*9880d681SAndroid Build Coastguard Worker }
316*9880d681SAndroid Build Coastguard Worker 
317*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *
getLargestLegalSuperClass(const TargetRegisterClass * RC,const MachineFunction & MF) const318*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
319*9880d681SAndroid Build Coastguard Worker                                            const MachineFunction &MF) const {
320*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
321*9880d681SAndroid Build Coastguard Worker   if (Subtarget.hasVSX()) {
322*9880d681SAndroid Build Coastguard Worker     // With VSX, we can inflate various sub-register classes to the full VSX
323*9880d681SAndroid Build Coastguard Worker     // register set.
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker     if (RC == &PPC::F8RCRegClass)
326*9880d681SAndroid Build Coastguard Worker       return &PPC::VSFRCRegClass;
327*9880d681SAndroid Build Coastguard Worker     else if (RC == &PPC::VRRCRegClass)
328*9880d681SAndroid Build Coastguard Worker       return &PPC::VSRCRegClass;
329*9880d681SAndroid Build Coastguard Worker     else if (RC == &PPC::F4RCRegClass && Subtarget.hasP8Vector())
330*9880d681SAndroid Build Coastguard Worker       return &PPC::VSSRCRegClass;
331*9880d681SAndroid Build Coastguard Worker   }
332*9880d681SAndroid Build Coastguard Worker 
333*9880d681SAndroid Build Coastguard Worker   return TargetRegisterInfo::getLargestLegalSuperClass(RC, MF);
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
337*9880d681SAndroid Build Coastguard Worker // Stack Frame Processing methods
338*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
339*9880d681SAndroid Build Coastguard Worker 
340*9880d681SAndroid Build Coastguard Worker /// lowerDynamicAlloc - Generate the code for allocating an object in the
341*9880d681SAndroid Build Coastguard Worker /// current frame.  The sequence of code will be in the general form
342*9880d681SAndroid Build Coastguard Worker ///
343*9880d681SAndroid Build Coastguard Worker ///   addi   R0, SP, \#frameSize ; get the address of the previous frame
344*9880d681SAndroid Build Coastguard Worker ///   stwxu  R0, SP, Rnegsize   ; add and update the SP with the negated size
345*9880d681SAndroid Build Coastguard Worker ///   addi   Rnew, SP, \#maxCalFrameSize ; get the top of the allocation
346*9880d681SAndroid Build Coastguard Worker ///
lowerDynamicAlloc(MachineBasicBlock::iterator II) const347*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const {
348*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
349*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;
350*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
351*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
352*9880d681SAndroid Build Coastguard Worker   // Get the basic block's function.
353*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
354*9880d681SAndroid Build Coastguard Worker   // Get the frame info.
355*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
356*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
357*9880d681SAndroid Build Coastguard Worker   // Get the instruction info.
358*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
359*9880d681SAndroid Build Coastguard Worker   // Determine whether 64-bit pointers are used.
360*9880d681SAndroid Build Coastguard Worker   bool LP64 = TM.isPPC64();
361*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
362*9880d681SAndroid Build Coastguard Worker 
363*9880d681SAndroid Build Coastguard Worker   // Get the maximum call stack size.
364*9880d681SAndroid Build Coastguard Worker   unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
365*9880d681SAndroid Build Coastguard Worker   // Get the total frame size.
366*9880d681SAndroid Build Coastguard Worker   unsigned FrameSize = MFI->getStackSize();
367*9880d681SAndroid Build Coastguard Worker 
368*9880d681SAndroid Build Coastguard Worker   // Get stack alignments.
369*9880d681SAndroid Build Coastguard Worker   const PPCFrameLowering *TFI = getFrameLowering(MF);
370*9880d681SAndroid Build Coastguard Worker   unsigned TargetAlign = TFI->getStackAlignment();
371*9880d681SAndroid Build Coastguard Worker   unsigned MaxAlign = MFI->getMaxAlignment();
372*9880d681SAndroid Build Coastguard Worker   assert((maxCallFrameSize & (MaxAlign-1)) == 0 &&
373*9880d681SAndroid Build Coastguard Worker          "Maximum call-frame size not sufficiently aligned");
374*9880d681SAndroid Build Coastguard Worker 
375*9880d681SAndroid Build Coastguard Worker   // Determine the previous frame's address.  If FrameSize can't be
376*9880d681SAndroid Build Coastguard Worker   // represented as 16 bits or we need special alignment, then we load the
377*9880d681SAndroid Build Coastguard Worker   // previous frame's address from 0(SP).  Why not do an addis of the hi?
378*9880d681SAndroid Build Coastguard Worker   // Because R0 is our only safe tmp register and addi/addis treat R0 as zero.
379*9880d681SAndroid Build Coastguard Worker   // Constructing the constant and adding would take 3 instructions.
380*9880d681SAndroid Build Coastguard Worker   // Fortunately, a frame greater than 32K is rare.
381*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
382*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
383*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
384*9880d681SAndroid Build Coastguard Worker 
385*9880d681SAndroid Build Coastguard Worker   if (MaxAlign < TargetAlign && isInt<16>(FrameSize)) {
386*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::ADDI), Reg)
387*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::R31)
388*9880d681SAndroid Build Coastguard Worker       .addImm(FrameSize);
389*9880d681SAndroid Build Coastguard Worker   } else if (LP64) {
390*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::LD), Reg)
391*9880d681SAndroid Build Coastguard Worker       .addImm(0)
392*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::X1);
393*9880d681SAndroid Build Coastguard Worker   } else {
394*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::LWZ), Reg)
395*9880d681SAndroid Build Coastguard Worker       .addImm(0)
396*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::R1);
397*9880d681SAndroid Build Coastguard Worker   }
398*9880d681SAndroid Build Coastguard Worker 
399*9880d681SAndroid Build Coastguard Worker   bool KillNegSizeReg = MI.getOperand(1).isKill();
400*9880d681SAndroid Build Coastguard Worker   unsigned NegSizeReg = MI.getOperand(1).getReg();
401*9880d681SAndroid Build Coastguard Worker 
402*9880d681SAndroid Build Coastguard Worker   // Grow the stack and update the stack pointer link, then determine the
403*9880d681SAndroid Build Coastguard Worker   // address of new allocated space.
404*9880d681SAndroid Build Coastguard Worker   if (LP64) {
405*9880d681SAndroid Build Coastguard Worker     if (MaxAlign > TargetAlign) {
406*9880d681SAndroid Build Coastguard Worker       unsigned UnalNegSizeReg = NegSizeReg;
407*9880d681SAndroid Build Coastguard Worker       NegSizeReg = MF.getRegInfo().createVirtualRegister(G8RC);
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker       // Unfortunately, there is no andi, only andi., and we can't insert that
410*9880d681SAndroid Build Coastguard Worker       // here because we might clobber cr0 while it is live.
411*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, II, dl, TII.get(PPC::LI8), NegSizeReg)
412*9880d681SAndroid Build Coastguard Worker         .addImm(~(MaxAlign-1));
413*9880d681SAndroid Build Coastguard Worker 
414*9880d681SAndroid Build Coastguard Worker       unsigned NegSizeReg1 = NegSizeReg;
415*9880d681SAndroid Build Coastguard Worker       NegSizeReg = MF.getRegInfo().createVirtualRegister(G8RC);
416*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, II, dl, TII.get(PPC::AND8), NegSizeReg)
417*9880d681SAndroid Build Coastguard Worker         .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg))
418*9880d681SAndroid Build Coastguard Worker         .addReg(NegSizeReg1, RegState::Kill);
419*9880d681SAndroid Build Coastguard Worker       KillNegSizeReg = true;
420*9880d681SAndroid Build Coastguard Worker     }
421*9880d681SAndroid Build Coastguard Worker 
422*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1)
423*9880d681SAndroid Build Coastguard Worker       .addReg(Reg, RegState::Kill)
424*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::X1)
425*9880d681SAndroid Build Coastguard Worker       .addReg(NegSizeReg, getKillRegState(KillNegSizeReg));
426*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::ADDI8), MI.getOperand(0).getReg())
427*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::X1)
428*9880d681SAndroid Build Coastguard Worker       .addImm(maxCallFrameSize);
429*9880d681SAndroid Build Coastguard Worker   } else {
430*9880d681SAndroid Build Coastguard Worker     if (MaxAlign > TargetAlign) {
431*9880d681SAndroid Build Coastguard Worker       unsigned UnalNegSizeReg = NegSizeReg;
432*9880d681SAndroid Build Coastguard Worker       NegSizeReg = MF.getRegInfo().createVirtualRegister(GPRC);
433*9880d681SAndroid Build Coastguard Worker 
434*9880d681SAndroid Build Coastguard Worker       // Unfortunately, there is no andi, only andi., and we can't insert that
435*9880d681SAndroid Build Coastguard Worker       // here because we might clobber cr0 while it is live.
436*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, II, dl, TII.get(PPC::LI), NegSizeReg)
437*9880d681SAndroid Build Coastguard Worker         .addImm(~(MaxAlign-1));
438*9880d681SAndroid Build Coastguard Worker 
439*9880d681SAndroid Build Coastguard Worker       unsigned NegSizeReg1 = NegSizeReg;
440*9880d681SAndroid Build Coastguard Worker       NegSizeReg = MF.getRegInfo().createVirtualRegister(GPRC);
441*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, II, dl, TII.get(PPC::AND), NegSizeReg)
442*9880d681SAndroid Build Coastguard Worker         .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg))
443*9880d681SAndroid Build Coastguard Worker         .addReg(NegSizeReg1, RegState::Kill);
444*9880d681SAndroid Build Coastguard Worker       KillNegSizeReg = true;
445*9880d681SAndroid Build Coastguard Worker     }
446*9880d681SAndroid Build Coastguard Worker 
447*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::STWUX), PPC::R1)
448*9880d681SAndroid Build Coastguard Worker       .addReg(Reg, RegState::Kill)
449*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::R1)
450*9880d681SAndroid Build Coastguard Worker       .addReg(NegSizeReg, getKillRegState(KillNegSizeReg));
451*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(PPC::ADDI), MI.getOperand(0).getReg())
452*9880d681SAndroid Build Coastguard Worker       .addReg(PPC::R1)
453*9880d681SAndroid Build Coastguard Worker       .addImm(maxCallFrameSize);
454*9880d681SAndroid Build Coastguard Worker   }
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker   // Discard the DYNALLOC instruction.
457*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
458*9880d681SAndroid Build Coastguard Worker }
459*9880d681SAndroid Build Coastguard Worker 
lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const460*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerDynamicAreaOffset(
461*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator II) const {
462*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
463*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;
464*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
465*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
466*9880d681SAndroid Build Coastguard Worker   // Get the basic block's function.
467*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
468*9880d681SAndroid Build Coastguard Worker   // Get the frame info.
469*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
470*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
471*9880d681SAndroid Build Coastguard Worker   // Get the instruction info.
472*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker   unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
475*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
476*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(PPC::LI), MI.getOperand(0).getReg())
477*9880d681SAndroid Build Coastguard Worker       .addImm(maxCallFrameSize);
478*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker 
481*9880d681SAndroid Build Coastguard Worker /// lowerCRSpilling - Generate the code for spilling a CR register. Instead of
482*9880d681SAndroid Build Coastguard Worker /// reserving a whole register (R0), we scrounge for one here. This generates
483*9880d681SAndroid Build Coastguard Worker /// code like this:
484*9880d681SAndroid Build Coastguard Worker ///
485*9880d681SAndroid Build Coastguard Worker ///   mfcr rA                  ; Move the conditional register into GPR rA.
486*9880d681SAndroid Build Coastguard Worker ///   rlwinm rA, rA, SB, 0, 31 ; Shift the bits left so they are in CR0's slot.
487*9880d681SAndroid Build Coastguard Worker ///   stw rA, FI               ; Store rA to the frame.
488*9880d681SAndroid Build Coastguard Worker ///
lowerCRSpilling(MachineBasicBlock::iterator II,unsigned FrameIndex) const489*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II,
490*9880d681SAndroid Build Coastguard Worker                                       unsigned FrameIndex) const {
491*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
492*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; SPILL_CR <SrcReg>, <offset>
493*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
494*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
495*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
496*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
497*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
498*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
499*9880d681SAndroid Build Coastguard Worker 
500*9880d681SAndroid Build Coastguard Worker   bool LP64 = TM.isPPC64();
501*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
502*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
503*9880d681SAndroid Build Coastguard Worker 
504*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
505*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI.getOperand(0).getReg();
506*9880d681SAndroid Build Coastguard Worker 
507*9880d681SAndroid Build Coastguard Worker   // We need to store the CR in the low 4-bits of the saved value. First, issue
508*9880d681SAndroid Build Coastguard Worker   // an MFOCRF to save all of the CRBits and, if needed, kill the SrcReg.
509*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), Reg)
510*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, getKillRegState(MI.getOperand(0).isKill()));
511*9880d681SAndroid Build Coastguard Worker 
512*9880d681SAndroid Build Coastguard Worker   // If the saved register wasn't CR0, shift the bits left so that they are in
513*9880d681SAndroid Build Coastguard Worker   // CR0's slot.
514*9880d681SAndroid Build Coastguard Worker   if (SrcReg != PPC::CR0) {
515*9880d681SAndroid Build Coastguard Worker     unsigned Reg1 = Reg;
516*9880d681SAndroid Build Coastguard Worker     Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
517*9880d681SAndroid Build Coastguard Worker 
518*9880d681SAndroid Build Coastguard Worker     // rlwinm rA, rA, ShiftBits, 0, 31.
519*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWINM8 : PPC::RLWINM), Reg)
520*9880d681SAndroid Build Coastguard Worker       .addReg(Reg1, RegState::Kill)
521*9880d681SAndroid Build Coastguard Worker       .addImm(getEncodingValue(SrcReg) * 4)
522*9880d681SAndroid Build Coastguard Worker       .addImm(0)
523*9880d681SAndroid Build Coastguard Worker       .addImm(31);
524*9880d681SAndroid Build Coastguard Worker   }
525*9880d681SAndroid Build Coastguard Worker 
526*9880d681SAndroid Build Coastguard Worker   addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::STW8 : PPC::STW))
527*9880d681SAndroid Build Coastguard Worker                     .addReg(Reg, RegState::Kill),
528*9880d681SAndroid Build Coastguard Worker                     FrameIndex);
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
531*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker 
lowerCRRestore(MachineBasicBlock::iterator II,unsigned FrameIndex) const534*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerCRRestore(MachineBasicBlock::iterator II,
535*9880d681SAndroid Build Coastguard Worker                                       unsigned FrameIndex) const {
536*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
537*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; <DestReg> = RESTORE_CR <offset>
538*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
539*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
540*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
541*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
542*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
543*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
544*9880d681SAndroid Build Coastguard Worker 
545*9880d681SAndroid Build Coastguard Worker   bool LP64 = TM.isPPC64();
546*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
547*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
548*9880d681SAndroid Build Coastguard Worker 
549*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
550*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
551*9880d681SAndroid Build Coastguard Worker   assert(MI.definesRegister(DestReg) &&
552*9880d681SAndroid Build Coastguard Worker     "RESTORE_CR does not define its destination");
553*9880d681SAndroid Build Coastguard Worker 
554*9880d681SAndroid Build Coastguard Worker   addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::LWZ8 : PPC::LWZ),
555*9880d681SAndroid Build Coastguard Worker                               Reg), FrameIndex);
556*9880d681SAndroid Build Coastguard Worker 
557*9880d681SAndroid Build Coastguard Worker   // If the reloaded register isn't CR0, shift the bits right so that they are
558*9880d681SAndroid Build Coastguard Worker   // in the right CR's slot.
559*9880d681SAndroid Build Coastguard Worker   if (DestReg != PPC::CR0) {
560*9880d681SAndroid Build Coastguard Worker     unsigned Reg1 = Reg;
561*9880d681SAndroid Build Coastguard Worker     Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
562*9880d681SAndroid Build Coastguard Worker 
563*9880d681SAndroid Build Coastguard Worker     unsigned ShiftBits = getEncodingValue(DestReg)*4;
564*9880d681SAndroid Build Coastguard Worker     // rlwinm r11, r11, 32-ShiftBits, 0, 31.
565*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWINM8 : PPC::RLWINM), Reg)
566*9880d681SAndroid Build Coastguard Worker              .addReg(Reg1, RegState::Kill).addImm(32-ShiftBits).addImm(0)
567*9880d681SAndroid Build Coastguard Worker              .addImm(31);
568*9880d681SAndroid Build Coastguard Worker   }
569*9880d681SAndroid Build Coastguard Worker 
570*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MTOCRF8 : PPC::MTOCRF), DestReg)
571*9880d681SAndroid Build Coastguard Worker              .addReg(Reg, RegState::Kill);
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
574*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker 
lowerCRBitSpilling(MachineBasicBlock::iterator II,unsigned FrameIndex) const577*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerCRBitSpilling(MachineBasicBlock::iterator II,
578*9880d681SAndroid Build Coastguard Worker                                          unsigned FrameIndex) const {
579*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
580*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; SPILL_CRBIT <SrcReg>, <offset>
581*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
582*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
583*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
584*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
585*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
586*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
587*9880d681SAndroid Build Coastguard Worker 
588*9880d681SAndroid Build Coastguard Worker   bool LP64 = TM.isPPC64();
589*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
590*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
591*9880d681SAndroid Build Coastguard Worker 
592*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
593*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI.getOperand(0).getReg();
594*9880d681SAndroid Build Coastguard Worker 
595*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(TargetOpcode::KILL),
596*9880d681SAndroid Build Coastguard Worker           getCRFromCRBit(SrcReg))
597*9880d681SAndroid Build Coastguard Worker           .addReg(SrcReg, getKillRegState(MI.getOperand(0).isKill()));
598*9880d681SAndroid Build Coastguard Worker 
599*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), Reg)
600*9880d681SAndroid Build Coastguard Worker       .addReg(getCRFromCRBit(SrcReg));
601*9880d681SAndroid Build Coastguard Worker 
602*9880d681SAndroid Build Coastguard Worker   // If the saved register wasn't CR0LT, shift the bits left so that the bit to
603*9880d681SAndroid Build Coastguard Worker   // store is the first one. Mask all but that bit.
604*9880d681SAndroid Build Coastguard Worker   unsigned Reg1 = Reg;
605*9880d681SAndroid Build Coastguard Worker   Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
606*9880d681SAndroid Build Coastguard Worker 
607*9880d681SAndroid Build Coastguard Worker   // rlwinm rA, rA, ShiftBits, 0, 0.
608*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWINM8 : PPC::RLWINM), Reg)
609*9880d681SAndroid Build Coastguard Worker     .addReg(Reg1, RegState::Kill)
610*9880d681SAndroid Build Coastguard Worker     .addImm(getEncodingValue(SrcReg))
611*9880d681SAndroid Build Coastguard Worker     .addImm(0).addImm(0);
612*9880d681SAndroid Build Coastguard Worker 
613*9880d681SAndroid Build Coastguard Worker   addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::STW8 : PPC::STW))
614*9880d681SAndroid Build Coastguard Worker                     .addReg(Reg, RegState::Kill),
615*9880d681SAndroid Build Coastguard Worker                     FrameIndex);
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
618*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker 
lowerCRBitRestore(MachineBasicBlock::iterator II,unsigned FrameIndex) const621*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerCRBitRestore(MachineBasicBlock::iterator II,
622*9880d681SAndroid Build Coastguard Worker                                       unsigned FrameIndex) const {
623*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
624*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; <DestReg> = RESTORE_CRBIT <offset>
625*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
626*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
627*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
628*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
629*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
630*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
631*9880d681SAndroid Build Coastguard Worker 
632*9880d681SAndroid Build Coastguard Worker   bool LP64 = TM.isPPC64();
633*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
634*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
635*9880d681SAndroid Build Coastguard Worker 
636*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
637*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
638*9880d681SAndroid Build Coastguard Worker   assert(MI.definesRegister(DestReg) &&
639*9880d681SAndroid Build Coastguard Worker     "RESTORE_CRBIT does not define its destination");
640*9880d681SAndroid Build Coastguard Worker 
641*9880d681SAndroid Build Coastguard Worker   addFrameReference(BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::LWZ8 : PPC::LWZ),
642*9880d681SAndroid Build Coastguard Worker                               Reg), FrameIndex);
643*9880d681SAndroid Build Coastguard Worker 
644*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(TargetOpcode::IMPLICIT_DEF), DestReg);
645*9880d681SAndroid Build Coastguard Worker 
646*9880d681SAndroid Build Coastguard Worker   unsigned RegO = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC);
647*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MFOCRF8 : PPC::MFOCRF), RegO)
648*9880d681SAndroid Build Coastguard Worker           .addReg(getCRFromCRBit(DestReg));
649*9880d681SAndroid Build Coastguard Worker 
650*9880d681SAndroid Build Coastguard Worker   unsigned ShiftBits = getEncodingValue(DestReg);
651*9880d681SAndroid Build Coastguard Worker   // rlwimi r11, r10, 32-ShiftBits, ..., ...
652*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::RLWIMI8 : PPC::RLWIMI), RegO)
653*9880d681SAndroid Build Coastguard Worker       .addReg(RegO, RegState::Kill)
654*9880d681SAndroid Build Coastguard Worker       .addReg(Reg, RegState::Kill)
655*9880d681SAndroid Build Coastguard Worker       .addImm(ShiftBits ? 32 - ShiftBits : 0)
656*9880d681SAndroid Build Coastguard Worker       .addImm(ShiftBits)
657*9880d681SAndroid Build Coastguard Worker       .addImm(ShiftBits);
658*9880d681SAndroid Build Coastguard Worker 
659*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(LP64 ? PPC::MTOCRF8 : PPC::MTOCRF),
660*9880d681SAndroid Build Coastguard Worker           getCRFromCRBit(DestReg))
661*9880d681SAndroid Build Coastguard Worker       .addReg(RegO, RegState::Kill)
662*9880d681SAndroid Build Coastguard Worker       // Make sure we have a use dependency all the way through this
663*9880d681SAndroid Build Coastguard Worker       // sequence of instructions. We can't have the other bits in the CR
664*9880d681SAndroid Build Coastguard Worker       // modified in between the mfocrf and the mtocrf.
665*9880d681SAndroid Build Coastguard Worker       .addReg(getCRFromCRBit(DestReg), RegState::Implicit);
666*9880d681SAndroid Build Coastguard Worker 
667*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
668*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
669*9880d681SAndroid Build Coastguard Worker }
670*9880d681SAndroid Build Coastguard Worker 
lowerVRSAVESpilling(MachineBasicBlock::iterator II,unsigned FrameIndex) const671*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerVRSAVESpilling(MachineBasicBlock::iterator II,
672*9880d681SAndroid Build Coastguard Worker                                           unsigned FrameIndex) const {
673*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
674*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; SPILL_VRSAVE <SrcReg>, <offset>
675*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
676*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
677*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
678*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
679*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
680*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
681*9880d681SAndroid Build Coastguard Worker 
682*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
683*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(GPRC);
684*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = MI.getOperand(0).getReg();
685*9880d681SAndroid Build Coastguard Worker 
686*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(PPC::MFVRSAVEv), Reg)
687*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, getKillRegState(MI.getOperand(0).isKill()));
688*9880d681SAndroid Build Coastguard Worker 
689*9880d681SAndroid Build Coastguard Worker   addFrameReference(
690*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, II, dl, TII.get(PPC::STW)).addReg(Reg, RegState::Kill),
691*9880d681SAndroid Build Coastguard Worker       FrameIndex);
692*9880d681SAndroid Build Coastguard Worker 
693*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
694*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
695*9880d681SAndroid Build Coastguard Worker }
696*9880d681SAndroid Build Coastguard Worker 
lowerVRSAVERestore(MachineBasicBlock::iterator II,unsigned FrameIndex) const697*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::lowerVRSAVERestore(MachineBasicBlock::iterator II,
698*9880d681SAndroid Build Coastguard Worker                                          unsigned FrameIndex) const {
699*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
700*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;       // ; <DestReg> = RESTORE_VRSAVE <offset>
701*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
702*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
703*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
704*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
705*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
706*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
707*9880d681SAndroid Build Coastguard Worker 
708*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
709*9880d681SAndroid Build Coastguard Worker   unsigned Reg = MF.getRegInfo().createVirtualRegister(GPRC);
710*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
711*9880d681SAndroid Build Coastguard Worker   assert(MI.definesRegister(DestReg) &&
712*9880d681SAndroid Build Coastguard Worker     "RESTORE_VRSAVE does not define its destination");
713*9880d681SAndroid Build Coastguard Worker 
714*9880d681SAndroid Build Coastguard Worker   addFrameReference(BuildMI(MBB, II, dl, TII.get(PPC::LWZ),
715*9880d681SAndroid Build Coastguard Worker                               Reg), FrameIndex);
716*9880d681SAndroid Build Coastguard Worker 
717*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(PPC::MTVRSAVEv), DestReg)
718*9880d681SAndroid Build Coastguard Worker              .addReg(Reg, RegState::Kill);
719*9880d681SAndroid Build Coastguard Worker 
720*9880d681SAndroid Build Coastguard Worker   // Discard the pseudo instruction.
721*9880d681SAndroid Build Coastguard Worker   MBB.erase(II);
722*9880d681SAndroid Build Coastguard Worker }
723*9880d681SAndroid Build Coastguard Worker 
hasReservedSpillSlot(const MachineFunction & MF,unsigned Reg,int & FrameIdx) const724*9880d681SAndroid Build Coastguard Worker bool PPCRegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
725*9880d681SAndroid Build Coastguard Worker                                            unsigned Reg, int &FrameIdx) const {
726*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
727*9880d681SAndroid Build Coastguard Worker   // For the nonvolatile condition registers (CR2, CR3, CR4) in an SVR4
728*9880d681SAndroid Build Coastguard Worker   // ABI, return true to prevent allocating an additional frame slot.
729*9880d681SAndroid Build Coastguard Worker   // For 64-bit, the CR save area is at SP+8; the value of FrameIdx = 0
730*9880d681SAndroid Build Coastguard Worker   // is arbitrary and will be subsequently ignored.  For 32-bit, we have
731*9880d681SAndroid Build Coastguard Worker   // previously created the stack slot if needed, so return its FrameIdx.
732*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isSVR4ABI() && PPC::CR2 <= Reg && Reg <= PPC::CR4) {
733*9880d681SAndroid Build Coastguard Worker     if (TM.isPPC64())
734*9880d681SAndroid Build Coastguard Worker       FrameIdx = 0;
735*9880d681SAndroid Build Coastguard Worker     else {
736*9880d681SAndroid Build Coastguard Worker       const PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
737*9880d681SAndroid Build Coastguard Worker       FrameIdx = FI->getCRSpillFrameIndex();
738*9880d681SAndroid Build Coastguard Worker     }
739*9880d681SAndroid Build Coastguard Worker     return true;
740*9880d681SAndroid Build Coastguard Worker   }
741*9880d681SAndroid Build Coastguard Worker   return false;
742*9880d681SAndroid Build Coastguard Worker }
743*9880d681SAndroid Build Coastguard Worker 
744*9880d681SAndroid Build Coastguard Worker // Figure out if the offset in the instruction must be a multiple of 4.
745*9880d681SAndroid Build Coastguard Worker // This is true for instructions like "STD".
usesIXAddr(const MachineInstr & MI)746*9880d681SAndroid Build Coastguard Worker static bool usesIXAddr(const MachineInstr &MI) {
747*9880d681SAndroid Build Coastguard Worker   unsigned OpC = MI.getOpcode();
748*9880d681SAndroid Build Coastguard Worker 
749*9880d681SAndroid Build Coastguard Worker   switch (OpC) {
750*9880d681SAndroid Build Coastguard Worker   default:
751*9880d681SAndroid Build Coastguard Worker     return false;
752*9880d681SAndroid Build Coastguard Worker   case PPC::LWA:
753*9880d681SAndroid Build Coastguard Worker   case PPC::LWA_32:
754*9880d681SAndroid Build Coastguard Worker   case PPC::LD:
755*9880d681SAndroid Build Coastguard Worker   case PPC::STD:
756*9880d681SAndroid Build Coastguard Worker     return true;
757*9880d681SAndroid Build Coastguard Worker   }
758*9880d681SAndroid Build Coastguard Worker }
759*9880d681SAndroid Build Coastguard Worker 
760*9880d681SAndroid Build Coastguard Worker // Return the OffsetOperandNo given the FIOperandNum (and the instruction).
getOffsetONFromFION(const MachineInstr & MI,unsigned FIOperandNum)761*9880d681SAndroid Build Coastguard Worker static unsigned getOffsetONFromFION(const MachineInstr &MI,
762*9880d681SAndroid Build Coastguard Worker                                     unsigned FIOperandNum) {
763*9880d681SAndroid Build Coastguard Worker   // Take into account whether it's an add or mem instruction
764*9880d681SAndroid Build Coastguard Worker   unsigned OffsetOperandNo = (FIOperandNum == 2) ? 1 : 2;
765*9880d681SAndroid Build Coastguard Worker   if (MI.isInlineAsm())
766*9880d681SAndroid Build Coastguard Worker     OffsetOperandNo = FIOperandNum - 1;
767*9880d681SAndroid Build Coastguard Worker   else if (MI.getOpcode() == TargetOpcode::STACKMAP ||
768*9880d681SAndroid Build Coastguard Worker            MI.getOpcode() == TargetOpcode::PATCHPOINT)
769*9880d681SAndroid Build Coastguard Worker     OffsetOperandNo = FIOperandNum + 1;
770*9880d681SAndroid Build Coastguard Worker 
771*9880d681SAndroid Build Coastguard Worker   return OffsetOperandNo;
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker 
774*9880d681SAndroid Build Coastguard Worker void
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const775*9880d681SAndroid Build Coastguard Worker PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
776*9880d681SAndroid Build Coastguard Worker                                      int SPAdj, unsigned FIOperandNum,
777*9880d681SAndroid Build Coastguard Worker                                      RegScavenger *RS) const {
778*9880d681SAndroid Build Coastguard Worker   assert(SPAdj == 0 && "Unexpected");
779*9880d681SAndroid Build Coastguard Worker 
780*9880d681SAndroid Build Coastguard Worker   // Get the instruction.
781*9880d681SAndroid Build Coastguard Worker   MachineInstr &MI = *II;
782*9880d681SAndroid Build Coastguard Worker   // Get the instruction's basic block.
783*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
784*9880d681SAndroid Build Coastguard Worker   // Get the basic block's function.
785*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
786*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
787*9880d681SAndroid Build Coastguard Worker   // Get the instruction info.
788*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
789*9880d681SAndroid Build Coastguard Worker   // Get the frame info.
790*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo *MFI = MF.getFrameInfo();
791*9880d681SAndroid Build Coastguard Worker   DebugLoc dl = MI.getDebugLoc();
792*9880d681SAndroid Build Coastguard Worker 
793*9880d681SAndroid Build Coastguard Worker   unsigned OffsetOperandNo = getOffsetONFromFION(MI, FIOperandNum);
794*9880d681SAndroid Build Coastguard Worker 
795*9880d681SAndroid Build Coastguard Worker   // Get the frame index.
796*9880d681SAndroid Build Coastguard Worker   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
797*9880d681SAndroid Build Coastguard Worker 
798*9880d681SAndroid Build Coastguard Worker   // Get the frame pointer save index.  Users of this index are primarily
799*9880d681SAndroid Build Coastguard Worker   // DYNALLOC instructions.
800*9880d681SAndroid Build Coastguard Worker   PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
801*9880d681SAndroid Build Coastguard Worker   int FPSI = FI->getFramePointerSaveIndex();
802*9880d681SAndroid Build Coastguard Worker   // Get the instruction opcode.
803*9880d681SAndroid Build Coastguard Worker   unsigned OpC = MI.getOpcode();
804*9880d681SAndroid Build Coastguard Worker 
805*9880d681SAndroid Build Coastguard Worker   if ((OpC == PPC::DYNAREAOFFSET || OpC == PPC::DYNAREAOFFSET8)) {
806*9880d681SAndroid Build Coastguard Worker     lowerDynamicAreaOffset(II);
807*9880d681SAndroid Build Coastguard Worker     return;
808*9880d681SAndroid Build Coastguard Worker   }
809*9880d681SAndroid Build Coastguard Worker 
810*9880d681SAndroid Build Coastguard Worker   // Special case for dynamic alloca.
811*9880d681SAndroid Build Coastguard Worker   if (FPSI && FrameIndex == FPSI &&
812*9880d681SAndroid Build Coastguard Worker       (OpC == PPC::DYNALLOC || OpC == PPC::DYNALLOC8)) {
813*9880d681SAndroid Build Coastguard Worker     lowerDynamicAlloc(II);
814*9880d681SAndroid Build Coastguard Worker     return;
815*9880d681SAndroid Build Coastguard Worker   }
816*9880d681SAndroid Build Coastguard Worker 
817*9880d681SAndroid Build Coastguard Worker   // Special case for pseudo-ops SPILL_CR and RESTORE_CR, etc.
818*9880d681SAndroid Build Coastguard Worker   if (OpC == PPC::SPILL_CR) {
819*9880d681SAndroid Build Coastguard Worker     lowerCRSpilling(II, FrameIndex);
820*9880d681SAndroid Build Coastguard Worker     return;
821*9880d681SAndroid Build Coastguard Worker   } else if (OpC == PPC::RESTORE_CR) {
822*9880d681SAndroid Build Coastguard Worker     lowerCRRestore(II, FrameIndex);
823*9880d681SAndroid Build Coastguard Worker     return;
824*9880d681SAndroid Build Coastguard Worker   } else if (OpC == PPC::SPILL_CRBIT) {
825*9880d681SAndroid Build Coastguard Worker     lowerCRBitSpilling(II, FrameIndex);
826*9880d681SAndroid Build Coastguard Worker     return;
827*9880d681SAndroid Build Coastguard Worker   } else if (OpC == PPC::RESTORE_CRBIT) {
828*9880d681SAndroid Build Coastguard Worker     lowerCRBitRestore(II, FrameIndex);
829*9880d681SAndroid Build Coastguard Worker     return;
830*9880d681SAndroid Build Coastguard Worker   } else if (OpC == PPC::SPILL_VRSAVE) {
831*9880d681SAndroid Build Coastguard Worker     lowerVRSAVESpilling(II, FrameIndex);
832*9880d681SAndroid Build Coastguard Worker     return;
833*9880d681SAndroid Build Coastguard Worker   } else if (OpC == PPC::RESTORE_VRSAVE) {
834*9880d681SAndroid Build Coastguard Worker     lowerVRSAVERestore(II, FrameIndex);
835*9880d681SAndroid Build Coastguard Worker     return;
836*9880d681SAndroid Build Coastguard Worker   }
837*9880d681SAndroid Build Coastguard Worker 
838*9880d681SAndroid Build Coastguard Worker   // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
839*9880d681SAndroid Build Coastguard Worker   MI.getOperand(FIOperandNum).ChangeToRegister(
840*9880d681SAndroid Build Coastguard Worker     FrameIndex < 0 ? getBaseRegister(MF) : getFrameRegister(MF), false);
841*9880d681SAndroid Build Coastguard Worker 
842*9880d681SAndroid Build Coastguard Worker   // Figure out if the offset in the instruction is shifted right two bits.
843*9880d681SAndroid Build Coastguard Worker   bool isIXAddr = usesIXAddr(MI);
844*9880d681SAndroid Build Coastguard Worker 
845*9880d681SAndroid Build Coastguard Worker   // If the instruction is not present in ImmToIdxMap, then it has no immediate
846*9880d681SAndroid Build Coastguard Worker   // form (and must be r+r).
847*9880d681SAndroid Build Coastguard Worker   bool noImmForm = !MI.isInlineAsm() && OpC != TargetOpcode::STACKMAP &&
848*9880d681SAndroid Build Coastguard Worker                    OpC != TargetOpcode::PATCHPOINT && !ImmToIdxMap.count(OpC);
849*9880d681SAndroid Build Coastguard Worker 
850*9880d681SAndroid Build Coastguard Worker   // Now add the frame object offset to the offset from r1.
851*9880d681SAndroid Build Coastguard Worker   int Offset = MFI->getObjectOffset(FrameIndex);
852*9880d681SAndroid Build Coastguard Worker   Offset += MI.getOperand(OffsetOperandNo).getImm();
853*9880d681SAndroid Build Coastguard Worker 
854*9880d681SAndroid Build Coastguard Worker   // If we're not using a Frame Pointer that has been set to the value of the
855*9880d681SAndroid Build Coastguard Worker   // SP before having the stack size subtracted from it, then add the stack size
856*9880d681SAndroid Build Coastguard Worker   // to Offset to get the correct offset.
857*9880d681SAndroid Build Coastguard Worker   // Naked functions have stack size 0, although getStackSize may not reflect
858*9880d681SAndroid Build Coastguard Worker   // that because we didn't call all the pieces that compute it for naked
859*9880d681SAndroid Build Coastguard Worker   // functions.
860*9880d681SAndroid Build Coastguard Worker   if (!MF.getFunction()->hasFnAttribute(Attribute::Naked)) {
861*9880d681SAndroid Build Coastguard Worker     if (!(hasBasePointer(MF) && FrameIndex < 0))
862*9880d681SAndroid Build Coastguard Worker       Offset += MFI->getStackSize();
863*9880d681SAndroid Build Coastguard Worker   }
864*9880d681SAndroid Build Coastguard Worker 
865*9880d681SAndroid Build Coastguard Worker   // If we can, encode the offset directly into the instruction.  If this is a
866*9880d681SAndroid Build Coastguard Worker   // normal PPC "ri" instruction, any 16-bit value can be safely encoded.  If
867*9880d681SAndroid Build Coastguard Worker   // this is a PPC64 "ix" instruction, only a 16-bit value with the low two bits
868*9880d681SAndroid Build Coastguard Worker   // clear can be encoded.  This is extremely uncommon, because normally you
869*9880d681SAndroid Build Coastguard Worker   // only "std" to a stack slot that is at least 4-byte aligned, but it can
870*9880d681SAndroid Build Coastguard Worker   // happen in invalid code.
871*9880d681SAndroid Build Coastguard Worker   assert(OpC != PPC::DBG_VALUE &&
872*9880d681SAndroid Build Coastguard Worker          "This should be handled in a target-independent way");
873*9880d681SAndroid Build Coastguard Worker   if (!noImmForm && ((isInt<16>(Offset) && (!isIXAddr || (Offset & 3) == 0)) ||
874*9880d681SAndroid Build Coastguard Worker                      OpC == TargetOpcode::STACKMAP ||
875*9880d681SAndroid Build Coastguard Worker                      OpC == TargetOpcode::PATCHPOINT)) {
876*9880d681SAndroid Build Coastguard Worker     MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
877*9880d681SAndroid Build Coastguard Worker     return;
878*9880d681SAndroid Build Coastguard Worker   }
879*9880d681SAndroid Build Coastguard Worker 
880*9880d681SAndroid Build Coastguard Worker   // The offset doesn't fit into a single register, scavenge one to build the
881*9880d681SAndroid Build Coastguard Worker   // offset in.
882*9880d681SAndroid Build Coastguard Worker 
883*9880d681SAndroid Build Coastguard Worker   bool is64Bit = TM.isPPC64();
884*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
885*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
886*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = is64Bit ? G8RC : GPRC;
887*9880d681SAndroid Build Coastguard Worker   unsigned SRegHi = MF.getRegInfo().createVirtualRegister(RC),
888*9880d681SAndroid Build Coastguard Worker            SReg = MF.getRegInfo().createVirtualRegister(RC);
889*9880d681SAndroid Build Coastguard Worker 
890*9880d681SAndroid Build Coastguard Worker   // Insert a set of rA with the full offset value before the ld, st, or add
891*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(is64Bit ? PPC::LIS8 : PPC::LIS), SRegHi)
892*9880d681SAndroid Build Coastguard Worker     .addImm(Offset >> 16);
893*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, II, dl, TII.get(is64Bit ? PPC::ORI8 : PPC::ORI), SReg)
894*9880d681SAndroid Build Coastguard Worker     .addReg(SRegHi, RegState::Kill)
895*9880d681SAndroid Build Coastguard Worker     .addImm(Offset);
896*9880d681SAndroid Build Coastguard Worker 
897*9880d681SAndroid Build Coastguard Worker   // Convert into indexed form of the instruction:
898*9880d681SAndroid Build Coastguard Worker   //
899*9880d681SAndroid Build Coastguard Worker   //   sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
900*9880d681SAndroid Build Coastguard Worker   //   addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
901*9880d681SAndroid Build Coastguard Worker   unsigned OperandBase;
902*9880d681SAndroid Build Coastguard Worker 
903*9880d681SAndroid Build Coastguard Worker   if (noImmForm)
904*9880d681SAndroid Build Coastguard Worker     OperandBase = 1;
905*9880d681SAndroid Build Coastguard Worker   else if (OpC != TargetOpcode::INLINEASM) {
906*9880d681SAndroid Build Coastguard Worker     assert(ImmToIdxMap.count(OpC) &&
907*9880d681SAndroid Build Coastguard Worker            "No indexed form of load or store available!");
908*9880d681SAndroid Build Coastguard Worker     unsigned NewOpcode = ImmToIdxMap.find(OpC)->second;
909*9880d681SAndroid Build Coastguard Worker     MI.setDesc(TII.get(NewOpcode));
910*9880d681SAndroid Build Coastguard Worker     OperandBase = 1;
911*9880d681SAndroid Build Coastguard Worker   } else {
912*9880d681SAndroid Build Coastguard Worker     OperandBase = OffsetOperandNo;
913*9880d681SAndroid Build Coastguard Worker   }
914*9880d681SAndroid Build Coastguard Worker 
915*9880d681SAndroid Build Coastguard Worker   unsigned StackReg = MI.getOperand(FIOperandNum).getReg();
916*9880d681SAndroid Build Coastguard Worker   MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
917*9880d681SAndroid Build Coastguard Worker   MI.getOperand(OperandBase + 1).ChangeToRegister(SReg, false, false, true);
918*9880d681SAndroid Build Coastguard Worker }
919*9880d681SAndroid Build Coastguard Worker 
getFrameRegister(const MachineFunction & MF) const920*9880d681SAndroid Build Coastguard Worker unsigned PPCRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
921*9880d681SAndroid Build Coastguard Worker   const PPCFrameLowering *TFI = getFrameLowering(MF);
922*9880d681SAndroid Build Coastguard Worker 
923*9880d681SAndroid Build Coastguard Worker   if (!TM.isPPC64())
924*9880d681SAndroid Build Coastguard Worker     return TFI->hasFP(MF) ? PPC::R31 : PPC::R1;
925*9880d681SAndroid Build Coastguard Worker   else
926*9880d681SAndroid Build Coastguard Worker     return TFI->hasFP(MF) ? PPC::X31 : PPC::X1;
927*9880d681SAndroid Build Coastguard Worker }
928*9880d681SAndroid Build Coastguard Worker 
getBaseRegister(const MachineFunction & MF) const929*9880d681SAndroid Build Coastguard Worker unsigned PPCRegisterInfo::getBaseRegister(const MachineFunction &MF) const {
930*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
931*9880d681SAndroid Build Coastguard Worker   if (!hasBasePointer(MF))
932*9880d681SAndroid Build Coastguard Worker     return getFrameRegister(MF);
933*9880d681SAndroid Build Coastguard Worker 
934*9880d681SAndroid Build Coastguard Worker   if (TM.isPPC64())
935*9880d681SAndroid Build Coastguard Worker     return PPC::X30;
936*9880d681SAndroid Build Coastguard Worker 
937*9880d681SAndroid Build Coastguard Worker   if (Subtarget.isSVR4ABI() && TM.isPositionIndependent())
938*9880d681SAndroid Build Coastguard Worker     return PPC::R29;
939*9880d681SAndroid Build Coastguard Worker 
940*9880d681SAndroid Build Coastguard Worker   return PPC::R30;
941*9880d681SAndroid Build Coastguard Worker }
942*9880d681SAndroid Build Coastguard Worker 
hasBasePointer(const MachineFunction & MF) const943*9880d681SAndroid Build Coastguard Worker bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
944*9880d681SAndroid Build Coastguard Worker   if (!EnableBasePointer)
945*9880d681SAndroid Build Coastguard Worker     return false;
946*9880d681SAndroid Build Coastguard Worker   if (AlwaysBasePointer)
947*9880d681SAndroid Build Coastguard Worker     return true;
948*9880d681SAndroid Build Coastguard Worker 
949*9880d681SAndroid Build Coastguard Worker   // If we need to realign the stack, then the stack pointer can no longer
950*9880d681SAndroid Build Coastguard Worker   // serve as an offset into the caller's stack space. As a result, we need a
951*9880d681SAndroid Build Coastguard Worker   // base pointer.
952*9880d681SAndroid Build Coastguard Worker   return needsStackRealignment(MF);
953*9880d681SAndroid Build Coastguard Worker }
954*9880d681SAndroid Build Coastguard Worker 
955*9880d681SAndroid Build Coastguard Worker /// Returns true if the instruction's frame index
956*9880d681SAndroid Build Coastguard Worker /// reference would be better served by a base register other than FP
957*9880d681SAndroid Build Coastguard Worker /// or SP. Used by LocalStackFrameAllocation to determine which frame index
958*9880d681SAndroid Build Coastguard Worker /// references it should create new base registers for.
959*9880d681SAndroid Build Coastguard Worker bool PPCRegisterInfo::
needsFrameBaseReg(MachineInstr * MI,int64_t Offset) const960*9880d681SAndroid Build Coastguard Worker needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
961*9880d681SAndroid Build Coastguard Worker   assert(Offset < 0 && "Local offset must be negative");
962*9880d681SAndroid Build Coastguard Worker 
963*9880d681SAndroid Build Coastguard Worker   // It's the load/store FI references that cause issues, as it can be difficult
964*9880d681SAndroid Build Coastguard Worker   // to materialize the offset if it won't fit in the literal field. Estimate
965*9880d681SAndroid Build Coastguard Worker   // based on the size of the local frame and some conservative assumptions
966*9880d681SAndroid Build Coastguard Worker   // about the rest of the stack frame (note, this is pre-regalloc, so
967*9880d681SAndroid Build Coastguard Worker   // we don't know everything for certain yet) whether this offset is likely
968*9880d681SAndroid Build Coastguard Worker   // to be out of range of the immediate. Return true if so.
969*9880d681SAndroid Build Coastguard Worker 
970*9880d681SAndroid Build Coastguard Worker   // We only generate virtual base registers for loads and stores that have
971*9880d681SAndroid Build Coastguard Worker   // an r+i form. Return false for everything else.
972*9880d681SAndroid Build Coastguard Worker   unsigned OpC = MI->getOpcode();
973*9880d681SAndroid Build Coastguard Worker   if (!ImmToIdxMap.count(OpC))
974*9880d681SAndroid Build Coastguard Worker     return false;
975*9880d681SAndroid Build Coastguard Worker 
976*9880d681SAndroid Build Coastguard Worker   // Don't generate a new virtual base register just to add zero to it.
977*9880d681SAndroid Build Coastguard Worker   if ((OpC == PPC::ADDI || OpC == PPC::ADDI8) &&
978*9880d681SAndroid Build Coastguard Worker       MI->getOperand(2).getImm() == 0)
979*9880d681SAndroid Build Coastguard Worker     return false;
980*9880d681SAndroid Build Coastguard Worker 
981*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI->getParent();
982*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
983*9880d681SAndroid Build Coastguard Worker   const PPCFrameLowering *TFI = getFrameLowering(MF);
984*9880d681SAndroid Build Coastguard Worker   unsigned StackEst = TFI->determineFrameLayout(MF, false, true);
985*9880d681SAndroid Build Coastguard Worker 
986*9880d681SAndroid Build Coastguard Worker   // If we likely don't need a stack frame, then we probably don't need a
987*9880d681SAndroid Build Coastguard Worker   // virtual base register either.
988*9880d681SAndroid Build Coastguard Worker   if (!StackEst)
989*9880d681SAndroid Build Coastguard Worker     return false;
990*9880d681SAndroid Build Coastguard Worker 
991*9880d681SAndroid Build Coastguard Worker   // Estimate an offset from the stack pointer.
992*9880d681SAndroid Build Coastguard Worker   // The incoming offset is relating to the SP at the start of the function,
993*9880d681SAndroid Build Coastguard Worker   // but when we access the local it'll be relative to the SP after local
994*9880d681SAndroid Build Coastguard Worker   // allocation, so adjust our SP-relative offset by that allocation size.
995*9880d681SAndroid Build Coastguard Worker   Offset += StackEst;
996*9880d681SAndroid Build Coastguard Worker 
997*9880d681SAndroid Build Coastguard Worker   // The frame pointer will point to the end of the stack, so estimate the
998*9880d681SAndroid Build Coastguard Worker   // offset as the difference between the object offset and the FP location.
999*9880d681SAndroid Build Coastguard Worker   return !isFrameOffsetLegal(MI, getBaseRegister(MF), Offset);
1000*9880d681SAndroid Build Coastguard Worker }
1001*9880d681SAndroid Build Coastguard Worker 
1002*9880d681SAndroid Build Coastguard Worker /// Insert defining instruction(s) for BaseReg to
1003*9880d681SAndroid Build Coastguard Worker /// be a pointer to FrameIdx at the beginning of the basic block.
1004*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::
materializeFrameBaseRegister(MachineBasicBlock * MBB,unsigned BaseReg,int FrameIdx,int64_t Offset) const1005*9880d681SAndroid Build Coastguard Worker materializeFrameBaseRegister(MachineBasicBlock *MBB,
1006*9880d681SAndroid Build Coastguard Worker                              unsigned BaseReg, int FrameIdx,
1007*9880d681SAndroid Build Coastguard Worker                              int64_t Offset) const {
1008*9880d681SAndroid Build Coastguard Worker   unsigned ADDriOpc = TM.isPPC64() ? PPC::ADDI8 : PPC::ADDI;
1009*9880d681SAndroid Build Coastguard Worker 
1010*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator Ins = MBB->begin();
1011*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;                  // Defaults to "unknown"
1012*9880d681SAndroid Build Coastguard Worker   if (Ins != MBB->end())
1013*9880d681SAndroid Build Coastguard Worker     DL = Ins->getDebugLoc();
1014*9880d681SAndroid Build Coastguard Worker 
1015*9880d681SAndroid Build Coastguard Worker   const MachineFunction &MF = *MBB->getParent();
1016*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
1017*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1018*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &MCID = TII.get(ADDriOpc);
1019*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
1020*9880d681SAndroid Build Coastguard Worker   MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this, MF));
1021*9880d681SAndroid Build Coastguard Worker 
1022*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, Ins, DL, MCID, BaseReg)
1023*9880d681SAndroid Build Coastguard Worker     .addFrameIndex(FrameIdx).addImm(Offset);
1024*9880d681SAndroid Build Coastguard Worker }
1025*9880d681SAndroid Build Coastguard Worker 
resolveFrameIndex(MachineInstr & MI,unsigned BaseReg,int64_t Offset) const1026*9880d681SAndroid Build Coastguard Worker void PPCRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
1027*9880d681SAndroid Build Coastguard Worker                                         int64_t Offset) const {
1028*9880d681SAndroid Build Coastguard Worker   unsigned FIOperandNum = 0;
1029*9880d681SAndroid Build Coastguard Worker   while (!MI.getOperand(FIOperandNum).isFI()) {
1030*9880d681SAndroid Build Coastguard Worker     ++FIOperandNum;
1031*9880d681SAndroid Build Coastguard Worker     assert(FIOperandNum < MI.getNumOperands() &&
1032*9880d681SAndroid Build Coastguard Worker            "Instr doesn't have FrameIndex operand!");
1033*9880d681SAndroid Build Coastguard Worker   }
1034*9880d681SAndroid Build Coastguard Worker 
1035*9880d681SAndroid Build Coastguard Worker   MI.getOperand(FIOperandNum).ChangeToRegister(BaseReg, false);
1036*9880d681SAndroid Build Coastguard Worker   unsigned OffsetOperandNo = getOffsetONFromFION(MI, FIOperandNum);
1037*9880d681SAndroid Build Coastguard Worker   Offset += MI.getOperand(OffsetOperandNo).getImm();
1038*9880d681SAndroid Build Coastguard Worker   MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
1039*9880d681SAndroid Build Coastguard Worker 
1040*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
1041*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
1042*9880d681SAndroid Build Coastguard Worker   const PPCSubtarget &Subtarget = MF.getSubtarget<PPCSubtarget>();
1043*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1044*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &MCID = MI.getDesc();
1045*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
1046*9880d681SAndroid Build Coastguard Worker   MRI.constrainRegClass(BaseReg,
1047*9880d681SAndroid Build Coastguard Worker                         TII.getRegClass(MCID, FIOperandNum, this, MF));
1048*9880d681SAndroid Build Coastguard Worker }
1049*9880d681SAndroid Build Coastguard Worker 
isFrameOffsetLegal(const MachineInstr * MI,unsigned BaseReg,int64_t Offset) const1050*9880d681SAndroid Build Coastguard Worker bool PPCRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
1051*9880d681SAndroid Build Coastguard Worker                                          unsigned BaseReg,
1052*9880d681SAndroid Build Coastguard Worker                                          int64_t Offset) const {
1053*9880d681SAndroid Build Coastguard Worker   unsigned FIOperandNum = 0;
1054*9880d681SAndroid Build Coastguard Worker   while (!MI->getOperand(FIOperandNum).isFI()) {
1055*9880d681SAndroid Build Coastguard Worker     ++FIOperandNum;
1056*9880d681SAndroid Build Coastguard Worker     assert(FIOperandNum < MI->getNumOperands() &&
1057*9880d681SAndroid Build Coastguard Worker            "Instr doesn't have FrameIndex operand!");
1058*9880d681SAndroid Build Coastguard Worker   }
1059*9880d681SAndroid Build Coastguard Worker 
1060*9880d681SAndroid Build Coastguard Worker   unsigned OffsetOperandNo = getOffsetONFromFION(*MI, FIOperandNum);
1061*9880d681SAndroid Build Coastguard Worker   Offset += MI->getOperand(OffsetOperandNo).getImm();
1062*9880d681SAndroid Build Coastguard Worker 
1063*9880d681SAndroid Build Coastguard Worker   return MI->getOpcode() == PPC::DBG_VALUE || // DBG_VALUE is always Reg+Imm
1064*9880d681SAndroid Build Coastguard Worker          MI->getOpcode() == TargetOpcode::STACKMAP ||
1065*9880d681SAndroid Build Coastguard Worker          MI->getOpcode() == TargetOpcode::PATCHPOINT ||
1066*9880d681SAndroid Build Coastguard Worker          (isInt<16>(Offset) && (!usesIXAddr(*MI) || (Offset & 3) == 0));
1067*9880d681SAndroid Build Coastguard Worker }
1068