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