HexagonFrameLowering.cpp revision 4aecc761c7c9069424630ed8dfb8cd382866dd45
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- HexagonFrameLowering.cpp - Define frame lowering ------------------===//
2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//                     The LLVM Compiler Infrastructure
4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source
6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details.
7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
10f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer
1179aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonFrameLowering.h"
12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "Hexagon.h"
13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonInstrInfo.h"
14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonRegisterInfo.h"
15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonSubtarget.h"
16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonTargetMachine.h"
17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "HexagonMachineFunctionInfo.h"
18f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/Function.h"
19f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/Type.h"
20f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/ADT/BitVector.h"
21f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/ADT/STLExtras.h"
22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/AsmPrinter.h"
23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineInstrBuilder.h"
24b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunction.h"
25f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineFunctionPass.h"
26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFrameInfo.h"
27f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/MachineModuleInfo.h"
28b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineRegisterInfo.h"
29f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/CodeGen/RegisterScavenging.h"
30b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MachineLocation.h"
31b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/MC/MCAsmInfo.h"
32b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetInstrInfo.h"
33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetMachine.h"
34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetOptions.h"
35f3fd7ee415ec8a6475a060e29959d04d6158f45fBenjamin Kramer#include "llvm/Support/CommandLine.h"
36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm;
38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic cl::opt<bool> DisableDeallocRet(
40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       "disable-hexagon-dealloc-ret",
41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       cl::Hidden,
42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                       cl::desc("Disable Dealloc Return for Hexagon target"));
43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// determineFrameLayout - Determine the size of the frame and maximum call
45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// frame size.
46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFrameInfo *MFI = MF.getFrameInfo();
48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get the number of bytes to allocate from the FrameInfo.
50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned FrameSize = MFI->getStackSize();
51b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get the alignments provided by the target.
53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get the maximum call frame size of all the calls.
55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // that allocations will be aligned.
59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MFI->hasVarSizedObjects())
60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    maxCallFrameSize = RoundUpToAlignment(maxCallFrameSize, TargetAlign);
61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Update maximum call frame size.
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MFI->setMaxCallFrameSize(maxCallFrameSize);
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Include call frame size in total.
66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  FrameSize += maxCallFrameSize;
67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Make sure the frame is aligned.
69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  FrameSize = RoundUpToAlignment(FrameSize, TargetAlign);
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Update frame info.
72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MFI->setStackSize(FrameSize);
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock &MBB = MF.front();
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFrameInfo *MFI = MF.getFrameInfo();
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineModuleInfo &MMI = MF.getMMI();
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator MBBI = MBB.begin();
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const HexagonRegisterInfo *QRI =
82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  determineFrameLayout(MF);
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Check if frame moves are needed for EH.
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool needsFrameMoves = MMI.hasDebugInfo() ||
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    !MF.getFunction()->needsUnwindTableEntry();
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Get the number of bytes to allocate from the FrameInfo.
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  int NumBytes = (int) MFI->getStackSize();
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // LLVM expects allocframe not to be the first instruction in the
94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // basic block.
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator InsertPt = MBB.begin();
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // ALLOCA adjust regs.  Iterate over ADJDYNALLOC nodes and change the offset.
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  HexagonMachineFunctionInfo *FuncInfo =
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MF.getInfo<HexagonMachineFunctionInfo>();
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const std::vector<MachineInstr*>& AdjustRegs =
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    FuncInfo->getAllocaAdjustInsts();
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (std::vector<MachineInstr*>::const_iterator i = AdjustRegs.begin(),
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         e = AdjustRegs.end();
106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       i != e; ++i) {
107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineInstr* MI = *i;
108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert((MI->getOpcode() == Hexagon::ADJDYNALLOC) &&
109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           "Expected adjust alloca node");
110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineOperand& MO = MI->getOperand(2);
112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert(MO.isImm() && "Expected immediate");
113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MO.setImm(MFI->getMaxCallFrameSize());
114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum std::vector<MachineMove> &Moves = MMI.getFrameMoves();
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum if (needsFrameMoves) {
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   // Advance CFA. DW_CFA_def_cfa
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   unsigned FPReg = QRI->getFrameRegister();
121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   unsigned RAReg = QRI->getRARegister();
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation Dst(MachineLocation::VirtualFP);
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation Src(FPReg, -8);
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   Moves.push_back(MachineMove(0, Dst, Src));
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   // R31 = (R31 - #4)
128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation LRDst(RAReg, -4);
129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation LRSrc(RAReg);
130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   Moves.push_back(MachineMove(0, LRDst, LRSrc));
131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   // R30 = (R30 - #8)
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation SPDst(FPReg, -8);
134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   MachineLocation SPSrc(FPReg);
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum   Moves.push_back(MachineMove(0, SPDst, SPSrc));
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum }
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Only insert ALLOCFRAME if we need to.
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (hasFP(MF)) {
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Check for overflow.
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
14422614a02eb8855548a892139e54e478c70050f9fTony Linthicum    const int ALLOCFRAME_MAX = 16384;
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (NumBytes >= ALLOCFRAME_MAX) {
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Emit allocframe(#0).
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Subtract offset from frame pointer.
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      HEXAGON_RESERVED_REG_1).addImm(NumBytes);
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      QRI->getStackRegister()).
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      addReg(QRI->getStackRegister()).
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                      addReg(HEXAGON_RESERVED_REG_1);
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Returns true if MBB has a machine instructions that indicates a tail call
164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// in the block.
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const {
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned RetOpcode = MBBI->getOpcode();
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;}
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     MachineBasicBlock &MBB) const {
173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator MBBI = prior(MBB.end());
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DebugLoc dl = MBBI->getDebugLoc();
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Only insert deallocframe if we need to.
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (hasFP(MF)) {
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock::iterator MBBI = prior(MBB.end());
180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock::iterator MBBI_end = MBB.end();
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // For Hexagon, we don't need the frame size.
183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineFrameInfo *MFI = MF.getFrameInfo();
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int NumBytes = (int) MFI->getStackSize();
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // versions.
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                        && !DisableDeallocRet) {
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Remove jumpr node.
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MBB.erase(MBBI);
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Add dealloc_return.
196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4))
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        .addImm(NumBytes);
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else { // Add deallocframe for V2 and V3.
199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes);
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineFrameInfo *MFI = MF.getFrameInfo();
206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const HexagonMachineFunctionInfo *FuncInfo =
207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MF.getInfo<HexagonMachineFunctionInfo>();
208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return (MFI->hasCalls() || (MFI->getStackSize() > 0) ||
209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          FuncInfo->hasClobberLR() );
210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
2124aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesenstatic inline
2134aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesenunsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) {
2144aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  MCSuperRegIterator SRI(Reg, TRI);
2154aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  assert(SRI.isValid() && "Expected a superreg");
2164aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  unsigned SuperReg = *SRI;
2174aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  ++SRI;
2184aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  assert(!SRI.isValid() && "Expected exactly one superreg");
2194aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen  return SuperReg;
2204aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen}
2214aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen
222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool
223b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonFrameLowering::spillCalleeSavedRegisters(
224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        MachineBasicBlock &MBB,
225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        MachineBasicBlock::iterator MI,
226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        const std::vector<CalleeSavedInfo> &CSI,
227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        const TargetRegisterInfo *TRI) const {
228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction *MF = MBB.getParent();
229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (CSI.empty()) {
232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // We can only schedule double loads if we spill contiguous callee-saved regs
236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For instance, we cannot scheduled double-word loads if we spill r24,
237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // r26, and r27.
238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // above.
240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool ContiguousRegs = true;
241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i < CSI.size(); ++i) {
243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned Reg = CSI[i].getReg();
244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Check if we can use a double-word store.
247b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
2484aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen    unsigned SuperReg = uniqueSuperReg(Reg, TRI);
249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool CanUseDblStore = false;
250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetRegisterClass* SuperRegClass = 0;
251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ContiguousRegs && (i < CSI.size()-1)) {
2534aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
2544aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
2554aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      CanUseDblStore = (SuperRegNext == SuperReg);
256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
259b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (CanUseDblStore) {
2604aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      TII.storeRegToStackSlot(MBB, MI, SuperReg, true,
261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                              CSI[i+1].getFrameIdx(), SuperRegClass, TRI);
2624aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      MBB.addLiveIn(SuperReg);
263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      ++i;
264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Cannot use a double-word store.
266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      ContiguousRegs = false;
267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), RC,
269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                              TRI);
270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MBB.addLiveIn(Reg);
271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;
274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFrameLowering::restoreCalleeSavedRegisters(
278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        MachineBasicBlock &MBB,
279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        MachineBasicBlock::iterator MI,
280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        const std::vector<CalleeSavedInfo> &CSI,
281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                        const TargetRegisterInfo *TRI) const {
282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineFunction *MF = MBB.getParent();
284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (CSI.empty()) {
287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // We can only schedule double loads if we spill contiguous callee-saved regs
291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // For instance, we cannot scheduled double-word loads if we spill r24,
292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // r26, and r27.
293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Hexagon_TODO: We can try to double-word align odd registers for -O2 and
294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // above.
295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool ContiguousRegs = true;
296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0; i < CSI.size(); ++i) {
298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned Reg = CSI[i].getReg();
299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Check if we can use a double-word load.
302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    //
3034aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen    unsigned SuperReg = uniqueSuperReg(Reg, TRI);
304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetRegisterClass* SuperRegClass = 0;
305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool CanUseDblLoad = false;
306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (ContiguousRegs && (i < CSI.size()-1)) {
3074aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI);
3084aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg);
3094aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      CanUseDblLoad = (SuperRegNext == SuperReg);
310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (CanUseDblLoad) {
3144aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(),
315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                               SuperRegClass, TRI);
3164aecc761c7c9069424630ed8dfb8cd382866dd45Jakob Stoklund Olesen      MBB.addLiveIn(SuperReg);
317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      ++i;
318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } else {
319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Cannot use a double-word load.
320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      ContiguousRegs = false;
321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), RC, TRI);
323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MBB.addLiveIn(Reg);
324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;
327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumint HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                              int FI) const {
331b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return MF.getFrameInfo()->getObjectOffset(FI);
332b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
333