1*9880d681SAndroid Build Coastguard Worker //===-- MipsSEFrameLowering.cpp - Mips32/64 Frame 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 Mips32/64 implementation of TargetFrameLowering class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "MipsSEFrameLowering.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/MipsBaseInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
17*9880d681SAndroid Build Coastguard Worker #include "MipsSEInstrInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "MipsSubtarget.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineModuleInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterScavenging.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetOptions.h"
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker namespace {
33*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::iterator Iter;
34*9880d681SAndroid Build Coastguard Worker
getMFHiLoOpc(unsigned Src)35*9880d681SAndroid Build Coastguard Worker static std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) {
36*9880d681SAndroid Build Coastguard Worker if (Mips::ACC64RegClass.contains(Src))
37*9880d681SAndroid Build Coastguard Worker return std::make_pair((unsigned)Mips::PseudoMFHI,
38*9880d681SAndroid Build Coastguard Worker (unsigned)Mips::PseudoMFLO);
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker if (Mips::ACC64DSPRegClass.contains(Src))
41*9880d681SAndroid Build Coastguard Worker return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP);
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker if (Mips::ACC128RegClass.contains(Src))
44*9880d681SAndroid Build Coastguard Worker return std::make_pair((unsigned)Mips::PseudoMFHI64,
45*9880d681SAndroid Build Coastguard Worker (unsigned)Mips::PseudoMFLO64);
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker return std::make_pair(0, 0);
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker /// Helper class to expand pseudos.
51*9880d681SAndroid Build Coastguard Worker class ExpandPseudo {
52*9880d681SAndroid Build Coastguard Worker public:
53*9880d681SAndroid Build Coastguard Worker ExpandPseudo(MachineFunction &MF);
54*9880d681SAndroid Build Coastguard Worker bool expand();
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker private:
57*9880d681SAndroid Build Coastguard Worker bool expandInstr(MachineBasicBlock &MBB, Iter I);
58*9880d681SAndroid Build Coastguard Worker void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
59*9880d681SAndroid Build Coastguard Worker void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
60*9880d681SAndroid Build Coastguard Worker void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
61*9880d681SAndroid Build Coastguard Worker void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
62*9880d681SAndroid Build Coastguard Worker unsigned MFLoOpc, unsigned RegSize);
63*9880d681SAndroid Build Coastguard Worker bool expandCopy(MachineBasicBlock &MBB, Iter I);
64*9880d681SAndroid Build Coastguard Worker bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
65*9880d681SAndroid Build Coastguard Worker unsigned MFLoOpc);
66*9880d681SAndroid Build Coastguard Worker bool expandBuildPairF64(MachineBasicBlock &MBB,
67*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, bool FP64) const;
68*9880d681SAndroid Build Coastguard Worker bool expandExtractElementF64(MachineBasicBlock &MBB,
69*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I, bool FP64) const;
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker MachineFunction &MF;
72*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI;
73*9880d681SAndroid Build Coastguard Worker const MipsSubtarget &Subtarget;
74*9880d681SAndroid Build Coastguard Worker const MipsSEInstrInfo &TII;
75*9880d681SAndroid Build Coastguard Worker const MipsRegisterInfo &RegInfo;
76*9880d681SAndroid Build Coastguard Worker };
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
ExpandPseudo(MachineFunction & MF_)79*9880d681SAndroid Build Coastguard Worker ExpandPseudo::ExpandPseudo(MachineFunction &MF_)
80*9880d681SAndroid Build Coastguard Worker : MF(MF_), MRI(MF.getRegInfo()),
81*9880d681SAndroid Build Coastguard Worker Subtarget(static_cast<const MipsSubtarget &>(MF.getSubtarget())),
82*9880d681SAndroid Build Coastguard Worker TII(*static_cast<const MipsSEInstrInfo *>(Subtarget.getInstrInfo())),
83*9880d681SAndroid Build Coastguard Worker RegInfo(*Subtarget.getRegisterInfo()) {}
84*9880d681SAndroid Build Coastguard Worker
expand()85*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expand() {
86*9880d681SAndroid Build Coastguard Worker bool Expanded = false;
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker for (auto &MBB : MF) {
89*9880d681SAndroid Build Coastguard Worker for (Iter I = MBB.begin(), End = MBB.end(); I != End;)
90*9880d681SAndroid Build Coastguard Worker Expanded |= expandInstr(MBB, I++);
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker return Expanded;
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker
expandInstr(MachineBasicBlock & MBB,Iter I)96*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
97*9880d681SAndroid Build Coastguard Worker switch(I->getOpcode()) {
98*9880d681SAndroid Build Coastguard Worker case Mips::LOAD_CCOND_DSP:
99*9880d681SAndroid Build Coastguard Worker expandLoadCCond(MBB, I);
100*9880d681SAndroid Build Coastguard Worker break;
101*9880d681SAndroid Build Coastguard Worker case Mips::STORE_CCOND_DSP:
102*9880d681SAndroid Build Coastguard Worker expandStoreCCond(MBB, I);
103*9880d681SAndroid Build Coastguard Worker break;
104*9880d681SAndroid Build Coastguard Worker case Mips::LOAD_ACC64:
105*9880d681SAndroid Build Coastguard Worker case Mips::LOAD_ACC64DSP:
106*9880d681SAndroid Build Coastguard Worker expandLoadACC(MBB, I, 4);
107*9880d681SAndroid Build Coastguard Worker break;
108*9880d681SAndroid Build Coastguard Worker case Mips::LOAD_ACC128:
109*9880d681SAndroid Build Coastguard Worker expandLoadACC(MBB, I, 8);
110*9880d681SAndroid Build Coastguard Worker break;
111*9880d681SAndroid Build Coastguard Worker case Mips::STORE_ACC64:
112*9880d681SAndroid Build Coastguard Worker expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
113*9880d681SAndroid Build Coastguard Worker break;
114*9880d681SAndroid Build Coastguard Worker case Mips::STORE_ACC64DSP:
115*9880d681SAndroid Build Coastguard Worker expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
116*9880d681SAndroid Build Coastguard Worker break;
117*9880d681SAndroid Build Coastguard Worker case Mips::STORE_ACC128:
118*9880d681SAndroid Build Coastguard Worker expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
119*9880d681SAndroid Build Coastguard Worker break;
120*9880d681SAndroid Build Coastguard Worker case Mips::BuildPairF64:
121*9880d681SAndroid Build Coastguard Worker if (expandBuildPairF64(MBB, I, false))
122*9880d681SAndroid Build Coastguard Worker MBB.erase(I);
123*9880d681SAndroid Build Coastguard Worker return false;
124*9880d681SAndroid Build Coastguard Worker case Mips::BuildPairF64_64:
125*9880d681SAndroid Build Coastguard Worker if (expandBuildPairF64(MBB, I, true))
126*9880d681SAndroid Build Coastguard Worker MBB.erase(I);
127*9880d681SAndroid Build Coastguard Worker return false;
128*9880d681SAndroid Build Coastguard Worker case Mips::ExtractElementF64:
129*9880d681SAndroid Build Coastguard Worker if (expandExtractElementF64(MBB, I, false))
130*9880d681SAndroid Build Coastguard Worker MBB.erase(I);
131*9880d681SAndroid Build Coastguard Worker return false;
132*9880d681SAndroid Build Coastguard Worker case Mips::ExtractElementF64_64:
133*9880d681SAndroid Build Coastguard Worker if (expandExtractElementF64(MBB, I, true))
134*9880d681SAndroid Build Coastguard Worker MBB.erase(I);
135*9880d681SAndroid Build Coastguard Worker return false;
136*9880d681SAndroid Build Coastguard Worker case TargetOpcode::COPY:
137*9880d681SAndroid Build Coastguard Worker if (!expandCopy(MBB, I))
138*9880d681SAndroid Build Coastguard Worker return false;
139*9880d681SAndroid Build Coastguard Worker break;
140*9880d681SAndroid Build Coastguard Worker default:
141*9880d681SAndroid Build Coastguard Worker return false;
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker MBB.erase(I);
145*9880d681SAndroid Build Coastguard Worker return true;
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
expandLoadCCond(MachineBasicBlock & MBB,Iter I)148*9880d681SAndroid Build Coastguard Worker void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
149*9880d681SAndroid Build Coastguard Worker // load $vr, FI
150*9880d681SAndroid Build Coastguard Worker // copy ccond, $vr
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = RegInfo.intRegClass(4);
155*9880d681SAndroid Build Coastguard Worker unsigned VR = MRI.createVirtualRegister(RC);
156*9880d681SAndroid Build Coastguard Worker unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
159*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
160*9880d681SAndroid Build Coastguard Worker .addReg(VR, RegState::Kill);
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
expandStoreCCond(MachineBasicBlock & MBB,Iter I)163*9880d681SAndroid Build Coastguard Worker void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
164*9880d681SAndroid Build Coastguard Worker // copy $vr, ccond
165*9880d681SAndroid Build Coastguard Worker // store $vr, FI
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = RegInfo.intRegClass(4);
170*9880d681SAndroid Build Coastguard Worker unsigned VR = MRI.createVirtualRegister(RC);
171*9880d681SAndroid Build Coastguard Worker unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
174*9880d681SAndroid Build Coastguard Worker .addReg(Src, getKillRegState(I->getOperand(0).isKill()));
175*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0);
176*9880d681SAndroid Build Coastguard Worker }
177*9880d681SAndroid Build Coastguard Worker
expandLoadACC(MachineBasicBlock & MBB,Iter I,unsigned RegSize)178*9880d681SAndroid Build Coastguard Worker void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
179*9880d681SAndroid Build Coastguard Worker unsigned RegSize) {
180*9880d681SAndroid Build Coastguard Worker // load $vr0, FI
181*9880d681SAndroid Build Coastguard Worker // copy lo, $vr0
182*9880d681SAndroid Build Coastguard Worker // load $vr1, FI + 4
183*9880d681SAndroid Build Coastguard Worker // copy hi, $vr1
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
188*9880d681SAndroid Build Coastguard Worker unsigned VR0 = MRI.createVirtualRegister(RC);
189*9880d681SAndroid Build Coastguard Worker unsigned VR1 = MRI.createVirtualRegister(RC);
190*9880d681SAndroid Build Coastguard Worker unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
191*9880d681SAndroid Build Coastguard Worker unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
192*9880d681SAndroid Build Coastguard Worker unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
193*9880d681SAndroid Build Coastguard Worker DebugLoc DL = I->getDebugLoc();
194*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
197*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
198*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
199*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker
expandStoreACC(MachineBasicBlock & MBB,Iter I,unsigned MFHiOpc,unsigned MFLoOpc,unsigned RegSize)202*9880d681SAndroid Build Coastguard Worker void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
203*9880d681SAndroid Build Coastguard Worker unsigned MFHiOpc, unsigned MFLoOpc,
204*9880d681SAndroid Build Coastguard Worker unsigned RegSize) {
205*9880d681SAndroid Build Coastguard Worker // mflo $vr0, src
206*9880d681SAndroid Build Coastguard Worker // store $vr0, FI
207*9880d681SAndroid Build Coastguard Worker // mfhi $vr1, src
208*9880d681SAndroid Build Coastguard Worker // store $vr1, FI + 4
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
213*9880d681SAndroid Build Coastguard Worker unsigned VR0 = MRI.createVirtualRegister(RC);
214*9880d681SAndroid Build Coastguard Worker unsigned VR1 = MRI.createVirtualRegister(RC);
215*9880d681SAndroid Build Coastguard Worker unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
216*9880d681SAndroid Build Coastguard Worker unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
217*9880d681SAndroid Build Coastguard Worker DebugLoc DL = I->getDebugLoc();
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
220*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0);
221*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
222*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize);
223*9880d681SAndroid Build Coastguard Worker }
224*9880d681SAndroid Build Coastguard Worker
expandCopy(MachineBasicBlock & MBB,Iter I)225*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
226*9880d681SAndroid Build Coastguard Worker unsigned Src = I->getOperand(1).getReg();
227*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker if (!Opcodes.first)
230*9880d681SAndroid Build Coastguard Worker return false;
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker
expandCopyACC(MachineBasicBlock & MBB,Iter I,unsigned MFHiOpc,unsigned MFLoOpc)235*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
236*9880d681SAndroid Build Coastguard Worker unsigned MFHiOpc, unsigned MFLoOpc) {
237*9880d681SAndroid Build Coastguard Worker // mflo $vr0, src
238*9880d681SAndroid Build Coastguard Worker // copy dst_lo, $vr0
239*9880d681SAndroid Build Coastguard Worker // mfhi $vr1, src
240*9880d681SAndroid Build Coastguard Worker // copy dst_hi, $vr1
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
243*9880d681SAndroid Build Coastguard Worker unsigned VRegSize = RegInfo.getMinimalPhysRegClass(Dst)->getSize() / 2;
244*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);
245*9880d681SAndroid Build Coastguard Worker unsigned VR0 = MRI.createVirtualRegister(RC);
246*9880d681SAndroid Build Coastguard Worker unsigned VR1 = MRI.createVirtualRegister(RC);
247*9880d681SAndroid Build Coastguard Worker unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
248*9880d681SAndroid Build Coastguard Worker unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
249*9880d681SAndroid Build Coastguard Worker unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
250*9880d681SAndroid Build Coastguard Worker DebugLoc DL = I->getDebugLoc();
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
253*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
254*9880d681SAndroid Build Coastguard Worker .addReg(VR0, RegState::Kill);
255*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
256*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
257*9880d681SAndroid Build Coastguard Worker .addReg(VR1, RegState::Kill);
258*9880d681SAndroid Build Coastguard Worker return true;
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker /// This method expands the same instruction that MipsSEInstrInfo::
262*9880d681SAndroid Build Coastguard Worker /// expandBuildPairF64 does, for the case when ABI is fpxx and mthc1 is not
263*9880d681SAndroid Build Coastguard Worker /// available and the case where the ABI is FP64A. It is implemented here
264*9880d681SAndroid Build Coastguard Worker /// because frame indexes are eliminated before MipsSEInstrInfo::
265*9880d681SAndroid Build Coastguard Worker /// expandBuildPairF64 is called.
expandBuildPairF64(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,bool FP64) const266*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
267*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I,
268*9880d681SAndroid Build Coastguard Worker bool FP64) const {
269*9880d681SAndroid Build Coastguard Worker // For fpxx and when mthc1 is not available, use:
270*9880d681SAndroid Build Coastguard Worker // spill + reload via ldc1
271*9880d681SAndroid Build Coastguard Worker //
272*9880d681SAndroid Build Coastguard Worker // The case where dmtc1 is available doesn't need to be handled here
273*9880d681SAndroid Build Coastguard Worker // because it never creates a BuildPairF64 node.
274*9880d681SAndroid Build Coastguard Worker //
275*9880d681SAndroid Build Coastguard Worker // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
276*9880d681SAndroid Build Coastguard Worker // for odd-numbered double precision values (because the lower 32-bits is
277*9880d681SAndroid Build Coastguard Worker // transferred with mtc1 which is redirected to the upper half of the even
278*9880d681SAndroid Build Coastguard Worker // register). Unfortunately, we have to make this decision before register
279*9880d681SAndroid Build Coastguard Worker // allocation so for now we use a spill/reload sequence for all
280*9880d681SAndroid Build Coastguard Worker // double-precision values in regardless of being an odd/even register.
281*9880d681SAndroid Build Coastguard Worker if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) ||
282*9880d681SAndroid Build Coastguard Worker (FP64 && !Subtarget.useOddSPReg())) {
283*9880d681SAndroid Build Coastguard Worker unsigned DstReg = I->getOperand(0).getReg();
284*9880d681SAndroid Build Coastguard Worker unsigned LoReg = I->getOperand(1).getReg();
285*9880d681SAndroid Build Coastguard Worker unsigned HiReg = I->getOperand(2).getReg();
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
288*9880d681SAndroid Build Coastguard Worker // the cases where mthc1 is not available). 64-bit architectures and
289*9880d681SAndroid Build Coastguard Worker // MIPS32r2 or later can use FGR64 though.
290*9880d681SAndroid Build Coastguard Worker assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
291*9880d681SAndroid Build Coastguard Worker !Subtarget.isFP64bit());
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = &Mips::GPR32RegClass;
294*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC2 =
295*9880d681SAndroid Build Coastguard Worker FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker // We re-use the same spill slot each time so that the stack frame doesn't
298*9880d681SAndroid Build Coastguard Worker // grow too much in functions with a large number of moves.
299*9880d681SAndroid Build Coastguard Worker int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(RC2);
300*9880d681SAndroid Build Coastguard Worker if (!Subtarget.isLittle())
301*9880d681SAndroid Build Coastguard Worker std::swap(LoReg, HiReg);
302*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC,
303*9880d681SAndroid Build Coastguard Worker &RegInfo, 0);
304*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC,
305*9880d681SAndroid Build Coastguard Worker &RegInfo, 4);
306*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, 0);
307*9880d681SAndroid Build Coastguard Worker return true;
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker return false;
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker /// This method expands the same instruction that MipsSEInstrInfo::
314*9880d681SAndroid Build Coastguard Worker /// expandExtractElementF64 does, for the case when ABI is fpxx and mfhc1 is not
315*9880d681SAndroid Build Coastguard Worker /// available and the case where the ABI is FP64A. It is implemented here
316*9880d681SAndroid Build Coastguard Worker /// because frame indexes are eliminated before MipsSEInstrInfo::
317*9880d681SAndroid Build Coastguard Worker /// expandExtractElementF64 is called.
expandExtractElementF64(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,bool FP64) const318*9880d681SAndroid Build Coastguard Worker bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
319*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I,
320*9880d681SAndroid Build Coastguard Worker bool FP64) const {
321*9880d681SAndroid Build Coastguard Worker const MachineOperand &Op1 = I->getOperand(1);
322*9880d681SAndroid Build Coastguard Worker const MachineOperand &Op2 = I->getOperand(2);
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) {
325*9880d681SAndroid Build Coastguard Worker unsigned DstReg = I->getOperand(0).getReg();
326*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg);
327*9880d681SAndroid Build Coastguard Worker return true;
328*9880d681SAndroid Build Coastguard Worker }
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Worker // For fpxx and when mfhc1 is not available, use:
331*9880d681SAndroid Build Coastguard Worker // spill + reload via ldc1
332*9880d681SAndroid Build Coastguard Worker //
333*9880d681SAndroid Build Coastguard Worker // The case where dmfc1 is available doesn't need to be handled here
334*9880d681SAndroid Build Coastguard Worker // because it never creates a ExtractElementF64 node.
335*9880d681SAndroid Build Coastguard Worker //
336*9880d681SAndroid Build Coastguard Worker // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
337*9880d681SAndroid Build Coastguard Worker // for odd-numbered double precision values (because the lower 32-bits is
338*9880d681SAndroid Build Coastguard Worker // transferred with mfc1 which is redirected to the upper half of the even
339*9880d681SAndroid Build Coastguard Worker // register). Unfortunately, we have to make this decision before register
340*9880d681SAndroid Build Coastguard Worker // allocation so for now we use a spill/reload sequence for all
341*9880d681SAndroid Build Coastguard Worker // double-precision values in regardless of being an odd/even register.
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) ||
344*9880d681SAndroid Build Coastguard Worker (FP64 && !Subtarget.useOddSPReg())) {
345*9880d681SAndroid Build Coastguard Worker unsigned DstReg = I->getOperand(0).getReg();
346*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Op1.getReg();
347*9880d681SAndroid Build Coastguard Worker unsigned N = Op2.getImm();
348*9880d681SAndroid Build Coastguard Worker int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
351*9880d681SAndroid Build Coastguard Worker // the cases where mfhc1 is not available). 64-bit architectures and
352*9880d681SAndroid Build Coastguard Worker // MIPS32r2 or later can use FGR64 though.
353*9880d681SAndroid Build Coastguard Worker assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
354*9880d681SAndroid Build Coastguard Worker !Subtarget.isFP64bit());
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC =
357*9880d681SAndroid Build Coastguard Worker FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
358*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker // We re-use the same spill slot each time so that the stack frame doesn't
361*9880d681SAndroid Build Coastguard Worker // grow too much in functions with a large number of moves.
362*9880d681SAndroid Build Coastguard Worker int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(RC);
363*9880d681SAndroid Build Coastguard Worker TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, &RegInfo, 0);
364*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, Offset);
365*9880d681SAndroid Build Coastguard Worker return true;
366*9880d681SAndroid Build Coastguard Worker }
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker return false;
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
MipsSEFrameLowering(const MipsSubtarget & STI)371*9880d681SAndroid Build Coastguard Worker MipsSEFrameLowering::MipsSEFrameLowering(const MipsSubtarget &STI)
372*9880d681SAndroid Build Coastguard Worker : MipsFrameLowering(STI, STI.stackAlignment()) {}
373*9880d681SAndroid Build Coastguard Worker
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const374*9880d681SAndroid Build Coastguard Worker void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
375*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
376*9880d681SAndroid Build Coastguard Worker assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
377*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
378*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker const MipsSEInstrInfo &TII =
381*9880d681SAndroid Build Coastguard Worker *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
382*9880d681SAndroid Build Coastguard Worker const MipsRegisterInfo &RegInfo =
383*9880d681SAndroid Build Coastguard Worker *static_cast<const MipsRegisterInfo *>(STI.getRegisterInfo());
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.begin();
386*9880d681SAndroid Build Coastguard Worker DebugLoc dl;
387*9880d681SAndroid Build Coastguard Worker MipsABIInfo ABI = STI.getABI();
388*9880d681SAndroid Build Coastguard Worker unsigned SP = ABI.GetStackPtr();
389*9880d681SAndroid Build Coastguard Worker unsigned FP = ABI.GetFramePtr();
390*9880d681SAndroid Build Coastguard Worker unsigned ZERO = ABI.GetNullPtr();
391*9880d681SAndroid Build Coastguard Worker unsigned MOVE = ABI.GetGPRMoveOp();
392*9880d681SAndroid Build Coastguard Worker unsigned ADDiu = ABI.GetPtrAddiuOp();
393*9880d681SAndroid Build Coastguard Worker unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?
396*9880d681SAndroid Build Coastguard Worker &Mips::GPR64RegClass : &Mips::GPR32RegClass;
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker // First, compute final stack size.
399*9880d681SAndroid Build Coastguard Worker uint64_t StackSize = MFI->getStackSize();
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker // No need to allocate space on the stack.
402*9880d681SAndroid Build Coastguard Worker if (StackSize == 0 && !MFI->adjustsStack()) return;
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker MachineModuleInfo &MMI = MF.getMMI();
405*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
406*9880d681SAndroid Build Coastguard Worker MachineLocation DstML, SrcML;
407*9880d681SAndroid Build Coastguard Worker
408*9880d681SAndroid Build Coastguard Worker // Adjust stack.
409*9880d681SAndroid Build Coastguard Worker TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker // emit ".cfi_def_cfa_offset StackSize"
412*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
413*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createDefCfaOffset(nullptr, -StackSize));
414*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
415*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->hasFnAttribute("interrupt"))
418*9880d681SAndroid Build Coastguard Worker emitInterruptPrologueStub(MF, MBB);
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker if (CSI.size()) {
423*9880d681SAndroid Build Coastguard Worker // Find the instruction past the last instruction that saves a callee-saved
424*9880d681SAndroid Build Coastguard Worker // register to the stack.
425*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < CSI.size(); ++i)
426*9880d681SAndroid Build Coastguard Worker ++MBBI;
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker // Iterate over list of callee-saved registers and emit .cfi_offset
429*9880d681SAndroid Build Coastguard Worker // directives.
430*9880d681SAndroid Build Coastguard Worker for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
431*9880d681SAndroid Build Coastguard Worker E = CSI.end(); I != E; ++I) {
432*9880d681SAndroid Build Coastguard Worker int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
433*9880d681SAndroid Build Coastguard Worker unsigned Reg = I->getReg();
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker // If Reg is a double precision register, emit two cfa_offsets,
436*9880d681SAndroid Build Coastguard Worker // one for each of the paired single precision registers.
437*9880d681SAndroid Build Coastguard Worker if (Mips::AFGR64RegClass.contains(Reg)) {
438*9880d681SAndroid Build Coastguard Worker unsigned Reg0 =
439*9880d681SAndroid Build Coastguard Worker MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_lo), true);
440*9880d681SAndroid Build Coastguard Worker unsigned Reg1 =
441*9880d681SAndroid Build Coastguard Worker MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_hi), true);
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker if (!STI.isLittle())
444*9880d681SAndroid Build Coastguard Worker std::swap(Reg0, Reg1);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
447*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, Reg0, Offset));
448*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
449*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker CFIIndex = MMI.addFrameInst(
452*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, Reg1, Offset + 4));
453*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
454*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
455*9880d681SAndroid Build Coastguard Worker } else if (Mips::FGR64RegClass.contains(Reg)) {
456*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = MRI->getDwarfRegNum(Reg, true);
457*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = MRI->getDwarfRegNum(Reg, true) + 1;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker if (!STI.isLittle())
460*9880d681SAndroid Build Coastguard Worker std::swap(Reg0, Reg1);
461*9880d681SAndroid Build Coastguard Worker
462*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
463*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, Reg0, Offset));
464*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
465*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker CFIIndex = MMI.addFrameInst(
468*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, Reg1, Offset + 4));
469*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
470*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
471*9880d681SAndroid Build Coastguard Worker } else {
472*9880d681SAndroid Build Coastguard Worker // Reg is either in GPR32 or FGR32.
473*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createOffset(
474*9880d681SAndroid Build Coastguard Worker nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));
475*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
476*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
477*9880d681SAndroid Build Coastguard Worker }
478*9880d681SAndroid Build Coastguard Worker }
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker
481*9880d681SAndroid Build Coastguard Worker if (MipsFI->callsEhReturn()) {
482*9880d681SAndroid Build Coastguard Worker // Insert instructions that spill eh data registers.
483*9880d681SAndroid Build Coastguard Worker for (int I = 0; I < 4; ++I) {
484*9880d681SAndroid Build Coastguard Worker if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))
485*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(ABI.GetEhDataReg(I));
486*9880d681SAndroid Build Coastguard Worker TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,
487*9880d681SAndroid Build Coastguard Worker MipsFI->getEhDataRegFI(I), RC, &RegInfo);
488*9880d681SAndroid Build Coastguard Worker }
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Worker // Emit .cfi_offset directives for eh data registers.
491*9880d681SAndroid Build Coastguard Worker for (int I = 0; I < 4; ++I) {
492*9880d681SAndroid Build Coastguard Worker int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
493*9880d681SAndroid Build Coastguard Worker unsigned Reg = MRI->getDwarfRegNum(ABI.GetEhDataReg(I), true);
494*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(
495*9880d681SAndroid Build Coastguard Worker MCCFIInstruction::createOffset(nullptr, Reg, Offset));
496*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
497*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
498*9880d681SAndroid Build Coastguard Worker }
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker // if framepointer enabled, set it to point to the stack pointer.
502*9880d681SAndroid Build Coastguard Worker if (hasFP(MF)) {
503*9880d681SAndroid Build Coastguard Worker // Insert instruction "move $fp, $sp" at this location.
504*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(MOVE), FP).addReg(SP).addReg(ZERO)
505*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
506*9880d681SAndroid Build Coastguard Worker
507*9880d681SAndroid Build Coastguard Worker // emit ".cfi_def_cfa_register $fp"
508*9880d681SAndroid Build Coastguard Worker unsigned CFIIndex = MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(
509*9880d681SAndroid Build Coastguard Worker nullptr, MRI->getDwarfRegNum(FP, true)));
510*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
511*9880d681SAndroid Build Coastguard Worker .addCFIIndex(CFIIndex);
512*9880d681SAndroid Build Coastguard Worker
513*9880d681SAndroid Build Coastguard Worker if (RegInfo.needsStackRealignment(MF)) {
514*9880d681SAndroid Build Coastguard Worker // addiu $Reg, $zero, -MaxAlignment
515*9880d681SAndroid Build Coastguard Worker // andi $sp, $sp, $Reg
516*9880d681SAndroid Build Coastguard Worker unsigned VR = MF.getRegInfo().createVirtualRegister(RC);
517*9880d681SAndroid Build Coastguard Worker assert(isInt<16>(MFI->getMaxAlignment()) &&
518*9880d681SAndroid Build Coastguard Worker "Function's alignment size requirement is not supported.");
519*9880d681SAndroid Build Coastguard Worker int MaxAlign = -(int)MFI->getMaxAlignment();
520*9880d681SAndroid Build Coastguard Worker
521*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO) .addImm(MaxAlign);
522*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);
523*9880d681SAndroid Build Coastguard Worker
524*9880d681SAndroid Build Coastguard Worker if (hasBP(MF)) {
525*9880d681SAndroid Build Coastguard Worker // move $s7, $sp
526*9880d681SAndroid Build Coastguard Worker unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7;
527*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP)
528*9880d681SAndroid Build Coastguard Worker .addReg(SP)
529*9880d681SAndroid Build Coastguard Worker .addReg(ZERO);
530*9880d681SAndroid Build Coastguard Worker }
531*9880d681SAndroid Build Coastguard Worker }
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker }
534*9880d681SAndroid Build Coastguard Worker
emitInterruptPrologueStub(MachineFunction & MF,MachineBasicBlock & MBB) const535*9880d681SAndroid Build Coastguard Worker void MipsSEFrameLowering::emitInterruptPrologueStub(
536*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, MachineBasicBlock &MBB) const {
537*9880d681SAndroid Build Coastguard Worker
538*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
539*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.begin();
540*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Report an error the target doesn't support Mips32r2 or later.
543*9880d681SAndroid Build Coastguard Worker // The epilogue relies on the use of the "ehb" to clear execution
544*9880d681SAndroid Build Coastguard Worker // hazards. Pre R2 Mips relies on an implementation defined number
545*9880d681SAndroid Build Coastguard Worker // of "ssnop"s to clear the execution hazard. Support for ssnop hazard
546*9880d681SAndroid Build Coastguard Worker // clearing is not provided so reject that configuration.
547*9880d681SAndroid Build Coastguard Worker if (!STI.hasMips32r2())
548*9880d681SAndroid Build Coastguard Worker report_fatal_error(
549*9880d681SAndroid Build Coastguard Worker "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
550*9880d681SAndroid Build Coastguard Worker "MIPS16 targets.");
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker // The GP register contains the "user" value, so we cannot perform
553*9880d681SAndroid Build Coastguard Worker // any gp relative loads until we restore the "kernel" or "system" gp
554*9880d681SAndroid Build Coastguard Worker // value. Until support is written we shall only accept the static
555*9880d681SAndroid Build Coastguard Worker // relocation model.
556*9880d681SAndroid Build Coastguard Worker if ((STI.getRelocationModel() != Reloc::Static))
557*9880d681SAndroid Build Coastguard Worker report_fatal_error("\"interrupt\" attribute is only supported for the "
558*9880d681SAndroid Build Coastguard Worker "static relocation model on MIPS at the present time.");
559*9880d681SAndroid Build Coastguard Worker
560*9880d681SAndroid Build Coastguard Worker if (!STI.isABI_O32() || STI.hasMips64())
561*9880d681SAndroid Build Coastguard Worker report_fatal_error("\"interrupt\" attribute is only supported for the "
562*9880d681SAndroid Build Coastguard Worker "O32 ABI on MIPS32R2+ at the present time.");
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker // Perform ISR handling like GCC
565*9880d681SAndroid Build Coastguard Worker StringRef IntKind =
566*9880d681SAndroid Build Coastguard Worker MF.getFunction()->getFnAttribute("interrupt").getValueAsString();
567*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker // EIC interrupt handling needs to read the Cause register to disable
570*9880d681SAndroid Build Coastguard Worker // interrupts.
571*9880d681SAndroid Build Coastguard Worker if (IntKind == "eic") {
572*9880d681SAndroid Build Coastguard Worker // Coprocessor registers are always live per se.
573*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Mips::COP013);
574*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K0)
575*9880d681SAndroid Build Coastguard Worker .addReg(Mips::COP013)
576*9880d681SAndroid Build Coastguard Worker .addImm(0)
577*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)
580*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K0)
581*9880d681SAndroid Build Coastguard Worker .addImm(10)
582*9880d681SAndroid Build Coastguard Worker .addImm(6)
583*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
584*9880d681SAndroid Build Coastguard Worker }
585*9880d681SAndroid Build Coastguard Worker
586*9880d681SAndroid Build Coastguard Worker // Fetch and spill EPC
587*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Mips::COP014);
588*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
589*9880d681SAndroid Build Coastguard Worker .addReg(Mips::COP014)
590*9880d681SAndroid Build Coastguard Worker .addImm(0)
591*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
592*9880d681SAndroid Build Coastguard Worker
593*9880d681SAndroid Build Coastguard Worker STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
594*9880d681SAndroid Build Coastguard Worker MipsFI->getISRRegFI(0), PtrRC,
595*9880d681SAndroid Build Coastguard Worker STI.getRegisterInfo(), 0);
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker // Fetch and Spill Status
598*9880d681SAndroid Build Coastguard Worker MBB.addLiveIn(Mips::COP012);
599*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
600*9880d681SAndroid Build Coastguard Worker .addReg(Mips::COP012)
601*9880d681SAndroid Build Coastguard Worker .addImm(0)
602*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Worker STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
605*9880d681SAndroid Build Coastguard Worker MipsFI->getISRRegFI(1), PtrRC,
606*9880d681SAndroid Build Coastguard Worker STI.getRegisterInfo(), 0);
607*9880d681SAndroid Build Coastguard Worker
608*9880d681SAndroid Build Coastguard Worker // Build the configuration for disabling lower priority interrupts. Non EIC
609*9880d681SAndroid Build Coastguard Worker // interrupts need to be masked off with zero, EIC from the Cause register.
610*9880d681SAndroid Build Coastguard Worker unsigned InsPosition = 8;
611*9880d681SAndroid Build Coastguard Worker unsigned InsSize = 0;
612*9880d681SAndroid Build Coastguard Worker unsigned SrcReg = Mips::ZERO;
613*9880d681SAndroid Build Coastguard Worker
614*9880d681SAndroid Build Coastguard Worker // If the interrupt we're tied to is the EIC, switch the source for the
615*9880d681SAndroid Build Coastguard Worker // masking off interrupts to the cause register.
616*9880d681SAndroid Build Coastguard Worker if (IntKind == "eic") {
617*9880d681SAndroid Build Coastguard Worker SrcReg = Mips::K0;
618*9880d681SAndroid Build Coastguard Worker InsPosition = 10;
619*9880d681SAndroid Build Coastguard Worker InsSize = 6;
620*9880d681SAndroid Build Coastguard Worker } else
621*9880d681SAndroid Build Coastguard Worker InsSize = StringSwitch<unsigned>(IntKind)
622*9880d681SAndroid Build Coastguard Worker .Case("sw0", 1)
623*9880d681SAndroid Build Coastguard Worker .Case("sw1", 2)
624*9880d681SAndroid Build Coastguard Worker .Case("hw0", 3)
625*9880d681SAndroid Build Coastguard Worker .Case("hw1", 4)
626*9880d681SAndroid Build Coastguard Worker .Case("hw2", 5)
627*9880d681SAndroid Build Coastguard Worker .Case("hw3", 6)
628*9880d681SAndroid Build Coastguard Worker .Case("hw4", 7)
629*9880d681SAndroid Build Coastguard Worker .Case("hw5", 8)
630*9880d681SAndroid Build Coastguard Worker .Default(0);
631*9880d681SAndroid Build Coastguard Worker assert(InsSize != 0 && "Unknown interrupt type!");
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
634*9880d681SAndroid Build Coastguard Worker .addReg(SrcReg)
635*9880d681SAndroid Build Coastguard Worker .addImm(InsPosition)
636*9880d681SAndroid Build Coastguard Worker .addImm(InsSize)
637*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
638*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
639*9880d681SAndroid Build Coastguard Worker
640*9880d681SAndroid Build Coastguard Worker // Mask off KSU, ERL, EXL
641*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
642*9880d681SAndroid Build Coastguard Worker .addReg(Mips::ZERO)
643*9880d681SAndroid Build Coastguard Worker .addImm(1)
644*9880d681SAndroid Build Coastguard Worker .addImm(4)
645*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
646*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
647*9880d681SAndroid Build Coastguard Worker
648*9880d681SAndroid Build Coastguard Worker // Disable the FPU as we are not spilling those register sets.
649*9880d681SAndroid Build Coastguard Worker if (!STI.useSoftFloat())
650*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
651*9880d681SAndroid Build Coastguard Worker .addReg(Mips::ZERO)
652*9880d681SAndroid Build Coastguard Worker .addImm(29)
653*9880d681SAndroid Build Coastguard Worker .addImm(1)
654*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
655*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
656*9880d681SAndroid Build Coastguard Worker
657*9880d681SAndroid Build Coastguard Worker // Set the new status
658*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
659*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
660*9880d681SAndroid Build Coastguard Worker .addImm(0)
661*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
662*9880d681SAndroid Build Coastguard Worker }
663*9880d681SAndroid Build Coastguard Worker
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const664*9880d681SAndroid Build Coastguard Worker void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
665*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &MBB) const {
666*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
667*9880d681SAndroid Build Coastguard Worker MachineFrameInfo *MFI = MF.getFrameInfo();
668*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
669*9880d681SAndroid Build Coastguard Worker
670*9880d681SAndroid Build Coastguard Worker const MipsSEInstrInfo &TII =
671*9880d681SAndroid Build Coastguard Worker *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
672*9880d681SAndroid Build Coastguard Worker const MipsRegisterInfo &RegInfo =
673*9880d681SAndroid Build Coastguard Worker *static_cast<const MipsRegisterInfo *>(STI.getRegisterInfo());
674*9880d681SAndroid Build Coastguard Worker
675*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MBBI->getDebugLoc();
676*9880d681SAndroid Build Coastguard Worker MipsABIInfo ABI = STI.getABI();
677*9880d681SAndroid Build Coastguard Worker unsigned SP = ABI.GetStackPtr();
678*9880d681SAndroid Build Coastguard Worker unsigned FP = ABI.GetFramePtr();
679*9880d681SAndroid Build Coastguard Worker unsigned ZERO = ABI.GetNullPtr();
680*9880d681SAndroid Build Coastguard Worker unsigned MOVE = ABI.GetGPRMoveOp();
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker // if framepointer enabled, restore the stack pointer.
683*9880d681SAndroid Build Coastguard Worker if (hasFP(MF)) {
684*9880d681SAndroid Build Coastguard Worker // Find the first instruction that restores a callee-saved register.
685*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I = MBBI;
686*9880d681SAndroid Build Coastguard Worker
687*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
688*9880d681SAndroid Build Coastguard Worker --I;
689*9880d681SAndroid Build Coastguard Worker
690*9880d681SAndroid Build Coastguard Worker // Insert instruction "move $sp, $fp" at this location.
691*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);
692*9880d681SAndroid Build Coastguard Worker }
693*9880d681SAndroid Build Coastguard Worker
694*9880d681SAndroid Build Coastguard Worker if (MipsFI->callsEhReturn()) {
695*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC =
696*9880d681SAndroid Build Coastguard Worker ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
697*9880d681SAndroid Build Coastguard Worker
698*9880d681SAndroid Build Coastguard Worker // Find first instruction that restores a callee-saved register.
699*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I = MBBI;
700*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
701*9880d681SAndroid Build Coastguard Worker --I;
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker // Insert instructions that restore eh data registers.
704*9880d681SAndroid Build Coastguard Worker for (int J = 0; J < 4; ++J) {
705*9880d681SAndroid Build Coastguard Worker TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),
706*9880d681SAndroid Build Coastguard Worker MipsFI->getEhDataRegFI(J), RC, &RegInfo);
707*9880d681SAndroid Build Coastguard Worker }
708*9880d681SAndroid Build Coastguard Worker }
709*9880d681SAndroid Build Coastguard Worker
710*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->hasFnAttribute("interrupt"))
711*9880d681SAndroid Build Coastguard Worker emitInterruptEpilogueStub(MF, MBB);
712*9880d681SAndroid Build Coastguard Worker
713*9880d681SAndroid Build Coastguard Worker // Get the number of bytes from FrameInfo
714*9880d681SAndroid Build Coastguard Worker uint64_t StackSize = MFI->getStackSize();
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker if (!StackSize)
717*9880d681SAndroid Build Coastguard Worker return;
718*9880d681SAndroid Build Coastguard Worker
719*9880d681SAndroid Build Coastguard Worker // Adjust stack.
720*9880d681SAndroid Build Coastguard Worker TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
721*9880d681SAndroid Build Coastguard Worker }
722*9880d681SAndroid Build Coastguard Worker
emitInterruptEpilogueStub(MachineFunction & MF,MachineBasicBlock & MBB) const723*9880d681SAndroid Build Coastguard Worker void MipsSEFrameLowering::emitInterruptEpilogueStub(
724*9880d681SAndroid Build Coastguard Worker MachineFunction &MF, MachineBasicBlock &MBB) const {
725*9880d681SAndroid Build Coastguard Worker
726*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
727*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
728*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
729*9880d681SAndroid Build Coastguard Worker
730*9880d681SAndroid Build Coastguard Worker // Perform ISR handling like GCC
731*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
732*9880d681SAndroid Build Coastguard Worker
733*9880d681SAndroid Build Coastguard Worker // Disable Interrupts.
734*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::ZERO);
735*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));
736*9880d681SAndroid Build Coastguard Worker
737*9880d681SAndroid Build Coastguard Worker // Restore EPC
738*9880d681SAndroid Build Coastguard Worker STI.getInstrInfo()->loadRegFromStackSlot(MBB, MBBI, Mips::K1,
739*9880d681SAndroid Build Coastguard Worker MipsFI->getISRRegFI(0), PtrRC,
740*9880d681SAndroid Build Coastguard Worker STI.getRegisterInfo());
741*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)
742*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
743*9880d681SAndroid Build Coastguard Worker .addImm(0);
744*9880d681SAndroid Build Coastguard Worker
745*9880d681SAndroid Build Coastguard Worker // Restore Status
746*9880d681SAndroid Build Coastguard Worker STI.getInstrInfo()->loadRegFromStackSlot(MBB, MBBI, Mips::K1,
747*9880d681SAndroid Build Coastguard Worker MipsFI->getISRRegFI(1), PtrRC,
748*9880d681SAndroid Build Coastguard Worker STI.getRegisterInfo());
749*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
750*9880d681SAndroid Build Coastguard Worker .addReg(Mips::K1)
751*9880d681SAndroid Build Coastguard Worker .addImm(0);
752*9880d681SAndroid Build Coastguard Worker }
753*9880d681SAndroid Build Coastguard Worker
getFrameIndexReference(const MachineFunction & MF,int FI,unsigned & FrameReg) const754*9880d681SAndroid Build Coastguard Worker int MipsSEFrameLowering::getFrameIndexReference(const MachineFunction &MF,
755*9880d681SAndroid Build Coastguard Worker int FI,
756*9880d681SAndroid Build Coastguard Worker unsigned &FrameReg) const {
757*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
758*9880d681SAndroid Build Coastguard Worker MipsABIInfo ABI = STI.getABI();
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker if (MFI->isFixedObjectIndex(FI))
761*9880d681SAndroid Build Coastguard Worker FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();
762*9880d681SAndroid Build Coastguard Worker else
763*9880d681SAndroid Build Coastguard Worker FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker return MFI->getObjectOffset(FI) + MFI->getStackSize() -
766*9880d681SAndroid Build Coastguard Worker getOffsetOfLocalArea() + MFI->getOffsetAdjustment();
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker
769*9880d681SAndroid Build Coastguard Worker bool MipsSEFrameLowering::
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const std::vector<CalleeSavedInfo> & CSI,const TargetRegisterInfo * TRI) const770*9880d681SAndroid Build Coastguard Worker spillCalleeSavedRegisters(MachineBasicBlock &MBB,
771*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator MI,
772*9880d681SAndroid Build Coastguard Worker const std::vector<CalleeSavedInfo> &CSI,
773*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI) const {
774*9880d681SAndroid Build Coastguard Worker MachineFunction *MF = MBB.getParent();
775*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *EntryBlock = &MF->front();
776*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *STI.getInstrInfo();
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
779*9880d681SAndroid Build Coastguard Worker // Add the callee-saved register as live-in. Do not add if the register is
780*9880d681SAndroid Build Coastguard Worker // RA and return address is taken, because it has already been added in
781*9880d681SAndroid Build Coastguard Worker // method MipsTargetLowering::LowerRETURNADDR.
782*9880d681SAndroid Build Coastguard Worker // It's killed at the spill, unless the register is RA and return address
783*9880d681SAndroid Build Coastguard Worker // is taken.
784*9880d681SAndroid Build Coastguard Worker unsigned Reg = CSI[i].getReg();
785*9880d681SAndroid Build Coastguard Worker bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
786*9880d681SAndroid Build Coastguard Worker && MF->getFrameInfo()->isReturnAddressTaken();
787*9880d681SAndroid Build Coastguard Worker if (!IsRAAndRetAddrIsTaken)
788*9880d681SAndroid Build Coastguard Worker EntryBlock->addLiveIn(Reg);
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker // ISRs require HI/LO to be spilled into kernel registers to be then
791*9880d681SAndroid Build Coastguard Worker // spilled to the stack frame.
792*9880d681SAndroid Build Coastguard Worker bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
793*9880d681SAndroid Build Coastguard Worker Reg == Mips::HI0 || Reg == Mips::HI0_64);
794*9880d681SAndroid Build Coastguard Worker const Function *Func = MBB.getParent()->getFunction();
795*9880d681SAndroid Build Coastguard Worker if (IsLOHI && Func->hasFnAttribute("interrupt")) {
796*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI->getDebugLoc();
797*9880d681SAndroid Build Coastguard Worker
798*9880d681SAndroid Build Coastguard Worker unsigned Op = 0;
799*9880d681SAndroid Build Coastguard Worker if (!STI.getABI().ArePtrs64bit()) {
800*9880d681SAndroid Build Coastguard Worker Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;
801*9880d681SAndroid Build Coastguard Worker Reg = Mips::K0;
802*9880d681SAndroid Build Coastguard Worker } else {
803*9880d681SAndroid Build Coastguard Worker Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
804*9880d681SAndroid Build Coastguard Worker Reg = Mips::K0_64;
805*9880d681SAndroid Build Coastguard Worker }
806*9880d681SAndroid Build Coastguard Worker BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0)
807*9880d681SAndroid Build Coastguard Worker .setMIFlag(MachineInstr::FrameSetup);
808*9880d681SAndroid Build Coastguard Worker }
809*9880d681SAndroid Build Coastguard Worker
810*9880d681SAndroid Build Coastguard Worker // Insert the spill to the stack frame.
811*9880d681SAndroid Build Coastguard Worker bool IsKill = !IsRAAndRetAddrIsTaken;
812*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
813*9880d681SAndroid Build Coastguard Worker TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
814*9880d681SAndroid Build Coastguard Worker CSI[i].getFrameIdx(), RC, TRI);
815*9880d681SAndroid Build Coastguard Worker }
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Worker return true;
818*9880d681SAndroid Build Coastguard Worker }
819*9880d681SAndroid Build Coastguard Worker
820*9880d681SAndroid Build Coastguard Worker bool
hasReservedCallFrame(const MachineFunction & MF) const821*9880d681SAndroid Build Coastguard Worker MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
822*9880d681SAndroid Build Coastguard Worker const MachineFrameInfo *MFI = MF.getFrameInfo();
823*9880d681SAndroid Build Coastguard Worker
824*9880d681SAndroid Build Coastguard Worker // Reserve call frame if the size of the maximum call frame fits into 16-bit
825*9880d681SAndroid Build Coastguard Worker // immediate field and there are no variable sized objects on the stack.
826*9880d681SAndroid Build Coastguard Worker // Make sure the second register scavenger spill slot can be accessed with one
827*9880d681SAndroid Build Coastguard Worker // instruction.
828*9880d681SAndroid Build Coastguard Worker return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) &&
829*9880d681SAndroid Build Coastguard Worker !MFI->hasVarSizedObjects();
830*9880d681SAndroid Build Coastguard Worker }
831*9880d681SAndroid Build Coastguard Worker
832*9880d681SAndroid Build Coastguard Worker /// Mark \p Reg and all registers aliasing it in the bitset.
setAliasRegs(MachineFunction & MF,BitVector & SavedRegs,unsigned Reg)833*9880d681SAndroid Build Coastguard Worker static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,
834*9880d681SAndroid Build Coastguard Worker unsigned Reg) {
835*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
836*9880d681SAndroid Build Coastguard Worker for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
837*9880d681SAndroid Build Coastguard Worker SavedRegs.set(*AI);
838*9880d681SAndroid Build Coastguard Worker }
839*9880d681SAndroid Build Coastguard Worker
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const840*9880d681SAndroid Build Coastguard Worker void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF,
841*9880d681SAndroid Build Coastguard Worker BitVector &SavedRegs,
842*9880d681SAndroid Build Coastguard Worker RegScavenger *RS) const {
843*9880d681SAndroid Build Coastguard Worker TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
844*9880d681SAndroid Build Coastguard Worker MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
845*9880d681SAndroid Build Coastguard Worker MipsABIInfo ABI = STI.getABI();
846*9880d681SAndroid Build Coastguard Worker unsigned FP = ABI.GetFramePtr();
847*9880d681SAndroid Build Coastguard Worker unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
848*9880d681SAndroid Build Coastguard Worker
849*9880d681SAndroid Build Coastguard Worker // Mark $fp as used if function has dedicated frame pointer.
850*9880d681SAndroid Build Coastguard Worker if (hasFP(MF))
851*9880d681SAndroid Build Coastguard Worker setAliasRegs(MF, SavedRegs, FP);
852*9880d681SAndroid Build Coastguard Worker // Mark $s7 as used if function has dedicated base pointer.
853*9880d681SAndroid Build Coastguard Worker if (hasBP(MF))
854*9880d681SAndroid Build Coastguard Worker setAliasRegs(MF, SavedRegs, BP);
855*9880d681SAndroid Build Coastguard Worker
856*9880d681SAndroid Build Coastguard Worker // Create spill slots for eh data registers if function calls eh_return.
857*9880d681SAndroid Build Coastguard Worker if (MipsFI->callsEhReturn())
858*9880d681SAndroid Build Coastguard Worker MipsFI->createEhDataRegsFI();
859*9880d681SAndroid Build Coastguard Worker
860*9880d681SAndroid Build Coastguard Worker // Create spill slots for Coprocessor 0 registers if function is an ISR.
861*9880d681SAndroid Build Coastguard Worker if (MipsFI->isISR())
862*9880d681SAndroid Build Coastguard Worker MipsFI->createISRRegFI();
863*9880d681SAndroid Build Coastguard Worker
864*9880d681SAndroid Build Coastguard Worker // Expand pseudo instructions which load, store or copy accumulators.
865*9880d681SAndroid Build Coastguard Worker // Add an emergency spill slot if a pseudo was expanded.
866*9880d681SAndroid Build Coastguard Worker if (ExpandPseudo(MF).expand()) {
867*9880d681SAndroid Build Coastguard Worker // The spill slot should be half the size of the accumulator. If target is
868*9880d681SAndroid Build Coastguard Worker // mips64, it should be 64-bit, otherwise it should be 32-bt.
869*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = STI.hasMips64() ?
870*9880d681SAndroid Build Coastguard Worker &Mips::GPR64RegClass : &Mips::GPR32RegClass;
871*9880d681SAndroid Build Coastguard Worker int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
872*9880d681SAndroid Build Coastguard Worker RC->getAlignment(), false);
873*9880d681SAndroid Build Coastguard Worker RS->addScavengingFrameIndex(FI);
874*9880d681SAndroid Build Coastguard Worker }
875*9880d681SAndroid Build Coastguard Worker
876*9880d681SAndroid Build Coastguard Worker // Set scavenging frame index if necessary.
877*9880d681SAndroid Build Coastguard Worker uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
878*9880d681SAndroid Build Coastguard Worker estimateStackSize(MF);
879*9880d681SAndroid Build Coastguard Worker
880*9880d681SAndroid Build Coastguard Worker if (isInt<16>(MaxSPOffset))
881*9880d681SAndroid Build Coastguard Worker return;
882*9880d681SAndroid Build Coastguard Worker
883*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC =
884*9880d681SAndroid Build Coastguard Worker ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
885*9880d681SAndroid Build Coastguard Worker int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
886*9880d681SAndroid Build Coastguard Worker RC->getAlignment(), false);
887*9880d681SAndroid Build Coastguard Worker RS->addScavengingFrameIndex(FI);
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker const MipsFrameLowering *
createMipsSEFrameLowering(const MipsSubtarget & ST)891*9880d681SAndroid Build Coastguard Worker llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
892*9880d681SAndroid Build Coastguard Worker return new MipsSEFrameLowering(ST);
893*9880d681SAndroid Build Coastguard Worker }
894