ARMBaseInstrInfo.cpp revision a609c1db269d37f9443af611b415a9f7af917474
1//===- ARMBaseInstrInfo.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//===----------------------------------------------------------------------===//
9//
10// This file contains the Base ARM implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMBaseInstrInfo.h"
15#include "ARM.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"
27using namespace llvm;
28
29static cl::opt<bool>
30EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
31               cl::desc("Enable ARM 2-addr to 3-addr conv"));
32
33ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI)
34  : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)) {
35}
36
37MachineInstr *
38ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
39                                        MachineBasicBlock::iterator &MBBI,
40                                        LiveVariables *LV) const {
41  if (!EnableARM3Addr)
42    return NULL;
43
44  MachineInstr *MI = MBBI;
45  MachineFunction &MF = *MI->getParent()->getParent();
46  unsigned TSFlags = MI->getDesc().TSFlags;
47  bool isPre = false;
48  switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
49  default: return NULL;
50  case ARMII::IndexModePre:
51    isPre = true;
52    break;
53  case ARMII::IndexModePost:
54    break;
55  }
56
57  // Try splitting an indexed load/store to an un-indexed one plus an add/sub
58  // operation.
59  unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
60  if (MemOpc == 0)
61    return NULL;
62
63  MachineInstr *UpdateMI = NULL;
64  MachineInstr *MemMI = NULL;
65  unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
66  const TargetInstrDesc &TID = MI->getDesc();
67  unsigned NumOps = TID.getNumOperands();
68  bool isLoad = !TID.mayStore();
69  const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
70  const MachineOperand &Base = MI->getOperand(2);
71  const MachineOperand &Offset = MI->getOperand(NumOps-3);
72  unsigned WBReg = WB.getReg();
73  unsigned BaseReg = Base.getReg();
74  unsigned OffReg = Offset.getReg();
75  unsigned OffImm = MI->getOperand(NumOps-2).getImm();
76  ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
77  switch (AddrMode) {
78  default:
79    assert(false && "Unknown indexed op!");
80    return NULL;
81  case ARMII::AddrMode2: {
82    bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
83    unsigned Amt = ARM_AM::getAM2Offset(OffImm);
84    if (OffReg == 0) {
85      if (ARM_AM::getSOImmVal(Amt) == -1)
86        // Can't encode it in a so_imm operand. This transformation will
87        // add more than 1 instruction. Abandon!
88        return NULL;
89      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
90                         get(isSub ? getOpcode(ARMII::SUBri) :
91                             getOpcode(ARMII::ADDri)), WBReg)
92        .addReg(BaseReg).addImm(Amt)
93        .addImm(Pred).addReg(0).addReg(0);
94    } else if (Amt != 0) {
95      ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
96      unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
97      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
98                         get(isSub ? getOpcode(ARMII::SUBrs) :
99                             getOpcode(ARMII::ADDrs)), WBReg)
100        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
101        .addImm(Pred).addReg(0).addReg(0);
102    } else
103      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
104                         get(isSub ? getOpcode(ARMII::SUBrr) :
105                             getOpcode(ARMII::ADDrr)), WBReg)
106        .addReg(BaseReg).addReg(OffReg)
107        .addImm(Pred).addReg(0).addReg(0);
108    break;
109  }
110  case ARMII::AddrMode3 : {
111    bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
112    unsigned Amt = ARM_AM::getAM3Offset(OffImm);
113    if (OffReg == 0)
114      // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
115      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
116                         get(isSub ? getOpcode(ARMII::SUBri) :
117                             getOpcode(ARMII::ADDri)), WBReg)
118        .addReg(BaseReg).addImm(Amt)
119        .addImm(Pred).addReg(0).addReg(0);
120    else
121      UpdateMI = BuildMI(MF, MI->getDebugLoc(),
122                         get(isSub ? getOpcode(ARMII::SUBrr) :
123                             getOpcode(ARMII::ADDrr)), WBReg)
124        .addReg(BaseReg).addReg(OffReg)
125        .addImm(Pred).addReg(0).addReg(0);
126    break;
127  }
128  }
129
130  std::vector<MachineInstr*> NewMIs;
131  if (isPre) {
132    if (isLoad)
133      MemMI = BuildMI(MF, MI->getDebugLoc(),
134                      get(MemOpc), MI->getOperand(0).getReg())
135        .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
136    else
137      MemMI = BuildMI(MF, MI->getDebugLoc(),
138                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
139        .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
140    NewMIs.push_back(MemMI);
141    NewMIs.push_back(UpdateMI);
142  } else {
143    if (isLoad)
144      MemMI = BuildMI(MF, MI->getDebugLoc(),
145                      get(MemOpc), MI->getOperand(0).getReg())
146        .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
147    else
148      MemMI = BuildMI(MF, MI->getDebugLoc(),
149                      get(MemOpc)).addReg(MI->getOperand(1).getReg())
150        .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
151    if (WB.isDead())
152      UpdateMI->getOperand(0).setIsDead();
153    NewMIs.push_back(UpdateMI);
154    NewMIs.push_back(MemMI);
155  }
156
157  // Transfer LiveVariables states, kill / dead info.
158  if (LV) {
159    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
160      MachineOperand &MO = MI->getOperand(i);
161      if (MO.isReg() && MO.getReg() &&
162          TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
163        unsigned Reg = MO.getReg();
164
165        LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
166        if (MO.isDef()) {
167          MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
168          if (MO.isDead())
169            LV->addVirtualRegisterDead(Reg, NewMI);
170        }
171        if (MO.isUse() && MO.isKill()) {
172          for (unsigned j = 0; j < 2; ++j) {
173            // Look at the two new MI's in reverse order.
174            MachineInstr *NewMI = NewMIs[j];
175            if (!NewMI->readsRegister(Reg))
176              continue;
177            LV->addVirtualRegisterKilled(Reg, NewMI);
178            if (VI.removeKill(MI))
179              VI.Kills.push_back(NewMI);
180            break;
181          }
182        }
183      }
184    }
185  }
186
187  MFI->insert(MBBI, NewMIs[1]);
188  MFI->insert(MBBI, NewMIs[0]);
189  return NewMIs[0];
190}
191
192// Branch analysis.
193bool
194ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
195                                MachineBasicBlock *&FBB,
196                                SmallVectorImpl<MachineOperand> &Cond,
197                                bool AllowModify) const {
198  // If the block has no terminators, it just falls into the block after it.
199  MachineBasicBlock::iterator I = MBB.end();
200  if (I == MBB.begin() || !isUnpredicatedTerminator(--I))
201    return false;
202
203  // Get the last instruction in the block.
204  MachineInstr *LastInst = I;
205
206  // If there is only one terminator instruction, process it.
207  unsigned LastOpc = LastInst->getOpcode();
208  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
209    if (LastOpc == getOpcode(ARMII::B)) {
210      TBB = LastInst->getOperand(0).getMBB();
211      return false;
212    }
213    if (LastOpc == getOpcode(ARMII::Bcc)) {
214      // Block ends with fall-through condbranch.
215      TBB = LastInst->getOperand(0).getMBB();
216      Cond.push_back(LastInst->getOperand(1));
217      Cond.push_back(LastInst->getOperand(2));
218      return false;
219    }
220    return true;  // Can't handle indirect branch.
221  }
222
223  // Get the instruction before it if it is a terminator.
224  MachineInstr *SecondLastInst = I;
225
226  // If there are three terminators, we don't know what sort of block this is.
227  if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
228    return true;
229
230  // If the block ends with ARMII::B and a ARMII::Bcc, handle it.
231  unsigned SecondLastOpc = SecondLastInst->getOpcode();
232  if ((SecondLastOpc == getOpcode(ARMII::Bcc)) &&
233      (LastOpc == getOpcode(ARMII::B))) {
234    TBB =  SecondLastInst->getOperand(0).getMBB();
235    Cond.push_back(SecondLastInst->getOperand(1));
236    Cond.push_back(SecondLastInst->getOperand(2));
237    FBB = LastInst->getOperand(0).getMBB();
238    return false;
239  }
240
241  // If the block ends with two unconditional branches, handle it.  The second
242  // one is not executed, so remove it.
243  if ((SecondLastOpc == getOpcode(ARMII::B)) &&
244      (LastOpc == getOpcode(ARMII::B))) {
245    TBB = SecondLastInst->getOperand(0).getMBB();
246    I = LastInst;
247    if (AllowModify)
248      I->eraseFromParent();
249    return false;
250  }
251
252  // ...likewise if it ends with a branch table followed by an unconditional
253  // branch. The branch folder can create these, and we must get rid of them for
254  // correctness of Thumb constant islands.
255  if (((SecondLastOpc == getOpcode(ARMII::BR_JTr)) ||
256       (SecondLastOpc == getOpcode(ARMII::BR_JTm)) ||
257       (SecondLastOpc == getOpcode(ARMII::BR_JTadd))) &&
258      (LastOpc == getOpcode(ARMII::B))) {
259    I = LastInst;
260    if (AllowModify)
261      I->eraseFromParent();
262    return true;
263  }
264
265  // Otherwise, can't handle this.
266  return true;
267}
268
269
270unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
271  int BOpc   = getOpcode(ARMII::B);
272  int BccOpc = getOpcode(ARMII::Bcc);
273
274  MachineBasicBlock::iterator I = MBB.end();
275  if (I == MBB.begin()) return 0;
276  --I;
277  if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc)
278    return 0;
279
280  // Remove the branch.
281  I->eraseFromParent();
282
283  I = MBB.end();
284
285  if (I == MBB.begin()) return 1;
286  --I;
287  if (I->getOpcode() != BccOpc)
288    return 1;
289
290  // Remove the branch.
291  I->eraseFromParent();
292  return 2;
293}
294
295unsigned
296ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
297                               MachineBasicBlock *FBB,
298                             const SmallVectorImpl<MachineOperand> &Cond) const {
299  // FIXME this should probably have a DebugLoc argument
300  DebugLoc dl = DebugLoc::getUnknownLoc();
301  int BOpc   = getOpcode(ARMII::B);
302  int BccOpc = getOpcode(ARMII::Bcc);
303
304  // Shouldn't be a fall through.
305  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
306  assert((Cond.size() == 2 || Cond.size() == 0) &&
307         "ARM branch conditions have two components!");
308
309  if (FBB == 0) {
310    if (Cond.empty()) // Unconditional branch?
311      BuildMI(&MBB, dl, get(BOpc)).addMBB(TBB);
312    else
313      BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB)
314        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
315    return 1;
316  }
317
318  // Two-way conditional branch.
319  BuildMI(&MBB, dl, get(BccOpc)).addMBB(TBB)
320    .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
321  BuildMI(&MBB, dl, get(BOpc)).addMBB(FBB);
322  return 2;
323}
324
325bool ARMBaseInstrInfo::
326ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
327  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
328  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
329  return false;
330}
331
332bool ARMBaseInstrInfo::
333PredicateInstruction(MachineInstr *MI,
334                     const SmallVectorImpl<MachineOperand> &Pred) const {
335  unsigned Opc = MI->getOpcode();
336  if (Opc == getOpcode(ARMII::B)) {
337    MI->setDesc(get(getOpcode(ARMII::Bcc)));
338    MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
339    MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false));
340    return true;
341  }
342
343  int PIdx = MI->findFirstPredOperandIdx();
344  if (PIdx != -1) {
345    MachineOperand &PMO = MI->getOperand(PIdx);
346    PMO.setImm(Pred[0].getImm());
347    MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
348    return true;
349  }
350  return false;
351}
352
353bool ARMBaseInstrInfo::
354SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
355                  const SmallVectorImpl<MachineOperand> &Pred2) const {
356  if (Pred1.size() > 2 || Pred2.size() > 2)
357    return false;
358
359  ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
360  ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
361  if (CC1 == CC2)
362    return true;
363
364  switch (CC1) {
365  default:
366    return false;
367  case ARMCC::AL:
368    return true;
369  case ARMCC::HS:
370    return CC2 == ARMCC::HI;
371  case ARMCC::LS:
372    return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
373  case ARMCC::GE:
374    return CC2 == ARMCC::GT;
375  case ARMCC::LE:
376    return CC2 == ARMCC::LT;
377  }
378}
379
380bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
381                                    std::vector<MachineOperand> &Pred) const {
382  const TargetInstrDesc &TID = MI->getDesc();
383  if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
384    return false;
385
386  bool Found = false;
387  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
388    const MachineOperand &MO = MI->getOperand(i);
389    if (MO.isReg() && MO.getReg() == ARM::CPSR) {
390      Pred.push_back(MO);
391      Found = true;
392    }
393  }
394
395  return Found;
396}
397
398
399/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
400static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
401                                unsigned JTI) DISABLE_INLINE;
402static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
403                                unsigned JTI) {
404  return JT[JTI].MBBs.size();
405}
406
407/// GetInstSize - Return the size of the specified MachineInstr.
408///
409unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
410  const MachineBasicBlock &MBB = *MI->getParent();
411  const MachineFunction *MF = MBB.getParent();
412  const TargetAsmInfo *TAI = MF->getTarget().getTargetAsmInfo();
413
414  // Basic size info comes from the TSFlags field.
415  const TargetInstrDesc &TID = MI->getDesc();
416  unsigned TSFlags = TID.TSFlags;
417
418  switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
419  default: {
420    // If this machine instr is an inline asm, measure it.
421    if (MI->getOpcode() == ARM::INLINEASM)
422      return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName());
423    if (MI->isLabel())
424      return 0;
425    switch (MI->getOpcode()) {
426    default:
427      llvm_unreachable("Unknown or unset size field for instr!");
428    case TargetInstrInfo::IMPLICIT_DEF:
429    case TargetInstrInfo::DECLARE:
430    case TargetInstrInfo::DBG_LABEL:
431    case TargetInstrInfo::EH_LABEL:
432      return 0;
433    }
434    break;
435  }
436  case ARMII::Size8Bytes: return 8;          // ARM instruction x 2.
437  case ARMII::Size4Bytes: return 4;          // ARM / Thumb2 instruction.
438  case ARMII::Size2Bytes: return 2;          // Thumb1 instruction.
439  case ARMII::SizeSpecial: {
440    bool IsThumb1JT = false;
441    switch (MI->getOpcode()) {
442    case ARM::CONSTPOOL_ENTRY:
443      // If this machine instr is a constant pool entry, its size is recorded as
444      // operand #2.
445      return MI->getOperand(2).getImm();
446    case ARM::Int_eh_sjlj_setjmp:
447      return 12;
448    case ARM::tBR_JTr:
449      IsThumb1JT = true;
450      // Fallthrough
451    case ARM::BR_JTr:
452    case ARM::BR_JTm:
453    case ARM::BR_JTadd:
454    case ARM::t2BR_JTr:
455    case ARM::t2BR_JTm:
456    case ARM::t2BR_JTadd: {
457      // These are jumptable branches, i.e. a branch followed by an inlined
458      // jumptable. The size is 4 + 4 * number of entries.
459      unsigned NumOps = TID.getNumOperands();
460      MachineOperand JTOP =
461        MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
462      unsigned JTI = JTOP.getIndex();
463      const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
464      const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
465      assert(JTI < JT.size());
466      // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
467      // 4 aligned. The assembler / linker may add 2 byte padding just before
468      // the JT entries.  The size does not include this padding; the
469      // constant islands pass does separate bookkeeping for it.
470      // FIXME: If we know the size of the function is less than (1 << 16) *2
471      // bytes, we can use 16-bit entries instead. Then there won't be an
472      // alignment issue.
473      return getNumJTEntries(JT, JTI) * 4 + (IsThumb1JT ? 2 : 4);
474    }
475    default:
476      // Otherwise, pseudo-instruction sizes are zero.
477      return 0;
478    }
479  }
480  }
481  return 0; // Not reached
482}
483
484/// Return true if the instruction is a register to register move and
485/// leave the source and dest operands in the passed parameters.
486///
487bool
488ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
489                              unsigned &SrcReg, unsigned &DstReg,
490                              unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
491  SrcSubIdx = DstSubIdx = 0; // No sub-registers.
492
493  unsigned oc = MI.getOpcode();
494  if (oc == ARM::FCPYS ||
495      oc == ARM::FCPYD ||
496      oc == ARM::VMOVD ||
497      oc == ARM::VMOVQ) {
498    SrcReg = MI.getOperand(1).getReg();
499    DstReg = MI.getOperand(0).getReg();
500    return true;
501  }
502  else if (oc == getOpcode(ARMII::MOVr)) {
503    assert(MI.getDesc().getNumOperands() >= 2 &&
504           MI.getOperand(0).isReg() &&
505           MI.getOperand(1).isReg() &&
506           "Invalid ARM MOV instruction");
507    SrcReg = MI.getOperand(1).getReg();
508    DstReg = MI.getOperand(0).getReg();
509    return true;
510  }
511
512  return false;
513}
514
515unsigned
516ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
517                                      int &FrameIndex) const {
518  unsigned oc = MI->getOpcode();
519  if (oc == getOpcode(ARMII::LDRrr)) {
520    if (MI->getOperand(1).isFI() &&
521        MI->getOperand(2).isReg() &&
522        MI->getOperand(3).isImm() &&
523        MI->getOperand(2).getReg() == 0 &&
524        MI->getOperand(3).getImm() == 0) {
525      FrameIndex = MI->getOperand(1).getIndex();
526      return MI->getOperand(0).getReg();
527    }
528  }
529  else if (oc == getOpcode(ARMII::LDRri)) {
530    if (MI->getOperand(1).isFI() &&
531        MI->getOperand(2).isImm() &&
532        MI->getOperand(2).getImm() == 0) {
533      FrameIndex = MI->getOperand(1).getIndex();
534      return MI->getOperand(0).getReg();
535    }
536  }
537  else if (oc == ARM::FLDD || oc == ARM::FLDS) {
538    if (MI->getOperand(1).isFI() &&
539        MI->getOperand(2).isImm() &&
540        MI->getOperand(2).getImm() == 0) {
541      FrameIndex = MI->getOperand(1).getIndex();
542      return MI->getOperand(0).getReg();
543    }
544  }
545
546  return 0;
547}
548
549unsigned
550ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
551                                     int &FrameIndex) const {
552  unsigned oc = MI->getOpcode();
553  if (oc == getOpcode(ARMII::STRrr)) {
554    if (MI->getOperand(1).isFI() &&
555        MI->getOperand(2).isReg() &&
556        MI->getOperand(3).isImm() &&
557        MI->getOperand(2).getReg() == 0 &&
558        MI->getOperand(3).getImm() == 0) {
559      FrameIndex = MI->getOperand(1).getIndex();
560      return MI->getOperand(0).getReg();
561    }
562  }
563  else if (oc == getOpcode(ARMII::STRri)) {
564    if (MI->getOperand(1).isFI() &&
565        MI->getOperand(2).isImm() &&
566        MI->getOperand(2).getImm() == 0) {
567      FrameIndex = MI->getOperand(1).getIndex();
568      return MI->getOperand(0).getReg();
569    }
570  }
571  else if (oc == ARM::FSTD || oc == ARM::FSTS) {
572    if (MI->getOperand(1).isFI() &&
573        MI->getOperand(2).isImm() &&
574        MI->getOperand(2).getImm() == 0) {
575      FrameIndex = MI->getOperand(1).getIndex();
576      return MI->getOperand(0).getReg();
577    }
578  }
579
580  return 0;
581}
582
583bool
584ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
585                               MachineBasicBlock::iterator I,
586                               unsigned DestReg, unsigned SrcReg,
587                               const TargetRegisterClass *DestRC,
588                               const TargetRegisterClass *SrcRC) const {
589  DebugLoc DL = DebugLoc::getUnknownLoc();
590  if (I != MBB.end()) DL = I->getDebugLoc();
591
592  if (DestRC != SrcRC) {
593    // Not yet supported!
594    return false;
595  }
596
597  if (DestRC == ARM::GPRRegisterClass)
598    AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::MOVr)),
599                                        DestReg).addReg(SrcReg)));
600  else if (DestRC == ARM::SPRRegisterClass)
601    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
602                   .addReg(SrcReg));
603  else if (DestRC == ARM::DPRRegisterClass)
604    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
605                   .addReg(SrcReg));
606  else if (DestRC == ARM::QPRRegisterClass)
607    BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg);
608  else
609    return false;
610
611  return true;
612}
613
614void ARMBaseInstrInfo::
615storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
616                    unsigned SrcReg, bool isKill, int FI,
617                    const TargetRegisterClass *RC) const {
618  DebugLoc DL = DebugLoc::getUnknownLoc();
619  if (I != MBB.end()) DL = I->getDebugLoc();
620
621  if (RC == ARM::GPRRegisterClass) {
622    AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::STRrr)))
623                   .addReg(SrcReg, getKillRegState(isKill))
624                   .addFrameIndex(FI).addReg(0).addImm(0));
625  } else if (RC == ARM::DPRRegisterClass) {
626    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
627                   .addReg(SrcReg, getKillRegState(isKill))
628                   .addFrameIndex(FI).addImm(0));
629  } else {
630    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
631    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
632                   .addReg(SrcReg, getKillRegState(isKill))
633                   .addFrameIndex(FI).addImm(0));
634  }
635}
636
637void ARMBaseInstrInfo::
638loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
639                     unsigned DestReg, int FI,
640                     const TargetRegisterClass *RC) const {
641  DebugLoc DL = DebugLoc::getUnknownLoc();
642  if (I != MBB.end()) DL = I->getDebugLoc();
643
644  if (RC == ARM::GPRRegisterClass) {
645    AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::LDRrr)), DestReg)
646                   .addFrameIndex(FI).addReg(0).addImm(0));
647  } else if (RC == ARM::DPRRegisterClass) {
648    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
649                   .addFrameIndex(FI).addImm(0));
650  } else {
651    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
652    AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
653                   .addFrameIndex(FI).addImm(0));
654  }
655}
656
657MachineInstr *ARMBaseInstrInfo::
658foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
659                      const SmallVectorImpl<unsigned> &Ops, int FI) const {
660  if (Ops.size() != 1) return NULL;
661
662  unsigned OpNum = Ops[0];
663  unsigned Opc = MI->getOpcode();
664  MachineInstr *NewMI = NULL;
665  if (Opc == getOpcode(ARMII::MOVr)) {
666    // If it is updating CPSR, then it cannot be folded.
667    if (MI->getOperand(4).getReg() != ARM::CPSR) {
668      unsigned Pred = MI->getOperand(2).getImm();
669      unsigned PredReg = MI->getOperand(3).getReg();
670      if (OpNum == 0) { // move -> store
671        unsigned SrcReg = MI->getOperand(1).getReg();
672        bool isKill = MI->getOperand(1).isKill();
673        bool isUndef = MI->getOperand(1).isUndef();
674        NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::STRrr)))
675          .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
676          .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
677      } else {          // move -> load
678        unsigned DstReg = MI->getOperand(0).getReg();
679        bool isDead = MI->getOperand(0).isDead();
680        bool isUndef = MI->getOperand(0).isUndef();
681        NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::LDRrr)))
682          .addReg(DstReg,
683                  RegState::Define |
684                  getDeadRegState(isDead) |
685                  getUndefRegState(isUndef))
686          .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
687      }
688    }
689  }
690  else if (Opc == ARM::FCPYS) {
691    unsigned Pred = MI->getOperand(2).getImm();
692    unsigned PredReg = MI->getOperand(3).getReg();
693    if (OpNum == 0) { // move -> store
694      unsigned SrcReg = MI->getOperand(1).getReg();
695      bool isKill = MI->getOperand(1).isKill();
696      bool isUndef = MI->getOperand(1).isUndef();
697      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
698        .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
699        .addFrameIndex(FI)
700        .addImm(0).addImm(Pred).addReg(PredReg);
701    } else {          // move -> load
702      unsigned DstReg = MI->getOperand(0).getReg();
703      bool isDead = MI->getOperand(0).isDead();
704      bool isUndef = MI->getOperand(0).isUndef();
705      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
706        .addReg(DstReg,
707                RegState::Define |
708                getDeadRegState(isDead) |
709                getUndefRegState(isUndef))
710        .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
711    }
712  }
713  else if (Opc == ARM::FCPYD) {
714    unsigned Pred = MI->getOperand(2).getImm();
715    unsigned PredReg = MI->getOperand(3).getReg();
716    if (OpNum == 0) { // move -> store
717      unsigned SrcReg = MI->getOperand(1).getReg();
718      bool isKill = MI->getOperand(1).isKill();
719      bool isUndef = MI->getOperand(1).isUndef();
720      NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
721        .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
722        .addFrameIndex(FI).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::FLDD))
728        .addReg(DstReg,
729                RegState::Define |
730                getDeadRegState(isDead) |
731                getUndefRegState(isUndef))
732        .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
733    }
734  }
735
736  return NewMI;
737}
738
739MachineInstr*
740ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
741                                        MachineInstr* MI,
742                                        const SmallVectorImpl<unsigned> &Ops,
743                                        MachineInstr* LoadMI) const {
744  return 0;
745}
746
747bool
748ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
749                                       const SmallVectorImpl<unsigned> &Ops) const {
750  if (Ops.size() != 1) return false;
751
752  unsigned Opc = MI->getOpcode();
753  if (Opc == getOpcode(ARMII::MOVr)) {
754    // If it is updating CPSR, then it cannot be folded.
755    return MI->getOperand(4).getReg() != ARM::CPSR;
756  } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) {
757    return true;
758  } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) {
759    return false; // FIXME
760  }
761
762  return false;
763}
764