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