Get rid of more dead code.
[oota-llvm.git] / lib / Target / ARM / Thumb1InstrInfo.cpp
1 //===- Thumb1InstrInfo.cpp - Thumb-1 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 Thumb-1 implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARMInstrInfo.h"
15 #include "ARM.h"
16 #include "ARMGenInstrInfo.inc"
17 #include "ARMMachineFunctionInfo.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "Thumb1InstrInfo.h"
22
23 using namespace llvm;
24
25 Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
26   : ARMBaseInstrInfo(STI), RI(*this, STI) {
27 }
28
29 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
30   return 0;
31 }
32
33 unsigned Thumb1InstrInfo::getOpcode(ARMII::Op Op) const {
34   switch (Op) {
35   case ARMII::ADDri: return ARM::tADDi8;
36   case ARMII::ADDrs: return 0;
37   case ARMII::ADDrr: return ARM::tADDrr;
38   case ARMII::MOVr: return ARM::tMOVr;
39   case ARMII::SUBri: return ARM::tSUBi8;
40   case ARMII::SUBrs: return 0;
41   case ARMII::SUBrr: return ARM::tSUBrr;
42   default:
43     break;
44   }
45
46   return 0;
47 }
48
49 bool
50 Thumb1InstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const {
51   if (MBB.empty()) return false;
52
53   switch (MBB.back().getOpcode()) {
54   case ARM::tBX_RET:
55   case ARM::tBX_RET_vararg:
56   case ARM::tPOP_RET:
57   case ARM::tB:
58   case ARM::tBR_JTr:
59     return true;
60   default:
61     break;
62   }
63
64   return false;
65 }
66
67 bool Thumb1InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
68                                    MachineBasicBlock::iterator I,
69                                    unsigned DestReg, unsigned SrcReg,
70                                    const TargetRegisterClass *DestRC,
71                                    const TargetRegisterClass *SrcRC) const {
72   DebugLoc DL = DebugLoc::getUnknownLoc();
73   if (I != MBB.end()) DL = I->getDebugLoc();
74
75   if (DestRC == ARM::GPRRegisterClass) {
76     if (SrcRC == ARM::GPRRegisterClass) {
77       BuildMI(MBB, I, DL, get(ARM::tMOVgpr2gpr), DestReg).addReg(SrcReg);
78       return true;
79     } else if (SrcRC == ARM::tGPRRegisterClass) {
80       BuildMI(MBB, I, DL, get(ARM::tMOVtgpr2gpr), DestReg).addReg(SrcReg);
81       return true;
82     }
83   } else if (DestRC == ARM::tGPRRegisterClass) {
84     if (SrcRC == ARM::GPRRegisterClass) {
85       BuildMI(MBB, I, DL, get(ARM::tMOVgpr2tgpr), DestReg).addReg(SrcReg);
86       return true;
87     } else if (SrcRC == ARM::tGPRRegisterClass) {
88       BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg).addReg(SrcReg);
89       return true;
90     }
91   }
92
93   return false;
94 }
95
96 bool Thumb1InstrInfo::
97 canFoldMemoryOperand(const MachineInstr *MI,
98                      const SmallVectorImpl<unsigned> &Ops) const {
99   if (Ops.size() != 1) return false;
100
101   unsigned OpNum = Ops[0];
102   unsigned Opc = MI->getOpcode();
103   switch (Opc) {
104   default: break;
105   case ARM::tMOVr:
106   case ARM::tMOVtgpr2gpr:
107   case ARM::tMOVgpr2tgpr:
108   case ARM::tMOVgpr2gpr: {
109     if (OpNum == 0) { // move -> store
110       unsigned SrcReg = MI->getOperand(1).getReg();
111       if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
112         // tSpill cannot take a high register operand.
113         return false;
114     } else {          // move -> load
115       unsigned DstReg = MI->getOperand(0).getReg();
116       if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
117         // tRestore cannot target a high register operand.
118         return false;
119     }
120     return true;
121   }
122   }
123
124   return false;
125 }
126
127 void Thumb1InstrInfo::
128 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
129                     unsigned SrcReg, bool isKill, int FI,
130                     const TargetRegisterClass *RC) const {
131   DebugLoc DL = DebugLoc::getUnknownLoc();
132   if (I != MBB.end()) DL = I->getDebugLoc();
133
134   assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
135
136   if (RC == ARM::tGPRRegisterClass) {
137     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tSpill))
138                    .addReg(SrcReg, getKillRegState(isKill))
139                    .addFrameIndex(FI).addImm(0));
140   }
141 }
142
143 void Thumb1InstrInfo::
144 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
145                      unsigned DestReg, int FI,
146                      const TargetRegisterClass *RC) const {
147   DebugLoc DL = DebugLoc::getUnknownLoc();
148   if (I != MBB.end()) DL = I->getDebugLoc();
149
150   assert(RC == ARM::tGPRRegisterClass && "Unknown regclass!");
151
152   if (RC == ARM::tGPRRegisterClass) {
153     AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::tRestore), DestReg)
154                    .addFrameIndex(FI).addImm(0));
155   }
156 }
157
158 bool Thumb1InstrInfo::
159 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
160                           MachineBasicBlock::iterator MI,
161                           const std::vector<CalleeSavedInfo> &CSI) const {
162   if (CSI.empty())
163     return false;
164
165   DebugLoc DL = DebugLoc::getUnknownLoc();
166   if (MI != MBB.end()) DL = MI->getDebugLoc();
167
168   MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
169   for (unsigned i = CSI.size(); i != 0; --i) {
170     unsigned Reg = CSI[i-1].getReg();
171     // Add the callee-saved register as live-in. It's killed at the spill.
172     MBB.addLiveIn(Reg);
173     MIB.addReg(Reg, RegState::Kill);
174   }
175   return true;
176 }
177
178 bool Thumb1InstrInfo::
179 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
180                             MachineBasicBlock::iterator MI,
181                             const std::vector<CalleeSavedInfo> &CSI) const {
182   MachineFunction &MF = *MBB.getParent();
183   ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
184   if (CSI.empty())
185     return false;
186
187   bool isVarArg = AFI->getVarArgsRegSaveSize() > 0;
188   MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc());
189   for (unsigned i = CSI.size(); i != 0; --i) {
190     unsigned Reg = CSI[i-1].getReg();
191     if (Reg == ARM::LR) {
192       // Special epilogue for vararg functions. See emitEpilogue
193       if (isVarArg)
194         continue;
195       Reg = ARM::PC;
196       PopMI->setDesc(get(ARM::tPOP_RET));
197       MI = MBB.erase(MI);
198     }
199     PopMI->addOperand(MachineOperand::CreateReg(Reg, true));
200   }
201
202   // It's illegal to emit pop instruction without operands.
203   if (PopMI->getNumOperands() > 0)
204     MBB.insert(MI, PopMI);
205
206   return true;
207 }
208
209 MachineInstr *Thumb1InstrInfo::
210 foldMemoryOperandImpl(MachineFunction &MF, MachineInstr *MI,
211                       const SmallVectorImpl<unsigned> &Ops, int FI) const {
212   if (Ops.size() != 1) return NULL;
213
214   unsigned OpNum = Ops[0];
215   unsigned Opc = MI->getOpcode();
216   MachineInstr *NewMI = NULL;
217   switch (Opc) {
218   default: break;
219   case ARM::tMOVr:
220   case ARM::tMOVtgpr2gpr:
221   case ARM::tMOVgpr2tgpr:
222   case ARM::tMOVgpr2gpr: {
223     if (OpNum == 0) { // move -> store
224       unsigned SrcReg = MI->getOperand(1).getReg();
225       bool isKill = MI->getOperand(1).isKill();
226       if (RI.isPhysicalRegister(SrcReg) && !isARMLowRegister(SrcReg))
227         // tSpill cannot take a high register operand.
228         break;
229       NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tSpill))
230                              .addReg(SrcReg, getKillRegState(isKill))
231                              .addFrameIndex(FI).addImm(0));
232     } else {          // move -> load
233       unsigned DstReg = MI->getOperand(0).getReg();
234       if (RI.isPhysicalRegister(DstReg) && !isARMLowRegister(DstReg))
235         // tRestore cannot target a high register operand.
236         break;
237       bool isDead = MI->getOperand(0).isDead();
238       NewMI = AddDefaultPred(BuildMI(MF, MI->getDebugLoc(), get(ARM::tRestore))
239                              .addReg(DstReg,
240                                      RegState::Define | getDeadRegState(isDead))
241                              .addFrameIndex(FI).addImm(0));
242     }
243     break;
244   }
245   }
246
247   return NewMI;
248 }