ARMRegisterInfo.cpp (194710) | ARMRegisterInfo.cpp (195340) |
---|---|
1//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 17 unchanged lines hidden (view full) --- 26#include "llvm/CodeGen/MachineLocation.h" 27#include "llvm/CodeGen/MachineRegisterInfo.h" 28#include "llvm/CodeGen/RegisterScavenging.h" 29#include "llvm/Target/TargetFrameInfo.h" 30#include "llvm/Target/TargetMachine.h" 31#include "llvm/Target/TargetOptions.h" 32#include "llvm/ADT/BitVector.h" 33#include "llvm/ADT/SmallVector.h" | 1//===- ARMRegisterInfo.cpp - ARM Register Information -----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 17 unchanged lines hidden (view full) --- 26#include "llvm/CodeGen/MachineLocation.h" 27#include "llvm/CodeGen/MachineRegisterInfo.h" 28#include "llvm/CodeGen/RegisterScavenging.h" 29#include "llvm/Target/TargetFrameInfo.h" 30#include "llvm/Target/TargetMachine.h" 31#include "llvm/Target/TargetOptions.h" 32#include "llvm/ADT/BitVector.h" 33#include "llvm/ADT/SmallVector.h" |
34#include "llvm/ADT/STLExtras.h" 35#include "llvm/Support/CommandLine.h" 36#include <algorithm> | |
37using namespace llvm; 38 | 34using namespace llvm; 35 |
39static cl::opt<bool> ThumbRegScavenging("enable-thumb-reg-scavenging", 40 cl::Hidden, 41 cl::desc("Enable register scavenging on Thumb")); 42 43unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) { | 36unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum) { |
44 using namespace ARM; 45 switch (RegEnum) { 46 case R0: case S0: case D0: return 0; 47 case R1: case S1: case D1: return 1; 48 case R2: case S2: case D2: return 2; 49 case R3: case S3: case D3: return 3; 50 case R4: case S4: case D4: return 4; 51 case R5: case S5: case D5: return 5; --- 24 unchanged lines hidden (view full) --- 76 case S30: return 30; 77 case S31: return 31; 78 default: 79 assert(0 && "Unknown ARM register!"); 80 abort(); 81 } 82} 83 | 37 using namespace ARM; 38 switch (RegEnum) { 39 case R0: case S0: case D0: return 0; 40 case R1: case S1: case D1: return 1; 41 case R2: case S2: case D2: return 2; 42 case R3: case S3: case D3: return 3; 43 case R4: case S4: case D4: return 4; 44 case R5: case S5: case D5: return 5; --- 24 unchanged lines hidden (view full) --- 69 case S30: return 30; 70 case S31: return 31; 71 default: 72 assert(0 && "Unknown ARM register!"); 73 abort(); 74 } 75} 76 |
84unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum, 85 bool &isSPVFP) { | 77unsigned ARMBaseRegisterInfo::getRegisterNumbering(unsigned RegEnum, 78 bool &isSPVFP) { |
86 isSPVFP = false; 87 88 using namespace ARM; 89 switch (RegEnum) { 90 default: 91 assert(0 && "Unknown ARM register!"); 92 abort(); 93 case R0: case D0: return 0; --- 9 unchanged lines hidden (view full) --- 103 case R10: case D10: return 10; 104 case R11: case D11: return 11; 105 case R12: case D12: return 12; 106 case SP: case D13: return 13; 107 case LR: case D14: return 14; 108 case PC: case D15: return 15; 109 110 case S0: case S1: case S2: case S3: | 79 isSPVFP = false; 80 81 using namespace ARM; 82 switch (RegEnum) { 83 default: 84 assert(0 && "Unknown ARM register!"); 85 abort(); 86 case R0: case D0: return 0; --- 9 unchanged lines hidden (view full) --- 96 case R10: case D10: return 10; 97 case R11: case D11: return 11; 98 case R12: case D12: return 12; 99 case SP: case D13: return 13; 100 case LR: case D14: return 14; 101 case PC: case D15: return 15; 102 103 case S0: case S1: case S2: case S3: |
111 case S4: case S5: case S6: case S7: 112 case S8: case S9: case S10: case S11: 113 case S12: case S13: case S14: case S15: 114 case S16: case S17: case S18: case S19: 115 case S20: case S21: case S22: case S23: 116 case S24: case S25: case S26: case S27: | 104 case S4: case S5: case S6: case S7: 105 case S8: case S9: case S10: case S11: 106 case S12: case S13: case S14: case S15: 107 case S16: case S17: case S18: case S19: 108 case S20: case S21: case S22: case S23: 109 case S24: case S25: case S26: case S27: |
117 case S28: case S29: case S30: case S31: { 118 isSPVFP = true; 119 switch (RegEnum) { 120 default: return 0; // Avoid compile time warning. 121 case S0: return 0; 122 case S1: return 1; 123 case S2: return 2; 124 case S3: return 3; --- 25 unchanged lines hidden (view full) --- 150 case S29: return 29; 151 case S30: return 30; 152 case S31: return 31; 153 } 154 } 155 } 156} 157 | 110 case S28: case S29: case S30: case S31: { 111 isSPVFP = true; 112 switch (RegEnum) { 113 default: return 0; // Avoid compile time warning. 114 case S0: return 0; 115 case S1: return 1; 116 case S2: return 2; 117 case S3: return 3; --- 25 unchanged lines hidden (view full) --- 143 case S29: return 29; 144 case S30: return 30; 145 case S31: return 31; 146 } 147 } 148 } 149} 150 |
158ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, 159 const ARMSubtarget &sti) | 151ARMBaseRegisterInfo::ARMBaseRegisterInfo(const TargetInstrInfo &tii, 152 const ARMSubtarget &sti) |
160 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), 161 TII(tii), STI(sti), 162 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) { 163} 164 | 153 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), 154 TII(tii), STI(sti), 155 FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11) { 156} 157 |
158ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, 159 const ARMSubtarget &sti) 160 : ARMBaseRegisterInfo(tii, sti) { 161} 162 |
|
165static inline 166const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 167 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 168} 169 170static inline 171const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 172 return MIB.addReg(0); 173} 174 175/// emitLoadConstPool - Emits a load from constpool to materialize the 176/// specified immediate. 177void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 178 MachineBasicBlock::iterator &MBBI, | 163static inline 164const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { 165 return MIB.addImm((int64_t)ARMCC::AL).addReg(0); 166} 167 168static inline 169const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 170 return MIB.addReg(0); 171} 172 173/// emitLoadConstPool - Emits a load from constpool to materialize the 174/// specified immediate. 175void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, 176 MachineBasicBlock::iterator &MBBI, |
177 const TargetInstrInfo *TII, DebugLoc dl, |
|
179 unsigned DestReg, int Val, | 178 unsigned DestReg, int Val, |
180 unsigned Pred, unsigned PredReg, 181 const TargetInstrInfo *TII, 182 bool isThumb, 183 DebugLoc dl) const { | 179 ARMCC::CondCodes Pred, 180 unsigned PredReg) const { |
184 MachineFunction &MF = *MBB.getParent(); 185 MachineConstantPool *ConstantPool = MF.getConstantPool(); 186 Constant *C = ConstantInt::get(Type::Int32Ty, Val); 187 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); | 181 MachineFunction &MF = *MBB.getParent(); 182 MachineConstantPool *ConstantPool = MF.getConstantPool(); 183 Constant *C = ConstantInt::get(Type::Int32Ty, Val); 184 unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); |
188 if (isThumb) 189 BuildMI(MBB, MBBI, dl, 190 TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx); 191 else 192 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg) 193 .addConstantPoolIndex(Idx) 194 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 195} | |
196 | 185 |
197/// isLowRegister - Returns true if the register is low register r0-r7. 198/// 199bool ARMRegisterInfo::isLowRegister(unsigned Reg) const { 200 using namespace ARM; 201 switch (Reg) { 202 case R0: case R1: case R2: case R3: 203 case R4: case R5: case R6: case R7: 204 return true; 205 default: 206 return false; 207 } | 186 BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg) 187 .addConstantPoolIndex(Idx) 188 .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); |
208} 209 | 189} 190 |
210const TargetRegisterClass* 211ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const { 212 if (STI.isThumb()) { 213 if (isLowRegister(Reg)) 214 return ARM::tGPRRegisterClass; 215 switch (Reg) { 216 default: 217 break; 218 case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: 219 case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: 220 return ARM::GPRRegisterClass; 221 } 222 } 223 return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); 224} 225 | |
226const unsigned* | 191const unsigned* |
227ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { | 192ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { |
228 static const unsigned CalleeSavedRegs[] = { 229 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, 230 ARM::R7, ARM::R6, ARM::R5, ARM::R4, 231 232 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 233 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 234 0 235 }; --- 7 unchanged lines hidden (view full) --- 243 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 244 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 245 0 246 }; 247 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs; 248} 249 250const TargetRegisterClass* const * | 193 static const unsigned CalleeSavedRegs[] = { 194 ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, 195 ARM::R7, ARM::R6, ARM::R5, ARM::R4, 196 197 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 198 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 199 0 200 }; --- 7 unchanged lines hidden (view full) --- 208 ARM::D15, ARM::D14, ARM::D13, ARM::D12, 209 ARM::D11, ARM::D10, ARM::D9, ARM::D8, 210 0 211 }; 212 return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs; 213} 214 215const TargetRegisterClass* const * |
251ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { | 216ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { |
252 static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 253 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 254 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 255 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 256 257 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 258 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 259 0 --- 32 unchanged lines hidden (view full) --- 292 if (STI.isThumb()) { 293 return STI.isTargetDarwin() 294 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses; 295 } 296 return STI.isTargetDarwin() 297 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses; 298} 299 | 217 static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 218 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 219 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 220 &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, 221 222 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 223 &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 224 0 --- 32 unchanged lines hidden (view full) --- 257 if (STI.isThumb()) { 258 return STI.isTargetDarwin() 259 ? DarwinThumbCalleeSavedRegClasses : ThumbCalleeSavedRegClasses; 260 } 261 return STI.isTargetDarwin() 262 ? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses; 263} 264 |
300BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { | 265BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const { |
301 // FIXME: avoid re-calculating this everytime. 302 BitVector Reserved(getNumRegs()); 303 Reserved.set(ARM::SP); 304 Reserved.set(ARM::PC); 305 if (STI.isTargetDarwin() || hasFP(MF)) 306 Reserved.set(FramePtr); 307 // Some targets reserve R9. 308 if (STI.isR9Reserved()) 309 Reserved.set(ARM::R9); 310 return Reserved; 311} 312 313bool | 266 // FIXME: avoid re-calculating this everytime. 267 BitVector Reserved(getNumRegs()); 268 Reserved.set(ARM::SP); 269 Reserved.set(ARM::PC); 270 if (STI.isTargetDarwin() || hasFP(MF)) 271 Reserved.set(FramePtr); 272 // Some targets reserve R9. 273 if (STI.isR9Reserved()) 274 Reserved.set(ARM::R9); 275 return Reserved; 276} 277 278bool |
314ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const { | 279ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const { |
315 switch (Reg) { 316 default: break; 317 case ARM::SP: 318 case ARM::PC: 319 return true; 320 case ARM::R7: 321 case ARM::R11: 322 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF))) 323 return true; 324 break; 325 case ARM::R9: 326 return STI.isR9Reserved(); 327 } 328 329 return false; 330} 331 | 280 switch (Reg) { 281 default: break; 282 case ARM::SP: 283 case ARM::PC: 284 return true; 285 case ARM::R7: 286 case ARM::R11: 287 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF))) 288 return true; 289 break; 290 case ARM::R9: 291 return STI.isR9Reserved(); 292 } 293 294 return false; 295} 296 |
332const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const { | 297const TargetRegisterClass *ARMBaseRegisterInfo::getPointerRegClass() const { |
333 return &ARM::GPRRegClass; 334} 335 336/// getAllocationOrder - Returns the register allocation order for a specified 337/// register class in the form of a pair of TargetRegisterClass iterators. 338std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> | 298 return &ARM::GPRRegClass; 299} 300 301/// getAllocationOrder - Returns the register allocation order for a specified 302/// register class in the form of a pair of TargetRegisterClass iterators. 303std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator> |
339ARMRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC, 340 unsigned HintType, unsigned HintReg, 341 const MachineFunction &MF) const { | 304ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC, 305 unsigned HintType, unsigned HintReg, 306 const MachineFunction &MF) const { |
342 // Alternative register allocation orders when favoring even / odd registers 343 // of register pairs. 344 345 // No FP, R9 is available. 346 static const unsigned GPREven1[] = { 347 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10, 348 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, 349 ARM::R9, ARM::R11 --- 124 unchanged lines hidden (view full) --- 474 } 475 return std::make_pair(RC->allocation_order_begin(MF), 476 RC->allocation_order_end(MF)); 477} 478 479/// ResolveRegAllocHint - Resolves the specified register allocation hint 480/// to a physical register. Returns the physical register if it is successful. 481unsigned | 307 // Alternative register allocation orders when favoring even / odd registers 308 // of register pairs. 309 310 // No FP, R9 is available. 311 static const unsigned GPREven1[] = { 312 ARM::R0, ARM::R2, ARM::R4, ARM::R6, ARM::R8, ARM::R10, 313 ARM::R1, ARM::R3, ARM::R12,ARM::LR, ARM::R5, ARM::R7, 314 ARM::R9, ARM::R11 --- 124 unchanged lines hidden (view full) --- 439 } 440 return std::make_pair(RC->allocation_order_begin(MF), 441 RC->allocation_order_end(MF)); 442} 443 444/// ResolveRegAllocHint - Resolves the specified register allocation hint 445/// to a physical register. Returns the physical register if it is successful. 446unsigned |
482ARMRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg, 483 const MachineFunction &MF) const { | 447ARMBaseRegisterInfo::ResolveRegAllocHint(unsigned Type, unsigned Reg, 448 const MachineFunction &MF) const { |
484 if (Reg == 0 || !isPhysicalRegister(Reg)) 485 return 0; 486 if (Type == 0) 487 return Reg; 488 else if (Type == (unsigned)ARMRI::RegPairOdd) 489 // Odd register. 490 return getRegisterPairOdd(Reg, MF); 491 else if (Type == (unsigned)ARMRI::RegPairEven) 492 // Even register. 493 return getRegisterPairEven(Reg, MF); 494 return 0; 495} 496 497void | 449 if (Reg == 0 || !isPhysicalRegister(Reg)) 450 return 0; 451 if (Type == 0) 452 return Reg; 453 else if (Type == (unsigned)ARMRI::RegPairOdd) 454 // Odd register. 455 return getRegisterPairOdd(Reg, MF); 456 else if (Type == (unsigned)ARMRI::RegPairEven) 457 // Even register. 458 return getRegisterPairEven(Reg, MF); 459 return 0; 460} 461 462void |
498ARMRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg, 499 MachineFunction &MF) const { | 463ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg, 464 MachineFunction &MF) const { |
500 MachineRegisterInfo *MRI = &MF.getRegInfo(); 501 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg); 502 if ((Hint.first == (unsigned)ARMRI::RegPairOdd || 503 Hint.first == (unsigned)ARMRI::RegPairEven) && 504 Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) { 505 // If 'Reg' is one of the even / odd register pair and it's now changed 506 // (e.g. coalesced) into a different register. The other register of the 507 // pair allocation hint must be updated to reflect the relationship 508 // change. 509 unsigned OtherReg = Hint.second; 510 Hint = MRI->getRegAllocationHint(OtherReg); 511 if (Hint.second == Reg) 512 // Make sure the pair has not already divorced. 513 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); 514 } 515} 516 517bool 518ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { | 465 MachineRegisterInfo *MRI = &MF.getRegInfo(); 466 std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(Reg); 467 if ((Hint.first == (unsigned)ARMRI::RegPairOdd || 468 Hint.first == (unsigned)ARMRI::RegPairEven) && 469 Hint.second && TargetRegisterInfo::isVirtualRegister(Hint.second)) { 470 // If 'Reg' is one of the even / odd register pair and it's now changed 471 // (e.g. coalesced) into a different register. The other register of the 472 // pair allocation hint must be updated to reflect the relationship 473 // change. 474 unsigned OtherReg = Hint.second; 475 Hint = MRI->getRegAllocationHint(OtherReg); 476 if (Hint.second == Reg) 477 // Make sure the pair has not already divorced. 478 MRI->setRegAllocationHint(OtherReg, Hint.first, NewReg); 479 } 480} 481 482bool 483ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { |
519 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 520 return ThumbRegScavenging || !AFI->isThumbFunction(); | 484 return true; |
521} 522 523/// hasFP - Return true if the specified function should have a dedicated frame 524/// pointer register. This is true if the function has variable sized allocas 525/// or if frame pointer elimination is disabled. 526/// | 485} 486 487/// hasFP - Return true if the specified function should have a dedicated frame 488/// pointer register. This is true if the function has variable sized allocas 489/// or if frame pointer elimination is disabled. 490/// |
527bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const { | 491bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const { |
528 const MachineFrameInfo *MFI = MF.getFrameInfo(); 529 return (NoFramePointerElim || 530 MFI->hasVarSizedObjects() || 531 MFI->isFrameAddressTaken()); 532} 533 534// hasReservedCallFrame - Under normal circumstances, when a frame pointer is 535// not required, we reserve argument space for call sites in the function 536// immediately on entry to the current function. This eliminates the need for 537// add/sub sp brackets around call sites. Returns true if the call frame is 538// included as part of the stack frame. 539bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 540 const MachineFrameInfo *FFI = MF.getFrameInfo(); 541 unsigned CFSize = FFI->getMaxCallFrameSize(); | 492 const MachineFrameInfo *MFI = MF.getFrameInfo(); 493 return (NoFramePointerElim || 494 MFI->hasVarSizedObjects() || 495 MFI->isFrameAddressTaken()); 496} 497 498// hasReservedCallFrame - Under normal circumstances, when a frame pointer is 499// not required, we reserve argument space for call sites in the function 500// immediately on entry to the current function. This eliminates the need for 501// add/sub sp brackets around call sites. Returns true if the call frame is 502// included as part of the stack frame. 503bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { 504 const MachineFrameInfo *FFI = MF.getFrameInfo(); 505 unsigned CFSize = FFI->getMaxCallFrameSize(); |
542 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | |
543 // It's not always a good idea to include the call frame as part of the 544 // stack frame. ARM (especially Thumb) has small immediate offset to 545 // address the stack frame. So a large call frame can cause poor codegen 546 // and may even makes it impossible to scavenge a register. | 506 // It's not always a good idea to include the call frame as part of the 507 // stack frame. ARM (especially Thumb) has small immediate offset to 508 // address the stack frame. So a large call frame can cause poor codegen 509 // and may even makes it impossible to scavenge a register. |
547 if (AFI->isThumbFunction()) { 548 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 549 return false; 550 } else { 551 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 552 return false; 553 } | 510 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 511 return false; 512 |
554 return !MF.getFrameInfo()->hasVarSizedObjects(); 555} 556 557/// emitARMRegPlusImmediate - Emits a series of instructions to materialize 558/// a destreg = basereg + immediate in ARM code. 559static 560void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 561 MachineBasicBlock::iterator &MBBI, 562 unsigned DestReg, unsigned BaseReg, int NumBytes, 563 ARMCC::CondCodes Pred, unsigned PredReg, 564 const TargetInstrInfo &TII, 565 DebugLoc dl) { 566 bool isSub = NumBytes < 0; 567 if (isSub) NumBytes = -NumBytes; 568 569 while (NumBytes) { 570 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 571 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 572 assert(ThisVal && "Didn't extract field correctly"); | 513 return !MF.getFrameInfo()->hasVarSizedObjects(); 514} 515 516/// emitARMRegPlusImmediate - Emits a series of instructions to materialize 517/// a destreg = basereg + immediate in ARM code. 518static 519void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 520 MachineBasicBlock::iterator &MBBI, 521 unsigned DestReg, unsigned BaseReg, int NumBytes, 522 ARMCC::CondCodes Pred, unsigned PredReg, 523 const TargetInstrInfo &TII, 524 DebugLoc dl) { 525 bool isSub = NumBytes < 0; 526 if (isSub) NumBytes = -NumBytes; 527 528 while (NumBytes) { 529 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes); 530 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt); 531 assert(ThisVal && "Didn't extract field correctly"); |
573 | 532 |
574 // We will handle these bits from offset, clear them. 575 NumBytes &= ~ThisVal; | 533 // We will handle these bits from offset, clear them. 534 NumBytes &= ~ThisVal; |
576 | 535 |
577 // Get the properly encoded SOImmVal field. 578 int SOImmVal = ARM_AM::getSOImmVal(ThisVal); 579 assert(SOImmVal != -1 && "Bit extraction didn't work?"); | 536 // Get the properly encoded SOImmVal field. 537 int SOImmVal = ARM_AM::getSOImmVal(ThisVal); 538 assert(SOImmVal != -1 && "Bit extraction didn't work?"); |
580 | 539 |
581 // Build the new ADD / SUB. 582 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) 583 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal) 584 .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 585 BaseReg = DestReg; 586 } 587} 588 | 540 // Build the new ADD / SUB. 541 BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) 542 .addReg(BaseReg, RegState::Kill).addImm(SOImmVal) 543 .addImm((unsigned)Pred).addReg(PredReg).addReg(0); 544 BaseReg = DestReg; 545 } 546} 547 |
589/// calcNumMI - Returns the number of instructions required to materialize 590/// the specific add / sub r, c instruction. 591static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, 592 unsigned NumBits, unsigned Scale) { 593 unsigned NumMIs = 0; 594 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 595 596 if (Opc == ARM::tADDrSPi) { 597 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 598 Bytes -= ThisVal; 599 NumMIs++; 600 NumBits = 8; 601 Scale = 1; // Followed by a number of tADDi8. 602 Chunk = ((1 << NumBits) - 1) * Scale; 603 } 604 605 NumMIs += Bytes / Chunk; 606 if ((Bytes % Chunk) != 0) 607 NumMIs++; 608 if (ExtraOpc) 609 NumMIs++; 610 return NumMIs; | 548static void 549emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 550 const TargetInstrInfo &TII, DebugLoc dl, 551 int NumBytes, 552 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) { 553 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, 554 Pred, PredReg, TII, dl); |
611} 612 | 555} 556 |
613/// emitThumbRegPlusImmInReg - Emits a series of instructions to materialize 614/// a destreg = basereg + immediate in Thumb code. Materialize the immediate 615/// in a register using mov / mvn sequences or load the immediate from a 616/// constpool entry. 617static 618void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, 619 MachineBasicBlock::iterator &MBBI, 620 unsigned DestReg, unsigned BaseReg, 621 int NumBytes, bool CanChangeCC, 622 const TargetInstrInfo &TII, 623 const ARMRegisterInfo& MRI, 624 DebugLoc dl) { 625 bool isHigh = !MRI.isLowRegister(DestReg) || 626 (BaseReg != 0 && !MRI.isLowRegister(BaseReg)); 627 bool isSub = false; 628 // Subtract doesn't have high register version. Load the negative value 629 // if either base or dest register is a high register. Also, if do not 630 // issue sub as part of the sequence if condition register is to be 631 // preserved. 632 if (NumBytes < 0 && !isHigh && CanChangeCC) { 633 isSub = true; 634 NumBytes = -NumBytes; 635 } 636 unsigned LdReg = DestReg; 637 if (DestReg == ARM::SP) { 638 assert(BaseReg == ARM::SP && "Unexpected!"); 639 LdReg = ARM::R3; 640 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 641 .addReg(ARM::R3, RegState::Kill); 642 } 643 644 if (NumBytes <= 255 && NumBytes >= 0) 645 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 646 else if (NumBytes < 0 && NumBytes >= -255) { 647 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); 648 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg) 649 .addReg(LdReg, RegState::Kill); 650 } else 651 MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII, 652 true, dl); 653 654 // Emit add / sub. 655 int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); 656 const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, 657 TII.get(Opc), DestReg); 658 if (DestReg == ARM::SP || isSub) 659 MIB.addReg(BaseReg).addReg(LdReg, RegState::Kill); 660 else 661 MIB.addReg(LdReg).addReg(BaseReg, RegState::Kill); 662 if (DestReg == ARM::SP) 663 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 664 .addReg(ARM::R12, RegState::Kill); 665} 666 667/// emitThumbRegPlusImmediate - Emits a series of instructions to materialize 668/// a destreg = basereg + immediate in Thumb code. 669static 670void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 671 MachineBasicBlock::iterator &MBBI, 672 unsigned DestReg, unsigned BaseReg, 673 int NumBytes, const TargetInstrInfo &TII, 674 const ARMRegisterInfo& MRI, 675 DebugLoc dl) { 676 bool isSub = NumBytes < 0; 677 unsigned Bytes = (unsigned)NumBytes; 678 if (isSub) Bytes = -NumBytes; 679 bool isMul4 = (Bytes & 3) == 0; 680 bool isTwoAddr = false; 681 bool DstNotEqBase = false; 682 unsigned NumBits = 1; 683 unsigned Scale = 1; 684 int Opc = 0; 685 int ExtraOpc = 0; 686 687 if (DestReg == BaseReg && BaseReg == ARM::SP) { 688 assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!"); 689 NumBits = 7; 690 Scale = 4; 691 Opc = isSub ? ARM::tSUBspi : ARM::tADDspi; 692 isTwoAddr = true; 693 } else if (!isSub && BaseReg == ARM::SP) { 694 // r1 = add sp, 403 695 // => 696 // r1 = add sp, 100 * 4 697 // r1 = add r1, 3 698 if (!isMul4) { 699 Bytes &= ~3; 700 ExtraOpc = ARM::tADDi3; 701 } 702 NumBits = 8; 703 Scale = 4; 704 Opc = ARM::tADDrSPi; 705 } else { 706 // sp = sub sp, c 707 // r1 = sub sp, c 708 // r8 = sub sp, c 709 if (DestReg != BaseReg) 710 DstNotEqBase = true; 711 NumBits = 8; 712 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 713 isTwoAddr = true; 714 } 715 716 unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale); 717 unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2; 718 if (NumMIs > Threshold) { 719 // This will expand into too many instructions. Load the immediate from a 720 // constpool entry. 721 emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, 722 MRI, dl); 723 return; 724 } 725 726 if (DstNotEqBase) { 727 if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) { 728 // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) 729 unsigned Chunk = (1 << 3) - 1; 730 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 731 Bytes -= ThisVal; 732 BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) 733 .addReg(BaseReg, RegState::Kill).addImm(ThisVal); 734 } else { 735 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) 736 .addReg(BaseReg, RegState::Kill); 737 } 738 BaseReg = DestReg; 739 } 740 741 unsigned Chunk = ((1 << NumBits) - 1) * Scale; 742 while (Bytes) { 743 unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; 744 Bytes -= ThisVal; 745 ThisVal /= Scale; 746 // Build the new tADD / tSUB. 747 if (isTwoAddr) 748 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 749 .addReg(DestReg).addImm(ThisVal); 750 else { 751 bool isKill = BaseReg != ARM::SP; 752 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) 753 .addReg(BaseReg, getKillRegState(isKill)).addImm(ThisVal); 754 BaseReg = DestReg; 755 756 if (Opc == ARM::tADDrSPi) { 757 // r4 = add sp, imm 758 // r4 = add r4, imm 759 // ... 760 NumBits = 8; 761 Scale = 1; 762 Chunk = ((1 << NumBits) - 1) * Scale; 763 Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8; 764 isTwoAddr = true; 765 } 766 } 767 } 768 769 if (ExtraOpc) 770 BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg) 771 .addReg(DestReg, RegState::Kill) 772 .addImm(((unsigned)NumBytes) & 3); 773} 774 775static 776void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 777 int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, 778 bool isThumb, const TargetInstrInfo &TII, 779 const ARMRegisterInfo& MRI, 780 DebugLoc dl) { 781 if (isThumb) 782 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII, 783 MRI, dl); 784 else 785 emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, 786 Pred, PredReg, TII, dl); 787} 788 | |
789void ARMRegisterInfo:: 790eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 791 MachineBasicBlock::iterator I) const { 792 if (!hasReservedCallFrame(MF)) { 793 // If we have alloca, convert as follows: 794 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 795 // ADJCALLSTACKUP -> add, sp, sp, amount 796 MachineInstr *Old = I; 797 DebugLoc dl = Old->getDebugLoc(); 798 unsigned Amount = Old->getOperand(0).getImm(); 799 if (Amount != 0) { | 557void ARMRegisterInfo:: 558eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 559 MachineBasicBlock::iterator I) const { 560 if (!hasReservedCallFrame(MF)) { 561 // If we have alloca, convert as follows: 562 // ADJCALLSTACKDOWN -> sub, sp, sp, amount 563 // ADJCALLSTACKUP -> add, sp, sp, amount 564 MachineInstr *Old = I; 565 DebugLoc dl = Old->getDebugLoc(); 566 unsigned Amount = Old->getOperand(0).getImm(); 567 if (Amount != 0) { |
800 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | |
801 // We need to keep the stack aligned properly. To do this, we round the 802 // amount of space needed for the outgoing arguments up to the next 803 // alignment boundary. 804 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 805 Amount = (Amount+Align-1)/Align*Align; 806 807 // Replace the pseudo instruction with a new instruction... 808 unsigned Opc = Old->getOpcode(); | 568 // We need to keep the stack aligned properly. To do this, we round the 569 // amount of space needed for the outgoing arguments up to the next 570 // alignment boundary. 571 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 572 Amount = (Amount+Align-1)/Align*Align; 573 574 // Replace the pseudo instruction with a new instruction... 575 unsigned Opc = Old->getOpcode(); |
809 bool isThumb = AFI->isThumbFunction(); 810 ARMCC::CondCodes Pred = isThumb 811 ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm(); | 576 ARMCC::CondCodes Pred = (ARMCC::CondCodes)Old->getOperand(1).getImm(); |
812 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 813 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. | 577 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 578 // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. |
814 unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg(); 815 emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl); | 579 unsigned PredReg = Old->getOperand(2).getReg(); 580 emitSPUpdate(MBB, I, TII, dl, -Amount, Pred, PredReg); |
816 } else { 817 // Note: PredReg is operand 3 for ADJCALLSTACKUP. | 581 } else { 582 // Note: PredReg is operand 3 for ADJCALLSTACKUP. |
818 unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg(); | 583 unsigned PredReg = Old->getOperand(3).getReg(); |
819 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); | 584 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); |
820 emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl); | 585 emitSPUpdate(MBB, I, TII, dl, Amount, Pred, PredReg); |
821 } 822 } 823 } 824 MBB.erase(I); 825} 826 | 586 } 587 } 588 } 589 MBB.erase(I); 590} 591 |
827/// emitThumbConstant - Emit a series of instructions to materialize a 828/// constant. 829static void emitThumbConstant(MachineBasicBlock &MBB, 830 MachineBasicBlock::iterator &MBBI, 831 unsigned DestReg, int Imm, 832 const TargetInstrInfo &TII, 833 const ARMRegisterInfo& MRI, 834 DebugLoc dl) { 835 bool isSub = Imm < 0; 836 if (isSub) Imm = -Imm; 837 838 int Chunk = (1 << 8) - 1; 839 int ThisVal = (Imm > Chunk) ? Chunk : Imm; 840 Imm -= ThisVal; 841 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); 842 if (Imm > 0) 843 emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl); 844 if (isSub) 845 BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg) 846 .addReg(DestReg, RegState::Kill); 847} 848 | |
849/// findScratchRegister - Find a 'free' ARM register. If register scavenger 850/// is not being used, R12 is available. Otherwise, try for a call-clobbered 851/// register first and then a spilled callee-saved register if that fails. 852static 853unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, 854 ARMFunctionInfo *AFI) { 855 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; 856 assert (!AFI->isThumbFunction()); --- 6 unchanged lines hidden (view full) --- 863 864void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 865 int SPAdj, RegScavenger *RS) const{ 866 unsigned i = 0; 867 MachineInstr &MI = *II; 868 MachineBasicBlock &MBB = *MI.getParent(); 869 MachineFunction &MF = *MBB.getParent(); 870 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 592/// findScratchRegister - Find a 'free' ARM register. If register scavenger 593/// is not being used, R12 is available. Otherwise, try for a call-clobbered 594/// register first and then a spilled callee-saved register if that fails. 595static 596unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, 597 ARMFunctionInfo *AFI) { 598 unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; 599 assert (!AFI->isThumbFunction()); --- 6 unchanged lines hidden (view full) --- 606 607void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 608 int SPAdj, RegScavenger *RS) const{ 609 unsigned i = 0; 610 MachineInstr &MI = *II; 611 MachineBasicBlock &MBB = *MI.getParent(); 612 MachineFunction &MF = *MBB.getParent(); 613 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
871 bool isThumb = AFI->isThumbFunction(); | |
872 DebugLoc dl = MI.getDebugLoc(); 873 874 while (!MI.getOperand(i).isFI()) { 875 ++i; 876 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 877 } | 614 DebugLoc dl = MI.getDebugLoc(); 615 616 while (!MI.getOperand(i).isFI()) { 617 ++i; 618 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 619 } |
878 | 620 |
879 unsigned FrameReg = ARM::SP; 880 int FrameIndex = MI.getOperand(i).getIndex(); | 621 unsigned FrameReg = ARM::SP; 622 int FrameIndex = MI.getOperand(i).getIndex(); |
881 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + | 623 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + |
882 MF.getFrameInfo()->getStackSize() + SPAdj; 883 884 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 885 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 886 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 887 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 888 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) 889 Offset -= AFI->getDPRCalleeSavedAreaOffset(); --- 31 unchanged lines hidden (view full) --- 921 // Common case: small offset, fits into instruction. 922 int ImmedOffset = ARM_AM::getSOImmVal(Offset); 923 if (ImmedOffset != -1) { 924 // Replace the FrameIndex with sp / fp 925 MI.getOperand(i).ChangeToRegister(FrameReg, false); 926 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); 927 return; 928 } | 624 MF.getFrameInfo()->getStackSize() + SPAdj; 625 626 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) 627 Offset -= AFI->getGPRCalleeSavedArea1Offset(); 628 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex)) 629 Offset -= AFI->getGPRCalleeSavedArea2Offset(); 630 else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) 631 Offset -= AFI->getDPRCalleeSavedAreaOffset(); --- 31 unchanged lines hidden (view full) --- 663 // Common case: small offset, fits into instruction. 664 int ImmedOffset = ARM_AM::getSOImmVal(Offset); 665 if (ImmedOffset != -1) { 666 // Replace the FrameIndex with sp / fp 667 MI.getOperand(i).ChangeToRegister(FrameReg, false); 668 MI.getOperand(i+1).ChangeToImmediate(ImmedOffset); 669 return; 670 } |
929 | 671 |
930 // Otherwise, we fallback to common code below to form the imm offset with 931 // a sequence of ADDri instructions. First though, pull as much of the imm 932 // into this ADDri as possible. 933 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 934 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); | 672 // Otherwise, we fallback to common code below to form the imm offset with 673 // a sequence of ADDri instructions. First though, pull as much of the imm 674 // into this ADDri as possible. 675 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset); 676 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt); |
935 | 677 |
936 // We will handle these bits from offset, clear them. 937 Offset &= ~ThisImmVal; | 678 // We will handle these bits from offset, clear them. 679 Offset &= ~ThisImmVal; |
938 | 680 |
939 // Get the properly encoded SOImmVal field. 940 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); | 681 // Get the properly encoded SOImmVal field. 682 int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal); |
941 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); | 683 assert(ThisSOImmVal != -1 && "Bit extraction didn't work?"); |
942 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); | 684 MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal); |
943 } else if (Opcode == ARM::tADDrSPi) { 944 Offset += MI.getOperand(i+1).getImm(); 945 946 // Can't use tADDrSPi if it's based off the frame pointer. 947 unsigned NumBits = 0; 948 unsigned Scale = 1; 949 if (FrameReg != ARM::SP) { 950 Opcode = ARM::tADDi3; 951 MI.setDesc(TII.get(ARM::tADDi3)); 952 NumBits = 3; 953 } else { 954 NumBits = 8; 955 Scale = 4; 956 assert((Offset & 3) == 0 && 957 "Thumb add/sub sp, #imm immediate must be multiple of 4!"); 958 } 959 960 if (Offset == 0) { 961 // Turn it into a move. 962 MI.setDesc(TII.get(ARM::tMOVhir2lor)); 963 MI.getOperand(i).ChangeToRegister(FrameReg, false); 964 MI.RemoveOperand(i+1); 965 return; 966 } 967 968 // Common case: small offset, fits into instruction. 969 unsigned Mask = (1 << NumBits) - 1; 970 if (((Offset / Scale) & ~Mask) == 0) { 971 // Replace the FrameIndex with sp / fp 972 MI.getOperand(i).ChangeToRegister(FrameReg, false); 973 MI.getOperand(i+1).ChangeToImmediate(Offset / Scale); 974 return; 975 } 976 977 unsigned DestReg = MI.getOperand(0).getReg(); 978 unsigned Bytes = (Offset > 0) ? Offset : -Offset; 979 unsigned NumMIs = calcNumMI(Opcode, 0, Bytes, NumBits, Scale); 980 // MI would expand into a large number of instructions. Don't try to 981 // simplify the immediate. 982 if (NumMIs > 2) { 983 emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, 984 *this, dl); 985 MBB.erase(II); 986 return; 987 } 988 989 if (Offset > 0) { 990 // Translate r0 = add sp, imm to 991 // r0 = add sp, 255*4 992 // r0 = add r0, (imm - 255*4) 993 MI.getOperand(i).ChangeToRegister(FrameReg, false); 994 MI.getOperand(i+1).ChangeToImmediate(Mask); 995 Offset = (Offset - Mask * Scale); 996 MachineBasicBlock::iterator NII = next(II); 997 emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, 998 *this, dl); 999 } else { 1000 // Translate r0 = add sp, -imm to 1001 // r0 = -imm (this is then translated into a series of instructons) 1002 // r0 = add r0, sp 1003 emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); 1004 MI.setDesc(TII.get(ARM::tADDhirr)); 1005 MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); 1006 MI.getOperand(i+1).ChangeToRegister(FrameReg, false); 1007 } 1008 return; | |
1009 } else { 1010 unsigned ImmIdx = 0; 1011 int InstrOffs = 0; 1012 unsigned NumBits = 0; 1013 unsigned Scale = 1; 1014 switch (AddrMode) { 1015 case ARMII::AddrMode2: { 1016 ImmIdx = i+2; --- 15 unchanged lines hidden (view full) --- 1032 ImmIdx = i+1; 1033 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 1034 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 1035 InstrOffs *= -1; 1036 NumBits = 8; 1037 Scale = 4; 1038 break; 1039 } | 685 } else { 686 unsigned ImmIdx = 0; 687 int InstrOffs = 0; 688 unsigned NumBits = 0; 689 unsigned Scale = 1; 690 switch (AddrMode) { 691 case ARMII::AddrMode2: { 692 ImmIdx = i+2; --- 15 unchanged lines hidden (view full) --- 708 ImmIdx = i+1; 709 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm()); 710 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub) 711 InstrOffs *= -1; 712 NumBits = 8; 713 Scale = 4; 714 break; 715 } |
1040 case ARMII::AddrModeTs: { 1041 ImmIdx = i+1; 1042 InstrOffs = MI.getOperand(ImmIdx).getImm(); 1043 NumBits = (FrameReg == ARM::SP) ? 8 : 5; 1044 Scale = 4; 1045 break; 1046 } | |
1047 default: 1048 assert(0 && "Unsupported addressing mode!"); 1049 abort(); 1050 break; 1051 } 1052 1053 Offset += InstrOffs * Scale; 1054 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); | 716 default: 717 assert(0 && "Unsupported addressing mode!"); 718 abort(); 719 break; 720 } 721 722 Offset += InstrOffs * Scale; 723 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!"); |
1055 if (Offset < 0 && !isThumb) { | 724 if (Offset < 0) { |
1056 Offset = -Offset; 1057 isSub = true; 1058 } 1059 1060 // Common case: small offset, fits into instruction. 1061 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 1062 int ImmedOffset = Offset / Scale; 1063 unsigned Mask = (1 << NumBits) - 1; 1064 if ((unsigned)Offset <= Mask * Scale) { 1065 // Replace the FrameIndex with sp 1066 MI.getOperand(i).ChangeToRegister(FrameReg, false); 1067 if (isSub) 1068 ImmedOffset |= 1 << NumBits; 1069 ImmOp.ChangeToImmediate(ImmedOffset); 1070 return; 1071 } 1072 | 725 Offset = -Offset; 726 isSub = true; 727 } 728 729 // Common case: small offset, fits into instruction. 730 MachineOperand &ImmOp = MI.getOperand(ImmIdx); 731 int ImmedOffset = Offset / Scale; 732 unsigned Mask = (1 << NumBits) - 1; 733 if ((unsigned)Offset <= Mask * Scale) { 734 // Replace the FrameIndex with sp 735 MI.getOperand(i).ChangeToRegister(FrameReg, false); 736 if (isSub) 737 ImmedOffset |= 1 << NumBits; 738 ImmOp.ChangeToImmediate(ImmedOffset); 739 return; 740 } 741 |
1073 bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill; 1074 if (AddrMode == ARMII::AddrModeTs) { 1075 // Thumb tLDRspi, tSTRspi. These will change to instructions that use 1076 // a different base register. 1077 NumBits = 5; 1078 Mask = (1 << NumBits) - 1; 1079 } 1080 // If this is a thumb spill / restore, we will be using a constpool load to 1081 // materialize the offset. 1082 if (AddrMode == ARMII::AddrModeTs && isThumSpillRestore) 1083 ImmOp.ChangeToImmediate(0); 1084 else { 1085 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 1086 ImmedOffset = ImmedOffset & Mask; 1087 if (isSub) 1088 ImmedOffset |= 1 << NumBits; 1089 ImmOp.ChangeToImmediate(ImmedOffset); 1090 Offset &= ~(Mask*Scale); 1091 } | 742 // Otherwise, it didn't fit. Pull in what we can to simplify the immed. 743 ImmedOffset = ImmedOffset & Mask; 744 if (isSub) 745 ImmedOffset |= 1 << NumBits; 746 ImmOp.ChangeToImmediate(ImmedOffset); 747 Offset &= ~(Mask*Scale); |
1092 } | 748 } |
1093 | 749 |
1094 // If we get here, the immediate doesn't fit into the instruction. We folded 1095 // as much as possible above, handle the rest, providing a register that is 1096 // SP+LargeImm. 1097 assert(Offset && "This code isn't needed if offset already handled!"); 1098 | 750 // If we get here, the immediate doesn't fit into the instruction. We folded 751 // as much as possible above, handle the rest, providing a register that is 752 // SP+LargeImm. 753 assert(Offset && "This code isn't needed if offset already handled!"); 754 |
1099 if (isThumb) { 1100 if (Desc.mayLoad()) { 1101 // Use the destination register to materialize sp + offset. 1102 unsigned TmpReg = MI.getOperand(0).getReg(); 1103 bool UseRR = false; 1104 if (Opcode == ARM::tRestore) { 1105 if (FrameReg == ARM::SP) 1106 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 1107 Offset, false, TII, *this, dl); 1108 else { 1109 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, 1110 true, dl); 1111 UseRR = true; 1112 } 1113 } else 1114 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 1115 *this, dl); 1116 MI.setDesc(TII.get(ARM::tLDR)); 1117 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 1118 if (UseRR) 1119 // Use [reg, reg] addrmode. 1120 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 1121 else // tLDR has an extra register operand. 1122 MI.addOperand(MachineOperand::CreateReg(0, false)); 1123 } else if (Desc.mayStore()) { 1124 // FIXME! This is horrific!!! We need register scavenging. 1125 // Our temporary workaround has marked r3 unavailable. Of course, r3 is 1126 // also a ABI register so it's possible that is is the register that is 1127 // being storing here. If that's the case, we do the following: 1128 // r12 = r2 1129 // Use r2 to materialize sp + offset 1130 // str r3, r2 1131 // r2 = r12 1132 unsigned ValReg = MI.getOperand(0).getReg(); 1133 unsigned TmpReg = ARM::R3; 1134 bool UseRR = false; 1135 if (ValReg == ARM::R3) { 1136 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 1137 .addReg(ARM::R2, RegState::Kill); 1138 TmpReg = ARM::R2; 1139 } 1140 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 1141 BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) 1142 .addReg(ARM::R3, RegState::Kill); 1143 if (Opcode == ARM::tSpill) { 1144 if (FrameReg == ARM::SP) 1145 emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, 1146 Offset, false, TII, *this, dl); 1147 else { 1148 emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, 1149 true, dl); 1150 UseRR = true; 1151 } 1152 } else 1153 emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, 1154 *this, dl); 1155 MI.setDesc(TII.get(ARM::tSTR)); 1156 MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 1157 if (UseRR) // Use [reg, reg] addrmode. 1158 MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); 1159 else // tSTR has an extra register operand. 1160 MI.addOperand(MachineOperand::CreateReg(0, false)); 1161 1162 MachineBasicBlock::iterator NII = next(II); 1163 if (ValReg == ARM::R3) 1164 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) 1165 .addReg(ARM::R12, RegState::Kill); 1166 if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) 1167 BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) 1168 .addReg(ARM::R12, RegState::Kill); 1169 } else 1170 assert(false && "Unexpected opcode!"); 1171 } else { 1172 // Insert a set of r12 with the full address: r12 = sp + offset 1173 // If the offset we have is too large to fit into the instruction, we need 1174 // to form it with a series of ADDri's. Do this by taking 8-bit chunks 1175 // out of 'Offset'. 1176 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); 1177 if (ScratchReg == 0) 1178 // No register is "free". Scavenge a register. 1179 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); 1180 int PIdx = MI.findFirstPredOperandIdx(); 1181 ARMCC::CondCodes Pred = (PIdx == -1) 1182 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 1183 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 1184 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, 1185 isSub ? -Offset : Offset, Pred, PredReg, TII, dl); 1186 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); 1187 } | 755 // Insert a set of r12 with the full address: r12 = sp + offset 756 // If the offset we have is too large to fit into the instruction, we need 757 // to form it with a series of ADDri's. Do this by taking 8-bit chunks 758 // out of 'Offset'. 759 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); 760 if (ScratchReg == 0) 761 // No register is "free". Scavenge a register. 762 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); 763 int PIdx = MI.findFirstPredOperandIdx(); 764 ARMCC::CondCodes Pred = (PIdx == -1) 765 ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); 766 unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); 767 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, 768 isSub ? -Offset : Offset, Pred, PredReg, TII, dl); 769 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); |
1188} 1189 1190static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { 1191 const MachineFrameInfo *FFI = MF.getFrameInfo(); 1192 int Offset = 0; 1193 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 1194 int FixedOff = -FFI->getObjectOffset(i); 1195 if (FixedOff > Offset) Offset = FixedOff; --- 5 unchanged lines hidden (view full) --- 1201 unsigned Align = FFI->getObjectAlignment(i); 1202 // Adjust to alignment boundary 1203 Offset = (Offset+Align-1)/Align*Align; 1204 } 1205 return (unsigned)Offset; 1206} 1207 1208void | 770} 771 772static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { 773 const MachineFrameInfo *FFI = MF.getFrameInfo(); 774 int Offset = 0; 775 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { 776 int FixedOff = -FFI->getObjectOffset(i); 777 if (FixedOff > Offset) Offset = FixedOff; --- 5 unchanged lines hidden (view full) --- 783 unsigned Align = FFI->getObjectAlignment(i); 784 // Adjust to alignment boundary 785 Offset = (Offset+Align-1)/Align*Align; 786 } 787 return (unsigned)Offset; 788} 789 790void |
1209ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 1210 RegScavenger *RS) const { | 791ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 792 RegScavenger *RS) const { |
1211 // This tells PEI to spill the FP as if it is any other callee-save register 1212 // to take advantage the eliminateFrameIndex machinery. This also ensures it 1213 // is spilled in the order specified by getCalleeSavedRegs() to make it easier 1214 // to combine multiple loads / stores. 1215 bool CanEliminateFrame = true; 1216 bool CS1Spilled = false; 1217 bool LRSpilled = false; 1218 unsigned NumGPRSpills = 0; --- 42 unchanged lines hidden (view full) --- 1261 case ARM::R5: 1262 case ARM::R6: 1263 case ARM::R7: 1264 CS1Spilled = true; 1265 break; 1266 default: 1267 break; 1268 } | 793 // This tells PEI to spill the FP as if it is any other callee-save register 794 // to take advantage the eliminateFrameIndex machinery. This also ensures it 795 // is spilled in the order specified by getCalleeSavedRegs() to make it easier 796 // to combine multiple loads / stores. 797 bool CanEliminateFrame = true; 798 bool CS1Spilled = false; 799 bool LRSpilled = false; 800 unsigned NumGPRSpills = 0; --- 42 unchanged lines hidden (view full) --- 843 case ARM::R5: 844 case ARM::R6: 845 case ARM::R7: 846 CS1Spilled = true; 847 break; 848 default: 849 break; 850 } |
1269 } else { | 851 } else { |
1270 if (!STI.isTargetDarwin()) { 1271 UnspilledCS1GPRs.push_back(Reg); 1272 continue; 1273 } 1274 1275 switch (Reg) { 1276 case ARM::R4: 1277 case ARM::R5: --- 49 unchanged lines hidden (view full) --- 1327 // of GPRs. Spill one extra callee save GPR so we won't have to pad between 1328 // the integer and double callee save areas. 1329 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); 1330 if (TargetAlign == 8 && (NumGPRSpills & 1)) { 1331 if (CS1Spilled && !UnspilledCS1GPRs.empty()) { 1332 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { 1333 unsigned Reg = UnspilledCS1GPRs[i]; 1334 // Don't spiil high register if the function is thumb | 852 if (!STI.isTargetDarwin()) { 853 UnspilledCS1GPRs.push_back(Reg); 854 continue; 855 } 856 857 switch (Reg) { 858 case ARM::R4: 859 case ARM::R5: --- 49 unchanged lines hidden (view full) --- 909 // of GPRs. Spill one extra callee save GPR so we won't have to pad between 910 // the integer and double callee save areas. 911 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); 912 if (TargetAlign == 8 && (NumGPRSpills & 1)) { 913 if (CS1Spilled && !UnspilledCS1GPRs.empty()) { 914 for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { 915 unsigned Reg = UnspilledCS1GPRs[i]; 916 // Don't spiil high register if the function is thumb |
1335 if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) { | 917 if (!AFI->isThumbFunction() || 918 isARMLowRegister(Reg) || Reg == ARM::LR) { |
1336 MF.getRegInfo().setPhysRegUsed(Reg); 1337 AFI->setCSRegisterIsSpilled(Reg); 1338 if (!isReservedReg(MF, Reg)) 1339 ExtraCSSpill = true; 1340 break; 1341 } 1342 } 1343 } else if (!UnspilledCS2GPRs.empty() && 1344 !AFI->isThumbFunction()) { 1345 unsigned Reg = UnspilledCS2GPRs.front(); 1346 MF.getRegInfo().setPhysRegUsed(Reg); 1347 AFI->setCSRegisterIsSpilled(Reg); 1348 if (!isReservedReg(MF, Reg)) 1349 ExtraCSSpill = true; 1350 } 1351 } 1352 1353 // Estimate if we might need to scavenge a register at some point in order | 919 MF.getRegInfo().setPhysRegUsed(Reg); 920 AFI->setCSRegisterIsSpilled(Reg); 921 if (!isReservedReg(MF, Reg)) 922 ExtraCSSpill = true; 923 break; 924 } 925 } 926 } else if (!UnspilledCS2GPRs.empty() && 927 !AFI->isThumbFunction()) { 928 unsigned Reg = UnspilledCS2GPRs.front(); 929 MF.getRegInfo().setPhysRegUsed(Reg); 930 AFI->setCSRegisterIsSpilled(Reg); 931 if (!isReservedReg(MF, Reg)) 932 ExtraCSSpill = true; 933 } 934 } 935 936 // Estimate if we might need to scavenge a register at some point in order |
1354 // to materialize a stack offset. If so, either spill one additiona | 937 // to materialize a stack offset. If so, either spill one additional |
1355 // callee-saved register or reserve a special spill slot to facilitate 1356 // register scavenging. 1357 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) { 1358 MachineFrameInfo *MFI = MF.getFrameInfo(); 1359 unsigned Size = estimateStackSize(MF, MFI); 1360 unsigned Limit = (1 << 12) - 1; 1361 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) 1362 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) { --- 92 unchanged lines hidden (view full) --- 1455 } 1456} 1457 1458void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 1459 MachineBasicBlock &MBB = MF.front(); 1460 MachineBasicBlock::iterator MBBI = MBB.begin(); 1461 MachineFrameInfo *MFI = MF.getFrameInfo(); 1462 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 938 // callee-saved register or reserve a special spill slot to facilitate 939 // register scavenging. 940 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) { 941 MachineFrameInfo *MFI = MF.getFrameInfo(); 942 unsigned Size = estimateStackSize(MF, MFI); 943 unsigned Limit = (1 << 12) - 1; 944 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) 945 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) { --- 92 unchanged lines hidden (view full) --- 1038 } 1039} 1040 1041void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { 1042 MachineBasicBlock &MBB = MF.front(); 1043 MachineBasicBlock::iterator MBBI = MBB.begin(); 1044 MachineFrameInfo *MFI = MF.getFrameInfo(); 1045 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
1463 bool isThumb = AFI->isThumbFunction(); | |
1464 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1465 unsigned NumBytes = MFI->getStackSize(); 1466 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 1467 DebugLoc dl = (MBBI != MBB.end() ? 1468 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 1469 | 1046 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1047 unsigned NumBytes = MFI->getStackSize(); 1048 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 1049 DebugLoc dl = (MBBI != MBB.end() ? 1050 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 1051 |
1470 if (isThumb) { 1471 // Check if R3 is live in. It might have to be used as a scratch register. 1472 for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(), 1473 E = MF.getRegInfo().livein_end(); I != E; ++I) { 1474 if (I->first == ARM::R3) { 1475 AFI->setR3IsLiveIn(true); 1476 break; 1477 } 1478 } 1479 1480 // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 1481 NumBytes = (NumBytes + 3) & ~3; 1482 MFI->setStackSize(NumBytes); 1483 } 1484 | |
1485 // Determine the sizes of each callee-save spill areas and record which frame 1486 // belongs to which callee-save spill areas. 1487 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 1488 int FramePtrSpillFI = 0; 1489 1490 if (VARegSaveSize) | 1052 // Determine the sizes of each callee-save spill areas and record which frame 1053 // belongs to which callee-save spill areas. 1054 unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 1055 int FramePtrSpillFI = 0; 1056 1057 if (VARegSaveSize) |
1491 emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII, 1492 *this, dl); | 1058 emitSPUpdate(MBB, MBBI, TII, dl, -VARegSaveSize); |
1493 1494 if (!AFI->hasStackFrame()) { 1495 if (NumBytes != 0) | 1059 1060 if (!AFI->hasStackFrame()) { 1061 if (NumBytes != 0) |
1496 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); | 1062 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes); |
1497 return; 1498 } 1499 1500 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1501 unsigned Reg = CSI[i].getReg(); 1502 int FI = CSI[i].getFrameIdx(); 1503 switch (Reg) { 1504 case ARM::R4: --- 21 unchanged lines hidden (view full) --- 1526 } 1527 break; 1528 default: 1529 AFI->addDPRCalleeSavedAreaFrame(FI); 1530 DPRCSSize += 8; 1531 } 1532 } 1533 | 1063 return; 1064 } 1065 1066 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 1067 unsigned Reg = CSI[i].getReg(); 1068 int FI = CSI[i].getFrameIdx(); 1069 switch (Reg) { 1070 case ARM::R4: --- 21 unchanged lines hidden (view full) --- 1092 } 1093 break; 1094 default: 1095 AFI->addDPRCalleeSavedAreaFrame(FI); 1096 DPRCSSize += 8; 1097 } 1098 } 1099 |
1534 if (!isThumb) { 1535 // Build the new SUBri to adjust SP for integer callee-save spill area 1. 1536 emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl); 1537 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); 1538 } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { 1539 ++MBBI; 1540 if (MBBI != MBB.end()) 1541 dl = MBBI->getDebugLoc(); 1542 } | 1100 // Build the new SUBri to adjust SP for integer callee-save spill area 1. 1101 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS1Size); 1102 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); |
1543 1544 // Darwin ABI requires FP to point to the stack slot that contains the 1545 // previous FP. 1546 if (STI.isTargetDarwin() || hasFP(MF)) { 1547 MachineInstrBuilder MIB = | 1103 1104 // Darwin ABI requires FP to point to the stack slot that contains the 1105 // previous FP. 1106 if (STI.isTargetDarwin() || hasFP(MF)) { 1107 MachineInstrBuilder MIB = |
1548 BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), 1549 FramePtr) | 1108 BuildMI(MBB, MBBI, dl, TII.get(ARM::ADDri), FramePtr) |
1550 .addFrameIndex(FramePtrSpillFI).addImm(0); | 1109 .addFrameIndex(FramePtrSpillFI).addImm(0); |
1551 if (!isThumb) AddDefaultCC(AddDefaultPred(MIB)); | 1110 AddDefaultCC(AddDefaultPred(MIB)); |
1552 } 1553 | 1111 } 1112 |
1554 if (!isThumb) { 1555 // Build the new SUBri to adjust SP for integer callee-save spill area 2. 1556 emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl); | 1113 // Build the new SUBri to adjust SP for integer callee-save spill area 2. 1114 emitSPUpdate(MBB, MBBI, TII, dl, -GPRCS2Size); |
1557 | 1115 |
1558 // Build the new SUBri to adjust SP for FP callee-save spill area. 1559 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); 1560 emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl); 1561 } | 1116 // Build the new SUBri to adjust SP for FP callee-save spill area. 1117 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); 1118 emitSPUpdate(MBB, MBBI, TII, dl, -DPRCSSize); |
1562 1563 // Determine starting offsets of spill areas. 1564 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 1565 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 1566 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 1567 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 1568 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 1569 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 1570 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); | 1119 1120 // Determine starting offsets of spill areas. 1121 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 1122 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 1123 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 1124 AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes); 1125 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 1126 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 1127 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); |
1571 | 1128 |
1572 NumBytes = DPRCSOffset; 1573 if (NumBytes) { 1574 // Insert it after all the callee-save spills. | 1129 NumBytes = DPRCSOffset; 1130 if (NumBytes) { 1131 // Insert it after all the callee-save spills. |
1575 if (!isThumb) 1576 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); 1577 emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); | 1132 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); 1133 emitSPUpdate(MBB, MBBI, TII, dl, -NumBytes); |
1578 } 1579 | 1134 } 1135 |
1580 if(STI.isTargetELF() && hasFP(MF)) { | 1136 if (STI.isTargetELF() && hasFP(MF)) { |
1581 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 1582 AFI->getFramePtrSpillOffset()); 1583 } 1584 1585 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 1586 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 1587 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 1588} 1589 1590static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 1591 for (unsigned i = 0; CSRegs[i]; ++i) 1592 if (Reg == CSRegs[i]) 1593 return true; 1594 return false; 1595} 1596 1597static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 1598 return ((MI->getOpcode() == ARM::FLDD || | 1137 MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 1138 AFI->getFramePtrSpillOffset()); 1139 } 1140 1141 AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 1142 AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 1143 AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 1144} 1145 1146static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { 1147 for (unsigned i = 0; CSRegs[i]; ++i) 1148 if (Reg == CSRegs[i]) 1149 return true; 1150 return false; 1151} 1152 1153static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { 1154 return ((MI->getOpcode() == ARM::FLDD || |
1599 MI->getOpcode() == ARM::LDR || 1600 MI->getOpcode() == ARM::tRestore) && | 1155 MI->getOpcode() == ARM::LDR) && |
1601 MI->getOperand(1).isFI() && 1602 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 1603} 1604 1605void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 1606 MachineBasicBlock &MBB) const { 1607 MachineBasicBlock::iterator MBBI = prior(MBB.end()); | 1156 MI->getOperand(1).isFI() && 1157 isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); 1158} 1159 1160void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, 1161 MachineBasicBlock &MBB) const { 1162 MachineBasicBlock::iterator MBBI = prior(MBB.end()); |
1608 assert((MBBI->getOpcode() == ARM::BX_RET || 1609 MBBI->getOpcode() == ARM::tBX_RET || 1610 MBBI->getOpcode() == ARM::tPOP_RET) && | 1163 assert(MBBI->getOpcode() == ARM::BX_RET && |
1611 "Can only insert epilog into returning blocks"); 1612 DebugLoc dl = MBBI->getDebugLoc(); 1613 MachineFrameInfo *MFI = MF.getFrameInfo(); 1614 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 1164 "Can only insert epilog into returning blocks"); 1165 DebugLoc dl = MBBI->getDebugLoc(); 1166 MachineFrameInfo *MFI = MF.getFrameInfo(); 1167 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
1615 bool isThumb = AFI->isThumbFunction(); | |
1616 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1617 int NumBytes = (int)MFI->getStackSize(); 1618 1619 if (!AFI->hasStackFrame()) { 1620 if (NumBytes != 0) | 1168 unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); 1169 int NumBytes = (int)MFI->getStackSize(); 1170 1171 if (!AFI->hasStackFrame()) { 1172 if (NumBytes != 0) |
1621 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); | 1173 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes); |
1622 } else { 1623 // Unwind MBBI to point to first LDR / FLDD. 1624 const unsigned *CSRegs = getCalleeSavedRegs(); 1625 if (MBBI != MBB.begin()) { 1626 do 1627 --MBBI; 1628 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 1629 if (!isCSRestore(MBBI, CSRegs)) 1630 ++MBBI; 1631 } 1632 1633 // Move SP to start of FP callee save spill area. 1634 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 1635 AFI->getGPRCalleeSavedArea2Size() + 1636 AFI->getDPRCalleeSavedAreaSize()); | 1174 } else { 1175 // Unwind MBBI to point to first LDR / FLDD. 1176 const unsigned *CSRegs = getCalleeSavedRegs(); 1177 if (MBBI != MBB.begin()) { 1178 do 1179 --MBBI; 1180 while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 1181 if (!isCSRestore(MBBI, CSRegs)) 1182 ++MBBI; 1183 } 1184 1185 // Move SP to start of FP callee save spill area. 1186 NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 1187 AFI->getGPRCalleeSavedArea2Size() + 1188 AFI->getDPRCalleeSavedAreaSize()); |
1637 if (isThumb) { 1638 if (hasFP(MF)) { 1639 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 1640 // Reset SP based on frame pointer only if the stack frame extends beyond 1641 // frame pointer stack slot or target is ELF and the function has FP. | 1189 1190 // Darwin ABI requires FP to point to the stack slot that contains the 1191 // previous FP. 1192 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) { 1193 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 1194 // Reset SP based on frame pointer only if the stack frame extends beyond 1195 // frame pointer stack slot or target is ELF and the function has FP. 1196 if (AFI->getGPRCalleeSavedArea2Size() || 1197 AFI->getDPRCalleeSavedAreaSize() || 1198 AFI->getDPRCalleeSavedAreaOffset()|| 1199 hasFP(MF)) { |
1642 if (NumBytes) | 1200 if (NumBytes) |
1643 emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, 1644 TII, *this, dl); | 1201 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) 1202 .addImm(NumBytes) 1203 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); |
1645 else | 1204 else |
1646 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::SP) 1647 .addReg(FramePtr); 1648 } else { 1649 if (MBBI->getOpcode() == ARM::tBX_RET && 1650 &MBB.front() != MBBI && 1651 prior(MBBI)->getOpcode() == ARM::tPOP) { 1652 MachineBasicBlock::iterator PMBBI = prior(MBBI); 1653 emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, 1654 *this, dl); 1655 } else 1656 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, 1657 *this, dl); | 1205 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) 1206 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); |
1658 } | 1207 } |
1659 } else { 1660 // Darwin ABI requires FP to point to the stack slot that contains the 1661 // previous FP. 1662 if ((STI.isTargetDarwin() && NumBytes) || hasFP(MF)) { 1663 NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 1664 // Reset SP based on frame pointer only if the stack frame extends beyond 1665 // frame pointer stack slot or target is ELF and the function has FP. 1666 if (AFI->getGPRCalleeSavedArea2Size() || 1667 AFI->getDPRCalleeSavedAreaSize() || 1668 AFI->getDPRCalleeSavedAreaOffset()|| 1669 hasFP(MF)) { 1670 if (NumBytes) 1671 BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) 1672 .addImm(NumBytes) 1673 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 1674 else 1675 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) 1676 .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); 1677 } 1678 } else if (NumBytes) { 1679 emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl); 1680 } | 1208 } else if (NumBytes) { 1209 emitSPUpdate(MBB, MBBI, TII, dl, NumBytes); 1210 } |
1681 | 1211 |
1682 // Move SP to start of integer callee save spill area 2. 1683 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); 1684 emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0, 1685 false, TII, *this, dl); | 1212 // Move SP to start of integer callee save spill area 2. 1213 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); 1214 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getDPRCalleeSavedAreaSize()); |
1686 | 1215 |
1687 // Move SP to start of integer callee save spill area 1. 1688 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); 1689 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0, 1690 false, TII, *this, dl); | 1216 // Move SP to start of integer callee save spill area 1. 1217 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); 1218 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea2Size()); |
1691 | 1219 |
1692 // Move SP to SP upon entry to the function. 1693 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); 1694 emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0, 1695 false, TII, *this, dl); 1696 } | 1220 // Move SP to SP upon entry to the function. 1221 movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); 1222 emitSPUpdate(MBB, MBBI, TII, dl, AFI->getGPRCalleeSavedArea1Size()); |
1697 } 1698 | 1223 } 1224 |
1699 if (VARegSaveSize) { 1700 if (isThumb) 1701 // Epilogue for vararg functions: pop LR to R3 and branch off it. 1702 // FIXME: Verify this is still ok when R3 is no longer being reserved. 1703 BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3); | 1225 if (VARegSaveSize) 1226 emitSPUpdate(MBB, MBBI, TII, dl, VARegSaveSize); |
1704 | 1227 |
1705 emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII, 1706 *this, dl); 1707 1708 if (isThumb) { 1709 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); 1710 MBB.erase(MBBI); 1711 } 1712 } | |
1713} 1714 | 1228} 1229 |
1715unsigned ARMRegisterInfo::getRARegister() const { | 1230unsigned ARMBaseRegisterInfo::getRARegister() const { |
1716 return ARM::LR; 1717} 1718 | 1231 return ARM::LR; 1232} 1233 |
1719unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { | 1234unsigned ARMBaseRegisterInfo::getFrameRegister(MachineFunction &MF) const { |
1720 if (STI.isTargetDarwin() || hasFP(MF)) 1721 return FramePtr; 1722 return ARM::SP; 1723} 1724 | 1235 if (STI.isTargetDarwin() || hasFP(MF)) 1236 return FramePtr; 1237 return ARM::SP; 1238} 1239 |
1725unsigned ARMRegisterInfo::getEHExceptionRegister() const { | 1240unsigned ARMBaseRegisterInfo::getEHExceptionRegister() const { |
1726 assert(0 && "What is the exception register"); 1727 return 0; 1728} 1729 | 1241 assert(0 && "What is the exception register"); 1242 return 0; 1243} 1244 |
1730unsigned ARMRegisterInfo::getEHHandlerRegister() const { | 1245unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const { |
1731 assert(0 && "What is the exception handler register"); 1732 return 0; 1733} 1734 | 1246 assert(0 && "What is the exception handler register"); 1247 return 0; 1248} 1249 |
1735int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { | 1250int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { |
1736 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 1737} 1738 | 1251 return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 1252} 1253 |
1739unsigned ARMRegisterInfo::getRegisterPairEven(unsigned Reg, 1740 const MachineFunction &MF) const { | 1254unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg, 1255 const MachineFunction &MF) const { |
1741 switch (Reg) { 1742 default: break; 1743 // Return 0 if either register of the pair is a special register. 1744 // So no R12, etc. 1745 case ARM::R1: 1746 return ARM::R0; 1747 case ARM::R3: 1748 // FIXME! --- 56 unchanged lines hidden (view full) --- 1805 return ARM::D12; 1806 case ARM::D15: 1807 return ARM::D14; 1808 } 1809 1810 return 0; 1811} 1812 | 1256 switch (Reg) { 1257 default: break; 1258 // Return 0 if either register of the pair is a special register. 1259 // So no R12, etc. 1260 case ARM::R1: 1261 return ARM::R0; 1262 case ARM::R3: 1263 // FIXME! --- 56 unchanged lines hidden (view full) --- 1320 return ARM::D12; 1321 case ARM::D15: 1322 return ARM::D14; 1323 } 1324 1325 return 0; 1326} 1327 |
1813unsigned ARMRegisterInfo::getRegisterPairOdd(unsigned Reg, | 1328unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg, |
1814 const MachineFunction &MF) const { 1815 switch (Reg) { 1816 default: break; 1817 // Return 0 if either register of the pair is a special register. 1818 // So no R12, etc. 1819 case ARM::R0: 1820 return ARM::R1; 1821 case ARM::R2: --- 66 unchanged lines hidden --- | 1329 const MachineFunction &MF) const { 1330 switch (Reg) { 1331 default: break; 1332 // Return 0 if either register of the pair is a special register. 1333 // So no R12, etc. 1334 case ARM::R0: 1335 return ARM::R1; 1336 case ARM::R2: --- 66 unchanged lines hidden --- |