1 //===- XCoreRegisterInfo.cpp - XCore 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 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the XCore implementation of the MRegisterInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "XCoreRegisterInfo.h" 15 #include "XCoreMachineFunctionInfo.h" 16 #include "XCore.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineFrameInfo.h" 20 #include "llvm/CodeGen/MachineLocation.h" 21 #include "llvm/CodeGen/MachineModuleInfo.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/CodeGen/RegisterScavenging.h" 24 #include "llvm/Target/TargetFrameInfo.h" 25 #include "llvm/Target/TargetMachine.h" 26 #include "llvm/Target/TargetOptions.h" 27 #include "llvm/Target/TargetInstrInfo.h" 28 #include "llvm/Type.h" 29 #include "llvm/Function.h" 30 #include "llvm/ADT/BitVector.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/raw_ostream.h" 35 36 using namespace llvm; 37 38 XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) 39 : XCoreGenRegisterInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 40 TII(tii) { 41 } 42 43 // helper functions 44 static inline bool isImmUs(unsigned val) { 45 return val <= 11; 46 } 47 48 static inline bool isImmU6(unsigned val) { 49 return val < (1 << 6); 50 } 51 52 static inline bool isImmU16(unsigned val) { 53 return val < (1 << 16); 54 } 55 56 static const unsigned XCore_ArgRegs[] = { 57 XCore::R0, XCore::R1, XCore::R2, XCore::R3 58 }; 59 60 const unsigned * XCoreRegisterInfo::getArgRegs(const MachineFunction *MF) 61 { 62 return XCore_ArgRegs; 63 } 64 65 unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF) 66 { 67 return array_lengthof(XCore_ArgRegs); 68 } 69 70 bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) 71 { 72 const MachineFrameInfo *MFI = MF.getFrameInfo(); 73 MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); 74 return (MMI && MMI->hasDebugInfo()) || 75 !MF.getFunction()->doesNotThrow() || 76 UnwindTablesMandatory; 77 } 78 79 const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 80 const { 81 static const unsigned CalleeSavedRegs[] = { 82 XCore::R4, XCore::R5, XCore::R6, XCore::R7, 83 XCore::R8, XCore::R9, XCore::R10, XCore::LR, 84 0 85 }; 86 return CalleeSavedRegs; 87 } 88 89 const TargetRegisterClass* const* 90 XCoreRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 91 static const TargetRegisterClass * const CalleeSavedRegClasses[] = { 92 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 93 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 94 XCore::GRRegsRegisterClass, XCore::GRRegsRegisterClass, 95 XCore::GRRegsRegisterClass, XCore::RRegsRegisterClass, 96 0 97 }; 98 return CalleeSavedRegClasses; 99 } 100 101 BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 102 BitVector Reserved(getNumRegs()); 103 Reserved.set(XCore::CP); 104 Reserved.set(XCore::DP); 105 Reserved.set(XCore::SP); 106 Reserved.set(XCore::LR); 107 if (hasFP(MF)) { 108 Reserved.set(XCore::R10); 109 } 110 return Reserved; 111 } 112 113 bool 114 XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 115 // TODO can we estimate stack size? 116 return hasFP(MF); 117 } 118 119 bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { 120 return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); 121 } 122 123 // This function eliminates ADJCALLSTACKDOWN, 124 // ADJCALLSTACKUP pseudo instructions 125 void XCoreRegisterInfo:: 126 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 127 MachineBasicBlock::iterator I) const { 128 if (!hasReservedCallFrame(MF)) { 129 // Turn the adjcallstackdown instruction into 'extsp <amt>' and the 130 // adjcallstackup instruction into 'ldaw sp, sp[<amt>]' 131 MachineInstr *Old = I; 132 uint64_t Amount = Old->getOperand(0).getImm(); 133 if (Amount != 0) { 134 // We need to keep the stack aligned properly. To do this, we round the 135 // amount of space needed for the outgoing arguments up to the next 136 // alignment boundary. 137 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 138 Amount = (Amount+Align-1)/Align*Align; 139 140 assert(Amount%4 == 0); 141 Amount /= 4; 142 143 bool isU6 = isImmU6(Amount); 144 145 if (!isU6 && !isImmU16(Amount)) { 146 // FIX could emit multiple instructions in this case. 147 #ifndef NDEBUG 148 cerr << "eliminateCallFramePseudoInstr size too big: " 149 << Amount << "\n"; 150 #endif 151 llvm_unreachable(0); 152 } 153 154 MachineInstr *New; 155 if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) { 156 int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 157 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode)) 158 .addImm(Amount); 159 } else { 160 assert(Old->getOpcode() == XCore::ADJCALLSTACKUP); 161 int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; 162 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP) 163 .addImm(Amount); 164 } 165 166 // Replace the pseudo instruction with a new instruction... 167 MBB.insert(I, New); 168 } 169 } 170 171 MBB.erase(I); 172 } 173 174 void XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 175 int SPAdj, RegScavenger *RS) const { 176 assert(SPAdj == 0 && "Unexpected"); 177 MachineInstr &MI = *II; 178 DebugLoc dl = MI.getDebugLoc(); 179 unsigned i = 0; 180 181 while (!MI.getOperand(i).isFI()) { 182 ++i; 183 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 184 } 185 186 MachineOperand &FrameOp = MI.getOperand(i); 187 int FrameIndex = FrameOp.getIndex(); 188 189 MachineFunction &MF = *MI.getParent()->getParent(); 190 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 191 int StackSize = MF.getFrameInfo()->getStackSize(); 192 193 #ifndef NDEBUG 194 DEBUG(errs() << "\nFunction : " 195 << MF.getFunction()->getName() << "\n"); 196 DOUT << "<--------->\n"; 197 MI.print(DOUT); 198 DOUT << "FrameIndex : " << FrameIndex << "\n"; 199 DOUT << "FrameOffset : " << Offset << "\n"; 200 DOUT << "StackSize : " << StackSize << "\n"; 201 #endif 202 203 Offset += StackSize; 204 205 // fold constant into offset. 206 Offset += MI.getOperand(i + 1).getImm(); 207 MI.getOperand(i + 1).ChangeToImmediate(0); 208 209 assert(Offset%4 == 0 && "Misaligned stack offset"); 210 211 #ifndef NDEBUG 212 DOUT << "Offset : " << Offset << "\n"; 213 DOUT << "<--------->\n"; 214 #endif 215 216 Offset/=4; 217 218 bool FP = hasFP(MF); 219 220 unsigned Reg = MI.getOperand(0).getReg(); 221 bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); 222 223 assert(XCore::GRRegsRegisterClass->contains(Reg) && 224 "Unexpected register operand"); 225 226 MachineBasicBlock &MBB = *MI.getParent(); 227 228 if (FP) { 229 bool isUs = isImmUs(Offset); 230 unsigned FramePtr = XCore::R10; 231 232 MachineInstr *New = 0; 233 if (!isUs) { 234 if (!RS) { 235 std::string msg; 236 raw_string_ostream Msg(msg); 237 Msg << "eliminateFrameIndex Frame size too big: " << Offset; 238 llvm_report_error(Msg.str()); 239 } 240 unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II, 241 SPAdj); 242 loadConstant(MBB, II, ScratchReg, Offset, dl); 243 switch (MI.getOpcode()) { 244 case XCore::LDWFI: 245 New = BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 246 .addReg(FramePtr) 247 .addReg(ScratchReg, RegState::Kill); 248 break; 249 case XCore::STWFI: 250 New = BuildMI(MBB, II, dl, TII.get(XCore::STW_3r)) 251 .addReg(Reg, getKillRegState(isKill)) 252 .addReg(FramePtr) 253 .addReg(ScratchReg, RegState::Kill); 254 break; 255 case XCore::LDAWFI: 256 New = BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 257 .addReg(FramePtr) 258 .addReg(ScratchReg, RegState::Kill); 259 break; 260 default: 261 llvm_unreachable("Unexpected Opcode"); 262 } 263 } else { 264 switch (MI.getOpcode()) { 265 case XCore::LDWFI: 266 New = BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 267 .addReg(FramePtr) 268 .addImm(Offset); 269 break; 270 case XCore::STWFI: 271 New = BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 272 .addReg(Reg, getKillRegState(isKill)) 273 .addReg(FramePtr) 274 .addImm(Offset); 275 break; 276 case XCore::LDAWFI: 277 New = BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 278 .addReg(FramePtr) 279 .addImm(Offset); 280 break; 281 default: 282 llvm_unreachable("Unexpected Opcode"); 283 } 284 } 285 } else { 286 bool isU6 = isImmU6(Offset); 287 if (!isU6 && !isImmU16(Offset)) { 288 std::string msg; 289 raw_string_ostream Msg(msg); 290 Msg << "eliminateFrameIndex Frame size too big: " << Offset; 291 llvm_report_error(Msg.str()); 292 } 293 294 switch (MI.getOpcode()) { 295 int NewOpcode; 296 case XCore::LDWFI: 297 NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 298 BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 299 .addImm(Offset); 300 break; 301 case XCore::STWFI: 302 NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 303 BuildMI(MBB, II, dl, TII.get(NewOpcode)) 304 .addReg(Reg, getKillRegState(isKill)) 305 .addImm(Offset); 306 break; 307 case XCore::LDAWFI: 308 NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 309 BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 310 .addImm(Offset); 311 break; 312 default: 313 llvm_unreachable("Unexpected Opcode"); 314 } 315 } 316 // Erase old instruction. 317 MBB.erase(II); 318 } 319 320 void 321 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 322 RegScavenger *RS) const { 323 MachineFrameInfo *MFI = MF.getFrameInfo(); 324 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 325 const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; 326 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 327 if (LRUsed) { 328 MF.getRegInfo().setPhysRegUnused(XCore::LR); 329 330 bool isVarArg = MF.getFunction()->isVarArg(); 331 int FrameIdx; 332 if (! isVarArg) { 333 // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. 334 FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0); 335 } else { 336 FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); 337 } 338 XFI->setUsesLR(FrameIdx); 339 XFI->setLRSpillSlot(FrameIdx); 340 } 341 if (requiresRegisterScavenging(MF)) { 342 // Reserve a slot close to SP or frame pointer. 343 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 344 RC->getAlignment())); 345 } 346 if (hasFP(MF)) { 347 // A callee save register is used to hold the FP. 348 // This needs saving / restoring in the epilogue / prologue. 349 XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), 350 RC->getAlignment())); 351 } 352 } 353 354 void XCoreRegisterInfo:: 355 processFunctionBeforeFrameFinalized(MachineFunction &MF) const { 356 357 } 358 359 void XCoreRegisterInfo:: 360 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 361 unsigned DstReg, int64_t Value, DebugLoc dl) const { 362 // TODO use mkmsk if possible. 363 if (!isImmU16(Value)) { 364 // TODO use constant pool. 365 std::string msg; 366 raw_string_ostream Msg(msg); 367 Msg << "loadConstant value too big " << Value; 368 llvm_report_error(Msg.str()); 369 } 370 int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 371 BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); 372 } 373 374 void XCoreRegisterInfo:: 375 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 376 unsigned SrcReg, int Offset, DebugLoc dl) const { 377 assert(Offset%4 == 0 && "Misaligned stack offset"); 378 Offset/=4; 379 bool isU6 = isImmU6(Offset); 380 if (!isU6 && !isImmU16(Offset)) { 381 std::string msg; 382 raw_string_ostream Msg(msg); 383 Msg << "storeToStack offset too big " << Offset; 384 llvm_report_error(Msg.str()); 385 } 386 int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 387 BuildMI(MBB, I, dl, TII.get(Opcode)) 388 .addReg(SrcReg) 389 .addImm(Offset); 390 } 391 392 void XCoreRegisterInfo:: 393 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 394 unsigned DstReg, int Offset, DebugLoc dl) const { 395 assert(Offset%4 == 0 && "Misaligned stack offset"); 396 Offset/=4; 397 bool isU6 = isImmU6(Offset); 398 if (!isU6 && !isImmU16(Offset)) { 399 std::string msg; 400 raw_string_ostream Msg(msg); 401 Msg << "loadFromStack offset too big " << Offset; 402 llvm_report_error(Msg.str()); 403 } 404 int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 405 BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) 406 .addImm(Offset); 407 } 408 409 void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { 410 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 411 MachineBasicBlock::iterator MBBI = MBB.begin(); 412 MachineFrameInfo *MFI = MF.getFrameInfo(); 413 MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); 414 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 415 DebugLoc dl = (MBBI != MBB.end() ? 416 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 417 418 bool FP = hasFP(MF); 419 420 // Work out frame sizes. 421 int FrameSize = MFI->getStackSize(); 422 423 assert(FrameSize%4 == 0 && "Misaligned frame size"); 424 425 FrameSize/=4; 426 427 bool isU6 = isImmU6(FrameSize); 428 429 if (!isU6 && !isImmU16(FrameSize)) { 430 // FIXME could emit multiple instructions. 431 std::string msg; 432 raw_string_ostream Msg(msg); 433 Msg << "emitPrologue Frame size too big: " << FrameSize; 434 llvm_report_error(Msg.str()); 435 } 436 bool emitFrameMoves = needsFrameMoves(MF); 437 438 // Do we need to allocate space on the stack? 439 if (FrameSize) { 440 bool saveLR = XFI->getUsesLR(); 441 bool LRSavedOnEntry = false; 442 int Opcode; 443 if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { 444 Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 445 MBB.addLiveIn(XCore::LR); 446 saveLR = false; 447 LRSavedOnEntry = true; 448 } else { 449 Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 450 } 451 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 452 453 if (emitFrameMoves) { 454 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 455 456 // Show update of SP. 457 unsigned FrameLabelId = MMI->NextLabelID(); 458 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 459 460 MachineLocation SPDst(MachineLocation::VirtualFP); 461 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); 462 Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 463 464 if (LRSavedOnEntry) { 465 MachineLocation CSDst(MachineLocation::VirtualFP, 0); 466 MachineLocation CSSrc(XCore::LR); 467 Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); 468 } 469 } 470 if (saveLR) { 471 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 472 storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl); 473 MBB.addLiveIn(XCore::LR); 474 475 if (emitFrameMoves) { 476 unsigned SaveLRLabelId = MMI->NextLabelID(); 477 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId); 478 MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); 479 MachineLocation CSSrc(XCore::LR); 480 MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId, 481 CSDst, CSSrc)); 482 } 483 } 484 } 485 486 if (FP) { 487 // Save R10 to the stack. 488 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 489 storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl); 490 // R10 is live-in. It is killed at the spill. 491 MBB.addLiveIn(XCore::R10); 492 if (emitFrameMoves) { 493 unsigned SaveR10LabelId = MMI->NextLabelID(); 494 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId); 495 MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); 496 MachineLocation CSSrc(XCore::R10); 497 MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId, 498 CSDst, CSSrc)); 499 } 500 // Set the FP from the SP. 501 unsigned FramePtr = XCore::R10; 502 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) 503 .addImm(0); 504 if (emitFrameMoves) { 505 // Show FP is now valid. 506 unsigned FrameLabelId = MMI->NextLabelID(); 507 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 508 MachineLocation SPDst(FramePtr); 509 MachineLocation SPSrc(MachineLocation::VirtualFP); 510 MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 511 } 512 } 513 514 if (emitFrameMoves) { 515 // Frame moves for callee saved. 516 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 517 std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels = 518 XFI->getSpillLabels(); 519 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 520 unsigned SpillLabel = SpillLabels[I].first; 521 CalleeSavedInfo &CSI = SpillLabels[I].second; 522 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 523 unsigned Reg = CSI.getReg(); 524 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 525 MachineLocation CSSrc(Reg); 526 Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); 527 } 528 } 529 } 530 531 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF, 532 MachineBasicBlock &MBB) const { 533 MachineFrameInfo *MFI = MF.getFrameInfo(); 534 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 535 DebugLoc dl = MBBI->getDebugLoc(); 536 537 bool FP = hasFP(MF); 538 539 if (FP) { 540 // Restore the stack pointer. 541 unsigned FramePtr = XCore::R10; 542 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) 543 .addReg(FramePtr); 544 } 545 546 // Work out frame sizes. 547 int FrameSize = MFI->getStackSize(); 548 549 assert(FrameSize%4 == 0 && "Misaligned frame size"); 550 551 FrameSize/=4; 552 553 bool isU6 = isImmU6(FrameSize); 554 555 if (!isU6 && !isImmU16(FrameSize)) { 556 // FIXME could emit multiple instructions. 557 std::string msg; 558 raw_string_ostream Msg(msg); 559 Msg << "emitEpilogue Frame size too big: " << FrameSize; 560 llvm_report_error(Msg.str()); 561 } 562 563 if (FrameSize) { 564 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 565 566 if (FP) { 567 // Restore R10 568 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 569 FPSpillOffset += FrameSize*4; 570 loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl); 571 } 572 bool restoreLR = XFI->getUsesLR(); 573 if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { 574 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 575 LRSpillOffset += FrameSize*4; 576 loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl); 577 restoreLR = false; 578 } 579 if (restoreLR) { 580 // Fold prologue into return instruction 581 assert(MBBI->getOpcode() == XCore::RETSP_u6 582 || MBBI->getOpcode() == XCore::RETSP_lu6); 583 int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 584 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 585 MBB.erase(MBBI); 586 } else { 587 int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; 588 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); 589 } 590 } 591 } 592 593 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 594 return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 595 } 596 597 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const { 598 bool FP = hasFP(MF); 599 600 return FP ? XCore::R10 : XCore::SP; 601 } 602 603 unsigned XCoreRegisterInfo::getRARegister() const { 604 return XCore::LR; 605 } 606 607 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) 608 const { 609 // Initial state of the frame pointer is SP. 610 MachineLocation Dst(MachineLocation::VirtualFP); 611 MachineLocation Src(XCore::SP, 0); 612 Moves.push_back(MachineMove(0, Dst, Src)); 613 } 614 615 #include "XCoreGenRegisterInfo.inc" 616 617