blob: 4838b7dcc0367e9f18cb55dc6b09827d57c81264 [file] [log] [blame]
Jim Grosbach31c24bf2009-11-07 22:00:39 +00001//===- ARMBaseInstrInfo.cpp - ARM Instruction Information -------*- C++ -*-===//
David Goodwin334c2642009-07-08 16:09:28 +00002//
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"
Evan Chengd457e6e2009-11-07 04:04:34 +000017#include "ARMConstantPoolValue.h"
David Goodwin334c2642009-07-08 16:09:28 +000018#include "ARMMachineFunctionInfo.h"
Anton Korobeynikovf95215f2009-11-02 00:10:38 +000019#include "ARMRegisterInfo.h"
Chris Lattner4dbbe342010-07-20 21:17:29 +000020#include "ARMGenInstrInfo.inc"
Evan Chengfdc83402009-11-08 00:15:23 +000021#include "llvm/Constants.h"
22#include "llvm/Function.h"
23#include "llvm/GlobalValue.h"
David Goodwin334c2642009-07-08 16:09:28 +000024#include "llvm/CodeGen/LiveVariables.h"
Evan Chengd457e6e2009-11-07 04:04:34 +000025#include "llvm/CodeGen/MachineConstantPool.h"
David Goodwin334c2642009-07-08 16:09:28 +000026#include "llvm/CodeGen/MachineFrameInfo.h"
27#include "llvm/CodeGen/MachineInstrBuilder.h"
28#include "llvm/CodeGen/MachineJumpTableInfo.h"
Anton Korobeynikov249fb332009-10-07 00:06:35 +000029#include "llvm/CodeGen/MachineMemOperand.h"
Evan Cheng2457f2c2010-05-22 01:47:14 +000030#include "llvm/CodeGen/MachineRegisterInfo.h"
Anton Korobeynikov249fb332009-10-07 00:06:35 +000031#include "llvm/CodeGen/PseudoSourceValue.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000032#include "llvm/MC/MCAsmInfo.h"
David Goodwin334c2642009-07-08 16:09:28 +000033#include "llvm/Support/CommandLine.h"
Anton Korobeynikovf95215f2009-11-02 00:10:38 +000034#include "llvm/Support/Debug.h"
Torok Edwinc25e7582009-07-11 20:10:48 +000035#include "llvm/Support/ErrorHandling.h"
Bill Wendling40a5eb12010-11-01 20:41:43 +000036#include "llvm/ADT/STLExtras.h"
David Goodwin334c2642009-07-08 16:09:28 +000037using namespace llvm;
38
39static cl::opt<bool>
40EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
41 cl::desc("Enable ARM 2-addr to 3-addr conv"));
42
Anton Korobeynikovf95215f2009-11-02 00:10:38 +000043ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI)
44 : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)),
45 Subtarget(STI) {
David Goodwin334c2642009-07-08 16:09:28 +000046}
47
48MachineInstr *
49ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
50 MachineBasicBlock::iterator &MBBI,
51 LiveVariables *LV) const {
Evan Cheng78703dd2009-07-27 18:44:00 +000052 // FIXME: Thumb2 support.
53
David Goodwin334c2642009-07-08 16:09:28 +000054 if (!EnableARM3Addr)
55 return NULL;
56
57 MachineInstr *MI = MBBI;
58 MachineFunction &MF = *MI->getParent()->getParent();
Bruno Cardoso Lopes99405df2010-06-08 22:51:23 +000059 uint64_t TSFlags = MI->getDesc().TSFlags;
David Goodwin334c2642009-07-08 16:09:28 +000060 bool isPre = false;
61 switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
62 default: return NULL;
63 case ARMII::IndexModePre:
64 isPre = true;
65 break;
66 case ARMII::IndexModePost:
67 break;
68 }
69
70 // Try splitting an indexed load/store to an un-indexed one plus an add/sub
71 // operation.
72 unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
73 if (MemOpc == 0)
74 return NULL;
75
76 MachineInstr *UpdateMI = NULL;
77 MachineInstr *MemMI = NULL;
78 unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
79 const TargetInstrDesc &TID = MI->getDesc();
80 unsigned NumOps = TID.getNumOperands();
81 bool isLoad = !TID.mayStore();
82 const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
83 const MachineOperand &Base = MI->getOperand(2);
84 const MachineOperand &Offset = MI->getOperand(NumOps-3);
85 unsigned WBReg = WB.getReg();
86 unsigned BaseReg = Base.getReg();
87 unsigned OffReg = Offset.getReg();
88 unsigned OffImm = MI->getOperand(NumOps-2).getImm();
89 ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm();
90 switch (AddrMode) {
91 default:
92 assert(false && "Unknown indexed op!");
93 return NULL;
94 case ARMII::AddrMode2: {
95 bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
96 unsigned Amt = ARM_AM::getAM2Offset(OffImm);
97 if (OffReg == 0) {
Evan Chenge7cbe412009-07-08 21:03:57 +000098 if (ARM_AM::getSOImmVal(Amt) == -1)
David Goodwin334c2642009-07-08 16:09:28 +000099 // Can't encode it in a so_imm operand. This transformation will
100 // add more than 1 instruction. Abandon!
101 return NULL;
102 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
Evan Cheng78703dd2009-07-27 18:44:00 +0000103 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
Evan Chenge7cbe412009-07-08 21:03:57 +0000104 .addReg(BaseReg).addImm(Amt)
David Goodwin334c2642009-07-08 16:09:28 +0000105 .addImm(Pred).addReg(0).addReg(0);
106 } else if (Amt != 0) {
107 ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
108 unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
109 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
Evan Cheng78703dd2009-07-27 18:44:00 +0000110 get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
David Goodwin334c2642009-07-08 16:09:28 +0000111 .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc)
112 .addImm(Pred).addReg(0).addReg(0);
113 } else
114 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
Evan Cheng78703dd2009-07-27 18:44:00 +0000115 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
David Goodwin334c2642009-07-08 16:09:28 +0000116 .addReg(BaseReg).addReg(OffReg)
117 .addImm(Pred).addReg(0).addReg(0);
118 break;
119 }
120 case ARMII::AddrMode3 : {
121 bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
122 unsigned Amt = ARM_AM::getAM3Offset(OffImm);
123 if (OffReg == 0)
124 // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
125 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
Evan Cheng78703dd2009-07-27 18:44:00 +0000126 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
David Goodwin334c2642009-07-08 16:09:28 +0000127 .addReg(BaseReg).addImm(Amt)
128 .addImm(Pred).addReg(0).addReg(0);
129 else
130 UpdateMI = BuildMI(MF, MI->getDebugLoc(),
Evan Cheng78703dd2009-07-27 18:44:00 +0000131 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
David Goodwin334c2642009-07-08 16:09:28 +0000132 .addReg(BaseReg).addReg(OffReg)
133 .addImm(Pred).addReg(0).addReg(0);
134 break;
135 }
136 }
137
138 std::vector<MachineInstr*> NewMIs;
139 if (isPre) {
140 if (isLoad)
141 MemMI = BuildMI(MF, MI->getDebugLoc(),
142 get(MemOpc), MI->getOperand(0).getReg())
Jim Grosbach3e556122010-10-26 22:37:02 +0000143 .addReg(WBReg).addImm(0).addImm(Pred);
David Goodwin334c2642009-07-08 16:09:28 +0000144 else
145 MemMI = BuildMI(MF, MI->getDebugLoc(),
146 get(MemOpc)).addReg(MI->getOperand(1).getReg())
147 .addReg(WBReg).addReg(0).addImm(0).addImm(Pred);
148 NewMIs.push_back(MemMI);
149 NewMIs.push_back(UpdateMI);
150 } else {
151 if (isLoad)
152 MemMI = BuildMI(MF, MI->getDebugLoc(),
153 get(MemOpc), MI->getOperand(0).getReg())
Jim Grosbach3e556122010-10-26 22:37:02 +0000154 .addReg(BaseReg).addImm(0).addImm(Pred);
David Goodwin334c2642009-07-08 16:09:28 +0000155 else
156 MemMI = BuildMI(MF, MI->getDebugLoc(),
157 get(MemOpc)).addReg(MI->getOperand(1).getReg())
158 .addReg(BaseReg).addReg(0).addImm(0).addImm(Pred);
159 if (WB.isDead())
160 UpdateMI->getOperand(0).setIsDead();
161 NewMIs.push_back(UpdateMI);
162 NewMIs.push_back(MemMI);
163 }
164
165 // Transfer LiveVariables states, kill / dead info.
166 if (LV) {
167 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
168 MachineOperand &MO = MI->getOperand(i);
169 if (MO.isReg() && MO.getReg() &&
170 TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
171 unsigned Reg = MO.getReg();
172
173 LiveVariables::VarInfo &VI = LV->getVarInfo(Reg);
174 if (MO.isDef()) {
175 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
176 if (MO.isDead())
177 LV->addVirtualRegisterDead(Reg, NewMI);
178 }
179 if (MO.isUse() && MO.isKill()) {
180 for (unsigned j = 0; j < 2; ++j) {
181 // Look at the two new MI's in reverse order.
182 MachineInstr *NewMI = NewMIs[j];
183 if (!NewMI->readsRegister(Reg))
184 continue;
185 LV->addVirtualRegisterKilled(Reg, NewMI);
186 if (VI.removeKill(MI))
187 VI.Kills.push_back(NewMI);
188 break;
189 }
190 }
191 }
192 }
193 }
194
195 MFI->insert(MBBI, NewMIs[1]);
196 MFI->insert(MBBI, NewMIs[0]);
197 return NewMIs[0];
198}
199
Eric Christopher8b3ca622010-11-18 19:40:05 +0000200
David Goodwin334c2642009-07-08 16:09:28 +0000201// Branch analysis.
202bool
203ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
204 MachineBasicBlock *&FBB,
205 SmallVectorImpl<MachineOperand> &Cond,
206 bool AllowModify) const {
207 // If the block has no terminators, it just falls into the block after it.
208 MachineBasicBlock::iterator I = MBB.end();
Dale Johannesen93d6a7e2010-04-02 01:38:09 +0000209 if (I == MBB.begin())
210 return false;
211 --I;
212 while (I->isDebugValue()) {
213 if (I == MBB.begin())
214 return false;
215 --I;
216 }
217 if (!isUnpredicatedTerminator(I))
David Goodwin334c2642009-07-08 16:09:28 +0000218 return false;
219
220 // Get the last instruction in the block.
221 MachineInstr *LastInst = I;
222
223 // If there is only one terminator instruction, process it.
224 unsigned LastOpc = LastInst->getOpcode();
225 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
Evan Cheng5ca53a72009-07-27 18:20:05 +0000226 if (isUncondBranchOpcode(LastOpc)) {
David Goodwin334c2642009-07-08 16:09:28 +0000227 TBB = LastInst->getOperand(0).getMBB();
228 return false;
229 }
Evan Cheng5ca53a72009-07-27 18:20:05 +0000230 if (isCondBranchOpcode(LastOpc)) {
David Goodwin334c2642009-07-08 16:09:28 +0000231 // Block ends with fall-through condbranch.
232 TBB = LastInst->getOperand(0).getMBB();
233 Cond.push_back(LastInst->getOperand(1));
234 Cond.push_back(LastInst->getOperand(2));
235 return false;
236 }
237 return true; // Can't handle indirect branch.
238 }
239
240 // Get the instruction before it if it is a terminator.
241 MachineInstr *SecondLastInst = I;
Evan Cheng108c8722010-09-23 06:54:40 +0000242 unsigned SecondLastOpc = SecondLastInst->getOpcode();
243
244 // If AllowModify is true and the block ends with two or more unconditional
245 // branches, delete all but the first unconditional branch.
246 if (AllowModify && isUncondBranchOpcode(LastOpc)) {
247 while (isUncondBranchOpcode(SecondLastOpc)) {
248 LastInst->eraseFromParent();
249 LastInst = SecondLastInst;
250 LastOpc = LastInst->getOpcode();
Evan Cheng676e2582010-09-23 19:42:03 +0000251 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
252 // Return now the only terminator is an unconditional branch.
253 TBB = LastInst->getOperand(0).getMBB();
254 return false;
255 } else {
Evan Cheng108c8722010-09-23 06:54:40 +0000256 SecondLastInst = I;
257 SecondLastOpc = SecondLastInst->getOpcode();
258 }
259 }
260 }
David Goodwin334c2642009-07-08 16:09:28 +0000261
262 // If there are three terminators, we don't know what sort of block this is.
263 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
264 return true;
265
Evan Cheng5ca53a72009-07-27 18:20:05 +0000266 // If the block ends with a B and a Bcc, handle it.
Evan Cheng5ca53a72009-07-27 18:20:05 +0000267 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
David Goodwin334c2642009-07-08 16:09:28 +0000268 TBB = SecondLastInst->getOperand(0).getMBB();
269 Cond.push_back(SecondLastInst->getOperand(1));
270 Cond.push_back(SecondLastInst->getOperand(2));
271 FBB = LastInst->getOperand(0).getMBB();
272 return false;
273 }
274
275 // If the block ends with two unconditional branches, handle it. The second
276 // one is not executed, so remove it.
Evan Cheng5ca53a72009-07-27 18:20:05 +0000277 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
David Goodwin334c2642009-07-08 16:09:28 +0000278 TBB = SecondLastInst->getOperand(0).getMBB();
279 I = LastInst;
280 if (AllowModify)
281 I->eraseFromParent();
282 return false;
283 }
284
285 // ...likewise if it ends with a branch table followed by an unconditional
286 // branch. The branch folder can create these, and we must get rid of them for
287 // correctness of Thumb constant islands.
Bob Wilson8d4de5a2009-10-28 18:26:41 +0000288 if ((isJumpTableBranchOpcode(SecondLastOpc) ||
289 isIndirectBranchOpcode(SecondLastOpc)) &&
Evan Cheng5ca53a72009-07-27 18:20:05 +0000290 isUncondBranchOpcode(LastOpc)) {
David Goodwin334c2642009-07-08 16:09:28 +0000291 I = LastInst;
292 if (AllowModify)
293 I->eraseFromParent();
294 return true;
295 }
296
297 // Otherwise, can't handle this.
298 return true;
299}
300
301
302unsigned ARMBaseInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
David Goodwin334c2642009-07-08 16:09:28 +0000303 MachineBasicBlock::iterator I = MBB.end();
304 if (I == MBB.begin()) return 0;
305 --I;
Dale Johannesen93d6a7e2010-04-02 01:38:09 +0000306 while (I->isDebugValue()) {
307 if (I == MBB.begin())
308 return 0;
309 --I;
310 }
Evan Cheng5ca53a72009-07-27 18:20:05 +0000311 if (!isUncondBranchOpcode(I->getOpcode()) &&
312 !isCondBranchOpcode(I->getOpcode()))
David Goodwin334c2642009-07-08 16:09:28 +0000313 return 0;
314
315 // Remove the branch.
316 I->eraseFromParent();
317
318 I = MBB.end();
319
320 if (I == MBB.begin()) return 1;
321 --I;
Evan Cheng5ca53a72009-07-27 18:20:05 +0000322 if (!isCondBranchOpcode(I->getOpcode()))
David Goodwin334c2642009-07-08 16:09:28 +0000323 return 1;
324
325 // Remove the branch.
326 I->eraseFromParent();
327 return 2;
328}
329
330unsigned
331ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000332 MachineBasicBlock *FBB,
333 const SmallVectorImpl<MachineOperand> &Cond,
334 DebugLoc DL) const {
Evan Cheng6495f632009-07-28 05:48:47 +0000335 ARMFunctionInfo *AFI = MBB.getParent()->getInfo<ARMFunctionInfo>();
336 int BOpc = !AFI->isThumbFunction()
337 ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB);
338 int BccOpc = !AFI->isThumbFunction()
339 ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc);
David Goodwin334c2642009-07-08 16:09:28 +0000340
341 // Shouldn't be a fall through.
342 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
343 assert((Cond.size() == 2 || Cond.size() == 0) &&
344 "ARM branch conditions have two components!");
345
346 if (FBB == 0) {
347 if (Cond.empty()) // Unconditional branch?
Stuart Hastings3bf91252010-06-17 22:43:56 +0000348 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
David Goodwin334c2642009-07-08 16:09:28 +0000349 else
Stuart Hastings3bf91252010-06-17 22:43:56 +0000350 BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
David Goodwin334c2642009-07-08 16:09:28 +0000351 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
352 return 1;
353 }
354
355 // Two-way conditional branch.
Stuart Hastings3bf91252010-06-17 22:43:56 +0000356 BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)
David Goodwin334c2642009-07-08 16:09:28 +0000357 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg());
Stuart Hastings3bf91252010-06-17 22:43:56 +0000358 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
David Goodwin334c2642009-07-08 16:09:28 +0000359 return 2;
360}
361
362bool ARMBaseInstrInfo::
363ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
364 ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
365 Cond[0].setImm(ARMCC::getOppositeCondition(CC));
366 return false;
367}
368
David Goodwin334c2642009-07-08 16:09:28 +0000369bool ARMBaseInstrInfo::
370PredicateInstruction(MachineInstr *MI,
371 const SmallVectorImpl<MachineOperand> &Pred) const {
372 unsigned Opc = MI->getOpcode();
Evan Cheng5ca53a72009-07-27 18:20:05 +0000373 if (isUncondBranchOpcode(Opc)) {
374 MI->setDesc(get(getMatchingCondBranchOpcode(Opc)));
David Goodwin334c2642009-07-08 16:09:28 +0000375 MI->addOperand(MachineOperand::CreateImm(Pred[0].getImm()));
376 MI->addOperand(MachineOperand::CreateReg(Pred[1].getReg(), false));
377 return true;
378 }
379
380 int PIdx = MI->findFirstPredOperandIdx();
381 if (PIdx != -1) {
382 MachineOperand &PMO = MI->getOperand(PIdx);
383 PMO.setImm(Pred[0].getImm());
384 MI->getOperand(PIdx+1).setReg(Pred[1].getReg());
385 return true;
386 }
387 return false;
388}
389
390bool ARMBaseInstrInfo::
391SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
392 const SmallVectorImpl<MachineOperand> &Pred2) const {
393 if (Pred1.size() > 2 || Pred2.size() > 2)
394 return false;
395
396 ARMCC::CondCodes CC1 = (ARMCC::CondCodes)Pred1[0].getImm();
397 ARMCC::CondCodes CC2 = (ARMCC::CondCodes)Pred2[0].getImm();
398 if (CC1 == CC2)
399 return true;
400
401 switch (CC1) {
402 default:
403 return false;
404 case ARMCC::AL:
405 return true;
406 case ARMCC::HS:
407 return CC2 == ARMCC::HI;
408 case ARMCC::LS:
409 return CC2 == ARMCC::LO || CC2 == ARMCC::EQ;
410 case ARMCC::GE:
411 return CC2 == ARMCC::GT;
412 case ARMCC::LE:
413 return CC2 == ARMCC::LT;
414 }
415}
416
417bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI,
418 std::vector<MachineOperand> &Pred) const {
Evan Cheng8fb90362009-08-08 03:20:32 +0000419 // FIXME: This confuses implicit_def with optional CPSR def.
David Goodwin334c2642009-07-08 16:09:28 +0000420 const TargetInstrDesc &TID = MI->getDesc();
421 if (!TID.getImplicitDefs() && !TID.hasOptionalDef())
422 return false;
423
424 bool Found = false;
425 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
426 const MachineOperand &MO = MI->getOperand(i);
427 if (MO.isReg() && MO.getReg() == ARM::CPSR) {
428 Pred.push_back(MO);
429 Found = true;
430 }
431 }
432
433 return Found;
434}
435
Evan Chengac0869d2009-11-21 06:21:52 +0000436/// isPredicable - Return true if the specified instruction can be predicated.
437/// By default, this returns true for every instruction with a
438/// PredicateOperand.
439bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const {
440 const TargetInstrDesc &TID = MI->getDesc();
441 if (!TID.isPredicable())
442 return false;
443
444 if ((TID.TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) {
445 ARMFunctionInfo *AFI =
446 MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
Evan Chengd7f08102009-11-24 08:06:15 +0000447 return AFI->isThumb2Function();
Evan Chengac0869d2009-11-21 06:21:52 +0000448 }
449 return true;
450}
David Goodwin334c2642009-07-08 16:09:28 +0000451
Chris Lattner56856b12009-12-03 06:58:32 +0000452/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing.
Chandler Carruth19e57022010-10-23 08:40:19 +0000453LLVM_ATTRIBUTE_NOINLINE
David Goodwin334c2642009-07-08 16:09:28 +0000454static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
Chris Lattner56856b12009-12-03 06:58:32 +0000455 unsigned JTI);
David Goodwin334c2642009-07-08 16:09:28 +0000456static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
457 unsigned JTI) {
Chris Lattner56856b12009-12-03 06:58:32 +0000458 assert(JTI < JT.size());
David Goodwin334c2642009-07-08 16:09:28 +0000459 return JT[JTI].MBBs.size();
460}
461
462/// GetInstSize - Return the size of the specified MachineInstr.
463///
464unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
465 const MachineBasicBlock &MBB = *MI->getParent();
466 const MachineFunction *MF = MBB.getParent();
Chris Lattner33adcfb2009-08-22 21:43:10 +0000467 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
David Goodwin334c2642009-07-08 16:09:28 +0000468
469 // Basic size info comes from the TSFlags field.
470 const TargetInstrDesc &TID = MI->getDesc();
Bruno Cardoso Lopes99405df2010-06-08 22:51:23 +0000471 uint64_t TSFlags = TID.TSFlags;
David Goodwin334c2642009-07-08 16:09:28 +0000472
Evan Chenga0ee8622009-07-31 22:22:22 +0000473 unsigned Opc = MI->getOpcode();
David Goodwin334c2642009-07-08 16:09:28 +0000474 switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
475 default: {
476 // If this machine instr is an inline asm, measure it.
477 if (MI->getOpcode() == ARM::INLINEASM)
Chris Lattner33adcfb2009-08-22 21:43:10 +0000478 return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI);
David Goodwin334c2642009-07-08 16:09:28 +0000479 if (MI->isLabel())
480 return 0;
Evan Chenga0ee8622009-07-31 22:22:22 +0000481 switch (Opc) {
David Goodwin334c2642009-07-08 16:09:28 +0000482 default:
Torok Edwinc23197a2009-07-14 16:55:14 +0000483 llvm_unreachable("Unknown or unset size field for instr!");
Chris Lattner518bb532010-02-09 19:54:29 +0000484 case TargetOpcode::IMPLICIT_DEF:
485 case TargetOpcode::KILL:
Bill Wendling7431bea2010-07-16 22:20:36 +0000486 case TargetOpcode::PROLOG_LABEL:
Chris Lattner518bb532010-02-09 19:54:29 +0000487 case TargetOpcode::EH_LABEL:
Dale Johannesen375be772010-04-07 19:51:44 +0000488 case TargetOpcode::DBG_VALUE:
David Goodwin334c2642009-07-08 16:09:28 +0000489 return 0;
490 }
491 break;
492 }
Evan Cheng78947622009-07-24 18:20:44 +0000493 case ARMII::Size8Bytes: return 8; // ARM instruction x 2.
494 case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction.
495 case ARMII::Size2Bytes: return 2; // Thumb1 instruction.
David Goodwin334c2642009-07-08 16:09:28 +0000496 case ARMII::SizeSpecial: {
Evan Chenga0ee8622009-07-31 22:22:22 +0000497 switch (Opc) {
Jim Grosbach3c38f962010-10-06 22:01:26 +0000498 case ARM::MOVi32imm:
499 case ARM::t2MOVi32imm:
500 return 8;
David Goodwin334c2642009-07-08 16:09:28 +0000501 case ARM::CONSTPOOL_ENTRY:
502 // If this machine instr is a constant pool entry, its size is recorded as
503 // operand #2.
504 return MI->getOperand(2).getImm();
Jim Grosbach5eb19512010-05-22 01:06:18 +0000505 case ARM::Int_eh_sjlj_longjmp:
506 return 16;
507 case ARM::tInt_eh_sjlj_longjmp:
508 return 10;
Evan Cheng78947622009-07-24 18:20:44 +0000509 case ARM::Int_eh_sjlj_setjmp:
Jim Grosbachd1007552010-04-28 20:33:09 +0000510 case ARM::Int_eh_sjlj_setjmp_nofp:
Jim Grosbach0798edd2010-05-27 23:49:24 +0000511 return 20;
Jim Grosbachd1228742009-12-01 18:10:36 +0000512 case ARM::tInt_eh_sjlj_setjmp:
Jim Grosbach5aa16842009-08-11 19:42:21 +0000513 case ARM::t2Int_eh_sjlj_setjmp:
Jim Grosbachd1007552010-04-28 20:33:09 +0000514 case ARM::t2Int_eh_sjlj_setjmp_nofp:
Jim Grosbach0798edd2010-05-27 23:49:24 +0000515 return 12;
David Goodwin334c2642009-07-08 16:09:28 +0000516 case ARM::BR_JTr:
517 case ARM::BR_JTm:
518 case ARM::BR_JTadd:
Evan Chenga0ee8622009-07-31 22:22:22 +0000519 case ARM::tBR_JTr:
Evan Chengd26b14c2009-07-31 18:28:05 +0000520 case ARM::t2BR_JT:
Jim Grosbachd092a872010-11-29 21:28:32 +0000521 case ARM::t2TBB_JT:
522 case ARM::t2TBH_JT: {
David Goodwin334c2642009-07-08 16:09:28 +0000523 // These are jumptable branches, i.e. a branch followed by an inlined
Evan Chengd26b14c2009-07-31 18:28:05 +0000524 // jumptable. The size is 4 + 4 * number of entries. For TBB, each
525 // entry is one byte; TBH two byte each.
Jim Grosbachd092a872010-11-29 21:28:32 +0000526 unsigned EntrySize = (Opc == ARM::t2TBB_JT)
527 ? 1 : ((Opc == ARM::t2TBH_JT) ? 2 : 4);
David Goodwin334c2642009-07-08 16:09:28 +0000528 unsigned NumOps = TID.getNumOperands();
529 MachineOperand JTOP =
530 MI->getOperand(NumOps - (TID.isPredicable() ? 3 : 2));
531 unsigned JTI = JTOP.getIndex();
532 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
Chris Lattnerb1e80392010-01-25 23:22:00 +0000533 assert(MJTI != 0);
David Goodwin334c2642009-07-08 16:09:28 +0000534 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
535 assert(JTI < JT.size());
536 // Thumb instructions are 2 byte aligned, but JT entries are 4 byte
537 // 4 aligned. The assembler / linker may add 2 byte padding just before
538 // the JT entries. The size does not include this padding; the
539 // constant islands pass does separate bookkeeping for it.
540 // FIXME: If we know the size of the function is less than (1 << 16) *2
541 // bytes, we can use 16-bit entries instead. Then there won't be an
542 // alignment issue.
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000543 unsigned InstSize = (Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT) ? 2 : 4;
544 unsigned NumEntries = getNumJTEntries(JT, JTI);
Jim Grosbachd092a872010-11-29 21:28:32 +0000545 if (Opc == ARM::t2TBB_JT && (NumEntries & 1))
Evan Cheng25f7cfc2009-08-01 06:13:52 +0000546 // Make sure the instruction that follows TBB is 2-byte aligned.
547 // FIXME: Constant island pass should insert an "ALIGN" instruction
548 // instead.
549 ++NumEntries;
550 return NumEntries * EntrySize + InstSize;
David Goodwin334c2642009-07-08 16:09:28 +0000551 }
552 default:
553 // Otherwise, pseudo-instruction sizes are zero.
554 return 0;
555 }
556 }
557 }
558 return 0; // Not reached
559}
560
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +0000561void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
562 MachineBasicBlock::iterator I, DebugLoc DL,
563 unsigned DestReg, unsigned SrcReg,
564 bool KillSrc) const {
565 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
566 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
Bob Wilson1665b0a2010-02-16 17:24:15 +0000567
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +0000568 if (GPRDest && GPRSrc) {
569 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr), DestReg)
570 .addReg(SrcReg, getKillRegState(KillSrc))));
571 return;
David Goodwin7bfdca02009-08-05 21:02:22 +0000572 }
David Goodwin334c2642009-07-08 16:09:28 +0000573
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +0000574 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
575 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
576
577 unsigned Opc;
578 if (SPRDest && SPRSrc)
579 Opc = ARM::VMOVS;
580 else if (GPRDest && SPRSrc)
581 Opc = ARM::VMOVRS;
582 else if (SPRDest && GPRSrc)
583 Opc = ARM::VMOVSR;
584 else if (ARM::DPRRegClass.contains(DestReg, SrcReg))
585 Opc = ARM::VMOVD;
586 else if (ARM::QPRRegClass.contains(DestReg, SrcReg))
587 Opc = ARM::VMOVQ;
588 else if (ARM::QQPRRegClass.contains(DestReg, SrcReg))
589 Opc = ARM::VMOVQQ;
590 else if (ARM::QQQQPRRegClass.contains(DestReg, SrcReg))
591 Opc = ARM::VMOVQQQQ;
592 else
593 llvm_unreachable("Impossible reg-to-reg copy");
594
595 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg);
596 MIB.addReg(SrcReg, getKillRegState(KillSrc));
597 if (Opc != ARM::VMOVQQ && Opc != ARM::VMOVQQQQ)
598 AddDefaultPred(MIB);
David Goodwin334c2642009-07-08 16:09:28 +0000599}
600
Evan Chengc10b5af2010-05-07 00:24:52 +0000601static const
602MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB,
603 unsigned Reg, unsigned SubIdx, unsigned State,
604 const TargetRegisterInfo *TRI) {
605 if (!SubIdx)
606 return MIB.addReg(Reg, State);
607
608 if (TargetRegisterInfo::isPhysicalRegister(Reg))
609 return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State);
610 return MIB.addReg(Reg, State, SubIdx);
611}
612
David Goodwin334c2642009-07-08 16:09:28 +0000613void ARMBaseInstrInfo::
614storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
615 unsigned SrcReg, bool isKill, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000616 const TargetRegisterClass *RC,
617 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000618 DebugLoc DL;
David Goodwin334c2642009-07-08 16:09:28 +0000619 if (I != MBB.end()) DL = I->getDebugLoc();
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000620 MachineFunction &MF = *MBB.getParent();
621 MachineFrameInfo &MFI = *MF.getFrameInfo();
Jim Grosbach31bc8492009-11-08 00:27:19 +0000622 unsigned Align = MFI.getObjectAlignment(FI);
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000623
624 MachineMemOperand *MMO =
Chris Lattner59db5492010-09-21 04:39:43 +0000625 MF.getMachineMemOperand(MachinePointerInfo(
626 PseudoSourceValue::getFixedStack(FI)),
627 MachineMemOperand::MOStore,
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000628 MFI.getObjectSize(FI),
Jim Grosbach31bc8492009-11-08 00:27:19 +0000629 Align);
David Goodwin334c2642009-07-08 16:09:28 +0000630
Bob Wilson0eb0c742010-02-16 22:01:59 +0000631 // tGPR is used sometimes in ARM instructions that need to avoid using
Jim Grosbach6ccfc502010-07-30 02:41:01 +0000632 // certain registers. Just treat it as GPR here. Likewise, rGPR.
633 if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass
634 || RC == ARM::rGPRRegisterClass)
Bob Wilson0eb0c742010-02-16 22:01:59 +0000635 RC = ARM::GPRRegisterClass;
636
Bob Wilsonebe99b22010-06-18 21:32:42 +0000637 switch (RC->getID()) {
638 case ARM::GPRRegClassID:
Jim Grosbach7e3383c2010-10-27 23:12:14 +0000639 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12))
David Goodwin334c2642009-07-08 16:09:28 +0000640 .addReg(SrcReg, getKillRegState(isKill))
Jim Grosbach7e3383c2010-10-27 23:12:14 +0000641 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000642 break;
643 case ARM::SPRRegClassID:
Evan Chengd31c5492010-05-06 01:34:11 +0000644 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
645 .addReg(SrcReg, getKillRegState(isKill))
646 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000647 break;
648 case ARM::DPRRegClassID:
649 case ARM::DPR_VFP2RegClassID:
650 case ARM::DPR_8RegClassID:
Jim Grosbache5165492009-11-09 00:11:35 +0000651 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
David Goodwin334c2642009-07-08 16:09:28 +0000652 .addReg(SrcReg, getKillRegState(isKill))
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000653 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000654 break;
655 case ARM::QPRRegClassID:
656 case ARM::QPR_VFP2RegClassID:
657 case ARM::QPR_8RegClassID:
Jim Grosbach0cfcf932010-09-08 00:26:59 +0000658 if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) {
Bob Wilson168f3822010-09-15 01:48:05 +0000659 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64Pseudo))
Bob Wilsonf967ca02010-07-06 21:26:18 +0000660 .addFrameIndex(FI).addImm(16)
Evan Cheng69b9f982010-05-13 01:12:06 +0000661 .addReg(SrcReg, getKillRegState(isKill))
662 .addMemOperand(MMO));
Jim Grosbach31bc8492009-11-08 00:27:19 +0000663 } else {
Bill Wendling73fe34a2010-11-16 01:16:36 +0000664 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQIA))
Evan Cheng69b9f982010-05-13 01:12:06 +0000665 .addReg(SrcReg, getKillRegState(isKill))
666 .addFrameIndex(FI)
Evan Cheng69b9f982010-05-13 01:12:06 +0000667 .addMemOperand(MMO));
Jim Grosbach31bc8492009-11-08 00:27:19 +0000668 }
Bob Wilsonebe99b22010-06-18 21:32:42 +0000669 break;
670 case ARM::QQPRRegClassID:
671 case ARM::QQPR_VFP2RegClassID:
Evan Cheng435d4992010-05-07 02:04:02 +0000672 if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
Evan Cheng22c687b2010-05-14 02:13:41 +0000673 // FIXME: It's possible to only store part of the QQ register if the
674 // spilled def has a sub-register index.
Bob Wilson168f3822010-09-15 01:48:05 +0000675 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1d64QPseudo))
676 .addFrameIndex(FI).addImm(16)
677 .addReg(SrcReg, getKillRegState(isKill))
678 .addMemOperand(MMO));
Evan Cheng435d4992010-05-07 02:04:02 +0000679 } else {
680 MachineInstrBuilder MIB =
Bill Wendling73fe34a2010-11-16 01:16:36 +0000681 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA))
682 .addFrameIndex(FI))
Evan Cheng435d4992010-05-07 02:04:02 +0000683 .addMemOperand(MMO);
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000684 MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
685 MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
686 MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
687 AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
Evan Cheng435d4992010-05-07 02:04:02 +0000688 }
Bob Wilsonebe99b22010-06-18 21:32:42 +0000689 break;
690 case ARM::QQQQPRRegClassID: {
Evan Cheng22c687b2010-05-14 02:13:41 +0000691 MachineInstrBuilder MIB =
Bill Wendling73fe34a2010-11-16 01:16:36 +0000692 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA))
693 .addFrameIndex(FI))
Evan Cheng22c687b2010-05-14 02:13:41 +0000694 .addMemOperand(MMO);
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000695 MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI);
696 MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
697 MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
698 MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
699 MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
700 MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
701 MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
702 AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
Bob Wilsonebe99b22010-06-18 21:32:42 +0000703 break;
704 }
705 default:
706 llvm_unreachable("Unknown regclass!");
David Goodwin334c2642009-07-08 16:09:28 +0000707 }
708}
709
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000710unsigned
711ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
712 int &FrameIndex) const {
713 switch (MI->getOpcode()) {
714 default: break;
Jim Grosbach7e3383c2010-10-27 23:12:14 +0000715 case ARM::STRrs:
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000716 case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
717 if (MI->getOperand(1).isFI() &&
718 MI->getOperand(2).isReg() &&
719 MI->getOperand(3).isImm() &&
720 MI->getOperand(2).getReg() == 0 &&
721 MI->getOperand(3).getImm() == 0) {
722 FrameIndex = MI->getOperand(1).getIndex();
723 return MI->getOperand(0).getReg();
724 }
725 break;
Jim Grosbach7e3383c2010-10-27 23:12:14 +0000726 case ARM::STRi12:
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000727 case ARM::t2STRi12:
728 case ARM::tSpill:
729 case ARM::VSTRD:
730 case ARM::VSTRS:
731 if (MI->getOperand(1).isFI() &&
732 MI->getOperand(2).isImm() &&
733 MI->getOperand(2).getImm() == 0) {
734 FrameIndex = MI->getOperand(1).getIndex();
735 return MI->getOperand(0).getReg();
736 }
737 break;
Jakob Stoklund Olesend64816a2010-09-15 17:27:09 +0000738 case ARM::VST1q64Pseudo:
739 if (MI->getOperand(0).isFI() &&
740 MI->getOperand(2).getSubReg() == 0) {
741 FrameIndex = MI->getOperand(0).getIndex();
742 return MI->getOperand(2).getReg();
743 }
Jakob Stoklund Olesen31bbc512010-09-15 21:40:09 +0000744 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +0000745 case ARM::VSTMQIA:
Jakob Stoklund Olesend64816a2010-09-15 17:27:09 +0000746 if (MI->getOperand(1).isFI() &&
Jakob Stoklund Olesend64816a2010-09-15 17:27:09 +0000747 MI->getOperand(0).getSubReg() == 0) {
748 FrameIndex = MI->getOperand(1).getIndex();
749 return MI->getOperand(0).getReg();
750 }
751 break;
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000752 }
753
754 return 0;
755}
756
David Goodwin334c2642009-07-08 16:09:28 +0000757void ARMBaseInstrInfo::
758loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
759 unsigned DestReg, int FI,
Evan Cheng746ad692010-05-06 19:06:44 +0000760 const TargetRegisterClass *RC,
761 const TargetRegisterInfo *TRI) const {
Chris Lattnerc7f3ace2010-04-02 20:16:16 +0000762 DebugLoc DL;
David Goodwin334c2642009-07-08 16:09:28 +0000763 if (I != MBB.end()) DL = I->getDebugLoc();
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000764 MachineFunction &MF = *MBB.getParent();
765 MachineFrameInfo &MFI = *MF.getFrameInfo();
Jim Grosbach31bc8492009-11-08 00:27:19 +0000766 unsigned Align = MFI.getObjectAlignment(FI);
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000767 MachineMemOperand *MMO =
Chris Lattner59db5492010-09-21 04:39:43 +0000768 MF.getMachineMemOperand(
769 MachinePointerInfo(PseudoSourceValue::getFixedStack(FI)),
770 MachineMemOperand::MOLoad,
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000771 MFI.getObjectSize(FI),
Jim Grosbach31bc8492009-11-08 00:27:19 +0000772 Align);
David Goodwin334c2642009-07-08 16:09:28 +0000773
Bob Wilson0eb0c742010-02-16 22:01:59 +0000774 // tGPR is used sometimes in ARM instructions that need to avoid using
775 // certain registers. Just treat it as GPR here.
Jim Grosbach6ccfc502010-07-30 02:41:01 +0000776 if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass
777 || RC == ARM::rGPRRegisterClass)
Bob Wilson0eb0c742010-02-16 22:01:59 +0000778 RC = ARM::GPRRegisterClass;
779
Bob Wilsonebe99b22010-06-18 21:32:42 +0000780 switch (RC->getID()) {
781 case ARM::GPRRegClassID:
Jim Grosbach3e556122010-10-26 22:37:02 +0000782 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg)
783 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000784 break;
785 case ARM::SPRRegClassID:
Evan Chengd31c5492010-05-06 01:34:11 +0000786 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
787 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000788 break;
789 case ARM::DPRRegClassID:
790 case ARM::DPR_VFP2RegClassID:
791 case ARM::DPR_8RegClassID:
Jim Grosbache5165492009-11-09 00:11:35 +0000792 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
Anton Korobeynikov249fb332009-10-07 00:06:35 +0000793 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
Bob Wilsonebe99b22010-06-18 21:32:42 +0000794 break;
795 case ARM::QPRRegClassID:
796 case ARM::QPR_VFP2RegClassID:
797 case ARM::QPR_8RegClassID:
Jim Grosbach0cfcf932010-09-08 00:26:59 +0000798 if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) {
Bob Wilson168f3822010-09-15 01:48:05 +0000799 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64Pseudo), DestReg)
Bob Wilsonf967ca02010-07-06 21:26:18 +0000800 .addFrameIndex(FI).addImm(16)
Evan Cheng69b9f982010-05-13 01:12:06 +0000801 .addMemOperand(MMO));
Jim Grosbach31bc8492009-11-08 00:27:19 +0000802 } else {
Bill Wendling73fe34a2010-11-16 01:16:36 +0000803 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQIA), DestReg)
Evan Cheng69b9f982010-05-13 01:12:06 +0000804 .addFrameIndex(FI)
Evan Cheng69b9f982010-05-13 01:12:06 +0000805 .addMemOperand(MMO));
Jim Grosbach31bc8492009-11-08 00:27:19 +0000806 }
Bob Wilsonebe99b22010-06-18 21:32:42 +0000807 break;
808 case ARM::QQPRRegClassID:
809 case ARM::QQPR_VFP2RegClassID:
Evan Cheng435d4992010-05-07 02:04:02 +0000810 if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) {
Bob Wilson168f3822010-09-15 01:48:05 +0000811 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1d64QPseudo), DestReg)
812 .addFrameIndex(FI).addImm(16)
813 .addMemOperand(MMO));
Evan Cheng435d4992010-05-07 02:04:02 +0000814 } else {
815 MachineInstrBuilder MIB =
Bill Wendling73fe34a2010-11-16 01:16:36 +0000816 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
817 .addFrameIndex(FI))
Evan Cheng435d4992010-05-07 02:04:02 +0000818 .addMemOperand(MMO);
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000819 MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI);
820 MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI);
821 MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI);
822 AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI);
Evan Cheng435d4992010-05-07 02:04:02 +0000823 }
Bob Wilsonebe99b22010-06-18 21:32:42 +0000824 break;
825 case ARM::QQQQPRRegClassID: {
826 MachineInstrBuilder MIB =
Bill Wendling73fe34a2010-11-16 01:16:36 +0000827 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA))
828 .addFrameIndex(FI))
Bob Wilsonebe99b22010-06-18 21:32:42 +0000829 .addMemOperand(MMO);
830 MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI);
831 MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI);
832 MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI);
833 MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI);
834 MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::Define, TRI);
835 MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::Define, TRI);
836 MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::Define, TRI);
837 AddDReg(MIB, DestReg, ARM::dsub_7, RegState::Define, TRI);
838 break;
839 }
840 default:
841 llvm_unreachable("Unknown regclass!");
David Goodwin334c2642009-07-08 16:09:28 +0000842 }
843}
844
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000845unsigned
846ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
847 int &FrameIndex) const {
848 switch (MI->getOpcode()) {
849 default: break;
Jim Grosbach3e556122010-10-26 22:37:02 +0000850 case ARM::LDRrs:
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000851 case ARM::t2LDRs: // FIXME: don't use t2LDRs to access frame.
852 if (MI->getOperand(1).isFI() &&
853 MI->getOperand(2).isReg() &&
854 MI->getOperand(3).isImm() &&
855 MI->getOperand(2).getReg() == 0 &&
856 MI->getOperand(3).getImm() == 0) {
857 FrameIndex = MI->getOperand(1).getIndex();
858 return MI->getOperand(0).getReg();
859 }
860 break;
Jim Grosbach3e556122010-10-26 22:37:02 +0000861 case ARM::LDRi12:
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000862 case ARM::t2LDRi12:
863 case ARM::tRestore:
864 case ARM::VLDRD:
865 case ARM::VLDRS:
866 if (MI->getOperand(1).isFI() &&
867 MI->getOperand(2).isImm() &&
868 MI->getOperand(2).getImm() == 0) {
869 FrameIndex = MI->getOperand(1).getIndex();
870 return MI->getOperand(0).getReg();
871 }
872 break;
Jakob Stoklund Olesend64816a2010-09-15 17:27:09 +0000873 case ARM::VLD1q64Pseudo:
874 if (MI->getOperand(1).isFI() &&
875 MI->getOperand(0).getSubReg() == 0) {
876 FrameIndex = MI->getOperand(1).getIndex();
877 return MI->getOperand(0).getReg();
878 }
879 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +0000880 case ARM::VLDMQIA:
Jakob Stoklund Olesen06f264e2010-09-15 21:40:11 +0000881 if (MI->getOperand(1).isFI() &&
Jakob Stoklund Olesen06f264e2010-09-15 21:40:11 +0000882 MI->getOperand(0).getSubReg() == 0) {
883 FrameIndex = MI->getOperand(1).getIndex();
884 return MI->getOperand(0).getReg();
885 }
886 break;
Jakob Stoklund Olesen34327852010-09-15 16:36:26 +0000887 }
888
889 return 0;
890}
891
Evan Cheng62b50652010-04-26 07:39:25 +0000892MachineInstr*
893ARMBaseInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF,
Evan Cheng8601a3d2010-04-29 01:13:30 +0000894 int FrameIx, uint64_t Offset,
Evan Cheng62b50652010-04-26 07:39:25 +0000895 const MDNode *MDPtr,
896 DebugLoc DL) const {
897 MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::DBG_VALUE))
898 .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr);
899 return &*MIB;
900}
901
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000902/// Create a copy of a const pool value. Update CPI to the new index and return
903/// the label UID.
904static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
905 MachineConstantPool *MCP = MF.getConstantPool();
906 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
907
908 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
909 assert(MCPE.isMachineConstantPoolEntry() &&
910 "Expecting a machine constantpool entry!");
911 ARMConstantPoolValue *ACPV =
912 static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
913
914 unsigned PCLabelId = AFI->createConstPoolEntryUId();
915 ARMConstantPoolValue *NewCPV = 0;
Jim Grosbach51f5b672010-09-10 21:38:22 +0000916 // FIXME: The below assumes PIC relocation model and that the function
917 // is Thumb mode (t1 or t2). PCAdjustment would be 8 for ARM mode PIC, and
918 // zero for non-PIC in ARM or Thumb. The callers are all of thumb LDR
919 // instructions, so that's probably OK, but is PIC always correct when
920 // we get here?
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000921 if (ACPV->isGlobalValue())
922 NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
923 ARMCP::CPValue, 4);
924 else if (ACPV->isExtSymbol())
925 NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
926 ACPV->getSymbol(), PCLabelId, 4);
927 else if (ACPV->isBlockAddress())
928 NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
929 ARMCP::CPBlockAddress, 4);
Jim Grosbach51f5b672010-09-10 21:38:22 +0000930 else if (ACPV->isLSDA())
931 NewCPV = new ARMConstantPoolValue(MF.getFunction(), PCLabelId,
932 ARMCP::CPLSDA, 4);
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000933 else
934 llvm_unreachable("Unexpected ARM constantpool value type!!");
935 CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
936 return PCLabelId;
937}
938
Evan Chengfdc83402009-11-08 00:15:23 +0000939void ARMBaseInstrInfo::
940reMaterialize(MachineBasicBlock &MBB,
941 MachineBasicBlock::iterator I,
942 unsigned DestReg, unsigned SubIdx,
Evan Chengd57cdd52009-11-14 02:55:43 +0000943 const MachineInstr *Orig,
Jakob Stoklund Olesen9edf7de2010-06-02 22:47:25 +0000944 const TargetRegisterInfo &TRI) const {
Evan Chengfdc83402009-11-08 00:15:23 +0000945 unsigned Opcode = Orig->getOpcode();
946 switch (Opcode) {
947 default: {
948 MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
Jakob Stoklund Olesen9edf7de2010-06-02 22:47:25 +0000949 MI->substituteRegister(Orig->getOperand(0).getReg(), DestReg, SubIdx, TRI);
Evan Chengfdc83402009-11-08 00:15:23 +0000950 MBB.insert(I, MI);
951 break;
952 }
953 case ARM::tLDRpci_pic:
954 case ARM::t2LDRpci_pic: {
955 MachineFunction &MF = *MBB.getParent();
Evan Chengfdc83402009-11-08 00:15:23 +0000956 unsigned CPI = Orig->getOperand(1).getIndex();
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000957 unsigned PCLabelId = duplicateCPV(MF, CPI);
Evan Chengfdc83402009-11-08 00:15:23 +0000958 MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode),
959 DestReg)
960 .addConstantPoolIndex(CPI).addImm(PCLabelId);
961 (*MIB).setMemRefs(Orig->memoperands_begin(), Orig->memoperands_end());
962 break;
963 }
964 }
Evan Chengfdc83402009-11-08 00:15:23 +0000965}
966
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000967MachineInstr *
968ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
969 MachineInstr *MI = TargetInstrInfoImpl::duplicate(Orig, MF);
970 switch(Orig->getOpcode()) {
971 case ARM::tLDRpci_pic:
972 case ARM::t2LDRpci_pic: {
973 unsigned CPI = Orig->getOperand(1).getIndex();
974 unsigned PCLabelId = duplicateCPV(MF, CPI);
975 Orig->getOperand(1).setIndex(CPI);
976 Orig->getOperand(2).setImm(PCLabelId);
977 break;
978 }
979 }
980 return MI;
981}
982
Evan Cheng506049f2010-03-03 01:44:33 +0000983bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
984 const MachineInstr *MI1) const {
Evan Chengd457e6e2009-11-07 04:04:34 +0000985 int Opcode = MI0->getOpcode();
Evan Cheng9b824252009-11-20 02:10:27 +0000986 if (Opcode == ARM::t2LDRpci ||
987 Opcode == ARM::t2LDRpci_pic ||
988 Opcode == ARM::tLDRpci ||
989 Opcode == ARM::tLDRpci_pic) {
Evan Chengd457e6e2009-11-07 04:04:34 +0000990 if (MI1->getOpcode() != Opcode)
991 return false;
992 if (MI0->getNumOperands() != MI1->getNumOperands())
993 return false;
994
995 const MachineOperand &MO0 = MI0->getOperand(1);
996 const MachineOperand &MO1 = MI1->getOperand(1);
997 if (MO0.getOffset() != MO1.getOffset())
998 return false;
999
1000 const MachineFunction *MF = MI0->getParent()->getParent();
1001 const MachineConstantPool *MCP = MF->getConstantPool();
1002 int CPI0 = MO0.getIndex();
1003 int CPI1 = MO1.getIndex();
1004 const MachineConstantPoolEntry &MCPE0 = MCP->getConstants()[CPI0];
1005 const MachineConstantPoolEntry &MCPE1 = MCP->getConstants()[CPI1];
1006 ARMConstantPoolValue *ACPV0 =
1007 static_cast<ARMConstantPoolValue*>(MCPE0.Val.MachineCPVal);
1008 ARMConstantPoolValue *ACPV1 =
1009 static_cast<ARMConstantPoolValue*>(MCPE1.Val.MachineCPVal);
1010 return ACPV0->hasSameValue(ACPV1);
1011 }
1012
Evan Cheng506049f2010-03-03 01:44:33 +00001013 return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
Evan Chengd457e6e2009-11-07 04:04:34 +00001014}
1015
Bill Wendling4b722102010-06-23 23:00:16 +00001016/// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
1017/// determine if two loads are loading from the same base address. It should
1018/// only return true if the base pointers are the same and the only differences
1019/// between the two addresses is the offset. It also returns the offsets by
1020/// reference.
1021bool ARMBaseInstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
1022 int64_t &Offset1,
1023 int64_t &Offset2) const {
1024 // Don't worry about Thumb: just ARM and Thumb2.
1025 if (Subtarget.isThumb1Only()) return false;
1026
1027 if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
1028 return false;
1029
1030 switch (Load1->getMachineOpcode()) {
1031 default:
1032 return false;
Jim Grosbach3e556122010-10-26 22:37:02 +00001033 case ARM::LDRi12:
Jim Grosbachc1d30212010-10-27 00:19:44 +00001034 case ARM::LDRBi12:
Bill Wendling4b722102010-06-23 23:00:16 +00001035 case ARM::LDRD:
1036 case ARM::LDRH:
1037 case ARM::LDRSB:
1038 case ARM::LDRSH:
1039 case ARM::VLDRD:
1040 case ARM::VLDRS:
1041 case ARM::t2LDRi8:
1042 case ARM::t2LDRDi8:
1043 case ARM::t2LDRSHi8:
1044 case ARM::t2LDRi12:
1045 case ARM::t2LDRSHi12:
1046 break;
1047 }
1048
1049 switch (Load2->getMachineOpcode()) {
1050 default:
1051 return false;
Jim Grosbach3e556122010-10-26 22:37:02 +00001052 case ARM::LDRi12:
Jim Grosbachc1d30212010-10-27 00:19:44 +00001053 case ARM::LDRBi12:
Bill Wendling4b722102010-06-23 23:00:16 +00001054 case ARM::LDRD:
1055 case ARM::LDRH:
1056 case ARM::LDRSB:
1057 case ARM::LDRSH:
1058 case ARM::VLDRD:
1059 case ARM::VLDRS:
1060 case ARM::t2LDRi8:
1061 case ARM::t2LDRDi8:
1062 case ARM::t2LDRSHi8:
1063 case ARM::t2LDRi12:
1064 case ARM::t2LDRSHi12:
1065 break;
1066 }
1067
1068 // Check if base addresses and chain operands match.
1069 if (Load1->getOperand(0) != Load2->getOperand(0) ||
1070 Load1->getOperand(4) != Load2->getOperand(4))
1071 return false;
1072
1073 // Index should be Reg0.
1074 if (Load1->getOperand(3) != Load2->getOperand(3))
1075 return false;
1076
1077 // Determine the offsets.
1078 if (isa<ConstantSDNode>(Load1->getOperand(1)) &&
1079 isa<ConstantSDNode>(Load2->getOperand(1))) {
1080 Offset1 = cast<ConstantSDNode>(Load1->getOperand(1))->getSExtValue();
1081 Offset2 = cast<ConstantSDNode>(Load2->getOperand(1))->getSExtValue();
1082 return true;
1083 }
1084
1085 return false;
1086}
1087
1088/// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
1089/// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
1090/// be scheduled togther. On some targets if two loads are loading from
1091/// addresses in the same cache line, it's better if they are scheduled
1092/// together. This function takes two integers that represent the load offsets
1093/// from the common base address. It returns true if it decides it's desirable
1094/// to schedule the two loads together. "NumLoads" is the number of loads that
1095/// have already been scheduled after Load1.
1096bool ARMBaseInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
1097 int64_t Offset1, int64_t Offset2,
1098 unsigned NumLoads) const {
1099 // Don't worry about Thumb: just ARM and Thumb2.
1100 if (Subtarget.isThumb1Only()) return false;
1101
1102 assert(Offset2 > Offset1);
1103
1104 if ((Offset2 - Offset1) / 8 > 64)
1105 return false;
1106
1107 if (Load1->getMachineOpcode() != Load2->getMachineOpcode())
1108 return false; // FIXME: overly conservative?
1109
1110 // Four loads in a row should be sufficient.
1111 if (NumLoads >= 3)
1112 return false;
1113
1114 return true;
1115}
1116
Evan Cheng86050dc2010-06-18 23:09:54 +00001117bool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
1118 const MachineBasicBlock *MBB,
1119 const MachineFunction &MF) const {
Jim Grosbach57bb3942010-06-25 18:43:14 +00001120 // Debug info is never a scheduling boundary. It's necessary to be explicit
1121 // due to the special treatment of IT instructions below, otherwise a
1122 // dbg_value followed by an IT will result in the IT instruction being
1123 // considered a scheduling hazard, which is wrong. It should be the actual
1124 // instruction preceding the dbg_value instruction(s), just like it is
1125 // when debug info is not present.
1126 if (MI->isDebugValue())
1127 return false;
1128
Evan Cheng86050dc2010-06-18 23:09:54 +00001129 // Terminators and labels can't be scheduled around.
1130 if (MI->getDesc().isTerminator() || MI->isLabel())
1131 return true;
1132
1133 // Treat the start of the IT block as a scheduling boundary, but schedule
1134 // t2IT along with all instructions following it.
1135 // FIXME: This is a big hammer. But the alternative is to add all potential
1136 // true and anti dependencies to IT block instructions as implicit operands
1137 // to the t2IT instruction. The added compile time and complexity does not
1138 // seem worth it.
1139 MachineBasicBlock::const_iterator I = MI;
Jim Grosbach57bb3942010-06-25 18:43:14 +00001140 // Make sure to skip any dbg_value instructions
1141 while (++I != MBB->end() && I->isDebugValue())
1142 ;
1143 if (I != MBB->end() && I->getOpcode() == ARM::t2IT)
Evan Cheng86050dc2010-06-18 23:09:54 +00001144 return true;
1145
1146 // Don't attempt to schedule around any instruction that defines
1147 // a stack-oriented pointer, as it's unlikely to be profitable. This
1148 // saves compile time, because it doesn't require every single
1149 // stack slot reference to depend on the instruction that does the
1150 // modification.
1151 if (MI->definesRegister(ARM::SP))
1152 return true;
1153
1154 return false;
1155}
1156
Owen Andersonb20b8512010-09-28 18:32:13 +00001157bool ARMBaseInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
Evan Cheng8239daf2010-11-03 00:45:17 +00001158 unsigned NumCyles,
1159 unsigned ExtraPredCycles,
Owen Andersone3cc84a2010-10-01 22:45:50 +00001160 float Probability,
1161 float Confidence) const {
Evan Cheng8239daf2010-11-03 00:45:17 +00001162 if (!NumCyles)
Evan Cheng13151432010-06-25 22:42:03 +00001163 return false;
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001164
Owen Andersonb20b8512010-09-28 18:32:13 +00001165 // Attempt to estimate the relative costs of predication versus branching.
Evan Cheng8239daf2010-11-03 00:45:17 +00001166 float UnpredCost = Probability * NumCyles;
Owen Anderson654d5442010-09-28 21:57:50 +00001167 UnpredCost += 1.0; // The branch itself
Owen Andersone3cc84a2010-10-01 22:45:50 +00001168 UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty();
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001169
Evan Cheng8239daf2010-11-03 00:45:17 +00001170 return (float)(NumCyles + ExtraPredCycles) < UnpredCost;
Evan Cheng13151432010-06-25 22:42:03 +00001171}
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001172
Evan Cheng13151432010-06-25 22:42:03 +00001173bool ARMBaseInstrInfo::
Evan Cheng8239daf2010-11-03 00:45:17 +00001174isProfitableToIfCvt(MachineBasicBlock &TMBB,
1175 unsigned TCycles, unsigned TExtra,
1176 MachineBasicBlock &FMBB,
1177 unsigned FCycles, unsigned FExtra,
Owen Andersone3cc84a2010-10-01 22:45:50 +00001178 float Probability, float Confidence) const {
Evan Cheng8239daf2010-11-03 00:45:17 +00001179 if (!TCycles || !FCycles)
Owen Andersonb20b8512010-09-28 18:32:13 +00001180 return false;
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001181
Owen Andersonb20b8512010-09-28 18:32:13 +00001182 // Attempt to estimate the relative costs of predication versus branching.
Evan Cheng8239daf2010-11-03 00:45:17 +00001183 float UnpredCost = Probability * TCycles + (1.0 - Probability) * FCycles;
Owen Anderson654d5442010-09-28 21:57:50 +00001184 UnpredCost += 1.0; // The branch itself
Owen Andersone3cc84a2010-10-01 22:45:50 +00001185 UnpredCost += (1.0 - Confidence) * Subtarget.getMispredictionPenalty();
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001186
Evan Cheng8239daf2010-11-03 00:45:17 +00001187 return (float)(TCycles + FCycles + TExtra + FExtra) < UnpredCost;
Evan Cheng13151432010-06-25 22:42:03 +00001188}
1189
Evan Cheng8fb90362009-08-08 03:20:32 +00001190/// getInstrPredicate - If instruction is predicated, returns its predicate
1191/// condition, otherwise returns AL. It also returns the condition code
1192/// register by reference.
Evan Cheng5adb66a2009-09-28 09:14:39 +00001193ARMCC::CondCodes
1194llvm::getInstrPredicate(const MachineInstr *MI, unsigned &PredReg) {
Evan Cheng8fb90362009-08-08 03:20:32 +00001195 int PIdx = MI->findFirstPredOperandIdx();
1196 if (PIdx == -1) {
1197 PredReg = 0;
1198 return ARMCC::AL;
1199 }
1200
1201 PredReg = MI->getOperand(PIdx+1).getReg();
1202 return (ARMCC::CondCodes)MI->getOperand(PIdx).getImm();
1203}
1204
1205
Evan Cheng6495f632009-07-28 05:48:47 +00001206int llvm::getMatchingCondBranchOpcode(int Opc) {
Evan Cheng5ca53a72009-07-27 18:20:05 +00001207 if (Opc == ARM::B)
1208 return ARM::Bcc;
1209 else if (Opc == ARM::tB)
1210 return ARM::tBcc;
1211 else if (Opc == ARM::t2B)
1212 return ARM::t2Bcc;
1213
1214 llvm_unreachable("Unknown unconditional branch opcode!");
1215 return 0;
1216}
1217
Evan Cheng6495f632009-07-28 05:48:47 +00001218
1219void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
1220 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
1221 unsigned DestReg, unsigned BaseReg, int NumBytes,
1222 ARMCC::CondCodes Pred, unsigned PredReg,
1223 const ARMBaseInstrInfo &TII) {
1224 bool isSub = NumBytes < 0;
1225 if (isSub) NumBytes = -NumBytes;
1226
1227 while (NumBytes) {
1228 unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
1229 unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
1230 assert(ThisVal && "Didn't extract field correctly");
1231
1232 // We will handle these bits from offset, clear them.
1233 NumBytes &= ~ThisVal;
1234
1235 assert(ARM_AM::getSOImmVal(ThisVal) != -1 && "Bit extraction didn't work?");
1236
1237 // Build the new ADD / SUB.
1238 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
1239 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
1240 .addReg(BaseReg, RegState::Kill).addImm(ThisVal)
1241 .addImm((unsigned)Pred).addReg(PredReg).addReg(0);
1242 BaseReg = DestReg;
1243 }
1244}
1245
Evan Chengcdbb3f52009-08-27 01:23:50 +00001246bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
1247 unsigned FrameReg, int &Offset,
1248 const ARMBaseInstrInfo &TII) {
Evan Cheng6495f632009-07-28 05:48:47 +00001249 unsigned Opcode = MI.getOpcode();
1250 const TargetInstrDesc &Desc = MI.getDesc();
1251 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1252 bool isSub = false;
Jim Grosbach764ab522009-08-11 15:33:49 +00001253
Evan Cheng6495f632009-07-28 05:48:47 +00001254 // Memory operands in inline assembly always use AddrMode2.
1255 if (Opcode == ARM::INLINEASM)
1256 AddrMode = ARMII::AddrMode2;
Jim Grosbach764ab522009-08-11 15:33:49 +00001257
Evan Cheng6495f632009-07-28 05:48:47 +00001258 if (Opcode == ARM::ADDri) {
1259 Offset += MI.getOperand(FrameRegIdx+1).getImm();
1260 if (Offset == 0) {
1261 // Turn it into a move.
1262 MI.setDesc(TII.get(ARM::MOVr));
1263 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1264 MI.RemoveOperand(FrameRegIdx+1);
Evan Chengcdbb3f52009-08-27 01:23:50 +00001265 Offset = 0;
1266 return true;
Evan Cheng6495f632009-07-28 05:48:47 +00001267 } else if (Offset < 0) {
1268 Offset = -Offset;
1269 isSub = true;
1270 MI.setDesc(TII.get(ARM::SUBri));
1271 }
1272
1273 // Common case: small offset, fits into instruction.
1274 if (ARM_AM::getSOImmVal(Offset) != -1) {
1275 // Replace the FrameIndex with sp / fp
1276 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
1277 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
Evan Chengcdbb3f52009-08-27 01:23:50 +00001278 Offset = 0;
1279 return true;
Evan Cheng6495f632009-07-28 05:48:47 +00001280 }
1281
1282 // Otherwise, pull as much of the immedidate into this ADDri/SUBri
1283 // as possible.
1284 unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
1285 unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, RotAmt);
1286
1287 // We will handle these bits from offset, clear them.
1288 Offset &= ~ThisImmVal;
1289
1290 // Get the properly encoded SOImmVal field.
1291 assert(ARM_AM::getSOImmVal(ThisImmVal) != -1 &&
1292 "Bit extraction didn't work?");
1293 MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal);
1294 } else {
1295 unsigned ImmIdx = 0;
1296 int InstrOffs = 0;
1297 unsigned NumBits = 0;
1298 unsigned Scale = 1;
1299 switch (AddrMode) {
Jim Grosbach3e556122010-10-26 22:37:02 +00001300 case ARMII::AddrMode_i12: {
1301 ImmIdx = FrameRegIdx + 1;
1302 InstrOffs = MI.getOperand(ImmIdx).getImm();
1303 NumBits = 12;
1304 break;
1305 }
Evan Cheng6495f632009-07-28 05:48:47 +00001306 case ARMII::AddrMode2: {
1307 ImmIdx = FrameRegIdx+2;
1308 InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
1309 if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1310 InstrOffs *= -1;
1311 NumBits = 12;
1312 break;
1313 }
1314 case ARMII::AddrMode3: {
1315 ImmIdx = FrameRegIdx+2;
1316 InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
1317 if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1318 InstrOffs *= -1;
1319 NumBits = 8;
1320 break;
1321 }
Anton Korobeynikovbaf31082009-08-08 13:35:48 +00001322 case ARMII::AddrMode4:
Jim Grosbacha4432172009-11-15 21:45:34 +00001323 case ARMII::AddrMode6:
Evan Chengcdbb3f52009-08-27 01:23:50 +00001324 // Can't fold any offset even if it's zero.
1325 return false;
Evan Cheng6495f632009-07-28 05:48:47 +00001326 case ARMII::AddrMode5: {
1327 ImmIdx = FrameRegIdx+1;
1328 InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
1329 if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
1330 InstrOffs *= -1;
1331 NumBits = 8;
1332 Scale = 4;
1333 break;
1334 }
1335 default:
1336 llvm_unreachable("Unsupported addressing mode!");
1337 break;
1338 }
1339
1340 Offset += InstrOffs * Scale;
1341 assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
1342 if (Offset < 0) {
1343 Offset = -Offset;
1344 isSub = true;
1345 }
1346
1347 // Attempt to fold address comp. if opcode has offset bits
1348 if (NumBits > 0) {
1349 // Common case: small offset, fits into instruction.
1350 MachineOperand &ImmOp = MI.getOperand(ImmIdx);
1351 int ImmedOffset = Offset / Scale;
1352 unsigned Mask = (1 << NumBits) - 1;
1353 if ((unsigned)Offset <= Mask * Scale) {
1354 // Replace the FrameIndex with sp
1355 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
Jim Grosbach77aee8e2010-10-27 01:19:41 +00001356 // FIXME: When addrmode2 goes away, this will simplify (like the
1357 // T2 version), as the LDR.i12 versions don't need the encoding
1358 // tricks for the offset value.
1359 if (isSub) {
1360 if (AddrMode == ARMII::AddrMode_i12)
1361 ImmedOffset = -ImmedOffset;
1362 else
1363 ImmedOffset |= 1 << NumBits;
1364 }
Evan Cheng6495f632009-07-28 05:48:47 +00001365 ImmOp.ChangeToImmediate(ImmedOffset);
Evan Chengcdbb3f52009-08-27 01:23:50 +00001366 Offset = 0;
1367 return true;
Evan Cheng6495f632009-07-28 05:48:47 +00001368 }
Jim Grosbach764ab522009-08-11 15:33:49 +00001369
Evan Cheng6495f632009-07-28 05:48:47 +00001370 // Otherwise, it didn't fit. Pull in what we can to simplify the immed.
1371 ImmedOffset = ImmedOffset & Mask;
Jim Grosbach063efbf2010-10-27 16:50:31 +00001372 if (isSub) {
1373 if (AddrMode == ARMII::AddrMode_i12)
1374 ImmedOffset = -ImmedOffset;
1375 else
1376 ImmedOffset |= 1 << NumBits;
1377 }
Evan Cheng6495f632009-07-28 05:48:47 +00001378 ImmOp.ChangeToImmediate(ImmedOffset);
1379 Offset &= ~(Mask*Scale);
1380 }
1381 }
1382
Evan Chengcdbb3f52009-08-27 01:23:50 +00001383 Offset = (isSub) ? -Offset : Offset;
1384 return Offset == 0;
Evan Cheng6495f632009-07-28 05:48:47 +00001385}
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001386
1387bool ARMBaseInstrInfo::
Eric Christophera99c3e92010-09-28 04:18:29 +00001388AnalyzeCompare(const MachineInstr *MI, unsigned &SrcReg, int &CmpMask,
1389 int &CmpValue) const {
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001390 switch (MI->getOpcode()) {
1391 default: break;
Bill Wendling38ae9972010-08-11 00:23:00 +00001392 case ARM::CMPri:
1393 case ARM::CMPzri:
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001394 case ARM::t2CMPri:
1395 case ARM::t2CMPzri:
1396 SrcReg = MI->getOperand(0).getReg();
Gabor Greif04ac81d2010-09-21 12:01:15 +00001397 CmpMask = ~0;
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001398 CmpValue = MI->getOperand(1).getImm();
1399 return true;
Gabor Greif04ac81d2010-09-21 12:01:15 +00001400 case ARM::TSTri:
1401 case ARM::t2TSTri:
1402 SrcReg = MI->getOperand(0).getReg();
1403 CmpMask = MI->getOperand(1).getImm();
1404 CmpValue = 0;
1405 return true;
1406 }
1407
1408 return false;
1409}
1410
Gabor Greif05642a32010-09-29 10:12:08 +00001411/// isSuitableForMask - Identify a suitable 'and' instruction that
1412/// operates on the given source register and applies the same mask
1413/// as a 'tst' instruction. Provide a limited look-through for copies.
1414/// When successful, MI will hold the found instruction.
1415static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg,
Gabor Greif8ff9bb12010-09-21 13:30:57 +00001416 int CmpMask, bool CommonUse) {
Gabor Greif05642a32010-09-29 10:12:08 +00001417 switch (MI->getOpcode()) {
Gabor Greif04ac81d2010-09-21 12:01:15 +00001418 case ARM::ANDri:
1419 case ARM::t2ANDri:
Gabor Greif05642a32010-09-29 10:12:08 +00001420 if (CmpMask != MI->getOperand(2).getImm())
Gabor Greif8ff9bb12010-09-21 13:30:57 +00001421 return false;
Gabor Greif05642a32010-09-29 10:12:08 +00001422 if (SrcReg == MI->getOperand(CommonUse ? 1 : 0).getReg())
Gabor Greif04ac81d2010-09-21 12:01:15 +00001423 return true;
1424 break;
Gabor Greif05642a32010-09-29 10:12:08 +00001425 case ARM::COPY: {
1426 // Walk down one instruction which is potentially an 'and'.
1427 const MachineInstr &Copy = *MI;
Michael J. Spencerf000a7a2010-10-05 06:00:43 +00001428 MachineBasicBlock::iterator AND(
1429 llvm::next(MachineBasicBlock::iterator(MI)));
Gabor Greif05642a32010-09-29 10:12:08 +00001430 if (AND == MI->getParent()->end()) return false;
1431 MI = AND;
1432 return isSuitableForMask(MI, Copy.getOperand(0).getReg(),
1433 CmpMask, true);
1434 }
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001435 }
1436
1437 return false;
1438}
1439
Bill Wendlinga6556862010-09-11 00:13:50 +00001440/// OptimizeCompareInstr - Convert the instruction supplying the argument to the
Evan Chengeb96a2f2010-11-15 21:20:45 +00001441/// comparison into one that sets the zero bit in the flags register.
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001442bool ARMBaseInstrInfo::
Gabor Greif04ac81d2010-09-21 12:01:15 +00001443OptimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg, int CmpMask,
Evan Chengeb96a2f2010-11-15 21:20:45 +00001444 int CmpValue, const MachineRegisterInfo *MRI) const {
Bill Wendling36656612010-09-10 23:46:12 +00001445 if (CmpValue != 0)
Bill Wendling92ad57f2010-09-10 23:34:19 +00001446 return false;
1447
Bill Wendlingb41ee962010-10-18 21:22:31 +00001448 MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg);
1449 if (llvm::next(DI) != MRI->def_end())
Bill Wendling92ad57f2010-09-10 23:34:19 +00001450 // Only support one definition.
1451 return false;
1452
1453 MachineInstr *MI = &*DI;
1454
Gabor Greif04ac81d2010-09-21 12:01:15 +00001455 // Masked compares sometimes use the same register as the corresponding 'and'.
1456 if (CmpMask != ~0) {
Gabor Greif05642a32010-09-29 10:12:08 +00001457 if (!isSuitableForMask(MI, SrcReg, CmpMask, false)) {
Gabor Greif04ac81d2010-09-21 12:01:15 +00001458 MI = 0;
Bill Wendlingb41ee962010-10-18 21:22:31 +00001459 for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg),
1460 UE = MRI->use_end(); UI != UE; ++UI) {
Gabor Greif04ac81d2010-09-21 12:01:15 +00001461 if (UI->getParent() != CmpInstr->getParent()) continue;
Gabor Greif05642a32010-09-29 10:12:08 +00001462 MachineInstr *PotentialAND = &*UI;
Gabor Greif8ff9bb12010-09-21 13:30:57 +00001463 if (!isSuitableForMask(PotentialAND, SrcReg, CmpMask, true))
Gabor Greif04ac81d2010-09-21 12:01:15 +00001464 continue;
Gabor Greif05642a32010-09-29 10:12:08 +00001465 MI = PotentialAND;
Gabor Greif04ac81d2010-09-21 12:01:15 +00001466 break;
1467 }
1468 if (!MI) return false;
1469 }
1470 }
1471
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001472 // Conservatively refuse to convert an instruction which isn't in the same BB
1473 // as the comparison.
1474 if (MI->getParent() != CmpInstr->getParent())
1475 return false;
1476
1477 // Check that CPSR isn't set between the comparison instruction and the one we
1478 // want to change.
Evan Cheng691e64a2010-09-21 23:49:07 +00001479 MachineBasicBlock::const_iterator I = CmpInstr, E = MI,
1480 B = MI->getParent()->begin();
Bill Wendling0aa38b92010-10-09 00:03:48 +00001481
1482 // Early exit if CmpInstr is at the beginning of the BB.
1483 if (I == B) return false;
1484
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001485 --I;
1486 for (; I != E; --I) {
1487 const MachineInstr &Instr = *I;
1488
1489 for (unsigned IO = 0, EO = Instr.getNumOperands(); IO != EO; ++IO) {
1490 const MachineOperand &MO = Instr.getOperand(IO);
Bill Wendling40a5eb12010-11-01 20:41:43 +00001491 if (!MO.isReg()) continue;
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001492
Bill Wendling40a5eb12010-11-01 20:41:43 +00001493 // This instruction modifies or uses CPSR after the one we want to
1494 // change. We can't do this transformation.
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001495 if (MO.getReg() == ARM::CPSR)
1496 return false;
1497 }
Evan Cheng691e64a2010-09-21 23:49:07 +00001498
1499 if (I == B)
1500 // The 'and' is below the comparison instruction.
1501 return false;
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001502 }
1503
1504 // Set the "zero" bit in CPSR.
1505 switch (MI->getOpcode()) {
1506 default: break;
Bill Wendling38ae9972010-08-11 00:23:00 +00001507 case ARM::ADDri:
Bob Wilson3a951822010-09-15 17:12:08 +00001508 case ARM::ANDri:
1509 case ARM::t2ANDri:
Bill Wendling38ae9972010-08-11 00:23:00 +00001510 case ARM::SUBri:
1511 case ARM::t2ADDri:
Bill Wendlingad422712010-08-18 21:32:07 +00001512 case ARM::t2SUBri:
Evan Cheng3642e642010-11-17 08:06:50 +00001513 // Toggle the optional operand to CPSR.
1514 MI->getOperand(5).setReg(ARM::CPSR);
1515 MI->getOperand(5).setIsDef(true);
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001516 CmpInstr->eraseFromParent();
1517 return true;
1518 }
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +00001519
1520 return false;
1521}
Evan Cheng5f54ce32010-09-09 18:18:55 +00001522
Evan Chengc4af4632010-11-17 20:13:28 +00001523bool ARMBaseInstrInfo::FoldImmediate(MachineInstr *UseMI,
1524 MachineInstr *DefMI, unsigned Reg,
1525 MachineRegisterInfo *MRI) const {
1526 // Fold large immediates into add, sub, or, xor.
1527 unsigned DefOpc = DefMI->getOpcode();
1528 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
1529 return false;
1530 if (!DefMI->getOperand(1).isImm())
1531 // Could be t2MOVi32imm <ga:xx>
1532 return false;
1533
1534 if (!MRI->hasOneNonDBGUse(Reg))
1535 return false;
1536
1537 unsigned UseOpc = UseMI->getOpcode();
Evan Cheng5c71c7a2010-11-18 01:43:23 +00001538 unsigned NewUseOpc = 0;
Evan Chengc4af4632010-11-17 20:13:28 +00001539 uint32_t ImmVal = (uint32_t)DefMI->getOperand(1).getImm();
Evan Cheng5c71c7a2010-11-18 01:43:23 +00001540 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
Evan Chengc4af4632010-11-17 20:13:28 +00001541 bool Commute = false;
1542 switch (UseOpc) {
1543 default: return false;
1544 case ARM::SUBrr:
1545 case ARM::ADDrr:
1546 case ARM::ORRrr:
1547 case ARM::EORrr:
1548 case ARM::t2SUBrr:
1549 case ARM::t2ADDrr:
1550 case ARM::t2ORRrr:
1551 case ARM::t2EORrr: {
1552 Commute = UseMI->getOperand(2).getReg() != Reg;
1553 switch (UseOpc) {
1554 default: break;
1555 case ARM::SUBrr: {
1556 if (Commute)
1557 return false;
1558 ImmVal = -ImmVal;
1559 NewUseOpc = ARM::SUBri;
1560 // Fallthrough
1561 }
1562 case ARM::ADDrr:
1563 case ARM::ORRrr:
1564 case ARM::EORrr: {
1565 if (!ARM_AM::isSOImmTwoPartVal(ImmVal))
1566 return false;
1567 SOImmValV1 = (uint32_t)ARM_AM::getSOImmTwoPartFirst(ImmVal);
1568 SOImmValV2 = (uint32_t)ARM_AM::getSOImmTwoPartSecond(ImmVal);
1569 switch (UseOpc) {
1570 default: break;
1571 case ARM::ADDrr: NewUseOpc = ARM::ADDri; break;
1572 case ARM::ORRrr: NewUseOpc = ARM::ORRri; break;
1573 case ARM::EORrr: NewUseOpc = ARM::EORri; break;
1574 }
1575 break;
1576 }
1577 case ARM::t2SUBrr: {
1578 if (Commute)
1579 return false;
1580 ImmVal = -ImmVal;
1581 NewUseOpc = ARM::t2SUBri;
1582 // Fallthrough
1583 }
1584 case ARM::t2ADDrr:
1585 case ARM::t2ORRrr:
1586 case ARM::t2EORrr: {
1587 if (!ARM_AM::isT2SOImmTwoPartVal(ImmVal))
1588 return false;
1589 SOImmValV1 = (uint32_t)ARM_AM::getT2SOImmTwoPartFirst(ImmVal);
1590 SOImmValV2 = (uint32_t)ARM_AM::getT2SOImmTwoPartSecond(ImmVal);
1591 switch (UseOpc) {
1592 default: break;
1593 case ARM::t2ADDrr: NewUseOpc = ARM::t2ADDri; break;
1594 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri; break;
1595 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri; break;
1596 }
1597 break;
1598 }
1599 }
1600 }
1601 }
1602
1603 unsigned OpIdx = Commute ? 2 : 1;
1604 unsigned Reg1 = UseMI->getOperand(OpIdx).getReg();
1605 bool isKill = UseMI->getOperand(OpIdx).isKill();
1606 unsigned NewReg = MRI->createVirtualRegister(MRI->getRegClass(Reg));
1607 AddDefaultCC(AddDefaultPred(BuildMI(*UseMI->getParent(),
1608 *UseMI, UseMI->getDebugLoc(),
1609 get(NewUseOpc), NewReg)
1610 .addReg(Reg1, getKillRegState(isKill))
1611 .addImm(SOImmValV1)));
1612 UseMI->setDesc(get(NewUseOpc));
1613 UseMI->getOperand(1).setReg(NewReg);
1614 UseMI->getOperand(1).setIsKill();
1615 UseMI->getOperand(2).ChangeToImmediate(SOImmValV2);
1616 DefMI->eraseFromParent();
1617 return true;
1618}
1619
Evan Cheng5f54ce32010-09-09 18:18:55 +00001620unsigned
Evan Cheng8239daf2010-11-03 00:45:17 +00001621ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
1622 const MachineInstr *MI) const {
Evan Cheng3ef1c872010-09-10 01:29:16 +00001623 if (!ItinData || ItinData->isEmpty())
Evan Cheng5f54ce32010-09-09 18:18:55 +00001624 return 1;
1625
1626 const TargetInstrDesc &Desc = MI->getDesc();
1627 unsigned Class = Desc.getSchedClass();
Bob Wilson064312d2010-09-15 16:28:21 +00001628 unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
Evan Cheng5f54ce32010-09-09 18:18:55 +00001629 if (UOps)
1630 return UOps;
1631
1632 unsigned Opc = MI->getOpcode();
1633 switch (Opc) {
1634 default:
1635 llvm_unreachable("Unexpected multi-uops instruction!");
1636 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001637 case ARM::VLDMQIA:
1638 case ARM::VLDMQDB:
1639 case ARM::VSTMQIA:
1640 case ARM::VSTMQDB:
Evan Cheng5f54ce32010-09-09 18:18:55 +00001641 return 2;
1642
1643 // The number of uOps for load / store multiple are determined by the number
1644 // registers.
Bill Wendling73fe34a2010-11-16 01:16:36 +00001645 //
Evan Cheng3ef1c872010-09-10 01:29:16 +00001646 // On Cortex-A8, each pair of register loads / stores can be scheduled on the
1647 // same cycle. The scheduling for the first load / store must be done
1648 // separately by assuming the the address is not 64-bit aligned.
Bill Wendling73fe34a2010-11-16 01:16:36 +00001649 //
Evan Cheng3ef1c872010-09-10 01:29:16 +00001650 // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2). If the address
Bill Wendling73fe34a2010-11-16 01:16:36 +00001651 // is not 64-bit aligned, then AGU would take an extra cycle. For VFP / NEON
1652 // load / store multiple, the formula is (#reg / 2) + (#reg % 2) + 1.
1653 case ARM::VLDMDIA:
1654 case ARM::VLDMDDB:
1655 case ARM::VLDMDIA_UPD:
1656 case ARM::VLDMDDB_UPD:
1657 case ARM::VLDMSIA:
1658 case ARM::VLDMSDB:
1659 case ARM::VLDMSIA_UPD:
1660 case ARM::VLDMSDB_UPD:
1661 case ARM::VSTMDIA:
1662 case ARM::VSTMDDB:
1663 case ARM::VSTMDIA_UPD:
1664 case ARM::VSTMDDB_UPD:
1665 case ARM::VSTMSIA:
1666 case ARM::VSTMSDB:
1667 case ARM::VSTMSIA_UPD:
1668 case ARM::VSTMSDB_UPD: {
Evan Cheng5f54ce32010-09-09 18:18:55 +00001669 unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
1670 return (NumRegs / 2) + (NumRegs % 2) + 1;
1671 }
Bill Wendling73fe34a2010-11-16 01:16:36 +00001672
1673 case ARM::LDMIA_RET:
1674 case ARM::LDMIA:
1675 case ARM::LDMDA:
1676 case ARM::LDMDB:
1677 case ARM::LDMIB:
1678 case ARM::LDMIA_UPD:
1679 case ARM::LDMDA_UPD:
1680 case ARM::LDMDB_UPD:
1681 case ARM::LDMIB_UPD:
1682 case ARM::STMIA:
1683 case ARM::STMDA:
1684 case ARM::STMDB:
1685 case ARM::STMIB:
1686 case ARM::STMIA_UPD:
1687 case ARM::STMDA_UPD:
1688 case ARM::STMDB_UPD:
1689 case ARM::STMIB_UPD:
1690 case ARM::tLDMIA:
1691 case ARM::tLDMIA_UPD:
1692 case ARM::tSTMIA:
1693 case ARM::tSTMIA_UPD:
Evan Cheng5f54ce32010-09-09 18:18:55 +00001694 case ARM::tPOP_RET:
1695 case ARM::tPOP:
1696 case ARM::tPUSH:
Bill Wendling73fe34a2010-11-16 01:16:36 +00001697 case ARM::t2LDMIA_RET:
1698 case ARM::t2LDMIA:
1699 case ARM::t2LDMDB:
1700 case ARM::t2LDMIA_UPD:
1701 case ARM::t2LDMDB_UPD:
1702 case ARM::t2STMIA:
1703 case ARM::t2STMDB:
1704 case ARM::t2STMIA_UPD:
1705 case ARM::t2STMDB_UPD: {
Evan Cheng3ef1c872010-09-10 01:29:16 +00001706 unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands() + 1;
1707 if (Subtarget.isCortexA8()) {
Evan Cheng8239daf2010-11-03 00:45:17 +00001708 if (NumRegs < 4)
1709 return 2;
1710 // 4 registers would be issued: 2, 2.
1711 // 5 registers would be issued: 2, 2, 1.
1712 UOps = (NumRegs / 2);
1713 if (NumRegs % 2)
1714 ++UOps;
1715 return UOps;
Evan Cheng3ef1c872010-09-10 01:29:16 +00001716 } else if (Subtarget.isCortexA9()) {
1717 UOps = (NumRegs / 2);
1718 // If there are odd number of registers or if it's not 64-bit aligned,
1719 // then it takes an extra AGU (Address Generation Unit) cycle.
1720 if ((NumRegs % 2) ||
1721 !MI->hasOneMemOperand() ||
1722 (*MI->memoperands_begin())->getAlignment() < 8)
1723 ++UOps;
1724 return UOps;
1725 } else {
1726 // Assume the worst.
1727 return NumRegs;
Michael J. Spencer2bbb7692010-10-05 06:00:33 +00001728 }
Evan Cheng5f54ce32010-09-09 18:18:55 +00001729 }
1730 }
1731}
Evan Chenga0792de2010-10-06 06:27:31 +00001732
1733int
Evan Cheng344d9db2010-10-07 23:12:15 +00001734ARMBaseInstrInfo::getVLDMDefCycle(const InstrItineraryData *ItinData,
1735 const TargetInstrDesc &DefTID,
1736 unsigned DefClass,
1737 unsigned DefIdx, unsigned DefAlign) const {
1738 int RegNo = (int)(DefIdx+1) - DefTID.getNumOperands() + 1;
1739 if (RegNo <= 0)
1740 // Def is the address writeback.
1741 return ItinData->getOperandCycle(DefClass, DefIdx);
1742
1743 int DefCycle;
1744 if (Subtarget.isCortexA8()) {
1745 // (regno / 2) + (regno % 2) + 1
1746 DefCycle = RegNo / 2 + 1;
1747 if (RegNo % 2)
1748 ++DefCycle;
1749 } else if (Subtarget.isCortexA9()) {
1750 DefCycle = RegNo;
1751 bool isSLoad = false;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001752
Evan Cheng344d9db2010-10-07 23:12:15 +00001753 switch (DefTID.getOpcode()) {
1754 default: break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001755 case ARM::VLDMSIA:
1756 case ARM::VLDMSDB:
1757 case ARM::VLDMSIA_UPD:
1758 case ARM::VLDMSDB_UPD:
Evan Cheng344d9db2010-10-07 23:12:15 +00001759 isSLoad = true;
1760 break;
1761 }
Bill Wendling73fe34a2010-11-16 01:16:36 +00001762
Evan Cheng344d9db2010-10-07 23:12:15 +00001763 // If there are odd number of 'S' registers or if it's not 64-bit aligned,
1764 // then it takes an extra cycle.
1765 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
1766 ++DefCycle;
1767 } else {
1768 // Assume the worst.
1769 DefCycle = RegNo + 2;
1770 }
1771
1772 return DefCycle;
1773}
1774
1775int
1776ARMBaseInstrInfo::getLDMDefCycle(const InstrItineraryData *ItinData,
1777 const TargetInstrDesc &DefTID,
1778 unsigned DefClass,
1779 unsigned DefIdx, unsigned DefAlign) const {
1780 int RegNo = (int)(DefIdx+1) - DefTID.getNumOperands() + 1;
1781 if (RegNo <= 0)
1782 // Def is the address writeback.
1783 return ItinData->getOperandCycle(DefClass, DefIdx);
1784
1785 int DefCycle;
1786 if (Subtarget.isCortexA8()) {
1787 // 4 registers would be issued: 1, 2, 1.
1788 // 5 registers would be issued: 1, 2, 2.
1789 DefCycle = RegNo / 2;
1790 if (DefCycle < 1)
1791 DefCycle = 1;
1792 // Result latency is issue cycle + 2: E2.
1793 DefCycle += 2;
1794 } else if (Subtarget.isCortexA9()) {
1795 DefCycle = (RegNo / 2);
1796 // If there are odd number of registers or if it's not 64-bit aligned,
1797 // then it takes an extra AGU (Address Generation Unit) cycle.
1798 if ((RegNo % 2) || DefAlign < 8)
1799 ++DefCycle;
1800 // Result latency is AGU cycles + 2.
1801 DefCycle += 2;
1802 } else {
1803 // Assume the worst.
1804 DefCycle = RegNo + 2;
1805 }
1806
1807 return DefCycle;
1808}
1809
1810int
1811ARMBaseInstrInfo::getVSTMUseCycle(const InstrItineraryData *ItinData,
1812 const TargetInstrDesc &UseTID,
1813 unsigned UseClass,
1814 unsigned UseIdx, unsigned UseAlign) const {
1815 int RegNo = (int)(UseIdx+1) - UseTID.getNumOperands() + 1;
1816 if (RegNo <= 0)
1817 return ItinData->getOperandCycle(UseClass, UseIdx);
1818
1819 int UseCycle;
1820 if (Subtarget.isCortexA8()) {
1821 // (regno / 2) + (regno % 2) + 1
1822 UseCycle = RegNo / 2 + 1;
1823 if (RegNo % 2)
1824 ++UseCycle;
1825 } else if (Subtarget.isCortexA9()) {
1826 UseCycle = RegNo;
1827 bool isSStore = false;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001828
Evan Cheng344d9db2010-10-07 23:12:15 +00001829 switch (UseTID.getOpcode()) {
1830 default: break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001831 case ARM::VSTMSIA:
1832 case ARM::VSTMSDB:
1833 case ARM::VSTMSIA_UPD:
1834 case ARM::VSTMSDB_UPD:
Evan Cheng344d9db2010-10-07 23:12:15 +00001835 isSStore = true;
1836 break;
1837 }
Bill Wendling73fe34a2010-11-16 01:16:36 +00001838
Evan Cheng344d9db2010-10-07 23:12:15 +00001839 // If there are odd number of 'S' registers or if it's not 64-bit aligned,
1840 // then it takes an extra cycle.
1841 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
1842 ++UseCycle;
1843 } else {
1844 // Assume the worst.
1845 UseCycle = RegNo + 2;
1846 }
1847
1848 return UseCycle;
1849}
1850
1851int
1852ARMBaseInstrInfo::getSTMUseCycle(const InstrItineraryData *ItinData,
1853 const TargetInstrDesc &UseTID,
1854 unsigned UseClass,
1855 unsigned UseIdx, unsigned UseAlign) const {
1856 int RegNo = (int)(UseIdx+1) - UseTID.getNumOperands() + 1;
1857 if (RegNo <= 0)
1858 return ItinData->getOperandCycle(UseClass, UseIdx);
1859
1860 int UseCycle;
1861 if (Subtarget.isCortexA8()) {
1862 UseCycle = RegNo / 2;
1863 if (UseCycle < 2)
1864 UseCycle = 2;
1865 // Read in E3.
1866 UseCycle += 2;
1867 } else if (Subtarget.isCortexA9()) {
1868 UseCycle = (RegNo / 2);
1869 // If there are odd number of registers or if it's not 64-bit aligned,
1870 // then it takes an extra AGU (Address Generation Unit) cycle.
1871 if ((RegNo % 2) || UseAlign < 8)
1872 ++UseCycle;
1873 } else {
1874 // Assume the worst.
1875 UseCycle = 1;
1876 }
1877 return UseCycle;
1878}
1879
1880int
Evan Chenga0792de2010-10-06 06:27:31 +00001881ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
1882 const TargetInstrDesc &DefTID,
1883 unsigned DefIdx, unsigned DefAlign,
1884 const TargetInstrDesc &UseTID,
1885 unsigned UseIdx, unsigned UseAlign) const {
1886 unsigned DefClass = DefTID.getSchedClass();
1887 unsigned UseClass = UseTID.getSchedClass();
1888
1889 if (DefIdx < DefTID.getNumDefs() && UseIdx < UseTID.getNumOperands())
1890 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
1891
1892 // This may be a def / use of a variable_ops instruction, the operand
1893 // latency might be determinable dynamically. Let the target try to
1894 // figure it out.
Evan Cheng9e08ee52010-10-28 02:00:25 +00001895 int DefCycle = -1;
Evan Cheng7e2fe912010-10-28 06:47:08 +00001896 bool LdmBypass = false;
Evan Chenga0792de2010-10-06 06:27:31 +00001897 switch (DefTID.getOpcode()) {
1898 default:
1899 DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
1900 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001901
1902 case ARM::VLDMDIA:
1903 case ARM::VLDMDDB:
1904 case ARM::VLDMDIA_UPD:
1905 case ARM::VLDMDDB_UPD:
1906 case ARM::VLDMSIA:
1907 case ARM::VLDMSDB:
1908 case ARM::VLDMSIA_UPD:
1909 case ARM::VLDMSDB_UPD:
Evan Cheng344d9db2010-10-07 23:12:15 +00001910 DefCycle = getVLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign);
Evan Cheng5a50cee2010-10-07 01:50:48 +00001911 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001912
1913 case ARM::LDMIA_RET:
1914 case ARM::LDMIA:
1915 case ARM::LDMDA:
1916 case ARM::LDMDB:
1917 case ARM::LDMIB:
1918 case ARM::LDMIA_UPD:
1919 case ARM::LDMDA_UPD:
1920 case ARM::LDMDB_UPD:
1921 case ARM::LDMIB_UPD:
1922 case ARM::tLDMIA:
1923 case ARM::tLDMIA_UPD:
Evan Chenga0792de2010-10-06 06:27:31 +00001924 case ARM::tPUSH:
Bill Wendling73fe34a2010-11-16 01:16:36 +00001925 case ARM::t2LDMIA_RET:
1926 case ARM::t2LDMIA:
1927 case ARM::t2LDMDB:
1928 case ARM::t2LDMIA_UPD:
1929 case ARM::t2LDMDB_UPD:
Evan Chenga0792de2010-10-06 06:27:31 +00001930 LdmBypass = 1;
Evan Cheng344d9db2010-10-07 23:12:15 +00001931 DefCycle = getLDMDefCycle(ItinData, DefTID, DefClass, DefIdx, DefAlign);
1932 break;
Evan Chenga0792de2010-10-06 06:27:31 +00001933 }
Evan Chenga0792de2010-10-06 06:27:31 +00001934
1935 if (DefCycle == -1)
1936 // We can't seem to determine the result latency of the def, assume it's 2.
1937 DefCycle = 2;
1938
1939 int UseCycle = -1;
1940 switch (UseTID.getOpcode()) {
1941 default:
1942 UseCycle = ItinData->getOperandCycle(UseClass, UseIdx);
1943 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001944
1945 case ARM::VSTMDIA:
1946 case ARM::VSTMDDB:
1947 case ARM::VSTMDIA_UPD:
1948 case ARM::VSTMDDB_UPD:
1949 case ARM::VSTMSIA:
1950 case ARM::VSTMSDB:
1951 case ARM::VSTMSIA_UPD:
1952 case ARM::VSTMSDB_UPD:
Evan Cheng344d9db2010-10-07 23:12:15 +00001953 UseCycle = getVSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign);
Evan Cheng5a50cee2010-10-07 01:50:48 +00001954 break;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001955
1956 case ARM::STMIA:
1957 case ARM::STMDA:
1958 case ARM::STMDB:
1959 case ARM::STMIB:
1960 case ARM::STMIA_UPD:
1961 case ARM::STMDA_UPD:
1962 case ARM::STMDB_UPD:
1963 case ARM::STMIB_UPD:
1964 case ARM::tSTMIA:
1965 case ARM::tSTMIA_UPD:
Evan Chenga0792de2010-10-06 06:27:31 +00001966 case ARM::tPOP_RET:
1967 case ARM::tPOP:
Bill Wendling73fe34a2010-11-16 01:16:36 +00001968 case ARM::t2STMIA:
1969 case ARM::t2STMDB:
1970 case ARM::t2STMIA_UPD:
1971 case ARM::t2STMDB_UPD:
Evan Cheng344d9db2010-10-07 23:12:15 +00001972 UseCycle = getSTMUseCycle(ItinData, UseTID, UseClass, UseIdx, UseAlign);
Evan Cheng5a50cee2010-10-07 01:50:48 +00001973 break;
Evan Chenga0792de2010-10-06 06:27:31 +00001974 }
Evan Chenga0792de2010-10-06 06:27:31 +00001975
1976 if (UseCycle == -1)
1977 // Assume it's read in the first stage.
1978 UseCycle = 1;
1979
1980 UseCycle = DefCycle - UseCycle + 1;
1981 if (UseCycle > 0) {
1982 if (LdmBypass) {
1983 // It's a variable_ops instruction so we can't use DefIdx here. Just use
1984 // first def operand.
1985 if (ItinData->hasPipelineForwarding(DefClass, DefTID.getNumOperands()-1,
1986 UseClass, UseIdx))
1987 --UseCycle;
1988 } else if (ItinData->hasPipelineForwarding(DefClass, DefIdx,
Bill Wendling73fe34a2010-11-16 01:16:36 +00001989 UseClass, UseIdx)) {
Evan Chenga0792de2010-10-06 06:27:31 +00001990 --UseCycle;
Bill Wendling73fe34a2010-11-16 01:16:36 +00001991 }
Evan Chenga0792de2010-10-06 06:27:31 +00001992 }
1993
1994 return UseCycle;
1995}
1996
1997int
1998ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
1999 const MachineInstr *DefMI, unsigned DefIdx,
2000 const MachineInstr *UseMI, unsigned UseIdx) const {
2001 if (DefMI->isCopyLike() || DefMI->isInsertSubreg() ||
2002 DefMI->isRegSequence() || DefMI->isImplicitDef())
2003 return 1;
2004
2005 const TargetInstrDesc &DefTID = DefMI->getDesc();
2006 if (!ItinData || ItinData->isEmpty())
2007 return DefTID.mayLoad() ? 3 : 1;
2008
Evan Chengdd9dd6f2010-10-23 02:04:38 +00002009
Evan Chenga0792de2010-10-06 06:27:31 +00002010 const TargetInstrDesc &UseTID = UseMI->getDesc();
Evan Chengdd9dd6f2010-10-23 02:04:38 +00002011 const MachineOperand &DefMO = DefMI->getOperand(DefIdx);
Evan Chenge09206d2010-10-29 23:16:55 +00002012 if (DefMO.getReg() == ARM::CPSR) {
2013 if (DefMI->getOpcode() == ARM::FMSTAT) {
2014 // fpscr -> cpsr stalls over 20 cycles on A8 (and earlier?)
2015 return Subtarget.isCortexA9() ? 1 : 20;
2016 }
2017
Evan Chengdd9dd6f2010-10-23 02:04:38 +00002018 // CPSR set and branch can be paired in the same cycle.
Evan Chenge09206d2010-10-29 23:16:55 +00002019 if (UseTID.isBranch())
2020 return 0;
2021 }
Evan Chengdd9dd6f2010-10-23 02:04:38 +00002022
Evan Chenga0792de2010-10-06 06:27:31 +00002023 unsigned DefAlign = DefMI->hasOneMemOperand()
2024 ? (*DefMI->memoperands_begin())->getAlignment() : 0;
2025 unsigned UseAlign = UseMI->hasOneMemOperand()
2026 ? (*UseMI->memoperands_begin())->getAlignment() : 0;
Evan Cheng7e2fe912010-10-28 06:47:08 +00002027 int Latency = getOperandLatency(ItinData, DefTID, DefIdx, DefAlign,
2028 UseTID, UseIdx, UseAlign);
2029
2030 if (Latency > 1 &&
2031 (Subtarget.isCortexA8() || Subtarget.isCortexA9())) {
2032 // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
2033 // variants are one cycle cheaper.
2034 switch (DefTID.getOpcode()) {
2035 default: break;
2036 case ARM::LDRrs:
2037 case ARM::LDRBrs: {
2038 unsigned ShOpVal = DefMI->getOperand(3).getImm();
2039 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2040 if (ShImm == 0 ||
2041 (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
2042 --Latency;
2043 break;
2044 }
2045 case ARM::t2LDRs:
2046 case ARM::t2LDRBs:
2047 case ARM::t2LDRHs:
2048 case ARM::t2LDRSHs: {
2049 // Thumb2 mode: lsl only.
2050 unsigned ShAmt = DefMI->getOperand(3).getImm();
2051 if (ShAmt == 0 || ShAmt == 2)
2052 --Latency;
2053 break;
2054 }
2055 }
2056 }
2057
2058 return Latency;
Evan Chenga0792de2010-10-06 06:27:31 +00002059}
2060
2061int
2062ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
2063 SDNode *DefNode, unsigned DefIdx,
2064 SDNode *UseNode, unsigned UseIdx) const {
2065 if (!DefNode->isMachineOpcode())
2066 return 1;
2067
2068 const TargetInstrDesc &DefTID = get(DefNode->getMachineOpcode());
2069 if (!ItinData || ItinData->isEmpty())
2070 return DefTID.mayLoad() ? 3 : 1;
2071
Evan Cheng08975152010-10-29 18:09:28 +00002072 if (!UseNode->isMachineOpcode()) {
2073 int Latency = ItinData->getOperandCycle(DefTID.getSchedClass(), DefIdx);
2074 if (Subtarget.isCortexA9())
2075 return Latency <= 2 ? 1 : Latency - 1;
2076 else
2077 return Latency <= 3 ? 1 : Latency - 2;
2078 }
Evan Chenga0792de2010-10-06 06:27:31 +00002079
2080 const TargetInstrDesc &UseTID = get(UseNode->getMachineOpcode());
2081 const MachineSDNode *DefMN = dyn_cast<MachineSDNode>(DefNode);
2082 unsigned DefAlign = !DefMN->memoperands_empty()
2083 ? (*DefMN->memoperands_begin())->getAlignment() : 0;
2084 const MachineSDNode *UseMN = dyn_cast<MachineSDNode>(UseNode);
2085 unsigned UseAlign = !UseMN->memoperands_empty()
2086 ? (*UseMN->memoperands_begin())->getAlignment() : 0;
Evan Cheng7e2fe912010-10-28 06:47:08 +00002087 int Latency = getOperandLatency(ItinData, DefTID, DefIdx, DefAlign,
2088 UseTID, UseIdx, UseAlign);
2089
2090 if (Latency > 1 &&
2091 (Subtarget.isCortexA8() || Subtarget.isCortexA9())) {
2092 // FIXME: Shifter op hack: no shift (i.e. [r +/- r]) or [r + r << 2]
2093 // variants are one cycle cheaper.
2094 switch (DefTID.getOpcode()) {
2095 default: break;
2096 case ARM::LDRrs:
2097 case ARM::LDRBrs: {
2098 unsigned ShOpVal =
2099 cast<ConstantSDNode>(DefNode->getOperand(2))->getZExtValue();
2100 unsigned ShImm = ARM_AM::getAM2Offset(ShOpVal);
2101 if (ShImm == 0 ||
2102 (ShImm == 2 && ARM_AM::getAM2ShiftOpc(ShOpVal) == ARM_AM::lsl))
2103 --Latency;
2104 break;
2105 }
2106 case ARM::t2LDRs:
2107 case ARM::t2LDRBs:
2108 case ARM::t2LDRHs:
2109 case ARM::t2LDRSHs: {
2110 // Thumb2 mode: lsl only.
2111 unsigned ShAmt =
2112 cast<ConstantSDNode>(DefNode->getOperand(2))->getZExtValue();
2113 if (ShAmt == 0 || ShAmt == 2)
2114 --Latency;
2115 break;
2116 }
2117 }
2118 }
2119
2120 return Latency;
Evan Chenga0792de2010-10-06 06:27:31 +00002121}
Evan Cheng23128422010-10-19 18:58:51 +00002122
Evan Cheng8239daf2010-11-03 00:45:17 +00002123int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
2124 const MachineInstr *MI,
2125 unsigned *PredCost) const {
2126 if (MI->isCopyLike() || MI->isInsertSubreg() ||
2127 MI->isRegSequence() || MI->isImplicitDef())
2128 return 1;
2129
2130 if (!ItinData || ItinData->isEmpty())
2131 return 1;
2132
2133 const TargetInstrDesc &TID = MI->getDesc();
2134 unsigned Class = TID.getSchedClass();
2135 unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
2136 if (PredCost && TID.hasImplicitDefOfPhysReg(ARM::CPSR))
2137 // When predicated, CPSR is an additional source operand for CPSR updating
2138 // instructions, this apparently increases their latencies.
2139 *PredCost = 1;
2140 if (UOps)
2141 return ItinData->getStageLatency(Class);
2142 return getNumMicroOps(ItinData, MI);
2143}
2144
2145int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
2146 SDNode *Node) const {
2147 if (!Node->isMachineOpcode())
2148 return 1;
2149
2150 if (!ItinData || ItinData->isEmpty())
2151 return 1;
2152
2153 unsigned Opcode = Node->getMachineOpcode();
2154 switch (Opcode) {
2155 default:
2156 return ItinData->getStageLatency(get(Opcode).getSchedClass());
Bill Wendling73fe34a2010-11-16 01:16:36 +00002157 case ARM::VLDMQIA:
2158 case ARM::VLDMQDB:
2159 case ARM::VSTMQIA:
2160 case ARM::VSTMQDB:
Evan Cheng8239daf2010-11-03 00:45:17 +00002161 return 2;
Eric Christopher8b3ca622010-11-18 19:40:05 +00002162 }
Evan Cheng8239daf2010-11-03 00:45:17 +00002163}
2164
Evan Cheng23128422010-10-19 18:58:51 +00002165bool ARMBaseInstrInfo::
2166hasHighOperandLatency(const InstrItineraryData *ItinData,
2167 const MachineRegisterInfo *MRI,
2168 const MachineInstr *DefMI, unsigned DefIdx,
2169 const MachineInstr *UseMI, unsigned UseIdx) const {
2170 unsigned DDomain = DefMI->getDesc().TSFlags & ARMII::DomainMask;
2171 unsigned UDomain = UseMI->getDesc().TSFlags & ARMII::DomainMask;
2172 if (Subtarget.isCortexA8() &&
2173 (DDomain == ARMII::DomainVFP || UDomain == ARMII::DomainVFP))
2174 // CortexA8 VFP instructions are not pipelined.
2175 return true;
2176
2177 // Hoist VFP / NEON instructions with 4 or higher latency.
2178 int Latency = getOperandLatency(ItinData, DefMI, DefIdx, UseMI, UseIdx);
2179 if (Latency <= 3)
2180 return false;
2181 return DDomain == ARMII::DomainVFP || DDomain == ARMII::DomainNEON ||
2182 UDomain == ARMII::DomainVFP || UDomain == ARMII::DomainNEON;
2183}
Evan Chengc8141df2010-10-26 02:08:50 +00002184
2185bool ARMBaseInstrInfo::
2186hasLowDefLatency(const InstrItineraryData *ItinData,
2187 const MachineInstr *DefMI, unsigned DefIdx) const {
2188 if (!ItinData || ItinData->isEmpty())
2189 return false;
2190
2191 unsigned DDomain = DefMI->getDesc().TSFlags & ARMII::DomainMask;
2192 if (DDomain == ARMII::DomainGeneral) {
2193 unsigned DefClass = DefMI->getDesc().getSchedClass();
2194 int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
2195 return (DefCycle != -1 && DefCycle <= 2);
2196 }
2197 return false;
2198}