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