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