ARMBaseRegisterInfo.cpp revision cf453ee70a1ae03cc641686fd5db0f8a7d8ce250
12cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner//===- ARMBaseRegisterInfo.cpp - ARM Register Information -------*- C++ -*-===//
2c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
3c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//                     The LLVM Compiler Infrastructure
4c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
5c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file is distributed under the University of Illinois Open Source
6c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// License. See LICENSE.TXT for details.
7c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
8c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===//
9c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
10c140c4803dc3e10e08138670829bc0494986abe9David Goodwin// This file contains the base ARM implementation of TargetRegisterInfo class.
11c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//
12c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===----------------------------------------------------------------------===//
13c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
14c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARM.h"
15c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMAddressingModes.h"
16db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin#include "ARMBaseInstrInfo.h"
17c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMBaseRegisterInfo.h"
18c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMInstrInfo.h"
19c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMMachineFunctionInfo.h"
20c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMSubtarget.h"
21c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Constants.h"
22c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/DerivedTypes.h"
239adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/Function.h"
249adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/LLVMContext.h"
25c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineConstantPool.h"
26c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFrameInfo.h"
27c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineFunction.h"
28c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineInstrBuilder.h"
29c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineLocation.h"
30c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/MachineRegisterInfo.h"
31c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/CodeGen/RegisterScavenging.h"
323dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach#include "llvm/Support/Debug.h"
33ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h"
34dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
35c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetFrameInfo.h"
36c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetMachine.h"
37c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetOptions.h"
38c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/BitVector.h"
39c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/SmallVector.h"
4018ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach#include "llvm/Support/CommandLine.h"
41c140c4803dc3e10e08138670829bc0494986abe9David Goodwinusing namespace llvm;
42c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
4318ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbachstatic cl::opt<bool>
44a6a99b4e160eea0060b25fbdeadc3437cd67d617Jim GrosbachReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true),
4518ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach          cl::desc("Reuse repeated frame index values"));
4618ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach
47c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
488295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                                                   bool *isSPVFP) {
498295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  if (isSPVFP)
508295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    *isSPVFP = false;
51c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
52c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  using namespace ARM;
53c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (RegEnum) {
54c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default:
55c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unknown ARM register!");
568295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R0:  case D0:  case Q0:  return 0;
578295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R1:  case D1:  case Q1:  return 1;
588295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R2:  case D2:  case Q2:  return 2;
598295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R3:  case D3:  case Q3:  return 3;
608295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R4:  case D4:  case Q4:  return 4;
618295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R5:  case D5:  case Q5:  return 5;
628295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R6:  case D6:  case Q6:  return 6;
638295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R7:  case D7:  case Q7:  return 7;
648295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R8:  case D8:  case Q8:  return 8;
658295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R9:  case D9:  case Q9:  return 9;
668295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R10: case D10: case Q10: return 10;
678295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R11: case D11: case Q11: return 11;
688295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R12: case D12: case Q12: return 12;
698295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case SP:  case D13: case Q13: return 13;
708295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case LR:  case D14: case Q14: return 14;
718295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case PC:  case D15: case Q15: return 15;
728295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng
738295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D16: return 16;
748295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D17: return 17;
758295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D18: return 18;
768295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D19: return 19;
778295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D20: return 20;
788295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D21: return 21;
798295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D22: return 22;
808295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D23: return 23;
818295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D24: return 24;
828295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D25: return 25;
838295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D26: return 27;
848295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D27: return 27;
858295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D28: return 28;
868295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D29: return 29;
878295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D30: return 30;
888295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D31: return 31;
89c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
90c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S0: case S1: case S2: case S3:
91c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S4: case S5: case S6: case S7:
92c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S8: case S9: case S10: case S11:
93c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S12: case S13: case S14: case S15:
94c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S16: case S17: case S18: case S19:
95c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S20: case S21: case S22: case S23:
96c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S24: case S25: case S26: case S27:
978295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case S28: case S29: case S30: case S31: {
988295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    if (isSPVFP)
998295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      *isSPVFP = true;
100c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    switch (RegEnum) {
101c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    default: return 0; // Avoid compile time warning.
102c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S0: return 0;
103c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S1: return 1;
104c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S2: return 2;
105c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S3: return 3;
106c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S4: return 4;
107c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S5: return 5;
108c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S6: return 6;
109c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S7: return 7;
110c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S8: return 8;
111c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S9: return 9;
112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S10: return 10;
113c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S11: return 11;
114c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S12: return 12;
115c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S13: return 13;
116c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S14: return 14;
117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S15: return 15;
118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S16: return 16;
119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S17: return 17;
120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S18: return 18;
121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S19: return 19;
122c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S20: return 20;
123c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S21: return 21;
124c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S22: return 22;
125c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S23: return 23;
126c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S24: return 24;
127c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S25: return 25;
128c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S26: return 26;
129c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S27: return 27;
130c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S28: return 28;
131c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S29: return 29;
132c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S30: return 30;
133c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S31: return 31;
134c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
135c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
136c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
137c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
138c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
139db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
140c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const ARMSubtarget &sti)
141c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
142c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    TII(tii), STI(sti),
143c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
144c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
145c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
146c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst unsigned*
147c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
148c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned CalleeSavedRegs[] = {
149c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
150c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
151c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
152c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
153c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
154c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
155c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
156c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
157c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned DarwinCalleeSavedRegs[] = {
158c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
159c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // register.
160c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::LR,  ARM::R7,  ARM::R6, ARM::R5, ARM::R4,
161c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11, ARM::R10, ARM::R8,
162c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
163c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
164c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
165c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
166c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
167c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
168c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
169c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
170c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst TargetRegisterClass* const *
171c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
172c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
17382b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
17482b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
17582b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
176c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
17782b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
17882b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
179c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
180c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
181c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
182c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = {
18382b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
18482b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass,
18582b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass,
186c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
18782b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
18882b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
189c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
190c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
191c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
192c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const DarwinCalleeSavedRegClasses[] = {
19382b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
19482b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
19582b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass, &ARM::GPRRegClass,
196c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
19782b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
19882b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
199c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
200c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
201c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
202c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const DarwinThumbCalleeSavedRegClasses[] ={
20382b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass,  &ARM::tGPRRegClass, &ARM::tGPRRegClass,
20482b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::tGPRRegClass, &ARM::tGPRRegClass, &ARM::GPRRegClass,
20582b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::GPRRegClass,  &ARM::GPRRegClass,
206c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
20782b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
20882b3c2e40417098f9af0c33150c4b1c66ae1747cJim Grosbach    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
209c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
210c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
211c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
212f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin  if (STI.isThumb1Only()) {
213c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isTargetDarwin()
214c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
215c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
216c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return STI.isTargetDarwin()
217c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
218c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
219c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
2209631864688c593711f82bb8d21f8b724c628d786Jim GrosbachBitVector ARMBaseRegisterInfo::
2219631864688c593711f82bb8d21f8b724c628d786Jim GrosbachgetReservedRegs(const MachineFunction &MF) const {
222c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FIXME: avoid re-calculating this everytime.
223c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  BitVector Reserved(getNumRegs());
224c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::SP);
225c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::PC);
226c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isTargetDarwin() || hasFP(MF))
227c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(FramePtr);
228c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Some targets reserve R9.
229c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isR9Reserved())
230c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(ARM::R9);
231c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return Reserved;
232c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
233c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
2342cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerbool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
2352cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattner                                        unsigned Reg) const {
236c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
237c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
238c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::SP:
239c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::PC:
240c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return true;
241c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
242c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
243c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
244c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return true;
245c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    break;
246c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
247c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isR9Reserved();
248c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
249c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
250c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return false;
251c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
252c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
2532cfd52c507bd5790457a171eb9bcb39019cc6860Chris Lattnerconst TargetRegisterClass *
2544f54c1293af174a8002db20faf7b4f82ba4e8514Evan ChengARMBaseRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
2554f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng                                              const TargetRegisterClass *B,
2564f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng                                              unsigned SubIdx) const {
2574f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  switch (SubIdx) {
2584f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  default: return 0;
2594f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 1:
2604f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 2:
2614f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 3:
2624f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 4:
2634f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    // S sub-registers.
2644f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    if (A->getSize() == 8) {
265ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      if (B == &ARM::SPR_8RegClass)
266ba908640b3e0c1218748776e244d4b7234451155Evan Cheng        return &ARM::DPR_8RegClass;
267ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      assert(B == &ARM::SPRRegClass && "Expecting SPR register class!");
2684f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng      if (A == &ARM::DPR_8RegClass)
2694f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng        return A;
2704f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng      return &ARM::DPR_VFP2RegClass;
2714f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    }
2724f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng
2734f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    assert(A->getSize() == 16 && "Expecting a Q register class!");
274ba908640b3e0c1218748776e244d4b7234451155Evan Cheng    if (B == &ARM::SPR_8RegClass)
275ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      return &ARM::QPR_8RegClass;
2764f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    return &ARM::QPR_VFP2RegClass;
2774f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 5:
2784f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  case 6:
2794f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    // D sub-registers.
280ba908640b3e0c1218748776e244d4b7234451155Evan Cheng    if (B == &ARM::DPR_VFP2RegClass)
281ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      return &ARM::QPR_VFP2RegClass;
282ba908640b3e0c1218748776e244d4b7234451155Evan Cheng    if (B == &ARM::DPR_8RegClass)
283ba908640b3e0c1218748776e244d4b7234451155Evan Cheng      return &ARM::QPR_8RegClass;
2844f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng    return A;
2854f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  }
2864f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng  return 0;
2874f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng}
2884f54c1293af174a8002db20faf7b4f82ba4e8514Evan Cheng
2894f54c1293af174a8002db20faf7b4f82ba4e8514Evan Chengconst TargetRegisterClass *
2902cfd52c507bd5790457a171eb9bcb39019cc6860Chris LattnerARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const {
291e11a8f565c6a019ddc54667227be9c4d8f117473Jim Grosbach  return ARM::GPRRegisterClass;
292c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
293c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
294c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// getAllocationOrder - Returns the register allocation order for a specified
295c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// register class in the form of a pair of TargetRegisterClass iterators.
296c140c4803dc3e10e08138670829bc0494986abe9David Goodwinstd::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
297c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
298c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        unsigned HintType, unsigned HintReg,
299c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        const MachineFunction &MF) const {
300c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Alternative register allocation orders when favoring even / odd registers
301c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // of register pairs.
302c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
303c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is available.
304c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven1[] = {
305c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
306c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
307c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
308c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
309c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd1[] = {
310c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
311c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
312c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
313c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
314c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
315c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is available.
316c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven2[] = {
317c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,          ARM::R8, ARM::R10,
318c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
319c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
320c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
321c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd2[] = {
322c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,          ARM::R9, ARM::R11,
323c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
324c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
325c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
326c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
327c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is available.
328c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven3[] = {
329c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
330c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
331c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9
332c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
333c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd3[] = {
334c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
335c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
336c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8
337c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
338c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
339c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is not available.
340c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven4[] = {
341c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,          ARM::R10,
342c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
343c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
344c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
345c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd4[] = {
346c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,          ARM::R11,
347c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
348c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
349c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
350c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
351c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is not available.
352c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven5[] = {
353c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,                   ARM::R10,
354c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
355c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
356c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
357c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd5[] = {
358c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,                   ARM::R11,
359c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
360c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
361c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
362c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
363c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is not available.
364c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven6[] = {
365c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,
366c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
367c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
368c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd6[] = {
369c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,
370c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
371c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
372c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
373c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
374c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (HintType == ARMRI::RegPairEven) {
375c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
376c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
377c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
378c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return std::make_pair(RC->allocation_order_begin(MF),
379c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                            RC->allocation_order_end(MF));
380c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
381c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!STI.isTargetDarwin() && !hasFP(MF)) {
382c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
383c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven1,
384c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
385c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
386c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven4,
387c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven4 + (sizeof(GPREven4)/sizeof(unsigned)));
388c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
389c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
390c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven2,
391c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven2 + (sizeof(GPREven2)/sizeof(unsigned)));
392c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
393c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven5,
394c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven5 + (sizeof(GPREven5)/sizeof(unsigned)));
395c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
396c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
397c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven3,
398c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven3 + (sizeof(GPREven3)/sizeof(unsigned)));
399c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
400c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven6,
401c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven6 + (sizeof(GPREven6)/sizeof(unsigned)));
402c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
403c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  } else if (HintType == ARMRI::RegPairOdd) {
404c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
405c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
406c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
407c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return std::make_pair(RC->allocation_order_begin(MF),
408c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                            RC->allocation_order_end(MF));
409c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
410c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!STI.isTargetDarwin() && !hasFP(MF)) {
411c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
412c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd1,
413c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
414c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
415c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd4,
416c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd4 + (sizeof(GPROdd4)/sizeof(unsigned)));
417c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
418c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
419c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd2,
420c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd2 + (sizeof(GPROdd2)/sizeof(unsigned)));
421c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
422c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd5,
423c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd5 + (sizeof(GPROdd5)/sizeof(unsigned)));
424c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
425c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
426c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd3,
427c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd3 + (sizeof(GPROdd3)/sizeof(unsigned)));
428c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
429c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd6,
430c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd6 + (sizeof(GPROdd6)/sizeof(unsigned)));
431c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
432c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
433c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return std::make_pair(RC->allocation_order_begin(MF),
434c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                        RC->allocation_order_end(MF));
435c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
436c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
437c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// ResolveRegAllocHint - Resolves the specified register allocation hint
438c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// to a physical register. Returns the physical register if it is successful.
439c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned
440c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
441c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const MachineFunction &MF) const {
442c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Reg == 0 || !isPhysicalRegister(Reg))
443c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return 0;
444c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Type == 0)
445c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return Reg;
446c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairOdd)
447c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Odd register.
448c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairOdd(Reg, MF);
449c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairEven)
450c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Even register.
451c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairEven(Reg, MF);
452c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
453c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
454c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
455c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
456c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
457c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        MachineFunction &MF) const {
458c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  MachineRegisterInfo *MRI = &MF.getRegInfo();
459c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
460c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
461c140c4803dc3e10e08138670829bc0494986abe9David Goodwin       Hint.first == (unsigned)ARMRI::RegPairEven) &&
462c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
463c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If 'Reg' is one of the even / odd register pair and it's now changed
464c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // (e.g. coalesced) into a different register. The other register of the
465c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // pair allocation hint must be updated to reflect the relationship
466c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // change.
467c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned OtherReg = Hint.second;
468c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Hint = MRI->getRegAllocationHint(OtherReg);
469c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (Hint.second == Reg)
470c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Make sure the pair has not already divorced.
471c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
472c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
473c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
474c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
475c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// hasFP - Return true if the specified function should have a dedicated frame
476c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// pointer register.  This is true if the function has variable sized allocas
477c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// or if frame pointer elimination is disabled.
478c140c4803dc3e10e08138670829bc0494986abe9David Goodwin///
479c140c4803dc3e10e08138670829bc0494986abe9David Goodwinbool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
480c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const MachineFrameInfo *MFI = MF.getFrameInfo();
481985d45dea357cbfe718b89cebd84b20b1298ab93Jim Grosbach  return ((NoFramePointerElim && MFI->hasCalls())||
4823dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach          needsStackRealignment(MF) ||
483c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          MFI->hasVarSizedObjects() ||
484c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          MFI->isFrameAddressTaken());
485c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
486c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
487e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbachbool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
488e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
489e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
490e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach  return (RealignStack &&
491e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach          !AFI->isThumb1OnlyFunction() &&
492e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach          !MFI->hasVarSizedObjects());
493e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach}
494e45ab8a0a90e4f3a59d8c38038ae3e495ee1fef3Jim Grosbach
4953dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbachbool ARMBaseRegisterInfo::
4963dab2778571b5bb00b35a0adcb7011dc85158bebJim GrosbachneedsStackRealignment(const MachineFunction &MF) const {
4973dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
4983dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
499ad353c74adda55556f7a3969721c3e49ac16d570Jim Grosbach  unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
5003dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  return (RealignStack &&
5013dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach          !AFI->isThumb1OnlyFunction() &&
502ad353c74adda55556f7a3969721c3e49ac16d570Jim Grosbach          (MFI->getMaxAlignment() > StackAlign) &&
5033dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach          !MFI->hasVarSizedObjects());
5043dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach}
5053dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach
5069631864688c593711f82bb8d21f8b724c628d786Jim Grosbachbool ARMBaseRegisterInfo::
5079631864688c593711f82bb8d21f8b724c628d786Jim GrosbachcannotEliminateFrame(const MachineFunction &MF) const {
50898a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng  const MachineFrameInfo *MFI = MF.getFrameInfo();
50998a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng  if (NoFramePointerElim && MFI->hasCalls())
51098a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng    return true;
51131bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach  return MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken()
51231bc849123011b8eae6bb3c79876d9a3c26a6a1dJim Grosbach    || needsStackRealignment(MF);
51398a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng}
51498a0104014e9bb6ed89c2572f615351fd526674aEvan Cheng
515542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng/// estimateStackSize - Estimate and return the size of the frame.
516c140c4803dc3e10e08138670829bc0494986abe9David Goodwinstatic unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
517c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const MachineFrameInfo *FFI = MF.getFrameInfo();
518c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  int Offset = 0;
519c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
520c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    int FixedOff = -FFI->getObjectOffset(i);
521c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FixedOff > Offset) Offset = FixedOff;
522c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
523c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
524c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FFI->isDeadObjectIndex(i))
525c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      continue;
526c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Offset += FFI->getObjectSize(i);
527c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned Align = FFI->getObjectAlignment(i);
528c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Adjust to alignment boundary
529c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Offset = (Offset+Align-1)/Align*Align;
530c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
531c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return (unsigned)Offset;
532c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
533c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
534542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng/// estimateRSStackSizeLimit - Look at each instruction that references stack
535542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng/// frames and return the stack size limit beyond which some of these
536ce3e769c15be90463abf14bb71b5a8e1205d3661Jim Grosbach/// instructions will require a scratch register during their expansion later.
537ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Chengunsigned
538ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan ChengARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
539542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng  unsigned Limit = (1 << 12) - 1;
540b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner  for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
541b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
542b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner         I != E; ++I) {
543b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
544b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        if (!I->getOperand(i).isFI()) continue;
545764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach
546b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        const TargetInstrDesc &Desc = TII.get(I->getOpcode());
547b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
548b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        if (AddrMode == ARMII::AddrMode3 ||
549b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner            AddrMode == ARMII::AddrModeT2_i8)
550b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner          return (1 << 8) - 1;
551764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach
552b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        if (AddrMode == ARMII::AddrMode5 ||
553b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner            AddrMode == ARMII::AddrModeT2_i8s4)
554b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
555ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Cheng
556ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Cheng        if (AddrMode == ARMII::AddrModeT2_i12 && hasFP(MF))
557ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Cheng          // When the stack offset is negative, we will end up using
558ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Cheng          // the i8 instructions instead.
559ee42fd309ee6a8febfafb97c2f3b6f2069758c5eEvan Cheng          return (1 << 8) - 1;
560ce3e769c15be90463abf14bb71b5a8e1205d3661Jim Grosbach
561ce3e769c15be90463abf14bb71b5a8e1205d3661Jim Grosbach        if (AddrMode == ARMII::AddrMode6)
562ce3e769c15be90463abf14bb71b5a8e1205d3661Jim Grosbach          return 0;
563b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner        break; // At most one FI per instruction
564b180d992d81f97862af6089dfe899d0363cac6f5Chris Lattner      }
565542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng    }
566542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng  }
567542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng
568542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng  return Limit;
569542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng}
570542383d93b146e11a1d70c01f8afea8ea9f08effEvan Cheng
571c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
572c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
5739631864688c593711f82bb8d21f8b724c628d786Jim Grosbach                                                       RegScavenger *RS) const {
574c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // This tells PEI to spill the FP as if it is any other callee-save register
575c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // to take advantage the eliminateFrameIndex machinery. This also ensures it
576c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // is spilled in the order specified by getCalleeSavedRegs() to make it easier
577c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // to combine multiple loads / stores.
578c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool CanEliminateFrame = true;
579c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool CS1Spilled = false;
580c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool LRSpilled = false;
581c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  unsigned NumGPRSpills = 0;
582c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  SmallVector<unsigned, 4> UnspilledCS1GPRs;
583c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  SmallVector<unsigned, 4> UnspilledCS2GPRs;
584c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
585c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
5867cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov  // Spill R4 if Thumb2 function requires stack realignment - it will be used as
5877cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov  // scratch register.
5887cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov  // FIXME: It will be better just to find spare register here.
5897cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov  if (needsStackRealignment(MF) &&
5907cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      AFI->isThumb2Function())
5917cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov    MF.getRegInfo().setPhysRegUsed(ARM::R4);
5927cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov
593c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Don't spill FP if the frame can be eliminated. This is determined
594c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // by scanning the callee-save registers to see if any is used.
595c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const unsigned *CSRegs = getCalleeSavedRegs();
596c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
597c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (unsigned i = 0; CSRegs[i]; ++i) {
598c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned Reg = CSRegs[i];
599c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    bool Spilled = false;
600c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (MF.getRegInfo().isPhysRegUsed(Reg)) {
601c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      AFI->setCSRegisterIsSpilled(Reg);
602c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      Spilled = true;
603c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      CanEliminateFrame = false;
604c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else {
605c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Check alias registers too.
606c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
607c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (MF.getRegInfo().isPhysRegUsed(*Aliases)) {
608c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          Spilled = true;
609c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CanEliminateFrame = false;
610c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
611c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
612c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
613c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
614ec9eef4a15157fc0a05feff933848aa9283bd1afJim Grosbach    if (CSRegClasses[i] == ARM::GPRRegisterClass ||
615ec9eef4a15157fc0a05feff933848aa9283bd1afJim Grosbach        CSRegClasses[i] == ARM::tGPRRegisterClass) {
616c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (Spilled) {
617c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        NumGPRSpills++;
618c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
619c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!STI.isTargetDarwin()) {
620c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          if (Reg == ARM::LR)
621c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            LRSpilled = true;
622c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CS1Spilled = true;
623c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          continue;
624c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
625c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
626c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
627c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        switch (Reg) {
628c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::LR:
629c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          LRSpilled = true;
630c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          // Fallthrough
631c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R4:
632c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R5:
633c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R6:
634c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R7:
635c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CS1Spilled = true;
636c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
637c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        default:
638c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
639c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
640c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      } else {
641c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!STI.isTargetDarwin()) {
642c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.push_back(Reg);
643c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          continue;
644c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
645c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
646c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        switch (Reg) {
647c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R4:
648c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R5:
649c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R6:
650c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R7:
651c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::LR:
652c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.push_back(Reg);
653c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
654c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        default:
655c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS2GPRs.push_back(Reg);
656c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
657c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
658c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
659c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
660c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
661c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
662c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool ForceLRSpill = false;
663f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin  if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
664c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned FnSize = TII.GetFunctionSizeInBytes(MF);
665c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Force LR to be spilled if the Thumb function size is > 2048. This enables
666c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // use of BL to implement far jump. If it turns out that it's not needed
667c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // then the branch fix up path will undo it.
668c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FnSize >= (1 << 11)) {
669c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      CanEliminateFrame = false;
670c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ForceLRSpill = true;
671c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
672c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
673c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
674c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool ExtraCSSpill = false;
675010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng  if (!CanEliminateFrame || cannotEliminateFrame(MF)) {
676c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setHasStackFrame(true);
677c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
678c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
679c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
680c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!LRSpilled && CS1Spilled) {
681c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MF.getRegInfo().setPhysRegUsed(ARM::LR);
682c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      AFI->setCSRegisterIsSpilled(ARM::LR);
683c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      NumGPRSpills++;
684c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
685c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
686c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ForceLRSpill = false;
687c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ExtraCSSpill = true;
688c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
689c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
690c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Darwin ABI requires FP to point to the stack slot that contains the
691c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // previous FP.
692c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (STI.isTargetDarwin() || hasFP(MF)) {
693c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MF.getRegInfo().setPhysRegUsed(FramePtr);
694c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      NumGPRSpills++;
695c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
696c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
697c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If stack and double are 8-byte aligned and we are spilling an odd number
698c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // of GPRs. Spill one extra callee save GPR so we won't have to pad between
699c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // the integer and double callee save areas.
700c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
701c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (TargetAlign == 8 && (NumGPRSpills & 1)) {
702c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
703c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
704c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          unsigned Reg = UnspilledCS1GPRs[i];
705f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin          // Don't spill high register if the function is thumb1
706f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin          if (!AFI->isThumb1OnlyFunction() ||
707c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              isARMLowRegister(Reg) || Reg == ARM::LR) {
708c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            MF.getRegInfo().setPhysRegUsed(Reg);
709c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            AFI->setCSRegisterIsSpilled(Reg);
710c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            if (!isReservedReg(MF, Reg))
711c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              ExtraCSSpill = true;
712c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            break;
713c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
714c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
715c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      } else if (!UnspilledCS2GPRs.empty() &&
716f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin                 !AFI->isThumb1OnlyFunction()) {
717c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        unsigned Reg = UnspilledCS2GPRs.front();
718c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        MF.getRegInfo().setPhysRegUsed(Reg);
719c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        AFI->setCSRegisterIsSpilled(Reg);
720c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!isReservedReg(MF, Reg))
721c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          ExtraCSSpill = true;
722c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
723c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
724c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
725c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Estimate if we might need to scavenge a register at some point in order
726c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // to materialize a stack offset. If so, either spill one additional
727c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // callee-saved register or reserve a special spill slot to facilitate
7283d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    // register scavenging. Thumb1 needs a spill slot for stack pointer
7293d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    // adjustments also, even when the frame itself is small.
7303d6cb88a64fe67064de206405951eb326d86fc0cJim Grosbach    if (RS && !ExtraCSSpill) {
731c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MachineFrameInfo  *MFI = MF.getFrameInfo();
732d1a5ca6cb11763059ba1ee1c965cc69abff92e38Jim Grosbach      // If any of the stack slot references may be out of range of an
733d1a5ca6cb11763059ba1ee1c965cc69abff92e38Jim Grosbach      // immediate offset, make sure a register (or a spill slot) is
734d1a5ca6cb11763059ba1ee1c965cc69abff92e38Jim Grosbach      // available for the register scavenger. Note that if we're indexing
735d1a5ca6cb11763059ba1ee1c965cc69abff92e38Jim Grosbach      // off the frame pointer, the effective stack size is 4 bytes larger
736460c482ed38f5c2f91e29eaacf241928d3d77edfJim Grosbach      // since the FP points to the stack slot of the previous FP.
737d1a5ca6cb11763059ba1ee1c965cc69abff92e38Jim Grosbach      if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
738540b05d227a79443b2a7b07d5152a35cb6392abfJim Grosbach          >= estimateRSStackSizeLimit(MF)) {
739c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // If any non-reserved CS register isn't spilled, just spill one or two
740c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // extra. That should take care of it!
741c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        unsigned NumExtras = TargetAlign / 4;
742c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        SmallVector<unsigned, 2> Extras;
743c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        while (NumExtras && !UnspilledCS1GPRs.empty()) {
744c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          unsigned Reg = UnspilledCS1GPRs.back();
745c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.pop_back();
746c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          if (!isReservedReg(MF, Reg)) {
747c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            Extras.push_back(Reg);
748c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            NumExtras--;
749c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
750c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
75117487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach        // For non-Thumb1 functions, also check for hi-reg CS registers
75217487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach        if (!AFI->isThumb1OnlyFunction()) {
75317487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach          while (NumExtras && !UnspilledCS2GPRs.empty()) {
75417487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach            unsigned Reg = UnspilledCS2GPRs.back();
75517487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach            UnspilledCS2GPRs.pop_back();
75617487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach            if (!isReservedReg(MF, Reg)) {
75717487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach              Extras.push_back(Reg);
75817487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach              NumExtras--;
75917487ba60d171aa32b17e6c3ad6d5809e78f9868Jim Grosbach            }
760c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
761c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
762c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (Extras.size() && NumExtras == 0) {
763c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
764c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            MF.getRegInfo().setPhysRegUsed(Extras[i]);
765c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            AFI->setCSRegisterIsSpilled(Extras[i]);
766c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
767540b05d227a79443b2a7b07d5152a35cb6392abfJim Grosbach        } else if (!AFI->isThumb1OnlyFunction()) {
768540b05d227a79443b2a7b07d5152a35cb6392abfJim Grosbach          // note: Thumb1 functions spill to R12, not the stack.
769c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          // Reserve a slot closest to SP or frame pointer.
770e11a8f565c6a019ddc54667227be9c4d8f117473Jim Grosbach          const TargetRegisterClass *RC = ARM::GPRRegisterClass;
771c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
7723f2bf85d14759cc4b28a86805f566ac805a54d00David Greene                                                             RC->getAlignment(),
7733f2bf85d14759cc4b28a86805f566ac805a54d00David Greene                                                             false));
774c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
775c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
776c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
777c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
778c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
779c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (ForceLRSpill) {
780c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    MF.getRegInfo().setPhysRegUsed(ARM::LR);
781c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setCSRegisterIsSpilled(ARM::LR);
782c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setLRIsSpilledForFarJump(true);
783c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
784c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
785c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
786c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRARegister() const {
787c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::LR;
788c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
789c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
7903f2bf85d14759cc4b28a86805f566ac805a54d00David Greeneunsigned
7913f2bf85d14759cc4b28a86805f566ac805a54d00David GreeneARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
792c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isTargetDarwin() || hasFP(MF))
793c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return FramePtr;
794c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::SP;
795c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
796c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
79750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbachint
79830c6b75ac2eef548c18110a38c9798ea5314cabaChris LattnerARMBaseRegisterInfo::getFrameIndexReference(const MachineFunction &MF, int FI,
79950f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach                                            unsigned &FrameReg) const {
80050f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  const MachineFrameInfo *MFI = MF.getFrameInfo();
80130c6b75ac2eef548c18110a38c9798ea5314cabaChris Lattner  const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
80250f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  int Offset = MFI->getObjectOffset(FI) + MFI->getStackSize();
80350f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  bool isFixed = MFI->isFixedObjectIndex(FI);
80450f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach
805a37aa546224ec03ba1f1a1598e0781af4b692673Jim Grosbach  FrameReg = ARM::SP;
80650f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  if (AFI->isGPRCalleeSavedArea1Frame(FI))
80750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    Offset -= AFI->getGPRCalleeSavedArea1Offset();
80850f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  else if (AFI->isGPRCalleeSavedArea2Frame(FI))
80950f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    Offset -= AFI->getGPRCalleeSavedArea2Offset();
81050f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  else if (AFI->isDPRCalleeSavedAreaFrame(FI))
81150f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    Offset -= AFI->getDPRCalleeSavedAreaOffset();
81250f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  else if (needsStackRealignment(MF)) {
81350f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    // When dynamically realigning the stack, use the frame pointer for
81450f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    // parameters, and the stack pointer for locals.
81550f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    assert (hasFP(MF) && "dynamic stack realignment without a FP!");
81650f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    if (isFixed) {
81750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      FrameReg = getFrameRegister(MF);
81850f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      Offset -= AFI->getFramePtrSpillOffset();
81950f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    }
82050f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  } else if (hasFP(MF) && AFI->hasStackFrame()) {
82150f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    if (isFixed || MFI->hasVarSizedObjects()) {
82250f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      // Use frame pointer to reference fixed objects unless this is a
82350f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      // frameless function.
82450f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      FrameReg = getFrameRegister(MF);
82550f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      Offset -= AFI->getFramePtrSpillOffset();
82650f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    } else if (AFI->isThumb2Function()) {
82750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      // In Thumb2 mode, the negative offset is very limited.
82850f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      int FPOffset = Offset - AFI->getFramePtrSpillOffset();
82950f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      if (FPOffset >= -255 && FPOffset < 0) {
83050f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach        FrameReg = getFrameRegister(MF);
83150f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach        Offset = FPOffset;
83250f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach      }
83350f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    }
83450f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  }
83550f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  return Offset;
83650f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach}
83750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach
83850f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach
83950f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbachint
84030c6b75ac2eef548c18110a38c9798ea5314cabaChris LattnerARMBaseRegisterInfo::getFrameIndexOffset(const MachineFunction &MF,
84130c6b75ac2eef548c18110a38c9798ea5314cabaChris Lattner                                         int FI) const {
84250f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  unsigned FrameReg;
84350f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  return getFrameIndexReference(MF, FI, FrameReg);
84450f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach}
84550f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach
846c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
847c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception register");
848c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
849c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
850c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
851c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
852c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception handler register");
853c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
854c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
855c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
856c140c4803dc3e10e08138670829bc0494986abe9David Goodwinint ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
857c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
858c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
859c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
860c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
8619631864688c593711f82bb8d21f8b724c628d786Jim Grosbach                                              const MachineFunction &MF) const {
862c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
863c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
864c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
865c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
866c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R1:
867c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R0;
868c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R3:
8696009751244909c277e6cee8e74a4ccf1846953bcJim Grosbach    return ARM::R2;
870c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R5:
871c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R4;
872c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
873c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R6;
874c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
875c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R8;
876c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
877c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
878c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
879c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S1:
880c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S0;
881c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S3:
882c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S2;
883c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S5:
884c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S4;
885c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S7:
886c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S6;
887c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S9:
888c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S8;
889c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S11:
890c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S10;
891c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S13:
892c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S12;
893c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S15:
894c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S14;
895c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S17:
896c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S16;
897c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S19:
898c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S18;
899c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S21:
900c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S20;
901c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S23:
902c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S22;
903c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S25:
904c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S24;
905c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S27:
906c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S26;
907c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S29:
908c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S28;
909c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S31:
910c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S30;
911c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
912c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D1:
913c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D0;
914c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D3:
915c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D2;
916c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D5:
917c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D4;
918c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D7:
919c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D6;
920c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D9:
921c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D8;
922c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D11:
923c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D10;
924c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D13:
925c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D12;
926c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D15:
927c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D14;
9288295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D17:
9298295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D16;
9308295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D19:
9318295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D18;
9328295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D21:
9338295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D20;
9348295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D23:
9358295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D22;
9368295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D25:
9378295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D24;
9388295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D27:
9398295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D26;
9408295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D29:
9418295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D28;
9428295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D31:
9438295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D30;
944c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
945c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
946c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
947c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
948c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
949c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
950c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                             const MachineFunction &MF) const {
951c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
952c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
953c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
954c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
955c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R0:
956c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R1;
957c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R2:
9586009751244909c277e6cee8e74a4ccf1846953bcJim Grosbach    return ARM::R3;
959c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R4:
960c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R5;
961c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R6:
962c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R7;
963c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R8:
964c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R9;
965c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R10:
966c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
967c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
968c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S0:
969c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S1;
970c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S2:
971c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S3;
972c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S4:
973c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S5;
974c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S6:
975c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S7;
976c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S8:
977c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S9;
978c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S10:
979c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S11;
980c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S12:
981c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S13;
982c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S14:
983c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S15;
984c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S16:
985c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S17;
986c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S18:
987c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S19;
988c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S20:
989c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S21;
990c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S22:
991c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S23;
992c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S24:
993c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S25;
994c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S26:
995c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S27;
996c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S28:
997c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S29;
998c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S30:
999c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S31;
1000c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1001c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D0:
1002c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D1;
1003c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D2:
1004c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D3;
1005c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D4:
1006c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D5;
1007c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D6:
1008c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D7;
1009c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D8:
1010c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D9;
1011c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D10:
1012c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D11;
1013c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D12:
1014c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D13;
1015c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D14:
1016c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D15;
10178295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D16:
10188295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D17;
10198295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D18:
10208295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D19;
10218295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D20:
10228295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D21;
10238295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D22:
10248295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D23;
10258295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D24:
10268295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D25;
10278295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D26:
10288295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D27;
10298295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D28:
10308295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D29;
10318295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D30:
10328295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D31;
1033c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
1034c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1035c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
1036c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
1037c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
1038db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitLoadConstPool - Emits a load from constpool to materialize the
1039db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// specified immediate.
1040db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1041db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitLoadConstPool(MachineBasicBlock &MBB,
1042db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  MachineBasicBlock::iterator &MBBI,
104377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                  DebugLoc dl,
1044378445303b10b092a898a75131141a8259cff50bEvan Cheng                  unsigned DestReg, unsigned SubIdx, int Val,
1045db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  ARMCC::CondCodes Pred,
1046db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  unsigned PredReg) const {
1047db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFunction &MF = *MBB.getParent();
1048db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineConstantPool *ConstantPool = MF.getConstantPool();
10491d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson  Constant *C =
10501d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson        ConstantInt::get(Type::getInt32Ty(MF.getFunction()->getContext()), Val);
1051db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
1052db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1053378445303b10b092a898a75131141a8259cff50bEvan Cheng  BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
1054378445303b10b092a898a75131141a8259cff50bEvan Cheng    .addReg(DestReg, getDefRegState(true), SubIdx)
1055db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addConstantPoolIndex(Idx)
1056db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
1057db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1058db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1059db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
1060db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinrequiresRegisterScavenging(const MachineFunction &MF) const {
1061db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return true;
1062db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
106341fff8c19ab6d8e28f5362481c184ad628f8c704Jim Grosbach
10647e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbachbool ARMBaseRegisterInfo::
10657e831db1d4f5dc51ca6526739cf41e59895c5c20Jim GrosbachrequiresFrameIndexScavenging(const MachineFunction &MF) const {
1066ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach  return true;
10677e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach}
1068db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1069db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
1070db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// not required, we reserve argument space for call sites in the function
1071db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// immediately on entry to the current function. This eliminates the need for
1072db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// add/sub sp brackets around call sites. Returns true if the call frame is
1073db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// included as part of the stack frame.
1074db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
1075db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinhasReservedCallFrame(MachineFunction &MF) const {
1076db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  const MachineFrameInfo *FFI = MF.getFrameInfo();
1077db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned CFSize = FFI->getMaxCallFrameSize();
1078db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // It's not always a good idea to include the call frame as part of the
1079db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // stack frame. ARM (especially Thumb) has small immediate offset to
1080db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // address the stack frame. So a large call frame can cause poor codegen
1081db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // and may even makes it impossible to scavenge a register.
1082db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (CFSize >= ((1 << 12) - 1) / 2)  // Half of imm12
1083db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    return false;
1084db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1085db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return !MF.getFrameInfo()->hasVarSizedObjects();
1086db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1087db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
10884642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach// canSimplifyCallFramePseudos - If there is a reserved call frame, the
10894642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach// call frame pseudos can be simplified. Unlike most targets, having a FP
10904642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach// is not sufficient here since we still may reference some objects via SP
10914642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach// even when FP is available in Thumb2 mode.
10924642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbachbool ARMBaseRegisterInfo::
10934642ad3af1cf508ac320b9afd25b065f08b36574Jim GrosbachcanSimplifyCallFramePseudos(MachineFunction &MF) const {
10944642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
10954642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach  return hasReservedCallFrame(MF) || (AFI->isThumb1OnlyFunction() && hasFP(MF));
10964642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach}
10974642ad3af1cf508ac320b9afd25b065f08b36574Jim Grosbach
1098db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void
10996495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengemitSPUpdate(bool isARM,
11006495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
11016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng             DebugLoc dl, const ARMBaseInstrInfo &TII,
1102db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             int NumBytes,
1103db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
11046495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (isARM)
11056495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
11066495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                            Pred, PredReg, TII);
11076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else
11086495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
11096495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng                           Pred, PredReg, TII);
1110db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1111db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
11126495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
1113db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1114db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1115db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                              MachineBasicBlock::iterator I) const {
1116db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!hasReservedCallFrame(MF)) {
1117db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // If we have alloca, convert as follows:
1118db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
1119db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKUP   -> add, sp, sp, amount
1120db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstr *Old = I;
1121db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    DebugLoc dl = Old->getDebugLoc();
1122db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Amount = Old->getOperand(0).getImm();
1123db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Amount != 0) {
1124db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // We need to keep the stack aligned properly.  To do this, we round the
1125db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // amount of space needed for the outgoing arguments up to the next
1126db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // alignment boundary.
1127db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
1128db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Amount = (Amount+Align-1)/Align*Align;
1129db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
11306495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
11316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      assert(!AFI->isThumb1OnlyFunction() &&
1132cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach             "This eliminateCallFramePseudoInstr does not support Thumb1!");
11336495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      bool isARM = !AFI->isThumbFunction();
11346495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
1135db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the pseudo instruction with a new instruction...
1136db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Opc = Old->getOpcode();
11374c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      int PIdx = Old->findFirstPredOperandIdx();
11384c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach      ARMCC::CondCodes Pred = (PIdx == -1)
11394c7628e43d8468f215ea345545479b6d728cee92Jim Grosbach        ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
1140db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
1141db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
1142db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(2).getReg();
11436495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
1144db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
1145db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 3 for ADJCALLSTACKUP.
1146db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(3).getReg();
1147db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
11486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
1149db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1150db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1151db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1152db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MBB.erase(I);
1153db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1154db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1155b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbachunsigned
11566495f63945e8dbde81f03a1dc2ab421993b9a495Evan ChengARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
1157b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach                                         int SPAdj, int *Value,
1158b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach                                         RegScavenger *RS) const {
11595ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  unsigned i = 0;
11605ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineInstr &MI = *II;
11615ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineBasicBlock &MBB = *MI.getParent();
11625ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  MachineFunction &MF = *MBB.getParent();
11635ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
11646495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  assert(!AFI->isThumb1OnlyFunction() &&
1165a15de00f8246f19180b26ee5fe7ff8f436e0de08Bob Wilson         "This eliminateFrameIndex does not support Thumb1!");
11665ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
11675ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  while (!MI.getOperand(i).isFI()) {
11685ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    ++i;
11695ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
11705ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  }
11715ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
11725ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin  int FrameIndex = MI.getOperand(i).getIndex();
1173a37aa546224ec03ba1f1a1598e0781af4b692673Jim Grosbach  unsigned FrameReg;
11745ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
11755a0815fae849038c0f125d04ea948785f52d35ccJim Grosbach  int Offset = getFrameIndexReference(MF, FrameIndex, FrameReg);
117650f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach  if (FrameReg != ARM::SP)
117750f8516d2dd87e6c02a46fa349b75101f9db8619Jim Grosbach    SPAdj = 0;
11785a0815fae849038c0f125d04ea948785f52d35ccJim Grosbach  Offset += SPAdj;
11795ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
118048d8afab73d72418cf9505a020f621014920463cEvan Cheng  // Modify MI as necessary to handle as much of 'Offset' as possible
1181cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  bool Done = false;
11826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  if (!AFI->isThumbFunction())
1183cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
11846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
11856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    assert(AFI->isThumb2Function());
1186cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
11876495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
1188cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Done)
1189b58f498f7502e7e1833decbbbb4df771367c7341Jim Grosbach    return 0;
11905ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin
1191db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // If we get here, the immediate doesn't fit into the instruction.  We folded
1192db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // as much as possible above, handle the rest, providing a register that is
1193db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // SP+LargeImm.
119419bb87d0f80f3e6eed38a9fa267bf2b0474aeaabDaniel Dunbar  assert((Offset ||
1195a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode4 ||
1196a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach          (MI.getDesc().TSFlags & ARMII::AddrModeMask) == ARMII::AddrMode6) &&
1197cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng         "This code isn't needed if offset already handled!");
1198db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
11997e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach  unsigned ScratchReg = 0;
1200db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int PIdx = MI.findFirstPredOperandIdx();
1201db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMCC::CondCodes Pred = (PIdx == -1)
1202db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1203db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1204cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng  if (Offset == 0)
1205a44321776ecd96fa0344335d3027758be3386e45Jim Grosbach    // Must be addrmode4/6.
1206cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
12076495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  else {
1208ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach    ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass);
1209ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach    if (Value) *Value = Offset;
1210cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    if (!AFI->isThumbFunction())
1211cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1212cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                              Offset, Pred, PredReg, TII);
1213cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    else {
1214cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      assert(AFI->isThumb2Function());
1215cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng      emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
1216cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng                             Offset, Pred, PredReg, TII);
1217cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    }
1218cdbb3f5d3311e0f46d22bc8daa211b2fab3541cbEvan Cheng    MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1219ca5dfb71ba4aa4a8392a021ec056cf0b70f74f1eJim Grosbach    if (!ReuseFrameIndexVals)
122018ed9c9a2bd7f1f56129495b499264c58b5cc4f4Jim Grosbach      ScratchReg = 0;
12216495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  }
12227e831db1d4f5dc51ca6526739cf41e59895c5c20Jim Grosbach  return ScratchReg;
1223db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1224db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
12254371cda7f8fc21fc3192ead122ba48b0152fb0e4Jim Grosbach/// Move iterator past the next bunch of callee save load / store ops for
1226db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// the particular spill area (1: integer area 1, 2: integer area 2,
1227db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// 3: fp area, 0: don't care).
1228db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
1229db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                                   MachineBasicBlock::iterator &MBBI,
12305ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin                                   int Opc1, int Opc2, unsigned Area,
1231db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                                   const ARMSubtarget &STI) {
1232db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  while (MBBI != MBB.end() &&
12335ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin         ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2)) &&
12345ff58b5c3ab6df332600678798ea5c69c5e943d3David Goodwin         MBBI->getOperand(1).isFI()) {
1235db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Area != 0) {
1236db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      bool Done = false;
1237db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Category = 0;
1238db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      switch (MBBI->getOperand(0).getReg()) {
1239db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::R4:  case ARM::R5:  case ARM::R6: case ARM::R7:
1240db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::LR:
1241db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = 1;
1242db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1243db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::R8:  case ARM::R9:  case ARM::R10: case ARM::R11:
1244db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = STI.isTargetDarwin() ? 2 : 1;
1245db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1246db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::D8:  case ARM::D9:  case ARM::D10: case ARM::D11:
1247db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
1248db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = 3;
1249db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1250db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      default:
1251db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Done = true;
1252db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1253db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1254db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Done || Category != Area)
1255db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1256db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1257db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1258db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ++MBBI;
1259db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1260db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1261db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1262db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1263db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitPrologue(MachineFunction &MF) const {
1264db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock &MBB = MF.front();
1265db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock::iterator MBBI = MBB.begin();
1266db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFrameInfo  *MFI = MF.getFrameInfo();
1267db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
12686495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  assert(!AFI->isThumb1OnlyFunction() &&
1269cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach         "This emitPrologue does not support Thumb1!");
12706495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  bool isARM = !AFI->isThumbFunction();
1271db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1272db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned NumBytes = MFI->getStackSize();
1273db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
1274db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  DebugLoc dl = (MBBI != MBB.end() ?
1275db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
1276db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1277db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Determine the sizes of each callee-save spill areas and record which frame
1278db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // belongs to which callee-save spill areas.
1279db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
1280db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int FramePtrSpillFI = 0;
1281db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1282c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // Allocate the vararg register save area. This is not counted in NumBytes.
1283db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (VARegSaveSize)
12846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize);
1285db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1286db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!AFI->hasStackFrame()) {
1287db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (NumBytes != 0)
12886495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
1289db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    return;
1290db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1291db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1292db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1293db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Reg = CSI[i].getReg();
1294db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    int FI = CSI[i].getFrameIdx();
1295db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    switch (Reg) {
1296db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R4:
1297db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R5:
1298db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R6:
1299db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R7:
1300db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::LR:
1301db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Reg == FramePtr)
1302db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        FramePtrSpillFI = FI;
1303db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      AFI->addGPRCalleeSavedArea1Frame(FI);
1304db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      GPRCS1Size += 4;
1305db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1306db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R8:
1307db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R9:
1308db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R10:
1309db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R11:
1310db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Reg == FramePtr)
1311db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        FramePtrSpillFI = FI;
1312db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (STI.isTargetDarwin()) {
1313db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        AFI->addGPRCalleeSavedArea2Frame(FI);
1314db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        GPRCS2Size += 4;
1315db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
1316db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        AFI->addGPRCalleeSavedArea1Frame(FI);
1317db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        GPRCS1Size += 4;
1318db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1319db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1320db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    default:
1321db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      AFI->addDPRCalleeSavedAreaFrame(FI);
1322db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      DPRCSSize += 8;
1323db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1324db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1325db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1326db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for integer callee-save spill area 1.
13276495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS1Size);
13285732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng  movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI);
1329db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1330c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // Set FP to point to the stack slot that contains the previous FP.
1331c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // For Darwin, FP is R7, which has now been stored in spill area 1.
1332c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // Otherwise, if this is not Darwin, all the callee-saved registers go
1333c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // into spill area 1, including the FP in R11.  In either case, it is
1334c8ce2d4cb9ef5ff8b3c574e522c870741d88ba58Bob Wilson  // now safe to emit this assignment.
1335db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (STI.isTargetDarwin() || hasFP(MF)) {
13366495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
1337db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstrBuilder MIB =
13386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
1339db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      .addFrameIndex(FramePtrSpillFI).addImm(0);
1340db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    AddDefaultCC(AddDefaultPred(MIB));
1341db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1342db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1343db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for integer callee-save spill area 2.
13446495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS2Size);
1345db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1346db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for FP callee-save spill area.
13475732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng  movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 2, STI);
13486495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize);
1349db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1350db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Determine starting offsets of spill areas.
1351db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
1352db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
1353db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
1354db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
1355db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
1356db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
1357db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1358db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1359e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  movePastCSLoadStoreOps(MBB, MBBI, ARM::VSTRD, 0, 3, STI);
1360db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  NumBytes = DPRCSOffset;
1361db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (NumBytes) {
1362c5848f4ced8f9174e7141c0d2589acaafa13ff35Jim Grosbach    // Adjust SP after all the callee-save spills.
13636495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
1364db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1365db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1366db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (STI.isTargetELF() && hasFP(MF)) {
1367db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
1368db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             AFI->getFramePtrSpillOffset());
1369db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1370db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1371db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
1372db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
1373db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
13743dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach
13753dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  // If we need dynamic stack realignment, do it here.
13763dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  if (needsStackRealignment(MF)) {
13773dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach    unsigned MaxAlign = MFI->getMaxAlignment();
13783dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach    assert (!AFI->isThumb1OnlyFunction());
13797cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov    if (!AFI->isThumbFunction()) {
13807cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // Emit bic sp, sp, MaxAlign
13817cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
13827cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov                                          TII.get(ARM::BICri), ARM::SP)
13833dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach                                  .addReg(ARM::SP, RegState::Kill)
13843dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach                                  .addImm(MaxAlign-1)));
13857cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov    } else {
13867cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // We cannot use sp as source/dest register here, thus we're emitting the
13877cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // following sequence:
13887cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // mov r4, sp
13897cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // bic r4, r4, MaxAlign
13907cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // mov sp, r4
13917cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      // FIXME: It will be better just to find spare register here.
1392e9912dc553bf7e37494eb9b07e8ff880f0481a56Jakob Stoklund Olesen      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2tgpr), ARM::R4)
13937cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov        .addReg(ARM::SP, RegState::Kill);
13947cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl,
13957cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov                                          TII.get(ARM::t2BICri), ARM::R4)
13967cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov                                  .addReg(ARM::R4, RegState::Kill)
13977cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov                                  .addImm(MaxAlign-1)));
13987cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov      BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
13997cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov        .addReg(ARM::R4, RegState::Kill);
14007cca606aaa6fee6ff4f548aa3686608b6be1f208Anton Korobeynikov    }
14013dab2778571b5bb00b35a0adcb7011dc85158bebJim Grosbach  }
1402db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1403db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1404db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
1405db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  for (unsigned i = 0; CSRegs[i]; ++i)
1406db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Reg == CSRegs[i])
1407db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      return true;
1408db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return false;
1409db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1410db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
141177521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwinstatic bool isCSRestore(MachineInstr *MI,
1412764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach                        const ARMBaseInstrInfo &TII,
141377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                        const unsigned *CSRegs) {
1414e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  return ((MI->getOpcode() == (int)ARM::VLDRD ||
14155732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng           MI->getOpcode() == (int)ARM::LDR ||
14165732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng           MI->getOpcode() == (int)ARM::t2LDRi12) &&
1417db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          MI->getOperand(1).isFI() &&
1418db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
1419db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1420db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1421db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1422293f8d9b8800ab68c64b67f38a7f76e00126715dEvan ChengemitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
1423db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock::iterator MBBI = prior(MBB.end());
14245ca53a7ad821613d324e4189ddbb0d468a326146Evan Cheng  assert(MBBI->getDesc().isReturn() &&
1425db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin         "Can only insert epilog into returning blocks");
1426db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  DebugLoc dl = MBBI->getDebugLoc();
1427db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFrameInfo *MFI = MF.getFrameInfo();
1428db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
14296495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  assert(!AFI->isThumb1OnlyFunction() &&
1430cf453ee70a1ae03cc641686fd5db0f8a7d8ce250Jim Grosbach         "This emitEpilogue does not support Thumb1!");
14316495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng  bool isARM = !AFI->isThumbFunction();
14326495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng
1433db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1434db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int NumBytes = (int)MFI->getStackSize();
1435db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1436db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!AFI->hasStackFrame()) {
1437db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (NumBytes != 0)
14386495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
1439db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  } else {
1440e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach    // Unwind MBBI to point to first LDR / VLDRD.
1441db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    const unsigned *CSRegs = getCalleeSavedRegs();
1442db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (MBBI != MBB.begin()) {
1443db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      do
1444db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        --MBBI;
144577521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
144677521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      if (!isCSRestore(MBBI, TII, CSRegs))
1447db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        ++MBBI;
1448db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1449db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1450db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of FP callee save spill area.
1451db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
1452db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 AFI->getGPRCalleeSavedArea2Size() +
1453db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 AFI->getDPRCalleeSavedAreaSize());
1454db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1455db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Darwin ABI requires FP to point to the stack slot that contains the
1456db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // previous FP.
1457010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng    bool HasFP = hasFP(MF);
1458010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng    if ((STI.isTargetDarwin() && NumBytes) || HasFP) {
1459db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1460db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Reset SP based on frame pointer only if the stack frame extends beyond
1461db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // frame pointer stack slot or target is ELF and the function has FP.
1462010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng      if (HasFP ||
1463010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng          AFI->getGPRCalleeSavedArea2Size() ||
1464db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          AFI->getDPRCalleeSavedAreaSize()  ||
1465010b1b9e7b11bced0b277a4d808226ba2af3044aEvan Cheng          AFI->getDPRCalleeSavedAreaOffset()) {
14666495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        if (NumBytes) {
1467861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng          if (isARM)
1468861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng            emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
1469861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng                                    ARMCC::AL, 0, TII);
1470861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng          else
1471861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng            emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
1472861986401e05e437cb33bfd8320d510b956fe41eEvan Cheng                                    ARMCC::AL, 0, TII);
14736495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        } else {
14746495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng          // Thumb2 or ARM.
1475764ab52dd80310a205c9888bf166d09dab858f90Jim Grosbach          if (isARM)
1476052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng            BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
1477052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng              .addReg(FramePtr)
1478052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng              .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1479052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng          else
1480052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng            BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
1481052053bbe3169a3574cb5af026cf0a5d616ae04dEvan Cheng              .addReg(FramePtr);
14826495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng        }
1483db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
14846495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    } else if (NumBytes)
14856495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng      emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
1486db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1487db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of integer callee save spill area 2.
1488e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach    movePastCSLoadStoreOps(MBB, MBBI, ARM::VLDRD, 0, 3, STI);
14896495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
1490db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1491db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of integer callee save spill area 1.
14925732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng    movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 2, STI);
14936495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea2Size());
1494db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1495db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to SP upon entry to the function.
14965732ca084aaa0cd26149e50dd4b487efff37fe41Evan Cheng    movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, ARM::t2LDRi12, 1, STI);
14976495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea1Size());
1498db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1499db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1500db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (VARegSaveSize)
15016495f63945e8dbde81f03a1dc2ab421993b9a495Evan Cheng    emitSPUpdate(isARM, MBB, MBBI, dl, TII, VARegSaveSize);
1502db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1503db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1504c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMGenRegisterInfo.inc"
1505