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