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 errs() << "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 DEBUG(errs() << "<--------->\n"); 197 DEBUG(MI.print(errs())); 198 DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); 199 DEBUG(errs() << "FrameOffset : " << Offset << "\n"); 200 DEBUG(errs() << "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 DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); 212 213 Offset/=4; 214 215 bool FP = hasFP(MF); 216 217 unsigned Reg = MI.getOperand(0).getReg(); 218 bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); 219 220 assert(XCore::GRRegsRegisterClass->contains(Reg) && 221 "Unexpected register operand"); 222 223 MachineBasicBlock &MBB = *MI.getParent(); 224 225 if (FP) { 226 bool isUs = isImmUs(Offset); 227 unsigned FramePtr = XCore::R10; 228 229 if (!isUs) { 230 if (!RS) { 231 std::string msg; 232 raw_string_ostream Msg(msg); 233 Msg << "eliminateFrameIndex Frame size too big: " << Offset; 234 llvm_report_error(Msg.str()); 235 } 236 unsigned ScratchReg = RS->scavengeRegister(XCore::GRRegsRegisterClass, II, 237 SPAdj); 238 loadConstant(MBB, II, ScratchReg, Offset, dl); 239 switch (MI.getOpcode()) { 240 case XCore::LDWFI: 241 BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 242 .addReg(FramePtr) 243 .addReg(ScratchReg, RegState::Kill); 244 break; 245 case XCore::STWFI: 246 BuildMI(MBB, II, dl, TII.get(XCore::STW_3r)) 247 .addReg(Reg, getKillRegState(isKill)) 248 .addReg(FramePtr) 249 .addReg(ScratchReg, RegState::Kill); 250 break; 251 case XCore::LDAWFI: 252 BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 253 .addReg(FramePtr) 254 .addReg(ScratchReg, RegState::Kill); 255 break; 256 default: 257 llvm_unreachable("Unexpected Opcode"); 258 } 259 } else { 260 switch (MI.getOpcode()) { 261 case XCore::LDWFI: 262 BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 263 .addReg(FramePtr) 264 .addImm(Offset); 265 break; 266 case XCore::STWFI: 267 BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 268 .addReg(Reg, getKillRegState(isKill)) 269 .addReg(FramePtr) 270 .addImm(Offset); 271 break; 272 case XCore::LDAWFI: 273 BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 274 .addReg(FramePtr) 275 .addImm(Offset); 276 break; 277 default: 278 llvm_unreachable("Unexpected Opcode"); 279 } 280 } 281 } else { 282 bool isU6 = isImmU6(Offset); 283 if (!isU6 && !isImmU16(Offset)) { 284 std::string msg; 285 raw_string_ostream Msg(msg); 286 Msg << "eliminateFrameIndex Frame size too big: " << Offset; 287 llvm_report_error(Msg.str()); 288 } 289 290 switch (MI.getOpcode()) { 291 int NewOpcode; 292 case XCore::LDWFI: 293 NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 294 BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 295 .addImm(Offset); 296 break; 297 case XCore::STWFI: 298 NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 299 BuildMI(MBB, II, dl, TII.get(NewOpcode)) 300 .addReg(Reg, getKillRegState(isKill)) 301 .addImm(Offset); 302 break; 303 case XCore::LDAWFI: 304 NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 305 BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 306 .addImm(Offset); 307 break; 308 default: 309 llvm_unreachable("Unexpected Opcode"); 310 } 311 } 312 // Erase old instruction. 313 MBB.erase(II); 314 } 315 316 void 317 XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 318 RegScavenger *RS) const { 319 MachineFrameInfo *MFI = MF.getFrameInfo(); 320 bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); 321 const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; 322 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 323 if (LRUsed) { 324 MF.getRegInfo().setPhysRegUnused(XCore::LR); 325 326 bool isVarArg = MF.getFunction()->isVarArg(); 327 int FrameIdx; 328 if (! isVarArg) { 329 // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. 330 FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0); 331 } else { 332 FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment()); 333 } 334 XFI->setUsesLR(FrameIdx); 335 XFI->setLRSpillSlot(FrameIdx); 336 } 337 if (requiresRegisterScavenging(MF)) { 338 // Reserve a slot close to SP or frame pointer. 339 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 340 RC->getAlignment())); 341 } 342 if (hasFP(MF)) { 343 // A callee save register is used to hold the FP. 344 // This needs saving / restoring in the epilogue / prologue. 345 XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), 346 RC->getAlignment())); 347 } 348 } 349 350 void XCoreRegisterInfo:: 351 processFunctionBeforeFrameFinalized(MachineFunction &MF) const { 352 353 } 354 355 void XCoreRegisterInfo:: 356 loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 357 unsigned DstReg, int64_t Value, DebugLoc dl) const { 358 // TODO use mkmsk if possible. 359 if (!isImmU16(Value)) { 360 // TODO use constant pool. 361 std::string msg; 362 raw_string_ostream Msg(msg); 363 Msg << "loadConstant value too big " << Value; 364 llvm_report_error(Msg.str()); 365 } 366 int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 367 BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); 368 } 369 370 void XCoreRegisterInfo:: 371 storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 372 unsigned SrcReg, int Offset, DebugLoc dl) const { 373 assert(Offset%4 == 0 && "Misaligned stack offset"); 374 Offset/=4; 375 bool isU6 = isImmU6(Offset); 376 if (!isU6 && !isImmU16(Offset)) { 377 std::string msg; 378 raw_string_ostream Msg(msg); 379 Msg << "storeToStack offset too big " << Offset; 380 llvm_report_error(Msg.str()); 381 } 382 int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 383 BuildMI(MBB, I, dl, TII.get(Opcode)) 384 .addReg(SrcReg) 385 .addImm(Offset); 386 } 387 388 void XCoreRegisterInfo:: 389 loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 390 unsigned DstReg, int Offset, DebugLoc dl) const { 391 assert(Offset%4 == 0 && "Misaligned stack offset"); 392 Offset/=4; 393 bool isU6 = isImmU6(Offset); 394 if (!isU6 && !isImmU16(Offset)) { 395 std::string msg; 396 raw_string_ostream Msg(msg); 397 Msg << "loadFromStack offset too big " << Offset; 398 llvm_report_error(Msg.str()); 399 } 400 int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 401 BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) 402 .addImm(Offset); 403 } 404 405 void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { 406 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 407 MachineBasicBlock::iterator MBBI = MBB.begin(); 408 MachineFrameInfo *MFI = MF.getFrameInfo(); 409 MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); 410 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 411 DebugLoc dl = (MBBI != MBB.end() ? 412 MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); 413 414 bool FP = hasFP(MF); 415 416 // Work out frame sizes. 417 int FrameSize = MFI->getStackSize(); 418 419 assert(FrameSize%4 == 0 && "Misaligned frame size"); 420 421 FrameSize/=4; 422 423 bool isU6 = isImmU6(FrameSize); 424 425 if (!isU6 && !isImmU16(FrameSize)) { 426 // FIXME could emit multiple instructions. 427 std::string msg; 428 raw_string_ostream Msg(msg); 429 Msg << "emitPrologue Frame size too big: " << FrameSize; 430 llvm_report_error(Msg.str()); 431 } 432 bool emitFrameMoves = needsFrameMoves(MF); 433 434 // Do we need to allocate space on the stack? 435 if (FrameSize) { 436 bool saveLR = XFI->getUsesLR(); 437 bool LRSavedOnEntry = false; 438 int Opcode; 439 if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { 440 Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; 441 MBB.addLiveIn(XCore::LR); 442 saveLR = false; 443 LRSavedOnEntry = true; 444 } else { 445 Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; 446 } 447 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 448 449 if (emitFrameMoves) { 450 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 451 452 // Show update of SP. 453 unsigned FrameLabelId = MMI->NextLabelID(); 454 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 455 456 MachineLocation SPDst(MachineLocation::VirtualFP); 457 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); 458 Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 459 460 if (LRSavedOnEntry) { 461 MachineLocation CSDst(MachineLocation::VirtualFP, 0); 462 MachineLocation CSSrc(XCore::LR); 463 Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); 464 } 465 } 466 if (saveLR) { 467 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 468 storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl); 469 MBB.addLiveIn(XCore::LR); 470 471 if (emitFrameMoves) { 472 unsigned SaveLRLabelId = MMI->NextLabelID(); 473 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId); 474 MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); 475 MachineLocation CSSrc(XCore::LR); 476 MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId, 477 CSDst, CSSrc)); 478 } 479 } 480 } 481 482 if (FP) { 483 // Save R10 to the stack. 484 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 485 storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl); 486 // R10 is live-in. It is killed at the spill. 487 MBB.addLiveIn(XCore::R10); 488 if (emitFrameMoves) { 489 unsigned SaveR10LabelId = MMI->NextLabelID(); 490 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId); 491 MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); 492 MachineLocation CSSrc(XCore::R10); 493 MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId, 494 CSDst, CSSrc)); 495 } 496 // Set the FP from the SP. 497 unsigned FramePtr = XCore::R10; 498 BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) 499 .addImm(0); 500 if (emitFrameMoves) { 501 // Show FP is now valid. 502 unsigned FrameLabelId = MMI->NextLabelID(); 503 BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId); 504 MachineLocation SPDst(FramePtr); 505 MachineLocation SPSrc(MachineLocation::VirtualFP); 506 MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); 507 } 508 } 509 510 if (emitFrameMoves) { 511 // Frame moves for callee saved. 512 std::vector<MachineMove> &Moves = MMI->getFrameMoves(); 513 std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels = 514 XFI->getSpillLabels(); 515 for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { 516 unsigned SpillLabel = SpillLabels[I].first; 517 CalleeSavedInfo &CSI = SpillLabels[I].second; 518 int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); 519 unsigned Reg = CSI.getReg(); 520 MachineLocation CSDst(MachineLocation::VirtualFP, Offset); 521 MachineLocation CSSrc(Reg); 522 Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); 523 } 524 } 525 } 526 527 void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF, 528 MachineBasicBlock &MBB) const { 529 MachineFrameInfo *MFI = MF.getFrameInfo(); 530 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 531 DebugLoc dl = MBBI->getDebugLoc(); 532 533 bool FP = hasFP(MF); 534 535 if (FP) { 536 // Restore the stack pointer. 537 unsigned FramePtr = XCore::R10; 538 BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) 539 .addReg(FramePtr); 540 } 541 542 // Work out frame sizes. 543 int FrameSize = MFI->getStackSize(); 544 545 assert(FrameSize%4 == 0 && "Misaligned frame size"); 546 547 FrameSize/=4; 548 549 bool isU6 = isImmU6(FrameSize); 550 551 if (!isU6 && !isImmU16(FrameSize)) { 552 // FIXME could emit multiple instructions. 553 std::string msg; 554 raw_string_ostream Msg(msg); 555 Msg << "emitEpilogue Frame size too big: " << FrameSize; 556 llvm_report_error(Msg.str()); 557 } 558 559 if (FrameSize) { 560 XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); 561 562 if (FP) { 563 // Restore R10 564 int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); 565 FPSpillOffset += FrameSize*4; 566 loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl); 567 } 568 bool restoreLR = XFI->getUsesLR(); 569 if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { 570 int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); 571 LRSpillOffset += FrameSize*4; 572 loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl); 573 restoreLR = false; 574 } 575 if (restoreLR) { 576 // Fold prologue into return instruction 577 assert(MBBI->getOpcode() == XCore::RETSP_u6 578 || MBBI->getOpcode() == XCore::RETSP_lu6); 579 int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; 580 BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); 581 MBB.erase(MBBI); 582 } else { 583 int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; 584 BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); 585 } 586 } 587 } 588 589 int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { 590 return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); 591 } 592 593 unsigned XCoreRegisterInfo::getFrameRegister(MachineFunction &MF) const { 594 bool FP = hasFP(MF); 595 596 return FP ? XCore::R10 : XCore::SP; 597 } 598 599 unsigned XCoreRegisterInfo::getRARegister() const { 600 return XCore::LR; 601 } 602 603 void XCoreRegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves) 604 const { 605 // Initial state of the frame pointer is SP. 606 MachineLocation Dst(MachineLocation::VirtualFP); 607 MachineLocation Src(XCore::SP, 0); 608 Moves.push_back(MachineMove(0, Dst, Src)); 609 } 610 611 #include "XCoreGenRegisterInfo.inc" 612 613