ARMBaseRegisterInfo.cpp revision 8295d99bff6f8e3dfdfdaf1871cb72adab423f20
1c140c4803dc3e10e08138670829bc0494986abe9David Goodwin//===- 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"
32ab7c09b6b6f4516a631fd6788918c237c83939afTorok Edwin#include "llvm/Support/ErrorHandling.h"
33dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
34c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetFrameInfo.h"
35c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetMachine.h"
36c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/Target/TargetOptions.h"
37c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/BitVector.h"
38c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "llvm/ADT/SmallVector.h"
39c140c4803dc3e10e08138670829bc0494986abe9David Goodwinusing namespace llvm;
40c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
41c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum,
428295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng                                                   bool *isSPVFP) {
438295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  if (isSPVFP)
448295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    *isSPVFP = false;
45c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
46c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  using namespace ARM;
47c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (RegEnum) {
48c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default:
49c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unknown ARM register!");
508295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R0:  case D0:  case Q0:  return 0;
518295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R1:  case D1:  case Q1:  return 1;
528295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R2:  case D2:  case Q2:  return 2;
538295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R3:  case D3:  case Q3:  return 3;
548295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R4:  case D4:  case Q4:  return 4;
558295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R5:  case D5:  case Q5:  return 5;
568295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R6:  case D6:  case Q6:  return 6;
578295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R7:  case D7:  case Q7:  return 7;
588295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R8:  case D8:  case Q8:  return 8;
598295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R9:  case D9:  case Q9:  return 9;
608295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R10: case D10: case Q10: return 10;
618295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R11: case D11: case Q11: return 11;
628295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case R12: case D12: case Q12: return 12;
638295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case SP:  case D13: case Q13: return 13;
648295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case LR:  case D14: case Q14: return 14;
658295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case PC:  case D15: case Q15: return 15;
668295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng
678295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D16: return 16;
688295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D17: return 17;
698295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D18: return 18;
708295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D19: return 19;
718295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D20: return 20;
728295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D21: return 21;
738295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D22: return 22;
748295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D23: return 23;
758295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D24: return 24;
768295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D25: return 25;
778295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D26: return 27;
788295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D27: return 27;
798295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D28: return 28;
808295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D29: return 29;
818295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D30: return 30;
828295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case D31: return 31;
83c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
84c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S0: case S1: case S2: case S3:
85c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S4: case S5: case S6: case S7:
86c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S8: case S9: case S10: case S11:
87c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S12: case S13: case S14: case S15:
88c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S16: case S17: case S18: case S19:
89c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S20: case S21: case S22: case S23:
90c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case S24: case S25: case S26: case S27:
918295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case S28: case S29: case S30: case S31: {
928295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    if (isSPVFP)
938295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng      *isSPVFP = true;
94c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    switch (RegEnum) {
95c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    default: return 0; // Avoid compile time warning.
96c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S0: return 0;
97c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S1: return 1;
98c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S2: return 2;
99c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S3: return 3;
100c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S4: return 4;
101c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S5: return 5;
102c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S6: return 6;
103c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S7: return 7;
104c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S8: return 8;
105c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S9: return 9;
106c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S10: return 10;
107c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S11: return 11;
108c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S12: return 12;
109c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S13: return 13;
110c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S14: return 14;
111c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S15: return 15;
112c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S16: return 16;
113c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S17: return 17;
114c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S18: return 18;
115c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S19: return 19;
116c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S20: return 20;
117c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S21: return 21;
118c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S22: return 22;
119c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S23: return 23;
120c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S24: return 24;
121c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S25: return 25;
122c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S26: return 26;
123c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S27: return 27;
124c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S28: return 28;
125c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S29: return 29;
126c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S30: return 30;
127c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    case S31: return 31;
128c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
129c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
130c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
131c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
132c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
133db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
134c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const ARMSubtarget &sti)
135c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
136c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    TII(tii), STI(sti),
137c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) {
138c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
139c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
14077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwinunsigned ARMBaseRegisterInfo::
14177521f5232e679aa3de10aaaed2464aa91d7ff55David GoodwingetOpcode(int Op) const {
14277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  return TII.getOpcode((ARMII::Op)Op);
14377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin}
14477521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin
145c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst unsigned*
146c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
147c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned CalleeSavedRegs[] = {
148c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
149c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
150c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
151c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
152c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
153c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
154c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
155c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
156c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned DarwinCalleeSavedRegs[] = {
157c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Darwin ABI deviates from ARM standard ABI. R9 is not a callee-saved
158c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // register.
159c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::LR,  ARM::R7,  ARM::R6, ARM::R5, ARM::R4,
160c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11, ARM::R10, ARM::R8,
161c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
162c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
163c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
164c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
165c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
166c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
167c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
168c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
169c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst TargetRegisterClass* const *
170c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
171c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
172c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
173c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
174c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
175c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
176c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
177c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
178c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
179c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
180c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
181c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = {
182c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
183c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass,
184c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass,
185c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
186c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
187c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
188c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
189c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
190c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
191c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const DarwinCalleeSavedRegClasses[] = {
192c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
193c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
194c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass, &ARM::GPRRegClass,
195c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
196c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
197c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
198c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
199c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
200c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
201c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const TargetRegisterClass * const DarwinThumbCalleeSavedRegClasses[] ={
202c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass,  &ARM::tGPRRegClass, &ARM::tGPRRegClass,
203c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::tGPRRegClass, &ARM::tGPRRegClass, &ARM::GPRRegClass,
204c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::GPRRegClass,  &ARM::GPRRegClass,
205c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
206c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
207c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
208c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    0
209c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
210c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
211f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin  if (STI.isThumb1Only()) {
212c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isTargetDarwin()
213c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses;
214c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
215c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return STI.isTargetDarwin()
216c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
217c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
218c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
219c140c4803dc3e10e08138670829bc0494986abe9David GoodwinBitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
220c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FIXME: avoid re-calculating this everytime.
221c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  BitVector Reserved(getNumRegs());
222c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::SP);
223c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  Reserved.set(ARM::PC);
224c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isTargetDarwin() || hasFP(MF))
225c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(FramePtr);
226c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Some targets reserve R9.
227c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isR9Reserved())
228c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Reserved.set(ARM::R9);
229c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return Reserved;
230c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
231c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
232c140c4803dc3e10e08138670829bc0494986abe9David Goodwinbool
233c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
234c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
235c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
236c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::SP:
237c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::PC:
238c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return true;
239c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
240c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
241c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
242c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return true;
243c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    break;
244c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
245c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return STI.isR9Reserved();
246c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
247c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
248c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return false;
249c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
250c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
251c140c4803dc3e10e08138670829bc0494986abe9David Goodwinconst TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const {
252c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return &ARM::GPRRegClass;
253c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
254c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
255c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// getAllocationOrder - Returns the register allocation order for a specified
256c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// register class in the form of a pair of TargetRegisterClass iterators.
257c140c4803dc3e10e08138670829bc0494986abe9David Goodwinstd::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
258c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
259c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        unsigned HintType, unsigned HintReg,
260c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        const MachineFunction &MF) const {
261c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Alternative register allocation orders when favoring even / odd registers
262c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // of register pairs.
263c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
264c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is available.
265c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven1[] = {
266c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10,
267c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7,
268c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
269c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
270c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd1[] = {
271c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7, ARM::R9, ARM::R11,
272c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
273c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
274c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
275c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
276c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is available.
277c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven2[] = {
278c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,          ARM::R8, ARM::R10,
279c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6,
280c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9, ARM::R11
281c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
282c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd2[] = {
283c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,          ARM::R9, ARM::R11,
284c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6,
285c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8, ARM::R10
286c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
287c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
288c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is available.
289c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven3[] = {
290c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8,
291c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7,
292c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R9
293c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
294c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd3[] = {
295c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R6, ARM::R9,
296c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R7,
297c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R8
298c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
299c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
300c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // No FP, R9 is not available.
301c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven4[] = {
302c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,          ARM::R10,
303c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8,
304c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
305c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
306c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd4[] = {
307c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,          ARM::R11,
308c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
309c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
310c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
311c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
312c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R7, R9 is not available.
313c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven5[] = {
314c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4,                   ARM::R10,
315c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R6, ARM::R8,
316c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R11
317c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
318c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd5[] = {
319c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5,                   ARM::R11,
320c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8,
321c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R10
322c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
323c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
324c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // FP is R11, R9 is not available.
325c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPREven6[] = {
326c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R4, ARM::R6,
327c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R10,ARM::R12,ARM::LR, ARM::R5, ARM::R7, ARM::R8
328c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
329c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  static const unsigned GPROdd6[] = {
330c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R1, ARM::R3, ARM::R5, ARM::R7,
331c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    ARM::R0, ARM::R2, ARM::R10,ARM::R12,ARM::LR, ARM::R4, ARM::R6, ARM::R8
332c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  };
333c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
334c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
335c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (HintType == ARMRI::RegPairEven) {
336c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairEven(HintReg, MF) == 0)
337c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
338c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
339c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return std::make_pair(RC->allocation_order_begin(MF),
340c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                            RC->allocation_order_end(MF));
341c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
342c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!STI.isTargetDarwin() && !hasFP(MF)) {
343c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
344c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven1,
345c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
346c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
347c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven4,
348c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven4 + (sizeof(GPREven4)/sizeof(unsigned)));
349c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
350c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
351c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven2,
352c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven2 + (sizeof(GPREven2)/sizeof(unsigned)));
353c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
354c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven5,
355c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven5 + (sizeof(GPREven5)/sizeof(unsigned)));
356c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
357c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
358c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven3,
359c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven3 + (sizeof(GPREven3)/sizeof(unsigned)));
360c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
361c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPREven6,
362c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPREven6 + (sizeof(GPREven6)/sizeof(unsigned)));
363c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
364c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  } else if (HintType == ARMRI::RegPairOdd) {
365c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0)
366c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // It's no longer possible to fulfill this hint. Return the default
367c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // allocation order.
368c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      return std::make_pair(RC->allocation_order_begin(MF),
369c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                            RC->allocation_order_end(MF));
370c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
371c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!STI.isTargetDarwin() && !hasFP(MF)) {
372c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
373c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd1,
374c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
375c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
376c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd4,
377c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd4 + (sizeof(GPROdd4)/sizeof(unsigned)));
378c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else if (FramePtr == ARM::R7) {
379c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
380c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd2,
381c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd2 + (sizeof(GPROdd2)/sizeof(unsigned)));
382c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
383c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd5,
384c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd5 + (sizeof(GPROdd5)/sizeof(unsigned)));
385c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else { // FramePtr == ARM::R11
386c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (!STI.isR9Reserved())
387c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd3,
388c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd3 + (sizeof(GPROdd3)/sizeof(unsigned)));
389c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      else
390c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        return std::make_pair(GPROdd6,
391c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                              GPROdd6 + (sizeof(GPROdd6)/sizeof(unsigned)));
392c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
393c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
394c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return std::make_pair(RC->allocation_order_begin(MF),
395c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                        RC->allocation_order_end(MF));
396c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
397c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
398c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// ResolveRegAllocHint - Resolves the specified register allocation hint
399c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// to a physical register. Returns the physical register if it is successful.
400c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned
401c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg,
402c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                         const MachineFunction &MF) const {
403c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Reg == 0 || !isPhysicalRegister(Reg))
404c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return 0;
405c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (Type == 0)
406c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return Reg;
407c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairOdd)
408c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Odd register.
409c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairOdd(Reg, MF);
410c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  else if (Type == (unsigned)ARMRI::RegPairEven)
411c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Even register.
412c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return getRegisterPairEven(Reg, MF);
413c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
414c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
415c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
416c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
417c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
418c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                        MachineFunction &MF) const {
419c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  MachineRegisterInfo *MRI = &MF.getRegInfo();
420c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg);
421c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if ((Hint.first == (unsigned)ARMRI::RegPairOdd ||
422c140c4803dc3e10e08138670829bc0494986abe9David Goodwin       Hint.first == (unsigned)ARMRI::RegPairEven) &&
423c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) {
424c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If 'Reg' is one of the even / odd register pair and it's now changed
425c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // (e.g. coalesced) into a different register. The other register of the
426c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // pair allocation hint must be updated to reflect the relationship
427c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // change.
428c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned OtherReg = Hint.second;
429c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Hint = MRI->getRegAllocationHint(OtherReg);
430c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (Hint.second == Reg)
431c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Make sure the pair has not already divorced.
432c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg);
433c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
434c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
435c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
436c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// hasFP - Return true if the specified function should have a dedicated frame
437c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// pointer register.  This is true if the function has variable sized allocas
438c140c4803dc3e10e08138670829bc0494986abe9David Goodwin/// or if frame pointer elimination is disabled.
439c140c4803dc3e10e08138670829bc0494986abe9David Goodwin///
440c140c4803dc3e10e08138670829bc0494986abe9David Goodwinbool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
441c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const MachineFrameInfo *MFI = MF.getFrameInfo();
442c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return (NoFramePointerElim ||
443c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          MFI->hasVarSizedObjects() ||
444c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          MFI->isFrameAddressTaken());
445c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
446c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
447c140c4803dc3e10e08138670829bc0494986abe9David Goodwinstatic unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
448c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const MachineFrameInfo *FFI = MF.getFrameInfo();
449c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  int Offset = 0;
450c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
451c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    int FixedOff = -FFI->getObjectOffset(i);
452c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FixedOff > Offset) Offset = FixedOff;
453c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
454c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
455c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FFI->isDeadObjectIndex(i))
456c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      continue;
457c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Offset += FFI->getObjectSize(i);
458c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned Align = FFI->getObjectAlignment(i);
459c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Adjust to alignment boundary
460c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    Offset = (Offset+Align-1)/Align*Align;
461c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
462c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return (unsigned)Offset;
463c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
464c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
465c140c4803dc3e10e08138670829bc0494986abe9David Goodwinvoid
466c140c4803dc3e10e08138670829bc0494986abe9David GoodwinARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
467c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                                          RegScavenger *RS) const {
468c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // This tells PEI to spill the FP as if it is any other callee-save register
469c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // to take advantage the eliminateFrameIndex machinery. This also ensures it
470c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // is spilled in the order specified by getCalleeSavedRegs() to make it easier
471c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // to combine multiple loads / stores.
472c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool CanEliminateFrame = true;
473c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool CS1Spilled = false;
474c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool LRSpilled = false;
475c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  unsigned NumGPRSpills = 0;
476c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  SmallVector<unsigned, 4> UnspilledCS1GPRs;
477c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  SmallVector<unsigned, 4> UnspilledCS2GPRs;
478c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
479c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
480c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Don't spill FP if the frame can be eliminated. This is determined
481c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // by scanning the callee-save registers to see if any is used.
482c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const unsigned *CSRegs = getCalleeSavedRegs();
483c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
484c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  for (unsigned i = 0; CSRegs[i]; ++i) {
485c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned Reg = CSRegs[i];
486c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    bool Spilled = false;
487c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (MF.getRegInfo().isPhysRegUsed(Reg)) {
488c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      AFI->setCSRegisterIsSpilled(Reg);
489c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      Spilled = true;
490c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      CanEliminateFrame = false;
491c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    } else {
492c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      // Check alias registers too.
493c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
494c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (MF.getRegInfo().isPhysRegUsed(*Aliases)) {
495c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          Spilled = true;
496c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CanEliminateFrame = false;
497c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
498c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
499c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
500c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
501c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (CSRegClasses[i] == &ARM::GPRRegClass) {
502c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (Spilled) {
503c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        NumGPRSpills++;
504c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
505c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!STI.isTargetDarwin()) {
506c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          if (Reg == ARM::LR)
507c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            LRSpilled = true;
508c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CS1Spilled = true;
509c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          continue;
510c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
511c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
512c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
513c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        switch (Reg) {
514c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::LR:
515c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          LRSpilled = true;
516c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          // Fallthrough
517c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R4:
518c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R5:
519c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R6:
520c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R7:
521c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          CS1Spilled = true;
522c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
523c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        default:
524c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
525c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
526c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      } else {
527c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!STI.isTargetDarwin()) {
528c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.push_back(Reg);
529c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          continue;
530c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
531c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
532c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        switch (Reg) {
533c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R4:
534c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R5:
535c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R6:
536c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::R7:
537c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        case ARM::LR:
538c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.push_back(Reg);
539c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
540c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        default:
541c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS2GPRs.push_back(Reg);
542c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          break;
543c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
544c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
545c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
546c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
547c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
548c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool ForceLRSpill = false;
549f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin  if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
550c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned FnSize = TII.GetFunctionSizeInBytes(MF);
551c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Force LR to be spilled if the Thumb function size is > 2048. This enables
552c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // use of BL to implement far jump. If it turns out that it's not needed
553c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // then the branch fix up path will undo it.
554c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (FnSize >= (1 << 11)) {
555c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      CanEliminateFrame = false;
556c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ForceLRSpill = true;
557c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
558c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
559c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
560c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  bool ExtraCSSpill = false;
561c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (!CanEliminateFrame || hasFP(MF)) {
562c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setHasStackFrame(true);
563c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
564c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
565c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
566c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (!LRSpilled && CS1Spilled) {
567c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MF.getRegInfo().setPhysRegUsed(ARM::LR);
568c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      AFI->setCSRegisterIsSpilled(ARM::LR);
569c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      NumGPRSpills++;
570c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
571c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
572c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ForceLRSpill = false;
573c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      ExtraCSSpill = true;
574c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
575c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
576c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Darwin ABI requires FP to point to the stack slot that contains the
577c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // previous FP.
578c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (STI.isTargetDarwin() || hasFP(MF)) {
579c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MF.getRegInfo().setPhysRegUsed(FramePtr);
580c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      NumGPRSpills++;
581c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
582c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
583c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // If stack and double are 8-byte aligned and we are spilling an odd number
584c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // of GPRs. Spill one extra callee save GPR so we won't have to pad between
585c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // the integer and double callee save areas.
586c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
587c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    if (TargetAlign == 8 && (NumGPRSpills & 1)) {
588c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
589c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
590c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          unsigned Reg = UnspilledCS1GPRs[i];
591f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin          // Don't spill high register if the function is thumb1
592f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin          if (!AFI->isThumb1OnlyFunction() ||
593c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              isARMLowRegister(Reg) || Reg == ARM::LR) {
594c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            MF.getRegInfo().setPhysRegUsed(Reg);
595c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            AFI->setCSRegisterIsSpilled(Reg);
596c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            if (!isReservedReg(MF, Reg))
597c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              ExtraCSSpill = true;
598c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            break;
599c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
600c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
601c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      } else if (!UnspilledCS2GPRs.empty() &&
602f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin                 !AFI->isThumb1OnlyFunction()) {
603c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        unsigned Reg = UnspilledCS2GPRs.front();
604c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        MF.getRegInfo().setPhysRegUsed(Reg);
605c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        AFI->setCSRegisterIsSpilled(Reg);
606c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (!isReservedReg(MF, Reg))
607c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          ExtraCSSpill = true;
608c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
609c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
610c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
611c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // Estimate if we might need to scavenge a register at some point in order
612c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // to materialize a stack offset. If so, either spill one additional
613c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // callee-saved register or reserve a special spill slot to facilitate
614c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // register scavenging.
615f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin    if (RS && !ExtraCSSpill && !AFI->isThumb1OnlyFunction()) {
616c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      MachineFrameInfo  *MFI = MF.getFrameInfo();
617c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      unsigned Size = estimateStackSize(MF, MFI);
618c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      unsigned Limit = (1 << 12) - 1;
619c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
620c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
621c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
622c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            if (I->getOperand(i).isFI()) {
623c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              unsigned Opcode = I->getOpcode();
624c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              const TargetInstrDesc &Desc = TII.get(Opcode);
625c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
626c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              if (AddrMode == ARMII::AddrMode3) {
627c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                Limit = (1 << 8) - 1;
628c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                goto DoneEstimating;
629c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              } else if (AddrMode == ARMII::AddrMode5) {
630c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                unsigned ThisLimit = ((1 << 8) - 1) * 4;
631c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                if (ThisLimit < Limit)
632c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                  Limit = ThisLimit;
633c140c4803dc3e10e08138670829bc0494986abe9David Goodwin              }
634c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            }
635c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
636c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    DoneEstimating:
637c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      if (Size >= Limit) {
638c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // If any non-reserved CS register isn't spilled, just spill one or two
639c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        // extra. That should take care of it!
640c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        unsigned NumExtras = TargetAlign / 4;
641c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        SmallVector<unsigned, 2> Extras;
642c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        while (NumExtras && !UnspilledCS1GPRs.empty()) {
643c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          unsigned Reg = UnspilledCS1GPRs.back();
644c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS1GPRs.pop_back();
645c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          if (!isReservedReg(MF, Reg)) {
646c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            Extras.push_back(Reg);
647c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            NumExtras--;
648c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
649c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
650c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        while (NumExtras && !UnspilledCS2GPRs.empty()) {
651c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          unsigned Reg = UnspilledCS2GPRs.back();
652c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          UnspilledCS2GPRs.pop_back();
653c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          if (!isReservedReg(MF, Reg)) {
654c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            Extras.push_back(Reg);
655c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            NumExtras--;
656c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
657c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
658c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        if (Extras.size() && NumExtras == 0) {
659c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
660c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            MF.getRegInfo().setPhysRegUsed(Extras[i]);
661c140c4803dc3e10e08138670829bc0494986abe9David Goodwin            AFI->setCSRegisterIsSpilled(Extras[i]);
662c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          }
663c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        } else {
664c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          // Reserve a slot closest to SP or frame pointer.
665c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          const TargetRegisterClass *RC = &ARM::GPRRegClass;
666c140c4803dc3e10e08138670829bc0494986abe9David Goodwin          RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
667c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                                           RC->getAlignment()));
668c140c4803dc3e10e08138670829bc0494986abe9David Goodwin        }
669c140c4803dc3e10e08138670829bc0494986abe9David Goodwin      }
670c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    }
671c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
672c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
673c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (ForceLRSpill) {
674c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    MF.getRegInfo().setPhysRegUsed(ARM::LR);
675c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setCSRegisterIsSpilled(ARM::LR);
676c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    AFI->setLRIsSpilledForFarJump(true);
677c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
678c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
679c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
680c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRARegister() const {
681c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::LR;
682c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
683c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
684c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const {
685c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  if (STI.isTargetDarwin() || hasFP(MF))
686c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return FramePtr;
687c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARM::SP;
688c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
689c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
690c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHExceptionRegister() const {
691c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception register");
692c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
693c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
694c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
695c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getEHHandlerRegister() const {
696c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  llvm_unreachable("What is the exception handler register");
697c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
698c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
699c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
700c140c4803dc3e10e08138670829bc0494986abe9David Goodwinint ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
701c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
702c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
703c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
704c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
705c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                               const MachineFunction &MF) const {
706c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
707c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
708c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
709c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
710c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R1:
711c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R0;
712c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R3:
713c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // FIXME!
714f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin    return STI.isThumb1Only() ? 0 : ARM::R2;
715c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R5:
716c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R4;
717c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R7:
718c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R6;
719c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R9:
720c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R8;
721c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R11:
722c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10;
723c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
724c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S1:
725c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S0;
726c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S3:
727c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S2;
728c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S5:
729c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S4;
730c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S7:
731c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S6;
732c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S9:
733c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S8;
734c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S11:
735c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S10;
736c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S13:
737c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S12;
738c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S15:
739c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S14;
740c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S17:
741c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S16;
742c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S19:
743c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S18;
744c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S21:
745c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S20;
746c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S23:
747c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S22;
748c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S25:
749c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S24;
750c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S27:
751c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S26;
752c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S29:
753c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S28;
754c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S31:
755c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S30;
756c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
757c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D1:
758c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D0;
759c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D3:
760c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D2;
761c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D5:
762c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D4;
763c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D7:
764c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D6;
765c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D9:
766c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D8;
767c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D11:
768c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D10;
769c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D13:
770c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D12;
771c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D15:
772c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D14;
7738295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D17:
7748295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D16;
7758295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D19:
7768295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D18;
7778295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D21:
7788295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D20;
7798295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D23:
7808295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D22;
7818295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D25:
7828295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D24;
7838295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D27:
7848295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D26;
7858295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D29:
7868295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D28;
7878295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D31:
7888295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D30;
789c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
790c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
791c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
792c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
793c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
794c140c4803dc3e10e08138670829bc0494986abe9David Goodwinunsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg,
795c140c4803dc3e10e08138670829bc0494986abe9David Goodwin                                             const MachineFunction &MF) const {
796c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  switch (Reg) {
797c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  default: break;
798c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // Return 0 if either register of the pair is a special register.
799c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  // So no R12, etc.
800c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R0:
801c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R1;
802c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R2:
803c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    // FIXME!
804f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin    return STI.isThumb1Only() ? 0 : ARM::R3;
805c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R4:
806c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::R5;
807c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R6:
808c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R7)  ? 0 : ARM::R7;
809c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R8:
810c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R9)  ? 0 :ARM::R9;
811c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::R10:
812c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11;
813c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
814c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S0:
815c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S1;
816c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S2:
817c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S3;
818c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S4:
819c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S5;
820c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S6:
821c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S7;
822c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S8:
823c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S9;
824c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S10:
825c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S11;
826c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S12:
827c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S13;
828c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S14:
829c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S15;
830c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S16:
831c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S17;
832c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S18:
833c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S19;
834c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S20:
835c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S21;
836c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S22:
837c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S23;
838c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S24:
839c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S25;
840c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S26:
841c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S27;
842c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S28:
843c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S29;
844c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::S30:
845c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::S31;
846c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
847c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D0:
848c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D1;
849c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D2:
850c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D3;
851c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D4:
852c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D5;
853c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D6:
854c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D7;
855c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D8:
856c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D9;
857c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D10:
858c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D11;
859c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D12:
860c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D13;
861c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  case ARM::D14:
862c140c4803dc3e10e08138670829bc0494986abe9David Goodwin    return ARM::D15;
8638295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D16:
8648295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D17;
8658295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D18:
8668295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D19;
8678295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D20:
8688295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D21;
8698295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D22:
8708295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D23;
8718295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D24:
8728295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D25;
8738295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D26:
8748295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D27;
8758295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D28:
8768295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D29;
8778295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng  case ARM::D30:
8788295d99bff6f8e3dfdfdaf1871cb72adab423f20Evan Cheng    return ARM::D31;
879c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  }
880c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
881c140c4803dc3e10e08138670829bc0494986abe9David Goodwin  return 0;
882c140c4803dc3e10e08138670829bc0494986abe9David Goodwin}
883c140c4803dc3e10e08138670829bc0494986abe9David Goodwin
884446c428bf394b7113b0f18cbacb5e87b4efd1e14Evan Cheng// FIXME: Dup in ARMBaseInstrInfo.cpp
885db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic inline
886db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinconst MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
887db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
888db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
889db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
890db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic inline
891db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinconst MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
892db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return MIB.addReg(0);
893db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
894db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
895db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitLoadConstPool - Emits a load from constpool to materialize the
896db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// specified immediate.
897db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
898db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitLoadConstPool(MachineBasicBlock &MBB,
899db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  MachineBasicBlock::iterator &MBBI,
90077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                  DebugLoc dl,
901378445303b10b092a898a75131141a8259cff50bEvan Cheng                  unsigned DestReg, unsigned SubIdx, int Val,
902db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  ARMCC::CondCodes Pred,
903db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                  unsigned PredReg) const {
904db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFunction &MF = *MBB.getParent();
905db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineConstantPool *ConstantPool = MF.getConstantPool();
9069adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson  Constant *C =
907e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson             MF.getFunction()->getContext().getConstantInt(Type::Int32Ty, Val);
908db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4);
909db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
910378445303b10b092a898a75131141a8259cff50bEvan Cheng  BuildMI(MBB, MBBI, dl, TII.get(ARM::LDRcp))
911378445303b10b092a898a75131141a8259cff50bEvan Cheng    .addReg(DestReg, getDefRegState(true), SubIdx)
912db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addConstantPoolIndex(Idx)
913db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    .addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
914db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
915db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
916db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
917db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinrequiresRegisterScavenging(const MachineFunction &MF) const {
918db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return true;
919db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
920db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
921db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
922db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// not required, we reserve argument space for call sites in the function
923db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// immediately on entry to the current function. This eliminates the need for
924db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// add/sub sp brackets around call sites. Returns true if the call frame is
925db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin// included as part of the stack frame.
926db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinbool ARMBaseRegisterInfo::
927db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinhasReservedCallFrame(MachineFunction &MF) const {
928db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  const MachineFrameInfo *FFI = MF.getFrameInfo();
929db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned CFSize = FFI->getMaxCallFrameSize();
930db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // It's not always a good idea to include the call frame as part of the
931db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // stack frame. ARM (especially Thumb) has small immediate offset to
932db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // address the stack frame. So a large call frame can cause poor codegen
933db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // and may even makes it impossible to scavenge a register.
934db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (CFSize >= ((1 << 12) - 1) / 2)  // Half of imm12
935db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    return false;
936db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
937db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return !MF.getFrameInfo()->hasVarSizedObjects();
938db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
939db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
940db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// emitARMRegPlusImmediate - Emits a series of instructions to materialize
941db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// a destreg = basereg + immediate in ARM code.
942db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic
943db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid emitARMRegPlusImmediate(MachineBasicBlock &MBB,
944db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             MachineBasicBlock::iterator &MBBI,
945db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             unsigned DestReg, unsigned BaseReg, int NumBytes,
946db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             ARMCC::CondCodes Pred, unsigned PredReg,
94777521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                             const ARMBaseInstrInfo &TII,
948db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             DebugLoc dl) {
949db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  bool isSub = NumBytes < 0;
950db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (isSub) NumBytes = -NumBytes;
951db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
952db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  while (NumBytes) {
953db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
954db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
955db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    assert(ThisVal && "Didn't extract field correctly");
956db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
957db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // We will handle these bits from offset, clear them.
958db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    NumBytes &= ~ThisVal;
959db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
960e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng    assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
961db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
962db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Build the new ADD / SUB.
96377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin    BuildMI(MBB, MBBI, dl, TII.get(TII.getOpcode(isSub ? ARMII::SUBri : ARMII::ADDri)), DestReg)
964e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng      .addReg(BaseReg, RegState::Kill).addImm(ThisVal)
965db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
966db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    BaseReg = DestReg;
967db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
968db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
969db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
970db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void
971db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
97277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin             const ARMBaseInstrInfo &TII, DebugLoc dl,
973db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             int NumBytes,
974db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
975db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes,
976db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                          Pred, PredReg, TII, dl);
977db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
978db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
979db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
980db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
981db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                              MachineBasicBlock::iterator I) const {
982db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!hasReservedCallFrame(MF)) {
983db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // If we have alloca, convert as follows:
984db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
985db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // ADJCALLSTACKUP   -> add, sp, sp, amount
986db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstr *Old = I;
987db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    DebugLoc dl = Old->getDebugLoc();
988db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Amount = Old->getOperand(0).getImm();
989db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Amount != 0) {
990db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // We need to keep the stack aligned properly.  To do this, we round the
991db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // amount of space needed for the outgoing arguments up to the next
992db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // alignment boundary.
993db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
994db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Amount = (Amount+Align-1)/Align*Align;
995db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
996db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the pseudo instruction with a new instruction...
997db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Opc = Old->getOpcode();
998db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm();
999db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
1000db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
1001db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(2).getReg();
1002db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg);
1003db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
1004db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        // Note: PredReg is operand 3 for ADJCALLSTACKUP.
1005db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        unsigned PredReg = Old->getOperand(3).getReg();
1006db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
1007db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg);
1008db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1009db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1010db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1011db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MBB.erase(I);
1012db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1013db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1014db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// findScratchRegister - Find a 'free' ARM register. If register scavenger
1015db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// is not being used, R12 is available. Otherwise, try for a call-clobbered
1016db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// register first and then a spilled callee-saved register if that fails.
1017db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic
1018db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinunsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC,
1019db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             ARMFunctionInfo *AFI) {
1020db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12;
1021f1daf7d8abebd6e0104a6b41a774ccbb19a51c60David Goodwin  assert (!AFI->isThumb1OnlyFunction());
1022db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (Reg == 0)
1023db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Try a already spilled CS register.
1024db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters());
1025db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1026db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return Reg;
1027db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1028db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1029db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1030db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwineliminateFrameIndex(MachineBasicBlock::iterator II,
1031db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                    int SPAdj, RegScavenger *RS) const{
1032db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned i = 0;
1033db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineInstr &MI = *II;
1034db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock &MBB = *MI.getParent();
1035db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFunction &MF = *MBB.getParent();
1036db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1037db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  DebugLoc dl = MI.getDebugLoc();
1038db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1039db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  while (!MI.getOperand(i).isFI()) {
1040db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ++i;
1041db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1042db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1043db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1044db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned FrameReg = ARM::SP;
1045db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int FrameIndex = MI.getOperand(i).getIndex();
1046db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
1047db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin               MF.getFrameInfo()->getStackSize() + SPAdj;
1048db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1049db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
1050db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset -= AFI->getGPRCalleeSavedArea1Offset();
1051db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
1052db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset -= AFI->getGPRCalleeSavedArea2Offset();
1053db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
1054db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset -= AFI->getDPRCalleeSavedAreaOffset();
1055db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  else if (hasFP(MF)) {
1056db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    assert(SPAdj == 0 && "Unexpected");
1057db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // There is alloca()'s in this function, must reference off the frame
1058db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // pointer instead.
1059db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    FrameReg = getFrameRegister(MF);
1060db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset -= AFI->getFramePtrSpillOffset();
1061db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1062db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1063db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned Opcode = MI.getOpcode();
1064db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  const TargetInstrDesc &Desc = MI.getDesc();
1065db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1066db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  bool isSub = false;
1067db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1068db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Memory operands in inline assembly always use AddrMode2.
1069db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (Opcode == ARM::INLINEASM)
1070db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    AddrMode = ARMII::AddrMode2;
1071db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
107277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  if (Opcode == getOpcode(ARMII::ADDri)) {
1073db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset += MI.getOperand(i+1).getImm();
1074db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Offset == 0) {
1075db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Turn it into a move.
107677521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      MI.setDesc(TII.get(getOpcode(ARMII::MOVr)));
1077db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      MI.getOperand(i).ChangeToRegister(FrameReg, false);
1078db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      MI.RemoveOperand(i+1);
1079db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      return;
1080db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    } else if (Offset < 0) {
1081db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Offset = -Offset;
1082db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      isSub = true;
108377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      MI.setDesc(TII.get(getOpcode(ARMII::SUBri)));
1084db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1085db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1086db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Common case: small offset, fits into instruction.
1087e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng    if (ARM_AM::getSOImmVal(Offset) != -1) {
1088db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the FrameIndex with sp / fp
1089db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      MI.getOperand(i).ChangeToRegister(FrameReg, false);
1090e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng      MI.getOperand(i+1).ChangeToImmediate(Offset);
1091db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      return;
1092db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1093db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1094db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Otherwise, we fallback to common code below to form the imm offset with
1095db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // a sequence of ADDri instructions.  First though, pull as much of the imm
1096db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // into this ADDri as possible.
1097db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
1098db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
1099db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1100db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // We will handle these bits from offset, clear them.
1101db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset &= ~ThisImmVal;
1102db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1103db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Get the properly encoded SOImmVal field.
1104e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng    assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
1105e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng           "Bit extraction didn't work?");
1106e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng    MI.getOperand(i+1).ChangeToImmediate(ThisImmVal);
1107db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  } else {
1108db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned ImmIdx = 0;
1109db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    int InstrOffs = 0;
1110db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned NumBits = 0;
1111db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Scale = 1;
1112db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    switch (AddrMode) {
1113db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARMII::AddrMode2: {
1114db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ImmIdx = i+2;
1115db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
1116db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1117db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        InstrOffs *= -1;
1118db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      NumBits = 12;
1119db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1120db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1121db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARMII::AddrMode3: {
1122db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ImmIdx = i+2;
1123db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
1124db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1125db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        InstrOffs *= -1;
1126db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      NumBits = 8;
1127db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1128db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1129db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARMII::AddrMode5: {
1130db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ImmIdx = i+1;
1131db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1132db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1133db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        InstrOffs *= -1;
1134db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      NumBits = 8;
1135db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Scale = 4;
1136db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1137db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
11388b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin    case ARMII::AddrModeT2_i12: {
1139ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin      ImmIdx = i+1;
11408b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      InstrOffs = MI.getOperand(ImmIdx).getImm();
11418b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      NumBits = 12;
11428b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      break;
11438b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin    }
11448b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin    case ARMII::AddrModeT2_i8: {
1145ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin      ImmIdx = i+1;
11468b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      InstrOffs = MI.getOperand(ImmIdx).getImm();
11478b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      NumBits = 8;
11488b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin      break;
11498b98b85c64543e7ec479f40e5c2b5a24aa862fedDavid Goodwin    }
1150ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin    case ARMII::AddrModeT2_so: {
1151ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin      ImmIdx = i+2;
1152ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin      InstrOffs = MI.getOperand(ImmIdx).getImm();
1153ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin      break;
1154ea670f1dd8067a9b65f952d0548669045bf0e21fDavid Goodwin    }
1155db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    default:
1156c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      llvm_unreachable("Unsupported addressing mode!");
1157db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1158db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1159db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1160db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset += InstrOffs * Scale;
1161db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1162db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Offset < 0) {
1163db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      Offset = -Offset;
1164db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      isSub = true;
1165db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1166db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1167db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Common case: small offset, fits into instruction.
1168db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1169db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    int ImmedOffset = Offset / Scale;
1170db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Mask = (1 << NumBits) - 1;
1171db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if ((unsigned)Offset <= Mask * Scale) {
1172db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Replace the FrameIndex with sp
1173db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      MI.getOperand(i).ChangeToRegister(FrameReg, false);
1174db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (isSub)
1175db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        ImmedOffset |= 1 << NumBits;
1176db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ImmOp.ChangeToImmediate(ImmedOffset);
1177db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      return;
1178db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1179db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1180db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1181db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ImmedOffset = ImmedOffset & Mask;
1182db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (isSub)
1183db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      ImmedOffset |= 1 << NumBits;
1184db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ImmOp.ChangeToImmediate(ImmedOffset);
1185db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    Offset &= ~(Mask*Scale);
1186db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1187db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1188db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // If we get here, the immediate doesn't fit into the instruction.  We folded
1189db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // as much as possible above, handle the rest, providing a register that is
1190db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // SP+LargeImm.
1191db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  assert(Offset && "This code isn't needed if offset already handled!");
1192db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1193db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Insert a set of r12 with the full address: r12 = sp + offset
1194db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // If the offset we have is too large to fit into the instruction, we need
1195db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // to form it with a series of ADDri's.  Do this by taking 8-bit chunks
1196db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // out of 'Offset'.
1197db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
1198db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (ScratchReg == 0)
1199db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // No register is "free". Scavenge a register.
1200db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj);
1201db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int PIdx = MI.findFirstPredOperandIdx();
1202db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMCC::CondCodes Pred = (PIdx == -1)
1203db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
1204db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
1205db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
1206db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                          isSub ? -Offset : Offset, Pred, PredReg, TII, dl);
1207db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
1208db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1209db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1210db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// Move iterator pass the next bunch of callee save load / store ops for
1211db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// the particular spill area (1: integer area 1, 2: integer area 2,
1212db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin/// 3: fp area, 0: don't care).
1213db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
1214db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                                   MachineBasicBlock::iterator &MBBI,
1215db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                                   int Opc, unsigned Area,
1216db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                                   const ARMSubtarget &STI) {
1217db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  while (MBBI != MBB.end() &&
1218db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin         MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) {
1219db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Area != 0) {
1220db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      bool Done = false;
1221db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      unsigned Category = 0;
1222db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      switch (MBBI->getOperand(0).getReg()) {
1223db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::R4:  case ARM::R5:  case ARM::R6: case ARM::R7:
1224db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::LR:
1225db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = 1;
1226db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1227db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::R8:  case ARM::R9:  case ARM::R10: case ARM::R11:
1228db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = STI.isTargetDarwin() ? 2 : 1;
1229db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1230db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::D8:  case ARM::D9:  case ARM::D10: case ARM::D11:
1231db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
1232db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Category = 3;
1233db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1234db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      default:
1235db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        Done = true;
1236db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1237db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1238db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Done || Category != Area)
1239db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        break;
1240db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1241db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1242db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    ++MBBI;
1243db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1244db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1245db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1246db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1247db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitPrologue(MachineFunction &MF) const {
1248db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock &MBB = MF.front();
1249db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock::iterator MBBI = MBB.begin();
1250db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFrameInfo  *MFI = MF.getFrameInfo();
1251db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1252db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1253db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned NumBytes = MFI->getStackSize();
1254db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
1255db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  DebugLoc dl = (MBBI != MBB.end() ?
1256db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc());
1257db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1258db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Determine the sizes of each callee-save spill areas and record which frame
1259db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // belongs to which callee-save spill areas.
1260db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
1261db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int FramePtrSpillFI = 0;
1262db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1263db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (VARegSaveSize)
1264db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize);
1265db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1266db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!AFI->hasStackFrame()) {
1267db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (NumBytes != 0)
1268db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1269db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    return;
1270db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1271db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1272db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
1273db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    unsigned Reg = CSI[i].getReg();
1274db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    int FI = CSI[i].getFrameIdx();
1275db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    switch (Reg) {
1276db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R4:
1277db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R5:
1278db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R6:
1279db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R7:
1280db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::LR:
1281db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Reg == FramePtr)
1282db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        FramePtrSpillFI = FI;
1283db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      AFI->addGPRCalleeSavedArea1Frame(FI);
1284db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      GPRCS1Size += 4;
1285db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1286db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R8:
1287db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R9:
1288db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R10:
1289db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    case ARM::R11:
1290db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (Reg == FramePtr)
1291db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        FramePtrSpillFI = FI;
1292db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (STI.isTargetDarwin()) {
1293db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        AFI->addGPRCalleeSavedArea2Frame(FI);
1294db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        GPRCS2Size += 4;
1295db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      } else {
1296db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        AFI->addGPRCalleeSavedArea1Frame(FI);
1297db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        GPRCS1Size += 4;
1298db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1299db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      break;
1300db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    default:
1301db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      AFI->addDPRCalleeSavedAreaFrame(FI);
1302db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      DPRCSSize += 8;
1303db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1304db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1305db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1306db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for integer callee-save spill area 1.
1307db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size);
130877521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STR), 1, STI);
1309db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1310db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Darwin ABI requires FP to point to the stack slot that contains the
1311db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // previous FP.
1312db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (STI.isTargetDarwin() || hasFP(MF)) {
1313db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MachineInstrBuilder MIB =
131477521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      BuildMI(MBB, MBBI, dl, TII.get(getOpcode(ARMII::ADDri)), FramePtr)
1315db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      .addFrameIndex(FramePtrSpillFI).addImm(0);
1316db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    AddDefaultCC(AddDefaultPred(MIB));
1317db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1318db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1319db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for integer callee-save spill area 2.
1320db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size);
1321db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1322db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Build the new SUBri to adjust SP for FP callee-save spill area.
132377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::STR), 2, STI);
1324db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize);
1325db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1326db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  // Determine starting offsets of spill areas.
1327db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
1328db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
1329db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
1330db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
1331db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
1332db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
1333db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
1334db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1335db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  NumBytes = DPRCSOffset;
1336db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (NumBytes) {
1337db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Insert it after all the callee-save spills.
133877521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin    movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FSTD), 3, STI);
1339db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes);
1340db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1341db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1342db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (STI.isTargetELF() && hasFP(MF)) {
1343db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
1344db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                             AFI->getFramePtrSpillOffset());
1345db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1346db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1347db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
1348db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
1349db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
1350db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1351db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1352db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinstatic bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
1353db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  for (unsigned i = 0; CSRegs[i]; ++i)
1354db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (Reg == CSRegs[i])
1355db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      return true;
1356db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  return false;
1357db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1358db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
135977521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwinstatic bool isCSRestore(MachineInstr *MI,
136077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                        const ARMBaseInstrInfo &TII,
136177521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin                        const unsigned *CSRegs) {
136277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  return ((MI->getOpcode() == (int)TII.getOpcode(ARMII::FLDD) ||
136377521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin           MI->getOpcode() == (int)TII.getOpcode(ARMII::LDR)) &&
1364db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          MI->getOperand(1).isFI() &&
1365db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
1366db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1367db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1368db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwinvoid ARMBaseRegisterInfo::
1369db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid GoodwinemitEpilogue(MachineFunction &MF,
1370db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin             MachineBasicBlock &MBB) const {
1371db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineBasicBlock::iterator MBBI = prior(MBB.end());
137277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin  assert(MBBI->getOpcode() == (int)getOpcode(ARMII::BX_RET) &&
1373db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin         "Can only insert epilog into returning blocks");
1374db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  DebugLoc dl = MBBI->getDebugLoc();
1375db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  MachineFrameInfo *MFI = MF.getFrameInfo();
1376db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1377db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
1378db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  int NumBytes = (int)MFI->getStackSize();
1379db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1380db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (!AFI->hasStackFrame()) {
1381db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (NumBytes != 0)
1382db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
1383db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  } else {
1384db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Unwind MBBI to point to first LDR / FLDD.
1385db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    const unsigned *CSRegs = getCalleeSavedRegs();
1386db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if (MBBI != MBB.begin()) {
1387db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      do
1388db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        --MBBI;
138977521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      while (MBBI != MBB.begin() && isCSRestore(MBBI, TII, CSRegs));
139077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin      if (!isCSRestore(MBBI, TII, CSRegs))
1391db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        ++MBBI;
1392db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1393db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1394db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of FP callee save spill area.
1395db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
1396db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 AFI->getGPRCalleeSavedArea2Size() +
1397db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin                 AFI->getDPRCalleeSavedAreaSize());
1398db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1399db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Darwin ABI requires FP to point to the stack slot that contains the
1400db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // previous FP.
1401db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) {
1402db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
1403db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // Reset SP based on frame pointer only if the stack frame extends beyond
1404db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      // frame pointer stack slot or target is ELF and the function has FP.
1405db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      if (AFI->getGPRCalleeSavedArea2Size() ||
1406db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          AFI->getDPRCalleeSavedAreaSize()  ||
1407db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          AFI->getDPRCalleeSavedAreaOffset()||
1408db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin          hasFP(MF)) {
1409db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        if (NumBytes)
141077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin          BuildMI(MBB, MBBI, dl, TII.get(getOpcode(ARMII::SUBri)), ARM::SP).addReg(FramePtr)
1411db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin            .addImm(NumBytes)
1412db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin            .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1413db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin        else
141477521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin          BuildMI(MBB, MBBI, dl, TII.get(getOpcode(ARMII::MOVr)), ARM::SP).addReg(FramePtr)
1415db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin            .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
1416db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      }
1417db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    } else if (NumBytes) {
1418db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin      emitSPUpdate(MBB, MBBI, TII, dl, NumBytes);
1419db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    }
1420db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1421db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of integer callee save spill area 2.
142277521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin    movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::FLDD), 3, STI);
1423db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize());
1424db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1425db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to start of integer callee save spill area 1.
142677521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin    movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDR), 2, STI);
1427db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size());
1428db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1429db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    // Move SP to SP upon entry to the function.
143077521f5232e679aa3de10aaaed2464aa91d7ff55David Goodwin    movePastCSLoadStoreOps(MBB, MBBI, getOpcode(ARMII::LDR), 1, STI);
1431db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size());
1432db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  }
1433db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1434db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin  if (VARegSaveSize)
1435db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin    emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize);
1436db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1437db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin}
1438db5a71a8e01ed9a0d93a19176df6ea0aea510d7bDavid Goodwin
1439c140c4803dc3e10e08138670829bc0494986abe9David Goodwin#include "ARMGenRegisterInfo.inc"
1440