1c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard//===----------------------- AMDGPUFrameLowering.cpp ----------------------===// 2c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// 3c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// The LLVM Compiler Infrastructure 4c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// 5c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// This file is distributed under the University of Illinois Open Source 6c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// License. See LICENSE.TXT for details. 7c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// 8c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard//==-----------------------------------------------------------------------===// 9c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// 10c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// Interface to describe a layout of a stack frame on a AMDIL target machine 11c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard// 12c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard//===----------------------------------------------------------------------===// 13c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "AMDGPUFrameLowering.h" 14c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "AMDGPURegisterInfo.h" 15c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "R600MachineFunctionInfo.h" 16c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineFrameInfo.h" 17c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h" 18c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "llvm/IR/Instructions.h" 19c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 20c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardusing namespace llvm; 21c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::AMDGPUFrameLowering(StackDirection D, unsigned StackAl, 22c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int LAO, unsigned TransAl) 23c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard : TargetFrameLowering(D, StackAl, LAO, TransAl) { } 24c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 25c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::~AMDGPUFrameLowering() { } 26c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 27c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardunsigned AMDGPUFrameLowering::getStackWidth(const MachineFunction &MF) const { 28c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 29c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // XXX: Hardcoding to 1 for now. 30c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 31c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // I think the StackWidth should stored as metadata associated with the 32c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // MachineFunction. This metadata can either be added by a frontend, or 33c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // calculated by a R600 specific LLVM IR pass. 34c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 35c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // The StackWidth determines how stack objects are laid out in memory. 36c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // For a vector stack variable, like: int4 stack[2], the data will be stored 37c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // in the following ways depending on the StackWidth. 38c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 39c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // StackWidth = 1: 40c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 41c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.X = stack[0].x 42c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.X = stack[0].y 43c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T2.X = stack[0].z 44c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T3.X = stack[0].w 45c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T4.X = stack[1].x 46c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T5.X = stack[1].y 47c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T6.X = stack[1].z 48c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T7.X = stack[1].w 49c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 50c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // StackWidth = 2: 51c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 52c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.X = stack[0].x 53c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.Y = stack[0].y 54c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.X = stack[0].z 55c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.Y = stack[0].w 56c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T2.X = stack[1].x 57c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T2.Y = stack[1].y 58c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T3.X = stack[1].z 59c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T3.Y = stack[1].w 60c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // 61c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // StackWidth = 4: 62c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.X = stack[0].x 63c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.Y = stack[0].y 64c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.Z = stack[0].z 65c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T0.W = stack[0].w 66c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.X = stack[1].x 67c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.Y = stack[1].y 68c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.Z = stack[1].z 69c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // T1.W = stack[1].w 70c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return 1; 71c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 72c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 73c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard/// \returns The number of registers allocated for \p FI. 74c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardint AMDGPUFrameLowering::getFrameIndexOffset(const MachineFunction &MF, 75c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int FI) const { 76c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const MachineFrameInfo *MFI = MF.getFrameInfo(); 77c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned Offset = 0; 78c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard int UpperBound = FI == -1 ? MFI->getNumObjects() : FI; 79c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 80c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard for (int i = MFI->getObjectIndexBegin(); i < UpperBound; ++i) { 81c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AllocaInst *Alloca = MFI->getObjectAllocation(i); 82c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned ArrayElements; 83c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const Type *AllocaType = Alloca->getAllocatedType(); 84c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const Type *ElementType; 85c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 86c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (AllocaType->isArrayTy()) { 87c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ArrayElements = AllocaType->getArrayNumElements(); 88c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ElementType = AllocaType->getArrayElementType(); 89c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 90c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ArrayElements = 1; 91c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard ElementType = AllocaType; 92c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 93c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 94c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard unsigned VectorElements; 95c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard if (ElementType->isVectorTy()) { 96c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard VectorElements = ElementType->getVectorNumElements(); 97c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } else { 98c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard VectorElements = 1; 99c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 100c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 101c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard Offset += (VectorElements / getStackWidth(MF)) * ArrayElements; 102c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 103c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return Offset; 104c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 105c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 106c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardconst TargetFrameLowering::SpillSlot * 107c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::getCalleeSavedSpillSlots(unsigned &NumEntries) const { 108c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard NumEntries = 0; 109c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return 0; 110c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 111c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardvoid 112c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::emitPrologue(MachineFunction &MF) const { 113c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 114c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardvoid 115c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::emitEpilogue(MachineFunction &MF, 116c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard MachineBasicBlock &MBB) const { 117c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 118c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 119c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellardbool 120c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom StellardAMDGPUFrameLowering::hasFP(const MachineFunction &MF) const { 121c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard return false; 122c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard} 123