1//===- ARMInstrInfo.cpp - ARM Instruction 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//===----------------------------------------------------------------------===// --- 26 unchanged lines hidden (view full) --- 35} 36 37static inline 38const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { 39 return MIB.addReg(0); 40} 41 42ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI) |
43 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)) { |
44} 45 46ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) |
47 : ARMBaseInstrInfo(STI), RI(*this, STI) { |
48} 49 |
50void ARMInstrInfo::reMaterialize(MachineBasicBlock &MBB, 51 MachineBasicBlock::iterator I, 52 unsigned DestReg, 53 const MachineInstr *Orig) const { |
54 DebugLoc dl = Orig->getDebugLoc(); 55 if (Orig->getOpcode() == ARM::MOVi2pieces) { |
56 RI.emitLoadConstPool(MBB, I, this, dl, 57 DestReg, 58 Orig->getOperand(1).getImm(), 59 (ARMCC::CondCodes)Orig->getOperand(2).getImm(), 60 Orig->getOperand(3).getReg()); |
61 return; 62 } 63 64 MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); 65 MI->getOperand(0).setReg(DestReg); 66 MBB.insert(I, MI); 67} 68 --- 176 unchanged lines hidden (view full) --- 245 246 MFI->insert(MBBI, NewMIs[1]); 247 MFI->insert(MBBI, NewMIs[0]); 248 return NewMIs[0]; 249} 250 251// Branch analysis. 252bool |
253ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 254 MachineBasicBlock *&FBB, 255 SmallVectorImpl 256 bool AllowModify) const { |
257 // If the block has no terminators, it just falls into the block after it. 258 MachineBasicBlock::iterator I = MBB.end(); 259 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) 260 return false; 261 262 // Get the last instruction in the block. 263 MachineInstr *LastInst = I; 264 265 // If there is only one terminator instruction, process it. 266 unsigned LastOpc = LastInst->getOpcode(); 267 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { |
268 if (LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B) { |
269 TBB = LastInst->getOperand(0).getMBB(); 270 return false; 271 } |
272 if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc || LastOpc == ARM::t2Bcc) { |
273 // Block ends with fall-through condbranch. 274 TBB = LastInst->getOperand(0).getMBB(); 275 Cond.push_back(LastInst->getOperand(1)); 276 Cond.push_back(LastInst->getOperand(2)); 277 return false; 278 } 279 return true; // Can't handle indirect branch. 280 } 281 282 // Get the instruction before it if it is a terminator. 283 MachineInstr *SecondLastInst = I; 284 285 // If there are three terminators, we don't know what sort of block this is. 286 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 287 return true; 288 |
289 // If the block ends with ARM::B/ARM::tB/ARM::t2B and a 290 // ARM::Bcc/ARM::tBcc/ARM::t2Bcc, handle it. |
291 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 292 if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) || |
293 (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB) || 294 (SecondLastOpc == ARM::t2Bcc && LastOpc == ARM::t2B)) { |
295 TBB = SecondLastInst->getOperand(0).getMBB(); 296 Cond.push_back(SecondLastInst->getOperand(1)); 297 Cond.push_back(SecondLastInst->getOperand(2)); 298 FBB = LastInst->getOperand(0).getMBB(); 299 return false; 300 } 301 302 // If the block ends with two unconditional branches, handle it. The second 303 // one is not executed, so remove it. |
304 if ((SecondLastOpc == ARM::B || SecondLastOpc==ARM::tB || 305 SecondLastOpc==ARM::t2B) && 306 (LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B)) { |
307 TBB = SecondLastInst->getOperand(0).getMBB(); 308 I = LastInst; 309 if (AllowModify) 310 I->eraseFromParent(); 311 return false; 312 } 313 314 // ...likewise if it ends with a branch table followed by an unconditional 315 // branch. The branch folder can create these, and we must get rid of them for 316 // correctness of Thumb constant islands. 317 if ((SecondLastOpc == ARM::BR_JTr || SecondLastOpc==ARM::BR_JTm || |
318 SecondLastOpc == ARM::BR_JTadd || SecondLastOpc==ARM::tBR_JTr || 319 SecondLastOpc == ARM::t2BR_JTr || SecondLastOpc==ARM::t2BR_JTm || 320 SecondLastOpc == ARM::t2BR_JTadd) && 321 (LastOpc == ARM::B || LastOpc == ARM::tB || LastOpc == ARM::t2B)) { |
322 I = LastInst; 323 if (AllowModify) 324 I->eraseFromParent(); 325 return true; 326 } 327 328 // Otherwise, can't handle this. 329 return true; 330} 331 332 333unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 334 MachineFunction &MF = *MBB.getParent(); 335 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
336 int BOpc = AFI->isThumbFunction() ? 337 (AFI->isThumb2Function() ? ARM::t2B : ARM::tB) : ARM::B; 338 int BccOpc = AFI->isThumbFunction() ? 339 (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; |
340 341 MachineBasicBlock::iterator I = MBB.end(); 342 if (I == MBB.begin()) return 0; 343 --I; 344 if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc) 345 return 0; 346 347 // Remove the branch. --- 14 unchanged lines hidden (view full) --- 362unsigned 363ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 364 MachineBasicBlock *FBB, 365 const SmallVectorImpl<MachineOperand> &Cond) const { 366 // FIXME this should probably have a DebugLoc argument 367 DebugLoc dl = DebugLoc::getUnknownLoc(); 368 MachineFunction &MF = *MBB.getParent(); 369 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
370 int BOpc = AFI->isThumbFunction() ? 371 (AFI->isThumb2Function() ? ARM::t2B : ARM::tB) : ARM::B; 372 int BccOpc = AFI->isThumbFunction() ? 373 (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc; |
374 375 // Shouldn't be a fall through. 376 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 377 assert((Cond.size() == 2 || Cond.size() == 0) && 378 "ARM branch conditions have two components!"); 379 380 if (FBB == 0) { 381 if (Cond.empty()) // Unconditional branch? --- 6 unchanged lines hidden (view full) --- 388 389 // Two-way conditional branch. 390 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB) 391 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); 392 BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB); 393 return 2; 394} 395 |
396bool 397ARMBaseInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { 398 if (MBB.empty()) return false; 399 400 switch (MBB.back().getOpcode()) { 401 case ARM::BX_RET: // Return. 402 case ARM::LDM_RET: 403 case ARM::tBX_RET: 404 case ARM::tBX_RET_vararg: 405 case ARM::tPOP_RET: 406 case ARM::B: 407 case ARM::tB: 408 case ARM::t2B: // Uncond branch. 409 case ARM::tBR_JTr: 410 case ARM::t2BR_JTr: 411 case ARM::BR_JTr: // Jumptable branch. 412 case ARM::t2BR_JTm: 413 case ARM::BR_JTm: // Jumptable branch through mem. 414 case ARM::t2BR_JTadd: 415 case ARM::BR_JTadd: // Jumptable branch add to pc. 416 return true; 417 default: return false; 418 } 419} 420 421bool ARMBaseInstrInfo:: 422ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 423 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm(); 424 Cond[0].setImm(ARMCC::getOppositeCondition(CC)); 425 return false; 426} 427 428bool ARMBaseInstrInfo::isPredicated(const MachineInstr *MI) const { 429 int PIdx = MI->findFirstPredOperandIdx(); 430 return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL; 431} 432 433bool ARMBaseInstrInfo:: 434PredicateInstruction(MachineInstr *MI, 435 const SmallVectorImpl<MachineOperand> &Pred) const { 436 unsigned Opc = MI->getOpcode(); 437 if (Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B) { 438 MI->setDesc(get((Opc == ARM::B) ? ARM::Bcc : 439 ((Opc == ARM::tB) ? ARM::tBcc : ARM::t2Bcc))); 440 MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm())); 441 MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false)); 442 return true; 443 } 444 445 int PIdx = MI->findFirstPredOperandIdx(); 446 if (PIdx != -1) { 447 MachineOperand &PMO = MI->getOperand(PIdx); 448 PMO.setImm(Pred[0].getImm()); 449 MI->getOperand(PIdx+1).setReg(Pred[1].getReg()); 450 return true; 451 } 452 return false; 453} 454 455bool ARMBaseInstrInfo:: 456SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1, 457 const SmallVectorImpl<MachineOperand> &Pred2) const { 458 if (Pred1.size() > 2 || Pred2.size() > 2) 459 return false; 460 461 ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm(); 462 ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm(); 463 if (CC1 == CC2) 464 return true; 465 466 switch (CC1) { 467 default: 468 return false; 469 case ARMCC::AL: 470 return true; 471 case ARMCC::HS: 472 return CC2 == ARMCC::HI; 473 case ARMCC::LS: 474 return CC2 == ARMCC::LO || CC2 == ARMCC::EQ; 475 case ARMCC::GE: 476 return CC2 == ARMCC::GT; 477 case ARMCC::LE: 478 return CC2 == ARMCC::LT; 479 } 480} 481 482bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, 483 std::vector<MachineOperand> &Pred) const { 484 const TargetInstrDesc &TID = MI->getDesc(); 485 if (!TID.getImplicitDefs() && !TID.hasOptionalDef()) 486 return false; 487 488 bool Found = false; 489 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 490 const MachineOperand &MO = MI->getOperand(i); 491 if (MO.isReg() && MO.getReg() == ARM::CPSR) { 492 Pred.push_back(MO); 493 Found = true; 494 } 495 } 496 497 return Found; 498} 499 500 501/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing 502static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 503 unsigned JTI) DISABLE_INLINE; 504static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, 505 unsigned JTI) { 506 return JT[JTI].MBBs.size(); 507} 508 509/// GetInstSize - Return the size of the specified MachineInstr. 510/// 511unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 512 const MachineBasicBlock &MBB = *MI->getParent(); 513 const MachineFunction *MF = MBB.getParent(); 514 const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo(); 515 516 // Basic size info comes from the TSFlags field. 517 const TargetInstrDesc &TID = MI->getDesc(); 518 unsigned TSFlags = TID.TSFlags; 519 520 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) { 521 default: { 522 // If this machine instr is an inline asm, measure it. 523 if (MI->getOpcode() == ARM::INLINEASM) 524 return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName()); 525 if (MI->isLabel()) 526 return 0; 527 switch (MI->getOpcode()) { 528 default: 529 assert(0 && "Unknown or unset size field for instr!"); 530 break; 531 case TargetInstrInfo::IMPLICIT_DEF: 532 case TargetInstrInfo::DECLARE: 533 case TargetInstrInfo::DBG_LABEL: 534 case TargetInstrInfo::EH_LABEL: 535 return 0; 536 } 537 break; 538 } 539 case ARMII::Size8Bytes: return 8; // Arm instruction x 2. 540 case ARMII::Size4Bytes: return 4; // Arm instruction. 541 case ARMII::Size2Bytes: return 2; // Thumb instruction. 542 case ARMII::SizeSpecial: { 543 switch (MI->getOpcode()) { 544 case ARM::CONSTPOOL_ENTRY: 545 // If this machine instr is a constant pool entry, its size is recorded as 546 // operand #2. 547 return MI->getOperand(2).getImm(); 548 case ARM::Int_eh_sjlj_setjmp: return 12; 549 case ARM::BR_JTr: 550 case ARM::BR_JTm: 551 case ARM::BR_JTadd: 552 case ARM::t2BR_JTr: 553 case ARM::t2BR_JTm: 554 case ARM::t2BR_JTadd: 555 case ARM::tBR_JTr: { 556 // These are jumptable branches, i.e. a branch followed by an inlined 557 // jumptable. The size is 4 + 4 * number of entries. 558 unsigned NumOps = TID.getNumOperands(); 559 MachineOperand JTOP = 560 MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2)); 561 unsigned JTI = JTOP.getIndex(); 562 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 563 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 564 assert(JTI < JT.size()); 565 // Thumb instructions are 2 byte aligned, but JT entries are 4 byte 566 // 4 aligned. The assembler / linker may add 2 byte padding just before 567 // the JT entries. The size does not include this padding; the 568 // constant islands pass does separate bookkeeping for it. 569 // FIXME: If we know the size of the function is less than (1 << 16) *2 570 // bytes, we can use 16-bit entries instead. Then there won't be an 571 // alignment issue. 572 return getNumJTEntries(JT, JTI) * 4 + 573 ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4); 574 } 575 default: 576 // Otherwise, pseudo-instruction sizes are zero. 577 return 0; 578 } 579 } 580 } 581 return 0; // Not reached 582} 583 584/// Return true if the instruction is a register to register move and 585/// leave the source and dest operands in the passed parameters. 586/// 587bool 588ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI, 589 unsigned &SrcReg, unsigned &DstReg, 590 unsigned& SrcSubIdx, unsigned& DstSubIdx) const { 591 SrcSubIdx = DstSubIdx = 0; // No sub-registers. 592 593 unsigned oc = MI.getOpcode(); 594 switch (oc) { 595 default: 596 return false; 597 case ARM::FCPYS: 598 case ARM::FCPYD: 599 case ARM::VMOVD: 600 case ARM::VMOVQ: 601 SrcReg = MI.getOperand(1).getReg(); 602 DstReg = MI.getOperand(0).getReg(); 603 return true; 604 case ARM::MOVr: 605 assert(MI.getDesc().getNumOperands() >= 2 && 606 MI.getOperand(0).isReg() && 607 MI.getOperand(1).isReg() && 608 "Invalid ARM MOV instruction"); 609 SrcReg = MI.getOperand(1).getReg(); 610 DstReg = MI.getOperand(0).getReg(); 611 return true; 612 } 613} 614 615unsigned 616ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 617 int &FrameIndex) const { 618 switch (MI->getOpcode()) { 619 default: break; 620 case ARM::LDR: 621 if (MI->getOperand(1).isFI() && 622 MI->getOperand(2).isReg() && 623 MI->getOperand(3).isImm() && 624 MI->getOperand(2).getReg() == 0 && 625 MI->getOperand(3).getImm() == 0) { 626 FrameIndex = MI->getOperand(1).getIndex(); 627 return MI->getOperand(0).getReg(); 628 } 629 break; 630 case ARM::FLDD: 631 case ARM::FLDS: 632 if (MI->getOperand(1).isFI() && 633 MI->getOperand(2).isImm() && 634 MI->getOperand(2).getImm() == 0) { 635 FrameIndex = MI->getOperand(1).getIndex(); 636 return MI->getOperand(0).getReg(); 637 } 638 break; 639 } 640 return 0; 641} 642 643unsigned 644ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 645 int &FrameIndex) const { 646 switch (MI->getOpcode()) { 647 default: break; 648 case ARM::STR: 649 if (MI->getOperand(1).isFI() && 650 MI->getOperand(2).isReg() && 651 MI->getOperand(3).isImm() && 652 MI->getOperand(2).getReg() == 0 && 653 MI->getOperand(3).getImm() == 0) { 654 FrameIndex = MI->getOperand(1).getIndex(); 655 return MI->getOperand(0).getReg(); 656 } 657 break; 658 case ARM::FSTD: 659 case ARM::FSTS: 660 if (MI->getOperand(1).isFI() && 661 MI->getOperand(2).isImm() && 662 MI->getOperand(2).getImm() == 0) { 663 FrameIndex = MI->getOperand(1).getIndex(); 664 return MI->getOperand(0).getReg(); 665 } 666 break; 667 } 668 669 return 0; 670} 671 672bool 673ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 674 MachineBasicBlock::iterator I, 675 unsigned DestReg, unsigned SrcReg, 676 const TargetRegisterClass *DestRC, 677 const TargetRegisterClass *SrcRC) const { |
678 DebugLoc DL = DebugLoc::getUnknownLoc(); 679 if (I != MBB.end()) DL = I->getDebugLoc(); 680 681 if (DestRC != SrcRC) { 682 // Not yet supported! 683 return false; 684 } 685 --- 9 unchanged lines hidden (view full) --- 695 else if (DestRC == ARM::QPRRegisterClass) 696 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); 697 else 698 return false; 699 700 return true; 701} 702 |
703void ARMBaseInstrInfo:: |
704storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 705 unsigned SrcReg, bool isKill, int FI, 706 const TargetRegisterClass *RC) const { 707 DebugLoc DL = DebugLoc::getUnknownLoc(); 708 if (I != MBB.end()) DL = I->getDebugLoc(); 709 710 if (RC == ARM::GPRRegisterClass) { 711 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) --- 6 unchanged lines hidden (view full) --- 718 } else { 719 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 720 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS)) 721 .addReg(SrcReg, getKillRegState(isKill)) 722 .addFrameIndex(FI).addImm(0)); 723 } 724} 725 |
726void 727ARMBaseInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 728 bool isKill, 729 SmallVectorImpl<MachineOperand> &Addr, 730 const TargetRegisterClass *RC, 731 SmallVectorImpl<MachineInstr*> &NewMIs) const{ |
732 DebugLoc DL = DebugLoc::getUnknownLoc(); 733 unsigned Opc = 0; 734 if (RC == ARM::GPRRegisterClass) { 735 Opc = ARM::STR; 736 } else if (RC == ARM::DPRRegisterClass) { 737 Opc = ARM::FSTD; 738 } else { 739 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); --- 4 unchanged lines hidden (view full) --- 744 BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)); 745 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 746 MIB.addOperand(Addr[i]); 747 AddDefaultPred(MIB); 748 NewMIs.push_back(MIB); 749 return; 750} 751 |
752void ARMBaseInstrInfo:: |
753loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 754 unsigned DestReg, int FI, 755 const TargetRegisterClass *RC) const { 756 DebugLoc DL = DebugLoc::getUnknownLoc(); 757 if (I != MBB.end()) DL = I->getDebugLoc(); 758 759 if (RC == ARM::GPRRegisterClass) { 760 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg) 761 .addFrameIndex(FI).addReg(0).addImm(0)); 762 } else if (RC == ARM::DPRRegisterClass) { 763 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg) 764 .addFrameIndex(FI).addImm(0)); 765 } else { 766 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); 767 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg) 768 .addFrameIndex(FI).addImm(0)); 769 } 770} 771 |
772void ARMBaseInstrInfo:: |
773loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 774 SmallVectorImpl<MachineOperand> &Addr, 775 const TargetRegisterClass *RC, 776 SmallVectorImpl<MachineInstr*> &NewMIs) const { 777 DebugLoc DL = DebugLoc::getUnknownLoc(); 778 unsigned Opc = 0; 779 if (RC == ARM::GPRRegisterClass) { 780 Opc = ARM::LDR; --- 7 unchanged lines hidden (view full) --- 788 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); 789 for (unsigned i = 0, e = Addr.size(); i != e; ++i) 790 MIB.addOperand(Addr[i]); 791 AddDefaultPred(MIB); 792 NewMIs.push_back(MIB); 793 return; 794} 795 |
796MachineInstr *ARMBaseInstrInfo:: |
797foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI, 798 const SmallVectorImpl<unsigned> &Ops, int FI) const { 799 if (Ops.size() != 1) return NULL; 800 801 unsigned OpNum = Ops[0]; 802 unsigned Opc = MI->getOpcode(); 803 MachineInstr *NewMI = NULL; 804 switch (Opc) { 805 default: break; 806 case ARM::MOVr: { 807 if (MI->getOperand(4).getReg() == ARM::CPSR) 808 // If it is updating CPSR, then it cannot be folded. 809 break; 810 unsigned Pred = MI->getOperand(2).getImm(); 811 unsigned PredReg = MI->getOperand(3).getReg(); 812 if (OpNum == 0) { // move -> store 813 unsigned SrcReg = MI->getOperand(1).getReg(); 814 bool isKill = MI->getOperand(1).isKill(); |
815 bool isUndef = MI->getOperand(1).isUndef(); |
816 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR)) |
817 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) |
818 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 819 } else { // move -> load 820 unsigned DstReg = MI->getOperand(0).getReg(); 821 bool isDead = MI->getOperand(0).isDead(); |
822 bool isUndef = MI->getOperand(0).isUndef(); |
823 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR)) |
824 .addReg(DstReg, 825 RegState::Define | 826 getDeadRegState(isDead) | 827 getUndefRegState(isUndef)) |
828 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg); 829 } 830 break; 831 } 832 case ARM::FCPYS: { 833 unsigned Pred = MI->getOperand(2).getImm(); 834 unsigned PredReg = MI->getOperand(3).getReg(); 835 if (OpNum == 0) { // move -> store 836 unsigned SrcReg = MI->getOperand(1).getReg(); |
837 bool isKill = MI->getOperand(1).isKill(); 838 bool isUndef = MI->getOperand(1).isUndef(); |
839 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS)) |
840 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) 841 .addFrameIndex(FI) |
842 .addImm(0).addImm(Pred).addReg(PredReg); 843 } else { // move -> load 844 unsigned DstReg = MI->getOperand(0).getReg(); |
845 bool isDead = MI->getOperand(0).isDead(); 846 bool isUndef = MI->getOperand(0).isUndef(); 847 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS)) 848 .addReg(DstReg, 849 RegState::Define | 850 getDeadRegState(isDead) | 851 getUndefRegState(isUndef)) 852 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); |
853 } 854 break; 855 } 856 case ARM::FCPYD: { 857 unsigned Pred = MI->getOperand(2).getImm(); 858 unsigned PredReg = MI->getOperand(3).getReg(); 859 if (OpNum == 0) { // move -> store 860 unsigned SrcReg = MI->getOperand(1).getReg(); 861 bool isKill = MI->getOperand(1).isKill(); |
862 bool isUndef = MI->getOperand(1).isUndef(); |
863 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD)) |
864 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) |
865 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 866 } else { // move -> load 867 unsigned DstReg = MI->getOperand(0).getReg(); 868 bool isDead = MI->getOperand(0).isDead(); |
869 bool isUndef = MI->getOperand(0).isUndef(); |
870 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD)) |
871 .addReg(DstReg, 872 RegState::Define | 873 getDeadRegState(isDead) | 874 getUndefRegState(isUndef)) |
875 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg); 876 } 877 break; 878 } 879 } 880 881 return NewMI; 882} 883 |
884MachineInstr* 885ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 886 MachineInstr* MI, 887 const SmallVectorImpl<unsigned> &Ops, 888 MachineInstr* LoadMI) const { 889 return 0; 890} 891 892bool 893ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, 894 const SmallVectorImpl<unsigned> &Ops) const { |
895 if (Ops.size() != 1) return false; 896 |
897 unsigned Opc = MI->getOpcode(); 898 switch (Opc) { 899 default: break; 900 case ARM::MOVr: 901 // If it is updating CPSR, then it cannot be folded. 902 return MI->getOperand(4).getReg() != ARM::CPSR; |
903 case ARM::FCPYS: 904 case ARM::FCPYD: 905 return true; 906 907 case ARM::VMOVD: 908 case ARM::VMOVQ: 909 return false; // FIXME 910 } 911 912 return false; 913} |