ARMRegisterInfo.cpp revision 193323
1193323Sed//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file contains the ARM implementation of the TargetRegisterInfo class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "ARM.h" 15193323Sed#include "ARMAddressingModes.h" 16193323Sed#include "ARMInstrInfo.h" 17193323Sed#include "ARMMachineFunctionInfo.h" 18193323Sed#include "ARMRegisterInfo.h" 19193323Sed#include "ARMSubtarget.h" 20193323Sed#include "llvm/Constants.h" 21193323Sed#include "llvm/DerivedTypes.h" 22193323Sed#include "llvm/CodeGen/MachineConstantPool.h" 23193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 24193323Sed#include "llvm/CodeGen/MachineFunction.h" 25193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 26193323Sed#include "llvm/CodeGen/MachineLocation.h" 27193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 28193323Sed#include "llvm/CodeGen/RegisterScavenging.h" 29193323Sed#include "llvm/Target/TargetFrameInfo.h" 30193323Sed#include "llvm/Target/TargetMachine.h" 31193323Sed#include "llvm/Target/TargetOptions.h" 32193323Sed#include "llvm/ADT/BitVector.h" 33193323Sed#include "llvm/ADT/SmallVector.h" 34193323Sed#include "llvm/ADT/STLExtras.h" 35193323Sed#include "llvm/Support/CommandLine.h" 36193323Sed#include <algorithm> 37193323Sedusing namespace llvm; 38193323Sed 39193323Sedstatic cl::opt<bool> ThumbRegScavenging("enable-thumb-reg-scavenging", 40193323Sed cl::Hidden, 41193323Sed cl::desc("Enable register scavenging on Thumb")); 42193323Sed 43193323Sedunsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) { 44193323Sed using namespace ARM; 45193323Sed switch (RegEnum) { 46193323Sed case R0: case S0: case D0: return 0; 47193323Sed case R1: case S1: case D1: return 1; 48193323Sed case R2: case S2: case D2: return 2; 49193323Sed case R3: case S3: case D3: return 3; 50193323Sed case R4: case S4: case D4: return 4; 51193323Sed case R5: case S5: case D5: return 5; 52193323Sed case R6: case S6: case D6: return 6; 53193323Sed case R7: case S7: case D7: return 7; 54193323Sed case R8: case S8: case D8: return 8; 55193323Sed case R9: case S9: case D9: return 9; 56193323Sed case R10: case S10: case D10: return 10; 57193323Sed case R11: case S11: case D11: return 11; 58193323Sed case R12: case S12: case D12: return 12; 59193323Sed case SP: case S13: case D13: return 13; 60193323Sed case LR: case S14: case D14: return 14; 61193323Sed case PC: case S15: case D15: return 15; 62193323Sed case S16: return 16; 63193323Sed case S17: return 17; 64193323Sed case S18: return 18; 65193323Sed case S19: return 19; 66193323Sed case S20: return 20; 67193323Sed case S21: return 21; 68193323Sed case S22: return 22; 69193323Sed case S23: return 23; 70193323Sed case S24: return 24; 71193323Sed case S25: return 25; 72193323Sed case S26: return 26; 73193323Sed case S27: return 27; 74193323Sed case S28: return 28; 75193323Sed case S29: return 29; 76193323Sed case S30: return 30; 77193323Sed case S31: return 31; 78193323Sed default: 79193323Sed assert(0 && "Unknown ARM register!"); 80193323Sed abort(); 81193323Sed } 82193323Sed} 83193323Sed 84193323Sedunsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum, 85193323Sed bool &isSPVFP) { 86193323Sed isSPVFP = false; 87193323Sed 88193323Sed using namespace ARM; 89193323Sed switch (RegEnum) { 90193323Sed default: 91193323Sed assert(0 && "Unknown ARM register!"); 92193323Sed abort(); 93193323Sed case R0: case D0: return 0; 94193323Sed case R1: case D1: return 1; 95193323Sed case R2: case D2: return 2; 96193323Sed case R3: case D3: return 3; 97193323Sed case R4: case D4: return 4; 98193323Sed case R5: case D5: return 5; 99193323Sed case R6: case D6: return 6; 100193323Sed case R7: case D7: return 7; 101193323Sed case R8: case D8: return 8; 102193323Sed case R9: case D9: return 9; 103193323Sed case R10: case D10: return 10; 104193323Sed case R11: case D11: return 11; 105193323Sed case R12: case D12: return 12; 106193323Sed case SP: case D13: return 13; 107193323Sed case LR: case D14: return 14; 108193323Sed case PC: case D15: return 15; 109193323Sed 110193323Sed case S0: case S1: case S2: case S3: 111193323Sed case S4: case S5: case S6: case S7: 112193323Sed case S8: case S9: case S10: case S11: 113193323Sed case S12: case S13: case S14: case S15: 114193323Sed case S16: case S17: case S18: case S19: 115193323Sed case S20: case S21: case S22: case S23: 116193323Sed case S24: case S25: case S26: case S27: 117193323Sed case S28: case S29: case S30: case S31: { 118193323Sed isSPVFP = true; 119193323Sed switch (RegEnum) { 120193323Sed default: return 0; // Avoid compile time warning. 121193323Sed case S0: return 0; 122193323Sed case S1: return 1; 123193323Sed case S2: return 2; 124193323Sed case S3: return 3; 125193323Sed case S4: return 4; 126193323Sed case S5: return 5; 127193323Sed case S6: return 6; 128193323Sed case S7: return 7; 129193323Sed case S8: return 8; 130193323Sed case S9: return 9; 131193323Sed case S10: return 10; 132193323Sed case S11: return 11; 133193323Sed case S12: return 12; 134193323Sed case S13: return 13; 135193323Sed case S14: return 14; 136193323Sed case S15: return 15; 137193323Sed case S16: return 16; 138193323Sed case S17: return 17; 139193323Sed case S18: return 18; 140193323Sed case S19: return 19; 141193323Sed case S20: return 20; 142193323Sed case S21: return 21; 143193323Sed case S22: return 22; 144193323Sed case S23: return 23; 145193323Sed case S24: return 24; 146193323Sed case S25: return 25; 147193323Sed case S26: return 26; 148193323Sed case S27: return 27; 149193323Sed case S28: return 28; 150193323Sed case S29: return 29; 151193323Sed case S30: return 30; 152193323Sed case S31: return 31; 153193323Sed } 154193323Sed } 155193323Sed } 156193323Sed} 157193323Sed 158193323SedARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, 159193323Sed const ARMSubtarget &sti) 160193323Sed : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), 161193323Sed TII(tii), STI(sti), 162193323Sed FramePtr((STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11) { 163193323Sed} 164193323Sed 165193323Sedstatic inline 166193323Sedconst MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 167193323Sed return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 168193323Sed} 169193323Sed 170193323Sedstatic inline 171193323Sedconst MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 172193323Sed return MIB.addReg(0); 173193323Sed} 174193323Sed 175193323Sed/// emitLoadConstPool - Emits a load from constpool to materialize the 176193323Sed/// specified immediate. 177193323Sedvoid ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 178193323Sed MachineBasicBlock::iterator &MBBI, 179193323Sed unsigned DestReg, int Val, 180193323Sed unsigned Pred, unsigned PredReg, 181193323Sed const TargetInstrInfo *TII, 182193323Sed bool isThumb, 183193323Sed DebugLoc dl) const { 184193323Sed MachineFunction &MF = *MBB.getParent(); 185193323Sed MachineConstantPool *ConstantPool = MF.getConstantPool(); 186193323Sed Constant *C = ConstantInt::get(Type::Int32Ty, Val); 187193323Sed unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); 188193323Sed if (isThumb) 189193323Sed BuildMI(MBB, MBBI, dl, 190193323Sed TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx); 191193323Sed else 192193323Sed BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg) 193193323Sed .addConstantPoolIndex(Idx) 194193323Sed .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 195193323Sed} 196193323Sed 197193323Sedconst TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const { 198193323Sed return &ARM::GPRRegClass; 199193323Sed} 200193323Sed 201193323Sed/// isLowRegister - Returns true if the register is low register r0-r7. 202193323Sed/// 203193323Sedbool ARMRegisterInfo::isLowRegister(unsigned Reg) const { 204193323Sed using namespace ARM; 205193323Sed switch (Reg) { 206193323Sed case R0: case R1: case R2: case R3: 207193323Sed case R4: case R5: case R6: case R7: 208193323Sed return true; 209193323Sed default: 210193323Sed return false; 211193323Sed } 212193323Sed} 213193323Sed 214193323Sedconst TargetRegisterClass* 215193323SedARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const { 216193323Sed if (STI.isThumb()) { 217193323Sed if (isLowRegister(Reg)) 218193323Sed return ARM::tGPRRegisterClass; 219193323Sed switch (Reg) { 220193323Sed default: 221193323Sed break; 222193323Sed case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 223193323Sed case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: 224193323Sed return ARM::GPRRegisterClass; 225193323Sed } 226193323Sed } 227193323Sed return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); 228193323Sed} 229193323Sed 230193323Sedconst unsigned* 231193323SedARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 232193323Sed static const unsigned CalleeSavedRegs[] = { 233193323Sed ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, 234193323Sed ARM::R7, ARM::R6, ARM::R5, ARM::R4, 235193323Sed 236193323Sed ARM::D15, ARM::D14, ARM::D13, ARM::D12, 237193323Sed ARM::D11, ARM::D10, ARM::D9, ARM::D8, 238193323Sed 0 239193323Sed }; 240193323Sed 241193323Sed static const unsigned DarwinCalleeSavedRegs[] = { 242193323Sed ARM::LR, ARM::R7, ARM::R6, ARM::R5, ARM::R4, 243193323Sed ARM::R11, ARM::R10, ARM::R9, ARM::R8, 244193323Sed 245193323Sed ARM::D15, ARM::D14, ARM::D13, ARM::D12, 246193323Sed ARM::D11, ARM::D10, ARM::D9, ARM::D8, 247193323Sed 0 248193323Sed }; 249193323Sed return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs; 250193323Sed} 251193323Sed 252193323Sedconst TargetRegisterClass* const * 253193323SedARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 254193323Sed static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 255193323Sed &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 256193323Sed &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 257193323Sed &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 258193323Sed 259193323Sed &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 260193323Sed &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 261193323Sed 0 262193323Sed }; 263193323Sed static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = { 264193323Sed &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 265193323Sed &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass, 266193323Sed &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass, 267193323Sed 268193323Sed &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 269193323Sed &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 270193323Sed 0 271193323Sed }; 272193323Sed return STI.isThumb() ? ThumbCalleeSavedRegClasses : CalleeSavedRegClasses; 273193323Sed} 274193323Sed 275193323SedBitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 276193323Sed // FIXME: avoid re-calculating this everytime. 277193323Sed BitVector Reserved(getNumRegs()); 278193323Sed Reserved.set(ARM::SP); 279193323Sed Reserved.set(ARM::PC); 280193323Sed if (STI.isTargetDarwin() || hasFP(MF)) 281193323Sed Reserved.set(FramePtr); 282193323Sed // Some targets reserve R9. 283193323Sed if (STI.isR9Reserved()) 284193323Sed Reserved.set(ARM::R9); 285193323Sed return Reserved; 286193323Sed} 287193323Sed 288193323Sedbool 289193323SedARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const { 290193323Sed switch (Reg) { 291193323Sed default: break; 292193323Sed case ARM::SP: 293193323Sed case ARM::PC: 294193323Sed return true; 295193323Sed case ARM::R7: 296193323Sed case ARM::R11: 297193323Sed if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF))) 298193323Sed return true; 299193323Sed break; 300193323Sed case ARM::R9: 301193323Sed return STI.isR9Reserved(); 302193323Sed } 303193323Sed 304193323Sed return false; 305193323Sed} 306193323Sed 307193323Sedbool 308193323SedARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 309193323Sed const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 310193323Sed return ThumbRegScavenging || !AFI->isThumbFunction(); 311193323Sed} 312193323Sed 313193323Sed/// hasFP - Return true if the specified function should have a dedicated frame 314193323Sed/// pointer register. This is true if the function has variable sized allocas 315193323Sed/// or if frame pointer elimination is disabled. 316193323Sed/// 317193323Sedbool ARMRegisterInfo::hasFP(const MachineFunction &MF) const { 318193323Sed const MachineFrameInfo *MFI = MF.getFrameInfo(); 319193323Sed return NoFramePointerElim || MFI->hasVarSizedObjects(); 320193323Sed} 321193323Sed 322193323Sed// hasReservedCallFrame - Under normal circumstances, when a frame pointer is 323193323Sed// not required, we reserve argument space for call sites in the function 324193323Sed// immediately on entry to the current function. This eliminates the need for 325193323Sed// add/sub sp brackets around call sites. Returns true if the call frame is 326193323Sed// included as part of the stack frame. 327193323Sedbool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 328193323Sed const MachineFrameInfo *FFI = MF.getFrameInfo(); 329193323Sed unsigned CFSize = FFI->getMaxCallFrameSize(); 330193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 331193323Sed // It's not always a good idea to include the call frame as part of the 332193323Sed // stack frame. ARM (especially Thumb) has small immediate offset to 333193323Sed // address the stack frame. So a large call frame can cause poor codegen 334193323Sed // and may even makes it impossible to scavenge a register. 335193323Sed if (AFI->isThumbFunction()) { 336193323Sed if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 337193323Sed return false; 338193323Sed } else { 339193323Sed if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 340193323Sed return false; 341193323Sed } 342193323Sed return !MF.getFrameInfo()->hasVarSizedObjects(); 343193323Sed} 344193323Sed 345193323Sed/// emitARMRegPlusImmediate - Emits a series of instructions to materialize 346193323Sed/// a destreg = basereg + immediate in ARM code. 347193323Sedstatic 348193323Sedvoid emitARMRegPlusImmediate(MachineBasicBlock &MBB, 349193323Sed MachineBasicBlock::iterator &MBBI, 350193323Sed unsigned DestReg, unsigned BaseReg, int NumBytes, 351193323Sed ARMCC::CondCodes Pred, unsigned PredReg, 352193323Sed const TargetInstrInfo &TII, 353193323Sed DebugLoc dl) { 354193323Sed bool isSub = NumBytes < 0; 355193323Sed if (isSub) NumBytes = -NumBytes; 356193323Sed 357193323Sed while (NumBytes) { 358193323Sed unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 359193323Sed unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 360193323Sed assert(ThisVal && "Didn't extract field correctly"); 361193323Sed 362193323Sed // We will handle these bits from offset, clear them. 363193323Sed NumBytes &= ~ThisVal; 364193323Sed 365193323Sed // Get the properly encoded SOImmVal field. 366193323Sed int SOImmVal = ARM_AM::getSOImmVal(ThisVal); 367193323Sed assert(SOImmVal != -1 && "Bit extraction didn't work?"); 368193323Sed 369193323Sed // Build the new ADD / SUB. 370193323Sed BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) 371193323Sed .addReg(BaseReg, RegState::Kill).addImm(SOImmVal) 372193323Sed .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 373193323Sed BaseReg = DestReg; 374193323Sed } 375193323Sed} 376193323Sed 377193323Sed/// calcNumMI - Returns the number of instructions required to materialize 378193323Sed/// the specific add / sub r, c instruction. 379193323Sedstatic unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 380193323Sed unsigned NumBits, unsigned Scale) { 381193323Sed unsigned NumMIs = 0; 382193323Sed unsigned Chunk = ((1 << NumBits) - 1) * Scale; 383193323Sed 384193323Sed if (Opc == ARM::tADDrSPi) { 385193323Sed unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 386193323Sed Bytes -= ThisVal; 387193323Sed NumMIs++; 388193323Sed NumBits = 8; 389193323Sed Scale = 1; // Followed by a number of tADDi8. 390193323Sed Chunk = ((1 << NumBits) - 1) * Scale; 391193323Sed } 392193323Sed 393193323Sed NumMIs += Bytes / Chunk; 394193323Sed if ((Bytes % Chunk) != 0) 395193323Sed NumMIs++; 396193323Sed if (ExtraOpc) 397193323Sed NumMIs++; 398193323Sed return NumMIs; 399193323Sed} 400193323Sed 401193323Sed/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 402193323Sed/// a destreg = basereg + immediate in Thumb code. Materialize the immediate 403193323Sed/// in a register using mov / mvn sequences or load the immediate from a 404193323Sed/// constpool entry. 405193323Sedstatic 406193323Sedvoid emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 407193323Sed MachineBasicBlock::iterator &MBBI, 408193323Sed unsigned DestReg, unsigned BaseReg, 409193323Sed int NumBytes, bool CanChangeCC, 410193323Sed const TargetInstrInfo &TII, 411193323Sed const ARMRegisterInfo& MRI, 412193323Sed DebugLoc dl) { 413193323Sed bool isHigh = !MRI.isLowRegister(DestReg) || 414193323Sed (BaseReg != 0 && !MRI.isLowRegister(BaseReg)); 415193323Sed bool isSub = false; 416193323Sed // Subtract doesn't have high register version. Load the negative value 417193323Sed // if either base or dest register is a high register. Also, if do not 418193323Sed // issue sub as part of the sequence if condition register is to be 419193323Sed // preserved. 420193323Sed if (NumBytes < 0 && !isHigh && CanChangeCC) { 421193323Sed isSub = true; 422193323Sed NumBytes = -NumBytes; 423193323Sed } 424193323Sed unsigned LdReg = DestReg; 425193323Sed if (DestReg == ARM::SP) { 426193323Sed assert(BaseReg == ARM::SP && "Unexpected!"); 427193323Sed LdReg = ARM::R3; 428193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 429193323Sed .addReg(ARM::R3, RegState::Kill); 430193323Sed } 431193323Sed 432193323Sed if (NumBytes <= 255 && NumBytes >= 0) 433193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 434193323Sed else if (NumBytes < 0 && NumBytes >= -255) { 435193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 436193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg) 437193323Sed .addReg(LdReg, RegState::Kill); 438193323Sed } else 439193323Sed MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII, 440193323Sed true, dl); 441193323Sed 442193323Sed // Emit add / sub. 443193323Sed int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 444193323Sed const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, 445193323Sed TII.get(Opc), DestReg); 446193323Sed if (DestReg == ARM::SP || isSub) 447193323Sed MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 448193323Sed else 449193323Sed MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 450193323Sed if (DestReg == ARM::SP) 451193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 452193323Sed .addReg(ARM::R12, RegState::Kill); 453193323Sed} 454193323Sed 455193323Sed/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 456193323Sed/// a destreg = basereg + immediate in Thumb code. 457193323Sedstatic 458193323Sedvoid emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 459193323Sed MachineBasicBlock::iterator &MBBI, 460193323Sed unsigned DestReg, unsigned BaseReg, 461193323Sed int NumBytes, const TargetInstrInfo &TII, 462193323Sed const ARMRegisterInfo& MRI, 463193323Sed DebugLoc dl) { 464193323Sed bool isSub = NumBytes < 0; 465193323Sed unsigned Bytes = (unsigned)NumBytes; 466193323Sed if (isSub) Bytes = -NumBytes; 467193323Sed bool isMul4 = (Bytes & 3) == 0; 468193323Sed bool isTwoAddr = false; 469193323Sed bool DstNotEqBase = false; 470193323Sed unsigned NumBits = 1; 471193323Sed unsigned Scale = 1; 472193323Sed int Opc = 0; 473193323Sed int ExtraOpc = 0; 474193323Sed 475193323Sed if (DestReg == BaseReg && BaseReg == ARM::SP) { 476193323Sed assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 477193323Sed NumBits = 7; 478193323Sed Scale = 4; 479193323Sed Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 480193323Sed isTwoAddr = true; 481193323Sed } else if (!isSub && BaseReg == ARM::SP) { 482193323Sed // r1 = add sp, 403 483193323Sed // => 484193323Sed // r1 = add sp, 100 * 4 485193323Sed // r1 = add r1, 3 486193323Sed if (!isMul4) { 487193323Sed Bytes &= ~3; 488193323Sed ExtraOpc = ARM::tADDi3; 489193323Sed } 490193323Sed NumBits = 8; 491193323Sed Scale = 4; 492193323Sed Opc = ARM::tADDrSPi; 493193323Sed } else { 494193323Sed // sp = sub sp, c 495193323Sed // r1 = sub sp, c 496193323Sed // r8 = sub sp, c 497193323Sed if (DestReg != BaseReg) 498193323Sed DstNotEqBase = true; 499193323Sed NumBits = 8; 500193323Sed Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 501193323Sed isTwoAddr = true; 502193323Sed } 503193323Sed 504193323Sed unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 505193323Sed unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 506193323Sed if (NumMIs > Threshold) { 507193323Sed // This will expand into too many instructions. Load the immediate from a 508193323Sed // constpool entry. 509193323Sed emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, 510193323Sed MRI, dl); 511193323Sed return; 512193323Sed } 513193323Sed 514193323Sed if (DstNotEqBase) { 515193323Sed if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) { 516193323Sed // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 517193323Sed unsigned Chunk = (1 << 3) - 1; 518193323Sed unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 519193323Sed Bytes -= ThisVal; 520193323Sed BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) 521193323Sed .addReg(BaseReg, RegState::Kill).addImm(ThisVal); 522193323Sed } else { 523193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 524193323Sed .addReg(BaseReg, RegState::Kill); 525193323Sed } 526193323Sed BaseReg = DestReg; 527193323Sed } 528193323Sed 529193323Sed unsigned Chunk = ((1 << NumBits) - 1) * Scale; 530193323Sed while (Bytes) { 531193323Sed unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 532193323Sed Bytes -= ThisVal; 533193323Sed ThisVal /= Scale; 534193323Sed // Build the new tADD / tSUB. 535193323Sed if (isTwoAddr) 536193323Sed BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 537193323Sed .addReg(DestReg).addImm(ThisVal); 538193323Sed else { 539193323Sed bool isKill = BaseReg != ARM::SP; 540193323Sed BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 541193323Sed .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 542193323Sed BaseReg = DestReg; 543193323Sed 544193323Sed if (Opc == ARM::tADDrSPi) { 545193323Sed // r4 = add sp, imm 546193323Sed // r4 = add r4, imm 547193323Sed // ... 548193323Sed NumBits = 8; 549193323Sed Scale = 1; 550193323Sed Chunk = ((1 << NumBits) - 1) * Scale; 551193323Sed Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 552193323Sed isTwoAddr = true; 553193323Sed } 554193323Sed } 555193323Sed } 556193323Sed 557193323Sed if (ExtraOpc) 558193323Sed BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg) 559193323Sed .addReg(DestReg, RegState::Kill) 560193323Sed .addImm(((unsigned)NumBytes) & 3); 561193323Sed} 562193323Sed 563193323Sedstatic 564193323Sedvoid emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 565193323Sed int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, 566193323Sed bool isThumb, const TargetInstrInfo &TII, 567193323Sed const ARMRegisterInfo& MRI, 568193323Sed DebugLoc dl) { 569193323Sed if (isThumb) 570193323Sed emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII, 571193323Sed MRI, dl); 572193323Sed else 573193323Sed emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, 574193323Sed Pred, PredReg, TII, dl); 575193323Sed} 576193323Sed 577193323Sedvoid ARMRegisterInfo:: 578193323SedeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 579193323Sed MachineBasicBlock::iterator I) const { 580193323Sed if (!hasReservedCallFrame(MF)) { 581193323Sed // If we have alloca, convert as follows: 582193323Sed // ADJCALLSTACKDOWN -> sub, sp, sp, amount 583193323Sed // ADJCALLSTACKUP -> add, sp, sp, amount 584193323Sed MachineInstr *Old = I; 585193323Sed DebugLoc dl = Old->getDebugLoc(); 586193323Sed unsigned Amount = Old->getOperand(0).getImm(); 587193323Sed if (Amount != 0) { 588193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 589193323Sed // We need to keep the stack aligned properly. To do this, we round the 590193323Sed // amount of space needed for the outgoing arguments up to the next 591193323Sed // alignment boundary. 592193323Sed unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 593193323Sed Amount = (Amount+Align-1)/Align*Align; 594193323Sed 595193323Sed // Replace the pseudo instruction with a new instruction... 596193323Sed unsigned Opc = Old->getOpcode(); 597193323Sed bool isThumb = AFI->isThumbFunction(); 598193323Sed ARMCC::CondCodes Pred = isThumb 599193323Sed ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm(); 600193323Sed if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 601193323Sed // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. 602193323Sed unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg(); 603193323Sed emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl); 604193323Sed } else { 605193323Sed // Note: PredReg is operand 3 for ADJCALLSTACKUP. 606193323Sed unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg(); 607193323Sed assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 608193323Sed emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl); 609193323Sed } 610193323Sed } 611193323Sed } 612193323Sed MBB.erase(I); 613193323Sed} 614193323Sed 615193323Sed/// emitThumbConstant - Emit a series of instructions to materialize a 616193323Sed/// constant. 617193323Sedstatic void emitThumbConstant(MachineBasicBlock &MBB, 618193323Sed MachineBasicBlock::iterator &MBBI, 619193323Sed unsigned DestReg, int Imm, 620193323Sed const TargetInstrInfo &TII, 621193323Sed const ARMRegisterInfo& MRI, 622193323Sed DebugLoc dl) { 623193323Sed bool isSub = Imm < 0; 624193323Sed if (isSub) Imm = -Imm; 625193323Sed 626193323Sed int Chunk = (1 << 8) - 1; 627193323Sed int ThisVal = (Imm > Chunk) ? Chunk : Imm; 628193323Sed Imm -= ThisVal; 629193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); 630193323Sed if (Imm > 0) 631193323Sed emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl); 632193323Sed if (isSub) 633193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg) 634193323Sed .addReg(DestReg, RegState::Kill); 635193323Sed} 636193323Sed 637193323Sed/// findScratchRegister - Find a 'free' ARM register. If register scavenger 638193323Sed/// is not being used, R12 is available. Otherwise, try for a call-clobbered 639193323Sed/// register first and then a spilled callee-saved register if that fails. 640193323Sedstatic 641193323Sedunsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, 642193323Sed ARMFunctionInfo *AFI) { 643193323Sed unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; 644193323Sed assert (!AFI->isThumbFunction()); 645193323Sed if (Reg == 0) 646193323Sed // Try a already spilled CS register. 647193323Sed Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); 648193323Sed 649193323Sed return Reg; 650193323Sed} 651193323Sed 652193323Sedvoid ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 653193323Sed int SPAdj, RegScavenger *RS) const{ 654193323Sed unsigned i = 0; 655193323Sed MachineInstr &MI = *II; 656193323Sed MachineBasicBlock &MBB = *MI.getParent(); 657193323Sed MachineFunction &MF = *MBB.getParent(); 658193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 659193323Sed bool isThumb = AFI->isThumbFunction(); 660193323Sed DebugLoc dl = MI.getDebugLoc(); 661193323Sed 662193323Sed while (!MI.getOperand(i).isFI()) { 663193323Sed ++i; 664193323Sed assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 665193323Sed } 666193323Sed 667193323Sed unsigned FrameReg = ARM::SP; 668193323Sed int FrameIndex = MI.getOperand(i).getIndex(); 669193323Sed int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 670193323Sed MF.getFrameInfo()->getStackSize() + SPAdj; 671193323Sed 672193323Sed if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 673193323Sed Offset -= AFI->getGPRCalleeSavedArea1Offset(); 674193323Sed else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 675193323Sed Offset -= AFI->getGPRCalleeSavedArea2Offset(); 676193323Sed else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) 677193323Sed Offset -= AFI->getDPRCalleeSavedAreaOffset(); 678193323Sed else if (hasFP(MF)) { 679193323Sed assert(SPAdj == 0 && "Unexpected"); 680193323Sed // There is alloca()'s in this function, must reference off the frame 681193323Sed // pointer instead. 682193323Sed FrameReg = getFrameRegister(MF); 683193323Sed Offset -= AFI->getFramePtrSpillOffset(); 684193323Sed } 685193323Sed 686193323Sed unsigned Opcode = MI.getOpcode(); 687193323Sed const TargetInstrDesc &Desc = MI.getDesc(); 688193323Sed unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 689193323Sed bool isSub = false; 690193323Sed 691193323Sed // Memory operands in inline assembly always use AddrMode2. 692193323Sed if (Opcode == ARM::INLINEASM) 693193323Sed AddrMode = ARMII::AddrMode2; 694193323Sed 695193323Sed if (Opcode == ARM::ADDri) { 696193323Sed Offset += MI.getOperand(i+1).getImm(); 697193323Sed if (Offset == 0) { 698193323Sed // Turn it into a move. 699193323Sed MI.setDesc(TII.get(ARM::MOVr)); 700193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 701193323Sed MI.RemoveOperand(i+1); 702193323Sed return; 703193323Sed } else if (Offset < 0) { 704193323Sed Offset = -Offset; 705193323Sed isSub = true; 706193323Sed MI.setDesc(TII.get(ARM::SUBri)); 707193323Sed } 708193323Sed 709193323Sed // Common case: small offset, fits into instruction. 710193323Sed int ImmedOffset = ARM_AM::getSOImmVal(Offset); 711193323Sed if (ImmedOffset != -1) { 712193323Sed // Replace the FrameIndex with sp / fp 713193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 714193323Sed MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); 715193323Sed return; 716193323Sed } 717193323Sed 718193323Sed // Otherwise, we fallback to common code below to form the imm offset with 719193323Sed // a sequence of ADDri instructions. First though, pull as much of the imm 720193323Sed // into this ADDri as possible. 721193323Sed unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 722193323Sed unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); 723193323Sed 724193323Sed // We will handle these bits from offset, clear them. 725193323Sed Offset &= ~ThisImmVal; 726193323Sed 727193323Sed // Get the properly encoded SOImmVal field. 728193323Sed int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); 729193323Sed assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); 730193323Sed MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); 731193323Sed } else if (Opcode == ARM::tADDrSPi) { 732193323Sed Offset += MI.getOperand(i+1).getImm(); 733193323Sed 734193323Sed // Can't use tADDrSPi if it's based off the frame pointer. 735193323Sed unsigned NumBits = 0; 736193323Sed unsigned Scale = 1; 737193323Sed if (FrameReg != ARM::SP) { 738193323Sed Opcode = ARM::tADDi3; 739193323Sed MI.setDesc(TII.get(ARM::tADDi3)); 740193323Sed NumBits = 3; 741193323Sed } else { 742193323Sed NumBits = 8; 743193323Sed Scale = 4; 744193323Sed assert((Offset & 3) == 0 && 745193323Sed "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 746193323Sed } 747193323Sed 748193323Sed if (Offset == 0) { 749193323Sed // Turn it into a move. 750193323Sed MI.setDesc(TII.get(ARM::tMOVhir2lor)); 751193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 752193323Sed MI.RemoveOperand(i+1); 753193323Sed return; 754193323Sed } 755193323Sed 756193323Sed // Common case: small offset, fits into instruction. 757193323Sed unsigned Mask = (1 << NumBits) - 1; 758193323Sed if (((Offset / Scale) & ~Mask) == 0) { 759193323Sed // Replace the FrameIndex with sp / fp 760193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 761193323Sed MI.getOperand(i+1).ChangeToImmediate(Offset / Scale); 762193323Sed return; 763193323Sed } 764193323Sed 765193323Sed unsigned DestReg = MI.getOperand(0).getReg(); 766193323Sed unsigned Bytes = (Offset > 0) ? Offset : -Offset; 767193323Sed unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 768193323Sed // MI would expand into a large number of instructions. Don't try to 769193323Sed // simplify the immediate. 770193323Sed if (NumMIs > 2) { 771193323Sed emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, 772193323Sed *this, dl); 773193323Sed MBB.erase(II); 774193323Sed return; 775193323Sed } 776193323Sed 777193323Sed if (Offset > 0) { 778193323Sed // Translate r0 = add sp, imm to 779193323Sed // r0 = add sp, 255*4 780193323Sed // r0 = add r0, (imm - 255*4) 781193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 782193323Sed MI.getOperand(i+1).ChangeToImmediate(Mask); 783193323Sed Offset = (Offset - Mask * Scale); 784193323Sed MachineBasicBlock::iterator NII = next(II); 785193323Sed emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, 786193323Sed *this, dl); 787193323Sed } else { 788193323Sed // Translate r0 = add sp, -imm to 789193323Sed // r0 = -imm (this is then translated into a series of instructons) 790193323Sed // r0 = add r0, sp 791193323Sed emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 792193323Sed MI.setDesc(TII.get(ARM::tADDhirr)); 793193323Sed MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); 794193323Sed MI.getOperand(i+1).ChangeToRegister(FrameReg, false); 795193323Sed } 796193323Sed return; 797193323Sed } else { 798193323Sed unsigned ImmIdx = 0; 799193323Sed int InstrOffs = 0; 800193323Sed unsigned NumBits = 0; 801193323Sed unsigned Scale = 1; 802193323Sed switch (AddrMode) { 803193323Sed case ARMII::AddrMode2: { 804193323Sed ImmIdx = i+2; 805193323Sed InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm()); 806193323Sed if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 807193323Sed InstrOffs *= -1; 808193323Sed NumBits = 12; 809193323Sed break; 810193323Sed } 811193323Sed case ARMII::AddrMode3: { 812193323Sed ImmIdx = i+2; 813193323Sed InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm()); 814193323Sed if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 815193323Sed InstrOffs *= -1; 816193323Sed NumBits = 8; 817193323Sed break; 818193323Sed } 819193323Sed case ARMII::AddrMode5: { 820193323Sed ImmIdx = i+1; 821193323Sed InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 822193323Sed if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 823193323Sed InstrOffs *= -1; 824193323Sed NumBits = 8; 825193323Sed Scale = 4; 826193323Sed break; 827193323Sed } 828193323Sed case ARMII::AddrModeTs: { 829193323Sed ImmIdx = i+1; 830193323Sed InstrOffs = MI.getOperand(ImmIdx).getImm(); 831193323Sed NumBits = (FrameReg == ARM::SP) ? 8 : 5; 832193323Sed Scale = 4; 833193323Sed break; 834193323Sed } 835193323Sed default: 836193323Sed assert(0 && "Unsupported addressing mode!"); 837193323Sed abort(); 838193323Sed break; 839193323Sed } 840193323Sed 841193323Sed Offset += InstrOffs * Scale; 842193323Sed assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); 843193323Sed if (Offset < 0 && !isThumb) { 844193323Sed Offset = -Offset; 845193323Sed isSub = true; 846193323Sed } 847193323Sed 848193323Sed // Common case: small offset, fits into instruction. 849193323Sed MachineOperand &ImmOp = MI.getOperand(ImmIdx); 850193323Sed int ImmedOffset = Offset / Scale; 851193323Sed unsigned Mask = (1 << NumBits) - 1; 852193323Sed if ((unsigned)Offset <= Mask * Scale) { 853193323Sed // Replace the FrameIndex with sp 854193323Sed MI.getOperand(i).ChangeToRegister(FrameReg, false); 855193323Sed if (isSub) 856193323Sed ImmedOffset |= 1 << NumBits; 857193323Sed ImmOp.ChangeToImmediate(ImmedOffset); 858193323Sed return; 859193323Sed } 860193323Sed 861193323Sed bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill; 862193323Sed if (AddrMode == ARMII::AddrModeTs) { 863193323Sed // Thumb tLDRspi, tSTRspi. These will change to instructions that use 864193323Sed // a different base register. 865193323Sed NumBits = 5; 866193323Sed Mask = (1 << NumBits) - 1; 867193323Sed } 868193323Sed // If this is a thumb spill / restore, we will be using a constpool load to 869193323Sed // materialize the offset. 870193323Sed if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore) 871193323Sed ImmOp.ChangeToImmediate(0); 872193323Sed else { 873193323Sed // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 874193323Sed ImmedOffset = ImmedOffset & Mask; 875193323Sed if (isSub) 876193323Sed ImmedOffset |= 1 << NumBits; 877193323Sed ImmOp.ChangeToImmediate(ImmedOffset); 878193323Sed Offset &= ~(Mask*Scale); 879193323Sed } 880193323Sed } 881193323Sed 882193323Sed // If we get here, the immediate doesn't fit into the instruction. We folded 883193323Sed // as much as possible above, handle the rest, providing a register that is 884193323Sed // SP+LargeImm. 885193323Sed assert(Offset && "This code isn't needed if offset already handled!"); 886193323Sed 887193323Sed if (isThumb) { 888193323Sed if (Desc.mayLoad()) { 889193323Sed // Use the destination register to materialize sp + offset. 890193323Sed unsigned TmpReg = MI.getOperand(0).getReg(); 891193323Sed bool UseRR = false; 892193323Sed if (Opcode == ARM::tRestore) { 893193323Sed if (FrameReg == ARM::SP) 894193323Sed emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 895193323Sed Offset, false, TII, *this, dl); 896193323Sed else { 897193323Sed emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, 898193323Sed true, dl); 899193323Sed UseRR = true; 900193323Sed } 901193323Sed } else 902193323Sed emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 903193323Sed *this, dl); 904193323Sed MI.setDesc(TII.get(ARM::tLDR)); 905193323Sed MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 906193323Sed if (UseRR) 907193323Sed // Use [reg, reg] addrmode. 908193323Sed MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 909193323Sed else // tLDR has an extra register operand. 910193323Sed MI.addOperand(MachineOperand::CreateReg(0, false)); 911193323Sed } else if (Desc.mayStore()) { 912193323Sed // FIXME! This is horrific!!! We need register scavenging. 913193323Sed // Our temporary workaround has marked r3 unavailable. Of course, r3 is 914193323Sed // also a ABI register so it's possible that is is the register that is 915193323Sed // being storing here. If that's the case, we do the following: 916193323Sed // r12 = r2 917193323Sed // Use r2 to materialize sp + offset 918193323Sed // str r3, r2 919193323Sed // r2 = r12 920193323Sed unsigned ValReg = MI.getOperand(0).getReg(); 921193323Sed unsigned TmpReg = ARM::R3; 922193323Sed bool UseRR = false; 923193323Sed if (ValReg == ARM::R3) { 924193323Sed BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 925193323Sed .addReg(ARM::R2, RegState::Kill); 926193323Sed TmpReg = ARM::R2; 927193323Sed } 928193323Sed if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 929193323Sed BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 930193323Sed .addReg(ARM::R3, RegState::Kill); 931193323Sed if (Opcode == ARM::tSpill) { 932193323Sed if (FrameReg == ARM::SP) 933193323Sed emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 934193323Sed Offset, false, TII, *this, dl); 935193323Sed else { 936193323Sed emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, 937193323Sed true, dl); 938193323Sed UseRR = true; 939193323Sed } 940193323Sed } else 941193323Sed emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 942193323Sed *this, dl); 943193323Sed MI.setDesc(TII.get(ARM::tSTR)); 944193323Sed MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 945193323Sed if (UseRR) // Use [reg, reg] addrmode. 946193323Sed MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 947193323Sed else // tSTR has an extra register operand. 948193323Sed MI.addOperand(MachineOperand::CreateReg(0, false)); 949193323Sed 950193323Sed MachineBasicBlock::iterator NII = next(II); 951193323Sed if (ValReg == ARM::R3) 952193323Sed BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) 953193323Sed .addReg(ARM::R12, RegState::Kill); 954193323Sed if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 955193323Sed BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 956193323Sed .addReg(ARM::R12, RegState::Kill); 957193323Sed } else 958193323Sed assert(false && "Unexpected opcode!"); 959193323Sed } else { 960193323Sed // Insert a set of r12 with the full address: r12 = sp + offset 961193323Sed // If the offset we have is too large to fit into the instruction, we need 962193323Sed // to form it with a series of ADDri's. Do this by taking 8-bit chunks 963193323Sed // out of 'Offset'. 964193323Sed unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); 965193323Sed if (ScratchReg == 0) 966193323Sed // No register is "free". Scavenge a register. 967193323Sed ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); 968193323Sed int PIdx = MI.findFirstPredOperandIdx(); 969193323Sed ARMCC::CondCodes Pred = (PIdx == -1) 970193323Sed ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 971193323Sed unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 972193323Sed emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, 973193323Sed isSub ? -Offset : Offset, Pred, PredReg, TII, dl); 974193323Sed MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); 975193323Sed } 976193323Sed} 977193323Sed 978193323Sedstatic unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { 979193323Sed const MachineFrameInfo *FFI = MF.getFrameInfo(); 980193323Sed int Offset = 0; 981193323Sed for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 982193323Sed int FixedOff = -FFI->getObjectOffset(i); 983193323Sed if (FixedOff > Offset) Offset = FixedOff; 984193323Sed } 985193323Sed for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { 986193323Sed if (FFI->isDeadObjectIndex(i)) 987193323Sed continue; 988193323Sed Offset += FFI->getObjectSize(i); 989193323Sed unsigned Align = FFI->getObjectAlignment(i); 990193323Sed // Adjust to alignment boundary 991193323Sed Offset = (Offset+Align-1)/Align*Align; 992193323Sed } 993193323Sed return (unsigned)Offset; 994193323Sed} 995193323Sed 996193323Sedvoid 997193323SedARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 998193323Sed RegScavenger *RS) const { 999193323Sed // This tells PEI to spill the FP as if it is any other callee-save register 1000193323Sed // to take advantage the eliminateFrameIndex machinery. This also ensures it 1001193323Sed // is spilled in the order specified by getCalleeSavedRegs() to make it easier 1002193323Sed // to combine multiple loads / stores. 1003193323Sed bool CanEliminateFrame = true; 1004193323Sed bool CS1Spilled = false; 1005193323Sed bool LRSpilled = false; 1006193323Sed unsigned NumGPRSpills = 0; 1007193323Sed SmallVector<unsigned, 4> UnspilledCS1GPRs; 1008193323Sed SmallVector<unsigned, 4> UnspilledCS2GPRs; 1009193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1010193323Sed 1011193323Sed // Don't spill FP if the frame can be eliminated. This is determined 1012193323Sed // by scanning the callee-save registers to see if any is used. 1013193323Sed const unsigned *CSRegs = getCalleeSavedRegs(); 1014193323Sed const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses(); 1015193323Sed for (unsigned i = 0; CSRegs[i]; ++i) { 1016193323Sed unsigned Reg = CSRegs[i]; 1017193323Sed bool Spilled = false; 1018193323Sed if (MF.getRegInfo().isPhysRegUsed(Reg)) { 1019193323Sed AFI->setCSRegisterIsSpilled(Reg); 1020193323Sed Spilled = true; 1021193323Sed CanEliminateFrame = false; 1022193323Sed } else { 1023193323Sed // Check alias registers too. 1024193323Sed for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) { 1025193323Sed if (MF.getRegInfo().isPhysRegUsed(*Aliases)) { 1026193323Sed Spilled = true; 1027193323Sed CanEliminateFrame = false; 1028193323Sed } 1029193323Sed } 1030193323Sed } 1031193323Sed 1032193323Sed if (CSRegClasses[i] == &ARM::GPRRegClass) { 1033193323Sed if (Spilled) { 1034193323Sed NumGPRSpills++; 1035193323Sed 1036193323Sed if (!STI.isTargetDarwin()) { 1037193323Sed if (Reg == ARM::LR) 1038193323Sed LRSpilled = true; 1039193323Sed CS1Spilled = true; 1040193323Sed continue; 1041193323Sed } 1042193323Sed 1043193323Sed // Keep track if LR and any of R4, R5, R6, and R7 is spilled. 1044193323Sed switch (Reg) { 1045193323Sed case ARM::LR: 1046193323Sed LRSpilled = true; 1047193323Sed // Fallthrough 1048193323Sed case ARM::R4: 1049193323Sed case ARM::R5: 1050193323Sed case ARM::R6: 1051193323Sed case ARM::R7: 1052193323Sed CS1Spilled = true; 1053193323Sed break; 1054193323Sed default: 1055193323Sed break; 1056193323Sed } 1057193323Sed } else { 1058193323Sed if (!STI.isTargetDarwin()) { 1059193323Sed UnspilledCS1GPRs.push_back(Reg); 1060193323Sed continue; 1061193323Sed } 1062193323Sed 1063193323Sed switch (Reg) { 1064193323Sed case ARM::R4: 1065193323Sed case ARM::R5: 1066193323Sed case ARM::R6: 1067193323Sed case ARM::R7: 1068193323Sed case ARM::LR: 1069193323Sed UnspilledCS1GPRs.push_back(Reg); 1070193323Sed break; 1071193323Sed default: 1072193323Sed UnspilledCS2GPRs.push_back(Reg); 1073193323Sed break; 1074193323Sed } 1075193323Sed } 1076193323Sed } 1077193323Sed } 1078193323Sed 1079193323Sed bool ForceLRSpill = false; 1080193323Sed if (!LRSpilled && AFI->isThumbFunction()) { 1081193323Sed unsigned FnSize = TII.GetFunctionSizeInBytes(MF); 1082193323Sed // Force LR to be spilled if the Thumb function size is > 2048. This enables 1083193323Sed // use of BL to implement far jump. If it turns out that it's not needed 1084193323Sed // then the branch fix up path will undo it. 1085193323Sed if (FnSize >= (1 << 11)) { 1086193323Sed CanEliminateFrame = false; 1087193323Sed ForceLRSpill = true; 1088193323Sed } 1089193323Sed } 1090193323Sed 1091193323Sed bool ExtraCSSpill = false; 1092193323Sed if (!CanEliminateFrame || hasFP(MF)) { 1093193323Sed AFI->setHasStackFrame(true); 1094193323Sed 1095193323Sed // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. 1096193323Sed // Spill LR as well so we can fold BX_RET to the registers restore (LDM). 1097193323Sed if (!LRSpilled && CS1Spilled) { 1098193323Sed MF.getRegInfo().setPhysRegUsed(ARM::LR); 1099193323Sed AFI->setCSRegisterIsSpilled(ARM::LR); 1100193323Sed NumGPRSpills++; 1101193323Sed UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), 1102193323Sed UnspilledCS1GPRs.end(), (unsigned)ARM::LR)); 1103193323Sed ForceLRSpill = false; 1104193323Sed ExtraCSSpill = true; 1105193323Sed } 1106193323Sed 1107193323Sed // Darwin ABI requires FP to point to the stack slot that contains the 1108193323Sed // previous FP. 1109193323Sed if (STI.isTargetDarwin() || hasFP(MF)) { 1110193323Sed MF.getRegInfo().setPhysRegUsed(FramePtr); 1111193323Sed NumGPRSpills++; 1112193323Sed } 1113193323Sed 1114193323Sed // If stack and double are 8-byte aligned and we are spilling an odd number 1115193323Sed // of GPRs. Spill one extra callee save GPR so we won't have to pad between 1116193323Sed // the integer and double callee save areas. 1117193323Sed unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); 1118193323Sed if (TargetAlign == 8 && (NumGPRSpills & 1)) { 1119193323Sed if (CS1Spilled && !UnspilledCS1GPRs.empty()) { 1120193323Sed for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { 1121193323Sed unsigned Reg = UnspilledCS1GPRs[i]; 1122193323Sed // Don't spiil high register if the function is thumb 1123193323Sed if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) { 1124193323Sed MF.getRegInfo().setPhysRegUsed(Reg); 1125193323Sed AFI->setCSRegisterIsSpilled(Reg); 1126193323Sed if (!isReservedReg(MF, Reg)) 1127193323Sed ExtraCSSpill = true; 1128193323Sed break; 1129193323Sed } 1130193323Sed } 1131193323Sed } else if (!UnspilledCS2GPRs.empty() && 1132193323Sed !AFI->isThumbFunction()) { 1133193323Sed unsigned Reg = UnspilledCS2GPRs.front(); 1134193323Sed MF.getRegInfo().setPhysRegUsed(Reg); 1135193323Sed AFI->setCSRegisterIsSpilled(Reg); 1136193323Sed if (!isReservedReg(MF, Reg)) 1137193323Sed ExtraCSSpill = true; 1138193323Sed } 1139193323Sed } 1140193323Sed 1141193323Sed // Estimate if we might need to scavenge a register at some point in order 1142193323Sed // to materialize a stack offset. If so, either spill one additiona 1143193323Sed // callee-saved register or reserve a special spill slot to facilitate 1144193323Sed // register scavenging. 1145193323Sed if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) { 1146193323Sed MachineFrameInfo *MFI = MF.getFrameInfo(); 1147193323Sed unsigned Size = estimateStackSize(MF, MFI); 1148193323Sed unsigned Limit = (1 << 12) - 1; 1149193323Sed for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) 1150193323Sed for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) { 1151193323Sed for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) 1152193323Sed if (I->getOperand(i).isFI()) { 1153193323Sed unsigned Opcode = I->getOpcode(); 1154193323Sed const TargetInstrDesc &Desc = TII.get(Opcode); 1155193323Sed unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 1156193323Sed if (AddrMode == ARMII::AddrMode3) { 1157193323Sed Limit = (1 << 8) - 1; 1158193323Sed goto DoneEstimating; 1159193323Sed } else if (AddrMode == ARMII::AddrMode5) { 1160193323Sed unsigned ThisLimit = ((1 << 8) - 1) * 4; 1161193323Sed if (ThisLimit < Limit) 1162193323Sed Limit = ThisLimit; 1163193323Sed } 1164193323Sed } 1165193323Sed } 1166193323Sed DoneEstimating: 1167193323Sed if (Size >= Limit) { 1168193323Sed // If any non-reserved CS register isn't spilled, just spill one or two 1169193323Sed // extra. That should take care of it! 1170193323Sed unsigned NumExtras = TargetAlign / 4; 1171193323Sed SmallVector<unsigned, 2> Extras; 1172193323Sed while (NumExtras && !UnspilledCS1GPRs.empty()) { 1173193323Sed unsigned Reg = UnspilledCS1GPRs.back(); 1174193323Sed UnspilledCS1GPRs.pop_back(); 1175193323Sed if (!isReservedReg(MF, Reg)) { 1176193323Sed Extras.push_back(Reg); 1177193323Sed NumExtras--; 1178193323Sed } 1179193323Sed } 1180193323Sed while (NumExtras && !UnspilledCS2GPRs.empty()) { 1181193323Sed unsigned Reg = UnspilledCS2GPRs.back(); 1182193323Sed UnspilledCS2GPRs.pop_back(); 1183193323Sed if (!isReservedReg(MF, Reg)) { 1184193323Sed Extras.push_back(Reg); 1185193323Sed NumExtras--; 1186193323Sed } 1187193323Sed } 1188193323Sed if (Extras.size() && NumExtras == 0) { 1189193323Sed for (unsigned i = 0, e = Extras.size(); i != e; ++i) { 1190193323Sed MF.getRegInfo().setPhysRegUsed(Extras[i]); 1191193323Sed AFI->setCSRegisterIsSpilled(Extras[i]); 1192193323Sed } 1193193323Sed } else { 1194193323Sed // Reserve a slot closest to SP or frame pointer. 1195193323Sed const TargetRegisterClass *RC = &ARM::GPRRegClass; 1196193323Sed RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 1197193323Sed RC->getAlignment())); 1198193323Sed } 1199193323Sed } 1200193323Sed } 1201193323Sed } 1202193323Sed 1203193323Sed if (ForceLRSpill) { 1204193323Sed MF.getRegInfo().setPhysRegUsed(ARM::LR); 1205193323Sed AFI->setCSRegisterIsSpilled(ARM::LR); 1206193323Sed AFI->setLRIsSpilledForFarJump(true); 1207193323Sed } 1208193323Sed} 1209193323Sed 1210193323Sed/// Move iterator pass the next bunch of callee save load / store ops for 1211193323Sed/// the particular spill area (1: integer area 1, 2: integer area 2, 1212193323Sed/// 3: fp area, 0: don't care). 1213193323Sedstatic void movePastCSLoadStoreOps(MachineBasicBlock &MBB, 1214193323Sed MachineBasicBlock::iterator &MBBI, 1215193323Sed int Opc, unsigned Area, 1216193323Sed const ARMSubtarget &STI) { 1217193323Sed while (MBBI != MBB.end() && 1218193323Sed MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) { 1219193323Sed if (Area != 0) { 1220193323Sed bool Done = false; 1221193323Sed unsigned Category = 0; 1222193323Sed switch (MBBI->getOperand(0).getReg()) { 1223193323Sed case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7: 1224193323Sed case ARM::LR: 1225193323Sed Category = 1; 1226193323Sed break; 1227193323Sed case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 1228193323Sed Category = STI.isTargetDarwin() ? 2 : 1; 1229193323Sed break; 1230193323Sed case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11: 1231193323Sed case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15: 1232193323Sed Category = 3; 1233193323Sed break; 1234193323Sed default: 1235193323Sed Done = true; 1236193323Sed break; 1237193323Sed } 1238193323Sed if (Done || Category != Area) 1239193323Sed break; 1240193323Sed } 1241193323Sed 1242193323Sed ++MBBI; 1243193323Sed } 1244193323Sed} 1245193323Sed 1246193323Sedvoid ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 1247193323Sed MachineBasicBlock &MBB = MF.front(); 1248193323Sed MachineBasicBlock::iterator MBBI = MBB.begin(); 1249193323Sed MachineFrameInfo *MFI = MF.getFrameInfo(); 1250193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1251193323Sed bool isThumb = AFI->isThumbFunction(); 1252193323Sed unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1253193323Sed unsigned NumBytes = MFI->getStackSize(); 1254193323Sed const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 1255193323Sed DebugLoc dl = (MBBI != MBB.end() ? 1256193323Sed MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 1257193323Sed 1258193323Sed if (isThumb) { 1259193323Sed // Check if R3 is live in. It might have to be used as a scratch register. 1260193323Sed for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(), 1261193323Sed E = MF.getRegInfo().livein_end(); I != E; ++I) { 1262193323Sed if (I->first == ARM::R3) { 1263193323Sed AFI->setR3IsLiveIn(true); 1264193323Sed break; 1265193323Sed } 1266193323Sed } 1267193323Sed 1268193323Sed // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 1269193323Sed NumBytes = (NumBytes + 3) & ~3; 1270193323Sed MFI->setStackSize(NumBytes); 1271193323Sed } 1272193323Sed 1273193323Sed // Determine the sizes of each callee-save spill areas and record which frame 1274193323Sed // belongs to which callee-save spill areas. 1275193323Sed unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 1276193323Sed int FramePtrSpillFI = 0; 1277193323Sed 1278193323Sed if (VARegSaveSize) 1279193323Sed emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII, 1280193323Sed *this, dl); 1281193323Sed 1282193323Sed if (!AFI->hasStackFrame()) { 1283193323Sed if (NumBytes != 0) 1284193323Sed emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); 1285193323Sed return; 1286193323Sed } 1287193323Sed 1288193323Sed for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1289193323Sed unsigned Reg = CSI[i].getReg(); 1290193323Sed int FI = CSI[i].getFrameIdx(); 1291193323Sed switch (Reg) { 1292193323Sed case ARM::R4: 1293193323Sed case ARM::R5: 1294193323Sed case ARM::R6: 1295193323Sed case ARM::R7: 1296193323Sed case ARM::LR: 1297193323Sed if (Reg == FramePtr) 1298193323Sed FramePtrSpillFI = FI; 1299193323Sed AFI->addGPRCalleeSavedArea1Frame(FI); 1300193323Sed GPRCS1Size += 4; 1301193323Sed break; 1302193323Sed case ARM::R8: 1303193323Sed case ARM::R9: 1304193323Sed case ARM::R10: 1305193323Sed case ARM::R11: 1306193323Sed if (Reg == FramePtr) 1307193323Sed FramePtrSpillFI = FI; 1308193323Sed if (STI.isTargetDarwin()) { 1309193323Sed AFI->addGPRCalleeSavedArea2Frame(FI); 1310193323Sed GPRCS2Size += 4; 1311193323Sed } else { 1312193323Sed AFI->addGPRCalleeSavedArea1Frame(FI); 1313193323Sed GPRCS1Size += 4; 1314193323Sed } 1315193323Sed break; 1316193323Sed default: 1317193323Sed AFI->addDPRCalleeSavedAreaFrame(FI); 1318193323Sed DPRCSSize += 8; 1319193323Sed } 1320193323Sed } 1321193323Sed 1322193323Sed if (!isThumb) { 1323193323Sed // Build the new SUBri to adjust SP for integer callee-save spill area 1. 1324193323Sed emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl); 1325193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); 1326193323Sed } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { 1327193323Sed ++MBBI; 1328193323Sed if (MBBI != MBB.end()) 1329193323Sed dl = MBBI->getDebugLoc(); 1330193323Sed } 1331193323Sed 1332193323Sed // Darwin ABI requires FP to point to the stack slot that contains the 1333193323Sed // previous FP. 1334193323Sed if (STI.isTargetDarwin() || hasFP(MF)) { 1335193323Sed MachineInstrBuilder MIB = 1336193323Sed BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), 1337193323Sed FramePtr) 1338193323Sed .addFrameIndex(FramePtrSpillFI).addImm(0); 1339193323Sed if (!isThumb) AddDefaultCC(AddDefaultPred(MIB)); 1340193323Sed } 1341193323Sed 1342193323Sed if (!isThumb) { 1343193323Sed // Build the new SUBri to adjust SP for integer callee-save spill area 2. 1344193323Sed emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl); 1345193323Sed 1346193323Sed // Build the new SUBri to adjust SP for FP callee-save spill area. 1347193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); 1348193323Sed emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl); 1349193323Sed } 1350193323Sed 1351193323Sed // Determine starting offsets of spill areas. 1352193323Sed unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 1353193323Sed unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 1354193323Sed unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 1355193323Sed AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 1356193323Sed AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 1357193323Sed AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 1358193323Sed AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 1359193323Sed 1360193323Sed NumBytes = DPRCSOffset; 1361193323Sed if (NumBytes) { 1362193323Sed // Insert it after all the callee-save spills. 1363193323Sed if (!isThumb) 1364193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); 1365193323Sed emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); 1366193323Sed } 1367193323Sed 1368193323Sed if(STI.isTargetELF() && hasFP(MF)) { 1369193323Sed MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 1370193323Sed AFI->getFramePtrSpillOffset()); 1371193323Sed } 1372193323Sed 1373193323Sed AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 1374193323Sed AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 1375193323Sed AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 1376193323Sed} 1377193323Sed 1378193323Sedstatic bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 1379193323Sed for (unsigned i = 0; CSRegs[i]; ++i) 1380193323Sed if (Reg == CSRegs[i]) 1381193323Sed return true; 1382193323Sed return false; 1383193323Sed} 1384193323Sed 1385193323Sedstatic bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 1386193323Sed return ((MI->getOpcode() == ARM::FLDD || 1387193323Sed MI->getOpcode() == ARM::LDR || 1388193323Sed MI->getOpcode() == ARM::tRestore) && 1389193323Sed MI->getOperand(1).isFI() && 1390193323Sed isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 1391193323Sed} 1392193323Sed 1393193323Sedvoid ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 1394193323Sed MachineBasicBlock &MBB) const { 1395193323Sed MachineBasicBlock::iterator MBBI = prior(MBB.end()); 1396193323Sed assert((MBBI->getOpcode() == ARM::BX_RET || 1397193323Sed MBBI->getOpcode() == ARM::tBX_RET || 1398193323Sed MBBI->getOpcode() == ARM::tPOP_RET) && 1399193323Sed "Can only insert epilog into returning blocks"); 1400193323Sed DebugLoc dl = MBBI->getDebugLoc(); 1401193323Sed MachineFrameInfo *MFI = MF.getFrameInfo(); 1402193323Sed ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1403193323Sed bool isThumb = AFI->isThumbFunction(); 1404193323Sed unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1405193323Sed int NumBytes = (int)MFI->getStackSize(); 1406193323Sed 1407193323Sed if (!AFI->hasStackFrame()) { 1408193323Sed if (NumBytes != 0) 1409193323Sed emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); 1410193323Sed } else { 1411193323Sed // Unwind MBBI to point to first LDR / FLDD. 1412193323Sed const unsigned *CSRegs = getCalleeSavedRegs(); 1413193323Sed if (MBBI != MBB.begin()) { 1414193323Sed do 1415193323Sed --MBBI; 1416193323Sed while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 1417193323Sed if (!isCSRestore(MBBI, CSRegs)) 1418193323Sed ++MBBI; 1419193323Sed } 1420193323Sed 1421193323Sed // Move SP to start of FP callee save spill area. 1422193323Sed NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 1423193323Sed AFI->getGPRCalleeSavedArea2Size() + 1424193323Sed AFI->getDPRCalleeSavedAreaSize()); 1425193323Sed if (isThumb) { 1426193323Sed if (hasFP(MF)) { 1427193323Sed NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 1428193323Sed // Reset SP based on frame pointer only if the stack frame extends beyond 1429193323Sed // frame pointer stack slot or target is ELF and the function has FP. 1430193323Sed if (NumBytes) 1431193323Sed emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, 1432193323Sed TII, *this, dl); 1433193323Sed else 1434193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP) 1435193323Sed .addReg(FramePtr); 1436193323Sed } else { 1437193323Sed if (MBBI->getOpcode() == ARM::tBX_RET && 1438193323Sed &MBB.front() != MBBI && 1439193323Sed prior(MBBI)->getOpcode() == ARM::tPOP) { 1440193323Sed MachineBasicBlock::iterator PMBBI = prior(MBBI); 1441193323Sed emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, 1442193323Sed *this, dl); 1443193323Sed } else 1444193323Sed emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, 1445193323Sed *this, dl); 1446193323Sed } 1447193323Sed } else { 1448193323Sed // Darwin ABI requires FP to point to the stack slot that contains the 1449193323Sed // previous FP. 1450193323Sed if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) { 1451193323Sed NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 1452193323Sed // Reset SP based on frame pointer only if the stack frame extends beyond 1453193323Sed // frame pointer stack slot or target is ELF and the function has FP. 1454193323Sed if (AFI->getGPRCalleeSavedArea2Size() || 1455193323Sed AFI->getDPRCalleeSavedAreaSize() || 1456193323Sed AFI->getDPRCalleeSavedAreaOffset()|| 1457193323Sed hasFP(MF)) { 1458193323Sed if (NumBytes) 1459193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) 1460193323Sed .addImm(NumBytes) 1461193323Sed .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 1462193323Sed else 1463193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) 1464193323Sed .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 1465193323Sed } 1466193323Sed } else if (NumBytes) { 1467193323Sed emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl); 1468193323Sed } 1469193323Sed 1470193323Sed // Move SP to start of integer callee save spill area 2. 1471193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); 1472193323Sed emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0, 1473193323Sed false, TII, *this, dl); 1474193323Sed 1475193323Sed // Move SP to start of integer callee save spill area 1. 1476193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); 1477193323Sed emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0, 1478193323Sed false, TII, *this, dl); 1479193323Sed 1480193323Sed // Move SP to SP upon entry to the function. 1481193323Sed movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); 1482193323Sed emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0, 1483193323Sed false, TII, *this, dl); 1484193323Sed } 1485193323Sed } 1486193323Sed 1487193323Sed if (VARegSaveSize) { 1488193323Sed if (isThumb) 1489193323Sed // Epilogue for vararg functions: pop LR to R3 and branch off it. 1490193323Sed // FIXME: Verify this is still ok when R3 is no longer being reserved. 1491193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3); 1492193323Sed 1493193323Sed emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII, 1494193323Sed *this, dl); 1495193323Sed 1496193323Sed if (isThumb) { 1497193323Sed BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); 1498193323Sed MBB.erase(MBBI); 1499193323Sed } 1500193323Sed } 1501193323Sed} 1502193323Sed 1503193323Sedunsigned ARMRegisterInfo::getRARegister() const { 1504193323Sed return ARM::LR; 1505193323Sed} 1506193323Sed 1507193323Sedunsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { 1508193323Sed if (STI.isTargetDarwin() || hasFP(MF)) 1509193323Sed return (STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11; 1510193323Sed else 1511193323Sed return ARM::SP; 1512193323Sed} 1513193323Sed 1514193323Sedunsigned ARMRegisterInfo::getEHExceptionRegister() const { 1515193323Sed assert(0 && "What is the exception register"); 1516193323Sed return 0; 1517193323Sed} 1518193323Sed 1519193323Sedunsigned ARMRegisterInfo::getEHHandlerRegister() const { 1520193323Sed assert(0 && "What is the exception handler register"); 1521193323Sed return 0; 1522193323Sed} 1523193323Sed 1524193323Sedint ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 1525193323Sed return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 1526193323Sed} 1527193323Sed 1528193323Sed#include "ARMGenRegisterInfo.inc" 1529