Put Target definitions inside Target specific header, and llvm namespace.
[oota-llvm.git] / lib / Target / ARM / ARMBaseInstrInfo.cpp
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"
27 using namespace llvm;
28
29 static cl::opt<bool>
30 EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
31                cl::desc("Enable ARM 2-addr to 3-addr conv"));
32
33 ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget &STI)
34   : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)) {
35 }
36
37 MachineInstr *
38 ARMBaseInstrInfo::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.
193 bool
194 ARMBaseInstrInfo::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
270 unsigned 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
295 unsigned
296 ARMBaseInstrInfo::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
325 bool ARMBaseInstrInfo::
326 ReverseBranchCondition(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
332 bool ARMBaseInstrInfo::
333 PredicateInstruction(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
353 bool ARMBaseInstrInfo::
354 SubsumesPredicate(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
380 bool 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
400 static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
401                                 unsigned JTI) DISABLE_INLINE;
402 static 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 ///
409 unsigned 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 instruction.
438   case ARMII::Size2Bytes: return 2;          // Thumb instruction.
439   case ARMII::SizeSpecial: {
440     switch (MI->getOpcode()) {
441     case ARM::CONSTPOOL_ENTRY:
442       // If this machine instr is a constant pool entry, its size is recorded as
443       // operand #2.
444       return MI->getOperand(2).getImm();
445     case ARM::Int_eh_sjlj_setjmp: return 12;
446     case ARM::BR_JTr:
447     case ARM::BR_JTm:
448     case ARM::BR_JTadd:
449     case ARM::t2BR_JTr:
450     case ARM::t2BR_JTm:
451     case ARM::t2BR_JTadd:
452     case ARM::tBR_JTr: {
453       // These are jumptable branches, i.e. a branch followed by an inlined
454       // jumptable. The size is 4 + 4 * number of entries.
455       unsigned NumOps = TID.getNumOperands();
456       MachineOperand JTOP =
457         MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
458       unsigned JTI = JTOP.getIndex();
459       const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
460       const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
461       assert(JTI < JT.size());
462       // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
463       // 4 aligned. The assembler / linker may add 2 byte padding just before
464       // the JT entries.  The size does not include this padding; the
465       // constant islands pass does separate bookkeeping for it.
466       // FIXME: If we know the size of the function is less than (1 << 16) *2
467       // bytes, we can use 16-bit entries instead. Then there won't be an
468       // alignment issue.
469       return getNumJTEntries(JT, JTI) * 4 +
470         ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4);
471     }
472     default:
473       // Otherwise, pseudo-instruction sizes are zero.
474       return 0;
475     }
476   }
477   }
478   return 0; // Not reached
479 }
480
481 /// Return true if the instruction is a register to register move and
482 /// leave the source and dest operands in the passed parameters.
483 ///
484 bool
485 ARMBaseInstrInfo::isMoveInstr(const MachineInstr &MI,
486                               unsigned &SrcReg, unsigned &DstReg,
487                               unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
488   SrcSubIdx = DstSubIdx = 0; // No sub-registers.
489
490   unsigned oc = MI.getOpcode();
491   if ((oc == getOpcode(ARMII::FCPYS)) ||
492       (oc == getOpcode(ARMII::FCPYD)) ||
493       (oc == getOpcode(ARMII::VMOVD)) ||
494       (oc == getOpcode(ARMII::VMOVQ))) {
495     SrcReg = MI.getOperand(1).getReg();
496     DstReg = MI.getOperand(0).getReg();
497     return true;
498   }
499   else if (oc == getOpcode(ARMII::MOVr)) {
500     assert(MI.getDesc().getNumOperands() >= 2 &&
501            MI.getOperand(0).isReg() &&
502            MI.getOperand(1).isReg() &&
503            "Invalid ARM MOV instruction");
504     SrcReg = MI.getOperand(1).getReg();
505     DstReg = MI.getOperand(0).getReg();
506     return true;
507   }
508
509   return false;
510 }
511
512 unsigned 
513 ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
514                                       int &FrameIndex) const {
515   unsigned oc = MI->getOpcode();
516   if (oc == getOpcode(ARMII::LDR)) {
517     if (MI->getOperand(1).isFI() &&
518         MI->getOperand(2).isReg() &&
519         MI->getOperand(3).isImm() &&
520         MI->getOperand(2).getReg() == 0 &&
521         MI->getOperand(3).getImm() == 0) {
522       FrameIndex = MI->getOperand(1).getIndex();
523       return MI->getOperand(0).getReg();
524     }
525   }
526   else if ((oc == getOpcode(ARMII::FLDD)) ||
527            (oc == getOpcode(ARMII::FLDS))) {
528     if (MI->getOperand(1).isFI() &&
529         MI->getOperand(2).isImm() &&
530         MI->getOperand(2).getImm() == 0) {
531       FrameIndex = MI->getOperand(1).getIndex();
532       return MI->getOperand(0).getReg();
533     }
534   }
535
536   return 0;
537 }
538
539 unsigned
540 ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
541                                      int &FrameIndex) const {
542   unsigned oc = MI->getOpcode();
543   if (oc == getOpcode(ARMII::STR)) {
544     if (MI->getOperand(1).isFI() &&
545         MI->getOperand(2).isReg() &&
546         MI->getOperand(3).isImm() &&
547         MI->getOperand(2).getReg() == 0 &&
548         MI->getOperand(3).getImm() == 0) {
549       FrameIndex = MI->getOperand(1).getIndex();
550       return MI->getOperand(0).getReg();
551     }
552   }
553   else if ((oc == getOpcode(ARMII::FSTD)) ||
554            (oc == getOpcode(ARMII::FSTS))) {
555     if (MI->getOperand(1).isFI() &&
556         MI->getOperand(2).isImm() &&
557         MI->getOperand(2).getImm() == 0) {
558       FrameIndex = MI->getOperand(1).getIndex();
559       return MI->getOperand(0).getReg();
560     }
561   }
562
563   return 0;
564 }
565
566 bool
567 ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
568                                MachineBasicBlock::iterator I,
569                                unsigned DestReg, unsigned SrcReg,
570                                const TargetRegisterClass *DestRC,
571                                const TargetRegisterClass *SrcRC) const {
572   DebugLoc DL = DebugLoc::getUnknownLoc();
573   if (I != MBB.end()) DL = I->getDebugLoc();
574
575   if (DestRC != SrcRC) {
576     // Not yet supported!
577     return false;
578   }
579
580   if (DestRC == ARM::GPRRegisterClass)
581     AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::MOVr)),
582                                         DestReg).addReg(SrcReg)));
583   else if (DestRC == ARM::SPRRegisterClass)
584     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FCPYS)), DestReg)
585                    .addReg(SrcReg));
586   else if (DestRC == ARM::DPRRegisterClass)
587     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FCPYD)), DestReg)
588                    .addReg(SrcReg));
589   else if (DestRC == ARM::QPRRegisterClass)
590     BuildMI(MBB, I, DL, get(getOpcode(ARMII::VMOVQ)), DestReg).addReg(SrcReg);
591   else
592     return false;
593
594   return true;
595 }
596
597 void ARMBaseInstrInfo::
598 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
599                     unsigned SrcReg, bool isKill, int FI,
600                     const TargetRegisterClass *RC) const {
601   DebugLoc DL = DebugLoc::getUnknownLoc();
602   if (I != MBB.end()) DL = I->getDebugLoc();
603
604   if (RC == ARM::GPRRegisterClass) {
605     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::STR)))
606                    .addReg(SrcReg, getKillRegState(isKill))
607                    .addFrameIndex(FI).addReg(0).addImm(0));
608   } else if (RC == ARM::DPRRegisterClass) {
609     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FSTD)))
610                    .addReg(SrcReg, getKillRegState(isKill))
611                    .addFrameIndex(FI).addImm(0));
612   } else {
613     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
614     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FSTS)))
615                    .addReg(SrcReg, getKillRegState(isKill))
616                    .addFrameIndex(FI).addImm(0));
617   }
618 }
619
620 void 
621 ARMBaseInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
622                                  bool isKill,
623                                  SmallVectorImpl<MachineOperand> &Addr,
624                                  const TargetRegisterClass *RC,
625                                  SmallVectorImpl<MachineInstr*> &NewMIs) const{
626   DebugLoc DL = DebugLoc::getUnknownLoc();
627   unsigned Opc = 0;
628   if (RC == ARM::GPRRegisterClass) {
629     Opc = getOpcode(ARMII::STR);
630   } else if (RC == ARM::DPRRegisterClass) {
631     Opc = getOpcode(ARMII::FSTD);
632   } else {
633     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
634     Opc = getOpcode(ARMII::FSTS);
635   }
636
637   MachineInstrBuilder MIB =
638     BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill));
639   for (unsigned i = 0, e = Addr.size(); i != e; ++i)
640     MIB.addOperand(Addr[i]);
641   AddDefaultPred(MIB);
642   NewMIs.push_back(MIB);
643   return;
644 }
645
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();
652
653   if (RC == ARM::GPRRegisterClass) {
654     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::LDR)), DestReg)
655                    .addFrameIndex(FI).addReg(0).addImm(0));
656   } else if (RC == ARM::DPRRegisterClass) {
657     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FLDD)), DestReg)
658                    .addFrameIndex(FI).addImm(0));
659   } else {
660     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
661     AddDefaultPred(BuildMI(MBB, I, DL, get(getOpcode(ARMII::FLDS)), DestReg)
662                    .addFrameIndex(FI).addImm(0));
663   }
664 }
665
666 void ARMBaseInstrInfo::
667 loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
668                 SmallVectorImpl<MachineOperand> &Addr,
669                 const TargetRegisterClass *RC,
670                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
671   DebugLoc DL = DebugLoc::getUnknownLoc();
672   unsigned Opc = 0;
673   if (RC == ARM::GPRRegisterClass) {
674     Opc = getOpcode(ARMII::LDR);
675   } else if (RC == ARM::DPRRegisterClass) {
676       Opc = getOpcode(ARMII::FLDD);
677   } else {
678     assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
679     Opc = getOpcode(ARMII::FLDS);
680   }
681
682   MachineInstrBuilder MIB =  BuildMI(MF, DL, get(Opc), DestReg);
683   for (unsigned i = 0, e = Addr.size(); i != e; ++i)
684     MIB.addOperand(Addr[i]);
685   AddDefaultPred(MIB);
686   NewMIs.push_back(MIB);
687   return;
688 }
689
690 MachineInstr *ARMBaseInstrInfo::
691 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
692                       const SmallVectorImpl<unsigned> &Ops, int FI) const {
693   if (Ops.size() != 1) return NULL;
694
695   unsigned OpNum = Ops[0];
696   unsigned Opc = MI->getOpcode();
697   MachineInstr *NewMI = NULL;
698   if (Opc == getOpcode(ARMII::MOVr)) {
699     // If it is updating CPSR, then it cannot be folded.
700     if (MI->getOperand(4).getReg() != ARM::CPSR) {
701       unsigned Pred = MI->getOperand(2).getImm();
702       unsigned PredReg = MI->getOperand(3).getReg();
703       if (OpNum == 0) { // move -> store
704         unsigned SrcReg = MI->getOperand(1).getReg();
705         bool isKill = MI->getOperand(1).isKill();
706         bool isUndef = MI->getOperand(1).isUndef();
707         NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::STR)))
708           .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
709           .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
710       } else {          // move -> load
711         unsigned DstReg = MI->getOperand(0).getReg();
712         bool isDead = MI->getOperand(0).isDead();
713         bool isUndef = MI->getOperand(0).isUndef();
714         NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::LDR)))
715           .addReg(DstReg,
716                   RegState::Define |
717                   getDeadRegState(isDead) |
718                   getUndefRegState(isUndef))
719           .addFrameIndex(FI).addReg(0).addImm(0).addImm(Pred).addReg(PredReg);
720       }
721     }
722   }
723   else if (Opc == getOpcode(ARMII::FCPYS)) {
724     unsigned Pred = MI->getOperand(2).getImm();
725     unsigned PredReg = MI->getOperand(3).getReg();
726     if (OpNum == 0) { // move -> store
727       unsigned SrcReg = MI->getOperand(1).getReg();
728       bool isKill = MI->getOperand(1).isKill();
729       bool isUndef = MI->getOperand(1).isUndef();
730       NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::FSTS)))
731         .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
732         .addFrameIndex(FI)
733         .addImm(0).addImm(Pred).addReg(PredReg);
734     } else {          // move -> load
735       unsigned DstReg = MI->getOperand(0).getReg();
736       bool isDead = MI->getOperand(0).isDead();
737       bool isUndef = MI->getOperand(0).isUndef();
738       NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::FLDS)))
739         .addReg(DstReg,
740                 RegState::Define |
741                 getDeadRegState(isDead) |
742                 getUndefRegState(isUndef))
743         .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
744     }
745   }
746   else if (Opc == getOpcode(ARMII::FCPYD)) {
747     unsigned Pred = MI->getOperand(2).getImm();
748     unsigned PredReg = MI->getOperand(3).getReg();
749     if (OpNum == 0) { // move -> store
750       unsigned SrcReg = MI->getOperand(1).getReg();
751       bool isKill = MI->getOperand(1).isKill();
752       bool isUndef = MI->getOperand(1).isUndef();
753       NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::FSTD)))
754         .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
755         .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
756     } else {          // move -> load
757       unsigned DstReg = MI->getOperand(0).getReg();
758       bool isDead = MI->getOperand(0).isDead();
759       bool isUndef = MI->getOperand(0).isUndef();
760       NewMI = BuildMI(MF, MI->getDebugLoc(), get(getOpcode(ARMII::FLDD)))
761         .addReg(DstReg,
762                 RegState::Define |
763                 getDeadRegState(isDead) |
764                 getUndefRegState(isUndef))
765         .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
766     }
767   }
768
769   return NewMI;
770 }
771
772 MachineInstr* 
773 ARMBaseInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
774                                         MachineInstr* MI,
775                                         const SmallVectorImpl<unsigned> &Ops,
776                                         MachineInstr* LoadMI) const {
777   return 0;
778 }
779
780 bool
781 ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
782                                        const SmallVectorImpl<unsigned> &Ops) const {
783   if (Ops.size() != 1) return false;
784
785   unsigned Opc = MI->getOpcode();
786   if (Opc == getOpcode(ARMII::MOVr)) {
787     // If it is updating CPSR, then it cannot be folded.
788     return MI->getOperand(4).getReg() != ARM::CPSR;
789   }
790   else if ((Opc == getOpcode(ARMII::FCPYS)) ||
791            (Opc == getOpcode(ARMII::FCPYD))) {
792     return true;
793   }
794   else if ((Opc == getOpcode(ARMII::VMOVD)) ||
795            (Opc == getOpcode(ARMII::VMOVQ))) {
796     return false; // FIXME
797   }
798
799   return false;
800 }