1 //===- ARMBaseInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Base ARM implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "ARMBaseInstrInfo.h"
16 #include "ARMAddressingModes.h"
17 #include "ARMGenInstrInfo.inc"
18 #include "ARMMachineFunctionInfo.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/CodeGen/LiveVariables.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineJumpTableInfo.h"
24 #include "llvm/Target/TargetAsmInfo.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/ErrorHandling.h"
30 EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
31 cl::desc("Enable ARM 2-addr to 3-addr conv"));
33 ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &sti)
34 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
39 ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
40 MachineBasicBlock::iterator &MBBI,
41 LiveVariables *LV) const {
42 // FIXME: Thumb2 support.
47 MachineInstr *MI = MBBI;
48 MachineFunction &MF = *MI->getParent()->getParent();
49 unsigned TSFlags = MI->getDesc().TSFlags;
51 switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
53 case ARMII::IndexModePre:
56 case ARMII::IndexModePost:
60 // Try splitting an indexed load/store to an un-indexed one plus an add/sub
62 unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
66 MachineInstr *UpdateMI = NULL;
67 MachineInstr *MemMI = NULL;
68 unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
69 const TargetInstrDesc &TID = MI->getDesc();
70 unsigned NumOps = TID.getNumOperands();
71 bool isLoad = !TID.mayStore();
72 const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
73 const MachineOperand &Base = MI->getOperand(2);
74 const MachineOperand &Offset = MI->getOperand(NumOps-3);
75 unsigned WBReg = WB.getReg();
76 unsigned BaseReg = Base.getReg();
77 unsigned OffReg = Offset.getReg();
78 unsigned OffImm = MI->getOperand(NumOps-2).getImm();
79 ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
82 assert(false && "Unknown indexed op!");
84 case ARMII::AddrMode2: {
85 bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
86 unsigned Amt = ARM_AM::getAM2Offset(OffImm);
88 if (ARM_AM::getSOImmVal(Amt) == -1)
89 // Can't encode it in a so_imm operand. This transformation will
90 // add more than 1 instruction. Abandon!
92 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
93 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
94 .addReg(BaseReg).addImm(Amt)
95 .addImm(Pred).addReg(0).addReg(0);
96 } else if (Amt != 0) {
97 ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
98 unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
99 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
100 get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
101 .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
102 .addImm(Pred).addReg(0).addReg(0);
104 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
105 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
106 .addReg(BaseReg).addReg(OffReg)
107 .addImm(Pred).addReg(0).addReg(0);
110 case ARMII::AddrMode3 : {
111 bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
112 unsigned Amt = ARM_AM::getAM3Offset(OffImm);
114 // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
115 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
116 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
117 .addReg(BaseReg).addImm(Amt)
118 .addImm(Pred).addReg(0).addReg(0);
120 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
121 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
122 .addReg(BaseReg).addReg(OffReg)
123 .addImm(Pred).addReg(0).addReg(0);
128 std::vector<MachineInstr*> NewMIs;
131 MemMI = BuildMI(MF, MI->getDebugLoc(),
132 get(MemOpc), MI->getOperand(0).getReg())
133 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
135 MemMI = BuildMI(MF, MI->getDebugLoc(),
136 get(MemOpc)).addReg(MI->getOperand(1).getReg())
137 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
138 NewMIs.push_back(MemMI);
139 NewMIs.push_back(UpdateMI);
142 MemMI = BuildMI(MF, MI->getDebugLoc(),
143 get(MemOpc), MI->getOperand(0).getReg())
144 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
146 MemMI = BuildMI(MF, MI->getDebugLoc(),
147 get(MemOpc)).addReg(MI->getOperand(1).getReg())
148 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
150 UpdateMI->getOperand(0).setIsDead();
151 NewMIs.push_back(UpdateMI);
152 NewMIs.push_back(MemMI);
155 // Transfer LiveVariables states, kill / dead info.
157 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
158 MachineOperand &MO = MI->getOperand(i);
159 if (MO.isReg() && MO.getReg() &&
160 TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
161 unsigned Reg = MO.getReg();
163 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
165 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
167 LV->addVirtualRegisterDead(Reg, NewMI);
169 if (MO.isUse() && MO.isKill()) {
170 for (unsigned j = 0; j < 2; ++j) {
171 // Look at the two new MI's in reverse order.
172 MachineInstr *NewMI = NewMIs[j];
173 if (!NewMI->readsRegister(Reg))
175 LV->addVirtualRegisterKilled(Reg, NewMI);
176 if (VI.removeKill(MI))
177 VI.Kills.push_back(NewMI);
185 MFI->insert(MBBI, NewMIs[1]);
186 MFI->insert(MBBI, NewMIs[0]);
192 ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
193 MachineBasicBlock *&FBB,
194 SmallVectorImpl<MachineOperand> &Cond,
195 bool AllowModify) const {
196 // If the block has no terminators, it just falls into the block after it.
197 MachineBasicBlock::iterator I = MBB.end();
198 if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
201 // Get the last instruction in the block.
202 MachineInstr *LastInst = I;
204 // If there is only one terminator instruction, process it.
205 unsigned LastOpc = LastInst->getOpcode();
206 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
207 if (isUncondBranchOpcode(LastOpc)) {
208 TBB = LastInst->getOperand(0).getMBB();
211 if (isCondBranchOpcode(LastOpc)) {
212 // Block ends with fall-through condbranch.
213 TBB = LastInst->getOperand(0).getMBB();
214 Cond.push_back(LastInst->getOperand(1));
215 Cond.push_back(LastInst->getOperand(2));
218 return true; // Can't handle indirect branch.
221 // Get the instruction before it if it is a terminator.
222 MachineInstr *SecondLastInst = I;
224 // If there are three terminators, we don't know what sort of block this is.
225 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
228 // If the block ends with a B and a Bcc, handle it.
229 unsigned SecondLastOpc = SecondLastInst->getOpcode();
230 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
231 TBB = SecondLastInst->getOperand(0).getMBB();
232 Cond.push_back(SecondLastInst->getOperand(1));
233 Cond.push_back(SecondLastInst->getOperand(2));
234 FBB = LastInst->getOperand(0).getMBB();
238 // If the block ends with two unconditional branches, handle it. The second
239 // one is not executed, so remove it.
240 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
241 TBB = SecondLastInst->getOperand(0).getMBB();
244 I->eraseFromParent();
248 // ...likewise if it ends with a branch table followed by an unconditional
249 // branch. The branch folder can create these, and we must get rid of them for
250 // correctness of Thumb constant islands.
251 if (isJumpTableBranchOpcode(SecondLastOpc) &&
252 isUncondBranchOpcode(LastOpc)) {
255 I->eraseFromParent();
259 // Otherwise, can't handle this.
264 unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
265 MachineBasicBlock::iterator I = MBB.end();
266 if (I == MBB.begin()) return 0;
268 if (!isUncondBranchOpcode(I->getOpcode()) &&
269 !isCondBranchOpcode(I->getOpcode()))
272 // Remove the branch.
273 I->eraseFromParent();
277 if (I == MBB.begin()) return 1;
279 if (!isCondBranchOpcode(I->getOpcode()))
282 // Remove the branch.
283 I->eraseFromParent();
288 ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
289 MachineBasicBlock *FBB,
290 const SmallVectorImpl<MachineOperand> &Cond) const {
291 // FIXME this should probably have a DebugLoc argument
292 DebugLoc dl = DebugLoc::getUnknownLoc();
293 int BOpc = !STI.isThumb()
294 ? ARM::B : (STI.isThumb2() ? ARM::t2B : ARM::tB);
295 int BccOpc = !STI.isThumb()
296 ? ARM::Bcc : (STI.isThumb2() ? ARM::t2Bcc : ARM::tBcc);
298 // Shouldn't be a fall through.
299 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
300 assert((Cond.size() == 2 || Cond.size() == 0) &&
301 "ARM branch conditions have two components!");
304 if (Cond.empty()) // Unconditional branch?
305 BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB);
307 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB)
308 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
312 // Two-way conditional branch.
313 BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB)
314 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
315 BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB);
319 bool ARMBaseInstrInfo::
320 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
321 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
322 Cond[0].setImm(ARMCC::getOppositeCondition(CC));
326 bool ARMBaseInstrInfo::
327 PredicateInstruction(MachineInstr *MI,
328 const SmallVectorImpl<MachineOperand> &Pred) const {
329 unsigned Opc = MI->getOpcode();
330 if (isUncondBranchOpcode(Opc)) {
331 MI->setDesc(get(getMatchingCondBranchOpcode(Opc)));
332 MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
333 MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false));
337 int PIdx = MI->findFirstPredOperandIdx();
339 MachineOperand &PMO = MI->getOperand(PIdx);
340 PMO.setImm(Pred[0].getImm());
341 MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
347 bool ARMBaseInstrInfo::
348 SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
349 const SmallVectorImpl<MachineOperand> &Pred2) const {
350 if (Pred1.size() > 2 || Pred2.size() > 2)
353 ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
354 ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
364 return CC2 == ARMCC::HI;
366 return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
368 return CC2 == ARMCC::GT;
370 return CC2 == ARMCC::LT;
374 bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
375 std::vector<MachineOperand> &Pred) const {
376 const TargetInstrDesc &TID = MI->getDesc();
377 if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
381 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
382 const MachineOperand &MO = MI->getOperand(i);
383 if (MO.isReg() && MO.getReg() == ARM::CPSR) {
393 /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
394 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
395 unsigned JTI) DISABLE_INLINE;
396 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
398 return JT[JTI].MBBs.size();
401 /// GetInstSize - Return the size of the specified MachineInstr.
403 unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
404 const MachineBasicBlock &MBB = *MI->getParent();
405 const MachineFunction *MF = MBB.getParent();
406 const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo();
408 // Basic size info comes from the TSFlags field.
409 const TargetInstrDesc &TID = MI->getDesc();
410 unsigned TSFlags = TID.TSFlags;
412 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
414 // If this machine instr is an inline asm, measure it.
415 if (MI->getOpcode() == ARM::INLINEASM)
416 return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName());
419 switch (MI->getOpcode()) {
421 llvm_unreachable("Unknown or unset size field for instr!");
422 case TargetInstrInfo::IMPLICIT_DEF:
423 case TargetInstrInfo::DECLARE:
424 case TargetInstrInfo::DBG_LABEL:
425 case TargetInstrInfo::EH_LABEL:
430 case ARMII::Size8Bytes: return 8; // ARM instruction x 2.
431 case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction.
432 case ARMII::Size2Bytes: return 2; // Thumb1 instruction.
433 case ARMII::SizeSpecial: {
434 bool IsThumb1JT = false;
435 switch (MI->getOpcode()) {
436 case ARM::CONSTPOOL_ENTRY:
437 // If this machine instr is a constant pool entry, its size is recorded as
439 return MI->getOperand(2).getImm();
440 case ARM::Int_eh_sjlj_setjmp:
449 // These are jumptable branches, i.e. a branch followed by an inlined
450 // jumptable. The size is 4 + 4 * number of entries.
451 unsigned NumOps = TID.getNumOperands();
452 MachineOperand JTOP =
453 MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
454 unsigned JTI = JTOP.getIndex();
455 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
456 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
457 assert(JTI < JT.size());
458 // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
459 // 4 aligned. The assembler / linker may add 2 byte padding just before
460 // the JT entries. The size does not include this padding; the
461 // constant islands pass does separate bookkeeping for it.
462 // FIXME: If we know the size of the function is less than (1 << 16) *2
463 // bytes, we can use 16-bit entries instead. Then there won't be an
465 return getNumJTEntries(JT, JTI) * 4 + (IsThumb1JT ? 2 : 4);
468 // Otherwise, pseudo-instruction sizes are zero.
473 return 0; // Not reached
476 /// Return true if the instruction is a register to register move and
477 /// leave the source and dest operands in the passed parameters.
480 ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
481 unsigned &SrcReg, unsigned &DstReg,
482 unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
483 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
485 switch (MI.getOpcode()) {
491 SrcReg = MI.getOperand(1).getReg();
492 DstReg = MI.getOperand(0).getReg();
497 case ARM::tMOVgpr2tgpr:
498 case ARM::tMOVtgpr2gpr:
499 case ARM::tMOVgpr2gpr:
501 assert(MI.getDesc().getNumOperands() >= 2 &&
502 MI.getOperand(0).isReg() &&
503 MI.getOperand(1).isReg() &&
504 "Invalid ARM MOV instruction");
505 SrcReg = MI.getOperand(1).getReg();
506 DstReg = MI.getOperand(0).getReg();
515 ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
516 int &FrameIndex) const {
517 switch (MI->getOpcode()) {
520 case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame.
521 if (MI->getOperand(1).isFI() &&
522 MI->getOperand(2).isReg() &&
523 MI->getOperand(3).isImm() &&
524 MI->getOperand(2).getReg() == 0 &&
525 MI->getOperand(3).getImm() == 0) {
526 FrameIndex = MI->getOperand(1).getIndex();
527 return MI->getOperand(0).getReg();
532 if (MI->getOperand(1).isFI() &&
533 MI->getOperand(2).isImm() &&
534 MI->getOperand(2).getImm() == 0) {
535 FrameIndex = MI->getOperand(1).getIndex();
536 return MI->getOperand(0).getReg();
541 if (MI->getOperand(1).isFI() &&
542 MI->getOperand(2).isImm() &&
543 MI->getOperand(2).getImm() == 0) {
544 FrameIndex = MI->getOperand(1).getIndex();
545 return MI->getOperand(0).getReg();
554 ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
555 int &FrameIndex) const {
556 switch (MI->getOpcode()) {
559 case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
560 if (MI->getOperand(1).isFI() &&
561 MI->getOperand(2).isReg() &&
562 MI->getOperand(3).isImm() &&
563 MI->getOperand(2).getReg() == 0 &&
564 MI->getOperand(3).getImm() == 0) {
565 FrameIndex = MI->getOperand(1).getIndex();
566 return MI->getOperand(0).getReg();
571 if (MI->getOperand(1).isFI() &&
572 MI->getOperand(2).isImm() &&
573 MI->getOperand(2).getImm() == 0) {
574 FrameIndex = MI->getOperand(1).getIndex();
575 return MI->getOperand(0).getReg();
580 if (MI->getOperand(1).isFI() &&
581 MI->getOperand(2).isImm() &&
582 MI->getOperand(2).getImm() == 0) {
583 FrameIndex = MI->getOperand(1).getIndex();
584 return MI->getOperand(0).getReg();
593 ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
594 MachineBasicBlock::iterator I,
595 unsigned DestReg, unsigned SrcReg,
596 const TargetRegisterClass *DestRC,
597 const TargetRegisterClass *SrcRC) const {
598 DebugLoc DL = DebugLoc::getUnknownLoc();
599 if (I != MBB.end()) DL = I->getDebugLoc();
601 if (DestRC != SrcRC) {
602 // Not yet supported!
606 if (DestRC == ARM::GPRRegisterClass)
607 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
608 DestReg).addReg(SrcReg)));
609 else if (DestRC == ARM::SPRRegisterClass)
610 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
612 else if (DestRC == ARM::DPRRegisterClass)
613 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
615 else if (DestRC == ARM::QPRRegisterClass)
616 BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
623 void ARMBaseInstrInfo::
624 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
625 unsigned SrcReg, bool isKill, int FI,
626 const TargetRegisterClass *RC) const {
627 DebugLoc DL = DebugLoc::getUnknownLoc();
628 if (I != MBB.end()) DL = I->getDebugLoc();
630 if (RC == ARM::GPRRegisterClass) {
631 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
632 .addReg(SrcReg, getKillRegState(isKill))
633 .addFrameIndex(FI).addReg(0).addImm(0));
634 } else if (RC == ARM::DPRRegisterClass) {
635 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
636 .addReg(SrcReg, getKillRegState(isKill))
637 .addFrameIndex(FI).addImm(0));
639 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
640 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
641 .addReg(SrcReg, getKillRegState(isKill))
642 .addFrameIndex(FI).addImm(0));
646 void ARMBaseInstrInfo::
647 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
648 unsigned DestReg, int FI,
649 const TargetRegisterClass *RC) const {
650 DebugLoc DL = DebugLoc::getUnknownLoc();
651 if (I != MBB.end()) DL = I->getDebugLoc();
653 if (RC == ARM::GPRRegisterClass) {
654 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDR), DestReg)
655 .addFrameIndex(FI).addReg(0).addImm(0));
656 } else if (RC == ARM::DPRRegisterClass) {
657 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
658 .addFrameIndex(FI).addImm(0));
660 assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
661 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
662 .addFrameIndex(FI).addImm(0));
666 MachineInstr *ARMBaseInstrInfo::
667 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
668 const SmallVectorImpl<unsigned> &Ops, int FI) const {
669 if (Ops.size() != 1) return NULL;
671 unsigned OpNum = Ops[0];
672 unsigned Opc = MI->getOpcode();
673 MachineInstr *NewMI = NULL;
674 if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) {
675 // If it is updating CPSR, then it cannot be folded.
676 if (MI->getOperand(4).getReg() != ARM::CPSR || MI->getOperand(4).isDead()) {
677 unsigned Pred = MI->getOperand(2).getImm();
678 unsigned PredReg = MI->getOperand(3).getReg();
679 if (OpNum == 0) { // move -> store
680 unsigned SrcReg = MI->getOperand(1).getReg();
681 bool isKill = MI->getOperand(1).isKill();
682 bool isUndef = MI->getOperand(1).isUndef();
683 if (Opc == ARM::MOVr)
684 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::STR))
685 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
686 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
688 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2STRi12))
689 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
690 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
691 } else { // move -> load
692 unsigned DstReg = MI->getOperand(0).getReg();
693 bool isDead = MI->getOperand(0).isDead();
694 bool isUndef = MI->getOperand(0).isUndef();
695 if (Opc == ARM::MOVr)
696 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::LDR))
699 getDeadRegState(isDead) |
700 getUndefRegState(isUndef))
701 .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
703 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::t2LDRi12))
706 getDeadRegState(isDead) |
707 getUndefRegState(isUndef))
708 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
712 else if (Opc == ARM::FCPYS) {
713 unsigned Pred = MI->getOperand(2).getImm();
714 unsigned PredReg = MI->getOperand(3).getReg();
715 if (OpNum == 0) { // move -> store
716 unsigned SrcReg = MI->getOperand(1).getReg();
717 bool isKill = MI->getOperand(1).isKill();
718 bool isUndef = MI->getOperand(1).isUndef();
719 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
720 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
722 .addImm(0).addImm(Pred).addReg(PredReg);
723 } else { // move -> load
724 unsigned DstReg = MI->getOperand(0).getReg();
725 bool isDead = MI->getOperand(0).isDead();
726 bool isUndef = MI->getOperand(0).isUndef();
727 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
730 getDeadRegState(isDead) |
731 getUndefRegState(isUndef))
732 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
735 else if (Opc == ARM::FCPYD) {
736 unsigned Pred = MI->getOperand(2).getImm();
737 unsigned PredReg = MI->getOperand(3).getReg();
738 if (OpNum == 0) { // move -> store
739 unsigned SrcReg = MI->getOperand(1).getReg();
740 bool isKill = MI->getOperand(1).isKill();
741 bool isUndef = MI->getOperand(1).isUndef();
742 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
743 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
744 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
745 } else { // move -> load
746 unsigned DstReg = MI->getOperand(0).getReg();
747 bool isDead = MI->getOperand(0).isDead();
748 bool isUndef = MI->getOperand(0).isUndef();
749 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD))
752 getDeadRegState(isDead) |
753 getUndefRegState(isUndef))
754 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
762 ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
764 const SmallVectorImpl<unsigned> &Ops,
765 MachineInstr* LoadMI) const {
771 ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
772 const SmallVectorImpl<unsigned> &Ops) const {
773 if (Ops.size() != 1) return false;
775 unsigned Opc = MI->getOpcode();
776 if (Opc == ARM::MOVr || Opc == ARM::t2MOVr) {
777 // If it is updating CPSR, then it cannot be folded.
778 return MI->getOperand(4).getReg() != ARM::CPSR ||MI->getOperand(4).isDead();
779 } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) {
781 } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) {
782 return false; // FIXME
788 int ARMBaseInstrInfo::getMatchingCondBranchOpcode(int Opc) const {
791 else if (Opc == ARM::tB)
793 else if (Opc == ARM::t2B)
796 llvm_unreachable("Unknown unconditional branch opcode!");