1//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Top-level implementation for the Cell SPU target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "SPU.h" 15#include "SPUFrameLowering.h" 16#include "SPUInstrBuilder.h" 17#include "SPUInstrInfo.h" 18#include "llvm/Function.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/Target/TargetData.h" 26#include "llvm/Target/TargetOptions.h" 27#include "llvm/Support/CommandLine.h" 28using namespace llvm; 29 30//===----------------------------------------------------------------------===// 31// SPUFrameLowering: 32//===----------------------------------------------------------------------===// 33 34SPUFrameLowering::SPUFrameLowering(const SPUSubtarget &sti) 35 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, 0), 36 Subtarget(sti) { 37 LR[0].first = SPU::R0; 38 LR[0].second = 16; 39} 40 41 42//-------------------------------------------------------------------------- 43// hasFP - Return true if the specified function actually has a dedicated frame 44// pointer register. This is true if the function needs a frame pointer and has 45// a non-zero stack size. 46bool SPUFrameLowering::hasFP(const MachineFunction &MF) const { 47 const MachineFrameInfo *MFI = MF.getFrameInfo(); 48 49 return MFI->getStackSize() && 50 (DisableFramePointerElim(MF) || MFI->hasVarSizedObjects()); 51} 52 53 54/// determineFrameLayout - Determine the size of the frame and maximum call 55/// frame size. 56void SPUFrameLowering::determineFrameLayout(MachineFunction &MF) const { 57 MachineFrameInfo *MFI = MF.getFrameInfo(); 58 59 // Get the number of bytes to allocate from the FrameInfo 60 unsigned FrameSize = MFI->getStackSize(); 61 62 // Get the alignments provided by the target, and the maximum alignment 63 // (if any) of the fixed frame objects. 64 unsigned TargetAlign = getStackAlignment(); 65 unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment()); 66 assert(isPowerOf2_32(Align) && "Alignment is not power of 2"); 67 unsigned AlignMask = Align - 1; 68 69 // Get the maximum call frame size of all the calls. 70 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); 71 72 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so 73 // that allocations will be aligned. 74 if (MFI->hasVarSizedObjects()) 75 maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask; 76 77 // Update maximum call frame size. 78 MFI->setMaxCallFrameSize(maxCallFrameSize); 79 80 // Include call frame size in total. 81 FrameSize += maxCallFrameSize; 82 83 // Make sure the frame is aligned. 84 FrameSize = (FrameSize + AlignMask) & ~AlignMask; 85 86 // Update frame info. 87 MFI->setStackSize(FrameSize); 88} 89 90void SPUFrameLowering::emitPrologue(MachineFunction &MF) const { 91 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 92 MachineBasicBlock::iterator MBBI = MBB.begin(); 93 MachineFrameInfo *MFI = MF.getFrameInfo(); 94 const SPUInstrInfo &TII = 95 *static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo()); 96 MachineModuleInfo &MMI = MF.getMMI(); 97 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 98 99 // Prepare for debug frame info. 100 bool hasDebugInfo = MMI.hasDebugInfo(); 101 MCSymbol *FrameLabel = 0; 102 103 // Move MBBI back to the beginning of the function. 104 MBBI = MBB.begin(); 105 106 // Work out frame sizes. 107 determineFrameLayout(MF); 108 int FrameSize = MFI->getStackSize(); 109 110 assert((FrameSize & 0xf) == 0 111 && "SPURegisterInfo::emitPrologue: FrameSize not aligned"); 112 113 // the "empty" frame size is 16 - just the register scavenger spill slot 114 if (FrameSize > 16 || MFI->adjustsStack()) { 115 FrameSize = -(FrameSize + SPUFrameLowering::minStackSize()); 116 if (hasDebugInfo) { 117 // Mark effective beginning of when frame pointer becomes valid. 118 FrameLabel = MMI.getContext().CreateTempSymbol(); 119 BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(FrameLabel); 120 } 121 122 // Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp) 123 // for the ABI 124 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R0).addImm(16) 125 .addReg(SPU::R1); 126 if (isInt<10>(FrameSize)) { 127 // Spill $sp to adjusted $sp 128 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R1).addImm(FrameSize) 129 .addReg(SPU::R1); 130 // Adjust $sp by required amout 131 BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1).addReg(SPU::R1) 132 .addImm(FrameSize); 133 } else if (isInt<16>(FrameSize)) { 134 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use 135 // $r2 to adjust $sp: 136 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2) 137 .addImm(-16) 138 .addReg(SPU::R1); 139 BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2) 140 .addImm(FrameSize); 141 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQXr32), SPU::R1) 142 .addReg(SPU::R2) 143 .addReg(SPU::R1); 144 BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1) 145 .addReg(SPU::R1) 146 .addReg(SPU::R2); 147 BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2) 148 .addReg(SPU::R2) 149 .addImm(16); 150 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2) 151 .addReg(SPU::R2) 152 .addReg(SPU::R1); 153 } else { 154 report_fatal_error("Unhandled frame size: " + Twine(FrameSize)); 155 } 156 157 if (hasDebugInfo) { 158 std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 159 160 // Show update of SP. 161 MachineLocation SPDst(MachineLocation::VirtualFP); 162 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize); 163 Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); 164 165 // Add callee saved registers to move list. 166 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 167 for (unsigned I = 0, E = CSI.size(); I != E; ++I) { 168 int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); 169 unsigned Reg = CSI[I].getReg(); 170 if (Reg == SPU::R0) continue; 171 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 172 MachineLocation CSSrc(Reg); 173 Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); 174 } 175 176 // Mark effective beginning of when frame pointer is ready. 177 MCSymbol *ReadyLabel = MMI.getContext().CreateTempSymbol(); 178 BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(ReadyLabel); 179 180 MachineLocation FPDst(SPU::R1); 181 MachineLocation FPSrc(MachineLocation::VirtualFP); 182 Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc)); 183 } 184 } 185} 186 187void SPUFrameLowering::emitEpilogue(MachineFunction &MF, 188 MachineBasicBlock &MBB) const { 189 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 190 const SPUInstrInfo &TII = 191 *static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo()); 192 const MachineFrameInfo *MFI = MF.getFrameInfo(); 193 int FrameSize = MFI->getStackSize(); 194 int LinkSlotOffset = SPUFrameLowering::stackSlotSize(); 195 DebugLoc dl = MBBI->getDebugLoc(); 196 197 assert(MBBI->getOpcode() == SPU::RET && 198 "Can only insert epilog into returning blocks"); 199 assert((FrameSize & 0xf) == 0 && "FrameSize not aligned"); 200 201 // the "empty" frame size is 16 - just the register scavenger spill slot 202 if (FrameSize > 16 || MFI->adjustsStack()) { 203 FrameSize = FrameSize + SPUFrameLowering::minStackSize(); 204 if (isInt<10>(FrameSize + LinkSlotOffset)) { 205 // Reload $lr, adjust $sp by required amount 206 // Note: We do this to slightly improve dual issue -- not by much, but it 207 // is an opportunity for dual issue. 208 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0) 209 .addImm(FrameSize + LinkSlotOffset) 210 .addReg(SPU::R1); 211 BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1) 212 .addReg(SPU::R1) 213 .addImm(FrameSize); 214 } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) { 215 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use 216 // $r2 to adjust $sp: 217 BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2) 218 .addImm(16) 219 .addReg(SPU::R1); 220 BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2) 221 .addImm(FrameSize); 222 BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1) 223 .addReg(SPU::R1) 224 .addReg(SPU::R2); 225 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0) 226 .addImm(16) 227 .addReg(SPU::R1); 228 BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2). 229 addReg(SPU::R2) 230 .addImm(16); 231 BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2) 232 .addReg(SPU::R2) 233 .addReg(SPU::R1); 234 } else { 235 report_fatal_error("Unhandled frame size: " + Twine(FrameSize)); 236 } 237 } 238} 239 240void SPUFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 241 RegScavenger *RS) const{ 242 // Mark LR and SP unused, since the prolog spills them to stack and 243 // we don't want anyone else to spill them for us. 244 // 245 // Also, unless R2 is really used someday, don't spill it automatically. 246 MF.getRegInfo().setPhysRegUnused(SPU::R0); 247 MF.getRegInfo().setPhysRegUnused(SPU::R1); 248 MF.getRegInfo().setPhysRegUnused(SPU::R2); 249 250 MachineFrameInfo *MFI = MF.getFrameInfo(); 251 const TargetRegisterClass *RC = &SPU::R32CRegClass; 252 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 253 RC->getAlignment(), 254 false)); 255} 256