149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//=======- NVPTXFrameLowering.cpp - NVPTX Frame Information ---*- C++ -*-=====//
249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//
349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//                     The LLVM Compiler Infrastructure
449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//
549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source
649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details.
749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//
849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===//
949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//
1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file contains the NVPTX implementation of TargetFrameLowering class.
1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//
1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===//
1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXFrameLowering.h"
1549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTX.h"
1649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXRegisterInfo.h"
1749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXSubtarget.h"
1849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXTargetMachine.h"
1949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/ADT/BitVector.h"
2049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineFrameInfo.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunction.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineInstrBuilder.h"
23a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski#include "llvm/CodeGen/MachineRegisterInfo.h"
2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MachineLocation.h"
2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetInstrInfo.h"
2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm;
2849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesNVPTXFrameLowering::NVPTXFrameLowering(NVPTXSubtarget &STI)
30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : TargetFrameLowering(TargetFrameLowering::StackGrowsUp, 8, 0),
31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      is64bit(STI.is64Bit()) {}
32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
333639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskibool NVPTXFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
3549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid NVPTXFrameLowering::emitPrologue(MachineFunction &MF) const {
3649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski  if (MF.getFrameInfo()->hasStackObjects()) {
3749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    MachineBasicBlock &MBB = MF.front();
3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    // Insert "mov.u32 %SP, %Depot"
3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    MachineBasicBlock::iterator MBBI = MBB.begin();
4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    // This instruction really occurs before first instruction
4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    // in the BB, so giving it no debug location.
4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    DebugLoc dl = DebugLoc();
4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
44a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski    MachineRegisterInfo &MRI = MF.getRegInfo();
45a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski
46a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski    // mov %SPL, %depot;
47a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski    // cvta.local %SP, %SPL;
48a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski    if (is64bit) {
49a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski      unsigned LocalReg = MRI.createVirtualRegister(&NVPTX::Int64RegsRegClass);
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MachineInstr *MI =
51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          BuildMI(MBB, MBBI, dl,
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  MF.getTarget().getInstrInfo()->get(NVPTX::cvta_local_yes_64),
53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  NVPTX::VRFrame).addReg(LocalReg);
54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      BuildMI(MBB, MI, dl,
55cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              MF.getTarget().getInstrInfo()->get(NVPTX::MOV_DEPOT_ADDR_64),
56a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski              LocalReg).addImm(MF.getFunctionNumber());
573639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski    } else {
58a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski      unsigned LocalReg = MRI.createVirtualRegister(&NVPTX::Int32RegsRegClass);
59cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MachineInstr *MI =
60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          BuildMI(MBB, MBBI, dl,
61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  MF.getTarget().getInstrInfo()->get(NVPTX::cvta_local_yes),
62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  NVPTX::VRFrame).addReg(LocalReg);
63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      BuildMI(MBB, MI, dl,
64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              MF.getTarget().getInstrInfo()->get(NVPTX::MOV_DEPOT_ADDR),
65a3635eefc749389aed84d9791fab657297203e1bJustin Holewinski              LocalReg).addImm(MF.getFunctionNumber());
6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski    }
6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski  }
6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski}
6949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski
7049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid NVPTXFrameLowering::emitEpilogue(MachineFunction &MF,
713639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski                                      MachineBasicBlock &MBB) const {}
72700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky
73700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky// This function eliminates ADJCALLSTACKDOWN,
74700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky// ADJCALLSTACKUP pseudo instructions
753639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskivoid NVPTXFrameLowering::eliminateCallFramePseudoInstr(
763639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski    MachineFunction &MF, MachineBasicBlock &MBB,
773639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski    MachineBasicBlock::iterator I) const {
78700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  // Simply discard ADJCALLSTACKDOWN,
79700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  // ADJCALLSTACKUP instructions.
80700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky  MBB.erase(I);
81700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky}
82