ARM backend contribution from Apple.
[oota-llvm.git] / lib / Target / ARM / ARMInstrInfo.cpp
1 //===- ARMInstrInfo.cpp - ARM Instruction Information -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the "Instituto Nokia de Tecnologia" and
6 // is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file contains the ARM implementation of the TargetInstrInfo class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "ARMInstrInfo.h"
16 #include "ARM.h"
17 #include "ARMAddressingModes.h"
18 #include "ARMGenInstrInfo.inc"
19 #include "ARMMachineFunctionInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/LiveVariables.h"
22 #include "llvm/Support/CommandLine.h"
23 using namespace llvm;
24
25 static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
26                                   cl::desc("Enable ARM 2-addr to 3-addr conv"));
27
28 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
29   : TargetInstrInfo(ARMInsts, sizeof(ARMInsts)/sizeof(ARMInsts[0])),
30     RI(*this, STI) {
31 }
32
33 unsigned ARMInstrInfo::getDWARF_LABELOpcode() const {
34   return ARM::DWARF_LABEL;
35 }
36
37 const TargetRegisterClass *ARMInstrInfo::getPointerRegClass() const {
38   return &ARM::GPRRegClass;
39 }
40
41 /// Return true if the instruction is a register to register move and
42 /// leave the source and dest operands in the passed parameters.
43 ///
44 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
45                                unsigned &SrcReg, unsigned &DstReg) const {
46   MachineOpCode oc = MI.getOpcode();
47   switch (oc) {
48   default:
49     return false;
50   case ARM::FCPYS:
51   case ARM::FCPYD:
52     SrcReg = MI.getOperand(1).getReg();
53     DstReg = MI.getOperand(0).getReg();
54     return true;
55   case ARM::MOVrr:
56   case ARM::tMOVrr:
57     assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() &&
58            MI.getOperand(1).isRegister() &&
59            "Invalid ARM MOV instruction");
60     SrcReg = MI.getOperand(1).getReg();
61     DstReg = MI.getOperand(0).getReg();
62     return true;
63   }
64 }
65
66 unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
67   switch (MI->getOpcode()) {
68   default: break;
69   case ARM::LDR:
70     if (MI->getOperand(1).isFrameIndex() &&
71         MI->getOperand(2).isReg() &&
72         MI->getOperand(3).isImmediate() && 
73         MI->getOperand(2).getReg() == 0 &&
74         MI->getOperand(3).getImmedValue() == 0) {
75       FrameIndex = MI->getOperand(1).getFrameIndex();
76       return MI->getOperand(0).getReg();
77     }
78     break;
79   case ARM::FLDD:
80   case ARM::FLDS:
81     if (MI->getOperand(1).isFrameIndex() &&
82         MI->getOperand(2).isImmediate() && 
83         MI->getOperand(2).getImmedValue() == 0) {
84       FrameIndex = MI->getOperand(1).getFrameIndex();
85       return MI->getOperand(0).getReg();
86     }
87     break;
88   case ARM::tLDRspi:
89     if (MI->getOperand(1).isFrameIndex() &&
90         MI->getOperand(2).isImmediate() && 
91         MI->getOperand(2).getImmedValue() == 0) {
92       FrameIndex = MI->getOperand(1).getFrameIndex();
93       return MI->getOperand(0).getReg();
94     }
95     break;
96   }
97   return 0;
98 }
99
100 unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
101   switch (MI->getOpcode()) {
102   default: break;
103   case ARM::STR:
104     if (MI->getOperand(1).isFrameIndex() &&
105         MI->getOperand(2).isReg() &&
106         MI->getOperand(3).isImmediate() && 
107         MI->getOperand(2).getReg() == 0 &&
108         MI->getOperand(3).getImmedValue() == 0) {
109       FrameIndex = MI->getOperand(1).getFrameIndex();
110       return MI->getOperand(0).getReg();
111     }
112     break;
113   case ARM::FSTD:
114   case ARM::FSTS:
115     if (MI->getOperand(1).isFrameIndex() &&
116         MI->getOperand(2).isImmediate() && 
117         MI->getOperand(2).getImmedValue() == 0) {
118       FrameIndex = MI->getOperand(1).getFrameIndex();
119       return MI->getOperand(0).getReg();
120     }
121     break;
122   case ARM::tSTRspi:
123     if (MI->getOperand(1).isFrameIndex() &&
124         MI->getOperand(2).isImmediate() && 
125         MI->getOperand(2).getImmedValue() == 0) {
126       FrameIndex = MI->getOperand(1).getFrameIndex();
127       return MI->getOperand(0).getReg();
128     }
129     break;
130   }
131   return 0;
132 }
133
134 static unsigned getUnindexedOpcode(unsigned Opc) {
135   switch (Opc) {
136   default: break;
137   case ARM::LDR_PRE:
138   case ARM::LDR_POST:
139     return ARM::LDR;
140   case ARM::LDRH_PRE:
141   case ARM::LDRH_POST:
142     return ARM::LDRH;
143   case ARM::LDRB_PRE:
144   case ARM::LDRB_POST:
145     return ARM::LDRB;
146   case ARM::LDRSH_PRE:
147   case ARM::LDRSH_POST:
148     return ARM::LDRSH;
149   case ARM::LDRSB_PRE:
150   case ARM::LDRSB_POST:
151     return ARM::LDRSB;
152   case ARM::STR_PRE:
153   case ARM::STR_POST:
154     return ARM::STR;
155   case ARM::STRH_PRE:
156   case ARM::STRH_POST:
157     return ARM::STRH;
158   case ARM::STRB_PRE:
159   case ARM::STRB_POST:
160     return ARM::STRB;
161   }
162   return 0;
163 }
164
165 MachineInstr *
166 ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
167                                     MachineBasicBlock::iterator &MBBI,
168                                     LiveVariables &LV) const {
169   if (!EnableARM3Addr)
170     return NULL;
171
172   MachineInstr *MI = MBBI;
173   unsigned TSFlags = MI->getInstrDescriptor()->TSFlags;
174   bool isPre = false;
175   switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
176   default: return NULL;
177   case ARMII::IndexModePre:
178     isPre = true;
179     break;
180   case ARMII::IndexModePost:
181     break;
182   }
183
184   // Try spliting an indexed load / store to a un-indexed one plus an add/sub
185   // operation.
186   unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
187   if (MemOpc == 0)
188     return NULL;
189
190   MachineInstr *UpdateMI = NULL;
191   MachineInstr *MemMI = NULL;
192   unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
193   unsigned NumOps = MI->getNumOperands();
194   bool isLoad = (MI->getInstrDescriptor()->Flags & M_LOAD_FLAG) != 0;
195   const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
196   const MachineOperand &Base = MI->getOperand(2);
197   const MachineOperand &Offset = MI->getOperand(NumOps-2);
198   unsigned WBReg = WB.getReg();
199   unsigned BaseReg = Base.getReg();
200   unsigned OffReg = Offset.getReg();
201   unsigned OffImm = MI->getOperand(NumOps-1).getImm();
202   switch (AddrMode) {
203   default:
204     assert(false && "Unknown indexed op!");
205     return NULL;
206   case ARMII::AddrMode2: {
207     bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
208     unsigned Amt = ARM_AM::getAM2Offset(OffImm);
209     if (OffReg == 0) {
210       int SOImmVal = ARM_AM::getSOImmVal(Amt);
211       if (SOImmVal == -1)
212         // Can't encode it in a so_imm operand. This transformation will
213         // add more than 1 instruction. Abandon!
214         return NULL;
215       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
216         .addReg(BaseReg).addImm(SOImmVal);
217     } else if (Amt != 0) {
218       ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
219       unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
220       UpdateMI = BuildMI(get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
221         .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc);
222     } else 
223       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
224         .addReg(BaseReg).addReg(OffReg);
225     break;
226   }
227   case ARMII::AddrMode3 : {
228     bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
229     unsigned Amt = ARM_AM::getAM3Offset(OffImm);
230     if (OffReg == 0)
231       // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
232       UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
233         .addReg(BaseReg).addImm(Amt);
234     else
235       UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
236         .addReg(BaseReg).addReg(OffReg);
237     break;
238   }
239   }
240
241   std::vector<MachineInstr*> NewMIs;
242   if (isPre) {
243     if (isLoad)
244       MemMI = BuildMI(get(MemOpc), MI->getOperand(0).getReg())
245         .addReg(WBReg).addReg(0).addImm(0);
246     else
247       MemMI = BuildMI(get(MemOpc)).addReg(MI->getOperand(1).getReg())
248         .addReg(WBReg).addReg(0).addImm(0);
249     NewMIs.push_back(MemMI);
250     NewMIs.push_back(UpdateMI);
251   } else {
252     if (isLoad)
253       MemMI = BuildMI(get(MemOpc), MI->getOperand(0).getReg())
254         .addReg(BaseReg).addReg(0).addImm(0);
255     else
256       MemMI = BuildMI(get(MemOpc)).addReg(MI->getOperand(1).getReg())
257         .addReg(BaseReg).addReg(0).addImm(0);
258     if (WB.isDead())
259       UpdateMI->getOperand(0).setIsDead();
260     NewMIs.push_back(UpdateMI);
261     NewMIs.push_back(MemMI);
262   }
263   
264   // Transfer LiveVariables states, kill / dead info.
265   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
266     MachineOperand &MO = MI->getOperand(i);
267     if (MO.isRegister() && MO.getReg() &&
268         MRegisterInfo::isVirtualRegister(MO.getReg())) {
269       unsigned Reg = MO.getReg();
270       LiveVariables::VarInfo &VI = LV.getVarInfo(Reg);
271       if (MO.isDef()) {
272         MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
273         if (MO.isDead())
274           LV.addVirtualRegisterDead(Reg, NewMI);
275         // Update the defining instruction.
276         if (VI.DefInst == MI)
277           VI.DefInst = NewMI;
278       }
279       if (MO.isUse() && MO.isKill()) {
280         for (unsigned j = 0; j < 2; ++j) {
281           // Look at the two new MI's in reverse order.
282           MachineInstr *NewMI = NewMIs[j];
283           MachineOperand *NMO = NewMI->findRegisterUseOperand(Reg);
284           if (!NMO)
285             continue;
286           LV.addVirtualRegisterKilled(Reg, NewMI);
287           if (VI.removeKill(MI))
288             VI.Kills.push_back(NewMI);
289           break;
290         }
291       }
292     }
293   }
294
295   MFI->insert(MBBI, NewMIs[1]);
296   MFI->insert(MBBI, NewMIs[0]);
297   return NewMIs[0];
298 }
299
300 // Branch analysis.
301 bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
302                                  MachineBasicBlock *&FBB,
303                                  std::vector<MachineOperand> &Cond) const {
304   // If the block has no terminators, it just falls into the block after it.
305   MachineBasicBlock::iterator I = MBB.end();
306   if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode()))
307     return false;
308   
309   // Get the last instruction in the block.
310   MachineInstr *LastInst = I;
311   
312   // If there is only one terminator instruction, process it.
313   unsigned LastOpc = LastInst->getOpcode();
314   if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) {
315     if (LastOpc == ARM::B || LastOpc == ARM::tB) {
316       TBB = LastInst->getOperand(0).getMachineBasicBlock();
317       return false;
318     }
319     if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) {
320       // Block ends with fall-through condbranch.
321       TBB = LastInst->getOperand(0).getMachineBasicBlock();
322       Cond.push_back(LastInst->getOperand(1));
323       return false;
324     }
325     return true;  // Can't handle indirect branch.
326   }
327   
328   // Get the instruction before it if it is a terminator.
329   MachineInstr *SecondLastInst = I;
330   
331   // If there are three terminators, we don't know what sort of block this is.
332   if (SecondLastInst && I != MBB.begin() &&
333       isTerminatorInstr((--I)->getOpcode()))
334     return true;
335   
336   // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it.
337   unsigned SecondLastOpc = SecondLastInst->getOpcode();
338   if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
339       (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
340     TBB =  SecondLastInst->getOperand(0).getMachineBasicBlock();
341     Cond.push_back(SecondLastInst->getOperand(1));
342     FBB = LastInst->getOperand(0).getMachineBasicBlock();
343     return false;
344   }
345   
346   // Otherwise, can't handle this.
347   return true;
348 }
349
350
351 void ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
352   MachineFunction &MF = *MBB.getParent();
353   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
354   int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
355   int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
356
357   MachineBasicBlock::iterator I = MBB.end();
358   if (I == MBB.begin()) return;
359   --I;
360   if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc)
361     return;
362   
363   // Remove the branch.
364   I->eraseFromParent();
365   
366   I = MBB.end();
367   
368   if (I == MBB.begin()) return;
369   --I;
370   if (I->getOpcode() != BccOpc)
371     return;
372   
373   // Remove the branch.
374   I->eraseFromParent();
375 }
376
377 void ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
378                                 MachineBasicBlock *FBB,
379                                 const std::vector<MachineOperand> &Cond) const {
380   MachineFunction &MF = *MBB.getParent();
381   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
382   int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
383   int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
384
385   // Shouldn't be a fall through.
386   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
387   assert((Cond.size() == 1 || Cond.size() == 0) &&
388          "ARM branch conditions have two components!");
389   
390   if (FBB == 0) {
391     if (Cond.empty()) // Unconditional branch?
392       BuildMI(&MBB, get(BOpc)).addMBB(TBB);
393     else
394       BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
395     return;
396   }
397   
398   // Two-way conditional branch.
399   BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
400   BuildMI(&MBB, get(BOpc)).addMBB(FBB);
401 }
402
403 bool ARMInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
404   if (MBB.empty()) return false;
405   
406   switch (MBB.back().getOpcode()) {
407   case ARM::B:
408   case ARM::tB:       // Uncond branch.
409   case ARM::BR_JTr:   // Jumptable branch.
410   case ARM::BR_JTm:   // Jumptable branch through mem.
411   case ARM::BR_JTadd: // Jumptable branch add to pc.
412     return true;
413   default: return false;
414   }
415 }
416
417 bool ARMInstrInfo::
418 ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
419   ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
420   Cond[0].setImm(ARMCC::getOppositeCondition(CC));
421   return false;
422 }