1 //===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Mips32/64 implementation of TargetFrameLowering class.
12 //===----------------------------------------------------------------------===//
14 #include "MipsSEFrameLowering.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "MipsAnalyzeImmediate.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsSEInstrInfo.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/RegisterScavenging.h"
25 #include "llvm/IR/DataLayout.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Target/TargetOptions.h"
33 typedef MachineBasicBlock::iterator Iter;
35 /// Helper class to expand pseudos.
38 ExpandPseudo(MachineFunction &MF);
42 bool expandInstr(MachineBasicBlock &MBB, Iter I);
43 void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
44 void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
45 bool expandCopy(MachineBasicBlock &MBB, Iter I);
46 bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst,
47 unsigned Src, unsigned RegSize);
50 const MipsSEInstrInfo &TII;
51 const MipsRegisterInfo &RegInfo;
52 MachineRegisterInfo &MRI;
56 ExpandPseudo::ExpandPseudo(MachineFunction &MF_)
58 TII(*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo())),
59 RegInfo(TII.getRegisterInfo()), MRI(MF.getRegInfo()) {}
61 bool ExpandPseudo::expand() {
62 bool Expanded = false;
64 for (MachineFunction::iterator BB = MF.begin(), BBEnd = MF.end();
66 for (Iter I = BB->begin(), End = BB->end(); I != End;)
67 Expanded |= expandInstr(*BB, I++);
72 bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
73 switch(I->getOpcode()) {
75 case Mips::LOAD_AC64_P8:
76 case Mips::LOAD_AC_DSP:
77 case Mips::LOAD_AC_DSP_P8:
78 expandLoadACC(MBB, I, 4);
80 case Mips::LOAD_AC128:
81 case Mips::LOAD_AC128_P8:
82 expandLoadACC(MBB, I, 8);
84 case Mips::STORE_AC64:
85 case Mips::STORE_AC64_P8:
86 case Mips::STORE_AC_DSP:
87 case Mips::STORE_AC_DSP_P8:
88 expandStoreACC(MBB, I, 4);
90 case Mips::STORE_AC128:
91 case Mips::STORE_AC128_P8:
92 expandStoreACC(MBB, I, 8);
94 case TargetOpcode::COPY:
95 if (!expandCopy(MBB, I))
106 void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
113 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
115 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
116 unsigned VR0 = MRI.createVirtualRegister(RC);
117 unsigned VR1 = MRI.createVirtualRegister(RC);
118 unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
119 unsigned Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
120 unsigned Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
121 DebugLoc DL = I->getDebugLoc();
122 const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
124 TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
125 BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
126 TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
127 BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
130 void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
135 // store $vr1, FI + 4
137 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
139 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
140 unsigned VR0 = MRI.createVirtualRegister(RC);
141 unsigned VR1 = MRI.createVirtualRegister(RC);
142 unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
143 unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
144 unsigned Lo = RegInfo.getSubReg(Src, Mips::sub_lo);
145 unsigned Hi = RegInfo.getSubReg(Src, Mips::sub_hi);
146 DebugLoc DL = I->getDebugLoc();
148 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(Lo, SrcKill);
149 TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0);
150 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(Hi, SrcKill);
151 TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize);
154 bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
155 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
157 if (Mips::ACRegsDSPRegClass.contains(Dst, Src))
158 return expandCopyACC(MBB, I, Dst, Src, 4);
160 if (Mips::ACRegs128RegClass.contains(Dst, Src))
161 return expandCopyACC(MBB, I, Dst, Src, 8);
166 bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst,
167 unsigned Src, unsigned RegSize) {
173 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
174 unsigned VR0 = MRI.createVirtualRegister(RC);
175 unsigned VR1 = MRI.createVirtualRegister(RC);
176 unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
177 unsigned DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
178 unsigned DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
179 unsigned SrcLo = RegInfo.getSubReg(Src, Mips::sub_lo);
180 unsigned SrcHi = RegInfo.getSubReg(Src, Mips::sub_hi);
181 DebugLoc DL = I->getDebugLoc();
183 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR0).addReg(SrcLo, SrcKill);
184 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
185 .addReg(VR0, RegState::Kill);
186 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), VR1).addReg(SrcHi, SrcKill);
187 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
188 .addReg(VR1, RegState::Kill);
192 unsigned MipsSEFrameLowering::ehDataReg(unsigned I) const {
193 static const unsigned EhDataReg[] = {
194 Mips::A0, Mips::A1, Mips::A2, Mips::A3
196 static const unsigned EhDataReg64[] = {
197 Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
200 return STI.isABI_N64() ? EhDataReg64[I] : EhDataReg[I];
203 void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
204 MachineBasicBlock &MBB = MF.front();
205 MachineFrameInfo *MFI = MF.getFrameInfo();
206 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
207 const MipsRegisterInfo *RegInfo =
208 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
209 const MipsSEInstrInfo &TII =
210 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
211 MachineBasicBlock::iterator MBBI = MBB.begin();
212 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
213 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
214 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
215 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
216 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
218 // First, compute final stack size.
219 uint64_t StackSize = MFI->getStackSize();
221 // No need to allocate space on the stack.
222 if (StackSize == 0 && !MFI->adjustsStack()) return;
224 MachineModuleInfo &MMI = MF.getMMI();
225 std::vector<MachineMove> &Moves = MMI.getFrameMoves();
226 MachineLocation DstML, SrcML;
229 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
231 // emit ".cfi_def_cfa_offset StackSize"
232 MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
233 BuildMI(MBB, MBBI, dl,
234 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
235 DstML = MachineLocation(MachineLocation::VirtualFP);
236 SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
237 Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
239 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
242 // Find the instruction past the last instruction that saves a callee-saved
243 // register to the stack.
244 for (unsigned i = 0; i < CSI.size(); ++i)
247 // Iterate over list of callee-saved registers and emit .cfi_offset
249 MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
250 BuildMI(MBB, MBBI, dl,
251 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
253 for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
254 E = CSI.end(); I != E; ++I) {
255 int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
256 unsigned Reg = I->getReg();
258 // If Reg is a double precision register, emit two cfa_offsets,
259 // one for each of the paired single precision registers.
260 if (Mips::AFGR64RegClass.contains(Reg)) {
261 MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
262 MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
263 MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
264 MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
267 std::swap(SrcML0, SrcML1);
269 Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
270 Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
272 // Reg is either in CPURegs or FGR32.
273 DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
274 SrcML = MachineLocation(Reg);
275 Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
280 if (MipsFI->callsEhReturn()) {
281 const TargetRegisterClass *RC = STI.isABI_N64() ?
282 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
284 // Insert instructions that spill eh data registers.
285 for (int I = 0; I < 4; ++I) {
286 if (!MBB.isLiveIn(ehDataReg(I)))
287 MBB.addLiveIn(ehDataReg(I));
288 TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false,
289 MipsFI->getEhDataRegFI(I), RC, RegInfo);
292 // Emit .cfi_offset directives for eh data registers.
293 MCSymbol *CSLabel2 = MMI.getContext().CreateTempSymbol();
294 BuildMI(MBB, MBBI, dl,
295 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2);
296 for (int I = 0; I < 4; ++I) {
297 int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I));
298 DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
299 SrcML = MachineLocation(ehDataReg(I));
300 Moves.push_back(MachineMove(CSLabel2, DstML, SrcML));
304 // if framepointer enabled, set it to point to the stack pointer.
306 // Insert instruction "move $fp, $sp" at this location.
307 BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
309 // emit ".cfi_def_cfa_register $fp"
310 MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
311 BuildMI(MBB, MBBI, dl,
312 TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
313 DstML = MachineLocation(FP);
314 SrcML = MachineLocation(MachineLocation::VirtualFP);
315 Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
319 void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
320 MachineBasicBlock &MBB) const {
321 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
322 MachineFrameInfo *MFI = MF.getFrameInfo();
323 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
324 const MipsRegisterInfo *RegInfo =
325 static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
326 const MipsSEInstrInfo &TII =
327 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
328 DebugLoc dl = MBBI->getDebugLoc();
329 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
330 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
331 unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
332 unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
334 // if framepointer enabled, restore the stack pointer.
336 // Find the first instruction that restores a callee-saved register.
337 MachineBasicBlock::iterator I = MBBI;
339 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
342 // Insert instruction "move $sp, $fp" at this location.
343 BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
346 if (MipsFI->callsEhReturn()) {
347 const TargetRegisterClass *RC = STI.isABI_N64() ?
348 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
350 // Find first instruction that restores a callee-saved register.
351 MachineBasicBlock::iterator I = MBBI;
352 for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
355 // Insert instructions that restore eh data registers.
356 for (int J = 0; J < 4; ++J) {
357 TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J),
362 // Get the number of bytes from FrameInfo
363 uint64_t StackSize = MFI->getStackSize();
369 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
372 bool MipsSEFrameLowering::
373 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
374 MachineBasicBlock::iterator MI,
375 const std::vector<CalleeSavedInfo> &CSI,
376 const TargetRegisterInfo *TRI) const {
377 MachineFunction *MF = MBB.getParent();
378 MachineBasicBlock *EntryBlock = MF->begin();
379 const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
381 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
382 // Add the callee-saved register as live-in. Do not add if the register is
383 // RA and return address is taken, because it has already been added in
384 // method MipsTargetLowering::LowerRETURNADDR.
385 // It's killed at the spill, unless the register is RA and return address
387 unsigned Reg = CSI[i].getReg();
388 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
389 && MF->getFrameInfo()->isReturnAddressTaken();
390 if (!IsRAAndRetAddrIsTaken)
391 EntryBlock->addLiveIn(Reg);
393 // Insert the spill to the stack frame.
394 bool IsKill = !IsRAAndRetAddrIsTaken;
395 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
396 TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
397 CSI[i].getFrameIdx(), RC, TRI);
404 MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
405 const MachineFrameInfo *MFI = MF.getFrameInfo();
407 // Reserve call frame if the size of the maximum call frame fits into 16-bit
408 // immediate field and there are no variable sized objects on the stack.
409 // Make sure the second register scavenger spill slot can be accessed with one
411 return isInt<16>(MFI->getMaxCallFrameSize() + getStackAlignment()) &&
412 !MFI->hasVarSizedObjects();
415 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
416 void MipsSEFrameLowering::
417 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
418 MachineBasicBlock::iterator I) const {
419 const MipsSEInstrInfo &TII =
420 *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
422 if (!hasReservedCallFrame(MF)) {
423 int64_t Amount = I->getOperand(0).getImm();
425 if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
428 unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
429 TII.adjustStackPtr(SP, Amount, MBB, I);
435 void MipsSEFrameLowering::
436 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
437 RegScavenger *RS) const {
438 MachineRegisterInfo &MRI = MF.getRegInfo();
439 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
440 unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
442 // Mark $fp as used if function has dedicated frame pointer.
444 MRI.setPhysRegUsed(FP);
446 // Create spill slots for eh data registers if function calls eh_return.
447 if (MipsFI->callsEhReturn())
448 MipsFI->createEhDataRegsFI();
450 // Expand pseudo instructions which load, store or copy accumulators.
451 // Add an emergency spill slot if a pseudo was expanded.
452 if (ExpandPseudo(MF).expand()) {
453 // The spill slot should be half the size of the accumulator. If target is
454 // mips64, it should be 64-bit, otherwise it should be 32-bt.
455 const TargetRegisterClass *RC = STI.hasMips64() ?
456 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
457 int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
458 RC->getAlignment(), false);
459 RS->addScavengingFrameIndex(FI);
462 // Set scavenging frame index if necessary.
463 uint64_t MaxSPOffset = MF.getInfo<MipsFunctionInfo>()->getIncomingArgSize() +
464 estimateStackSize(MF);
466 if (isInt<16>(MaxSPOffset))
469 const TargetRegisterClass *RC = STI.isABI_N64() ?
470 &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass;
471 int FI = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
472 RC->getAlignment(), false);
473 RS->addScavengingFrameIndex(FI);
476 const MipsFrameLowering *
477 llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
478 return new MipsSEFrameLowering(ST);