blob: 4f1c4539243136ee6cf411ab295b85a4f0e2a784 [file] [log] [blame]
Jim Grosbach31c24bf2009-11-07 22:00:39 +00001//===- ARMBaseInstrInfo.h - ARM Base 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#ifndef ARMBASEINSTRUCTIONINFO_H
15#define ARMBASEINSTRUCTIONINFO_H
16
David Goodwin334c2642009-07-08 16:09:28 +000017#include "ARM.h"
Anton Korobeynikovb8e9ac82009-07-16 23:26:06 +000018#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/Target/TargetInstrInfo.h"
David Goodwin334c2642009-07-08 16:09:28 +000020
21namespace llvm {
Chris Lattner4dbbe342010-07-20 21:17:29 +000022 class ARMSubtarget;
23 class ARMBaseRegisterInfo;
David Goodwin334c2642009-07-08 16:09:28 +000024
25/// ARMII - This namespace holds all of the target specific flags that
26/// instruction info tracks.
27///
28namespace ARMII {
29 enum {
30 //===------------------------------------------------------------------===//
31 // Instruction Flags.
32
33 //===------------------------------------------------------------------===//
34 // This four-bit field describes the addressing mode used.
35
36 AddrModeMask = 0xf,
37 AddrModeNone = 0,
38 AddrMode1 = 1,
39 AddrMode2 = 2,
40 AddrMode3 = 3,
41 AddrMode4 = 4,
42 AddrMode5 = 5,
43 AddrMode6 = 6,
44 AddrModeT1_1 = 7,
45 AddrModeT1_2 = 8,
46 AddrModeT1_4 = 9,
47 AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
48 AddrModeT2_i12 = 11,
49 AddrModeT2_i8 = 12,
50 AddrModeT2_so = 13,
51 AddrModeT2_pc = 14, // +/- i12 for pc relative data
52 AddrModeT2_i8s4 = 15, // i8 * 4
53
54 // Size* - Flags to keep track of the size of an instruction.
55 SizeShift = 4,
56 SizeMask = 7 << SizeShift,
57 SizeSpecial = 1, // 0 byte pseudo or special case.
58 Size8Bytes = 2,
59 Size4Bytes = 3,
60 Size2Bytes = 4,
61
Bob Wilsonbffb5b32010-03-13 07:34:35 +000062 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
63 // and store ops only. Generic "updating" flag is used for ld/st multiple.
David Goodwin334c2642009-07-08 16:09:28 +000064 IndexModeShift = 7,
65 IndexModeMask = 3 << IndexModeShift,
66 IndexModePre = 1,
67 IndexModePost = 2,
Bob Wilsonbffb5b32010-03-13 07:34:35 +000068 IndexModeUpd = 3,
David Goodwin334c2642009-07-08 16:09:28 +000069
70 //===------------------------------------------------------------------===//
71 // Instruction encoding formats.
72 //
73 FormShift = 9,
74 FormMask = 0x3f << FormShift,
75
76 // Pseudo instructions
77 Pseudo = 0 << FormShift,
78
79 // Multiply instructions
80 MulFrm = 1 << FormShift,
81
82 // Branch instructions
83 BrFrm = 2 << FormShift,
84 BrMiscFrm = 3 << FormShift,
85
86 // Data Processing instructions
87 DPFrm = 4 << FormShift,
88 DPSoRegFrm = 5 << FormShift,
89
90 // Load and Store
91 LdFrm = 6 << FormShift,
92 StFrm = 7 << FormShift,
93 LdMiscFrm = 8 << FormShift,
94 StMiscFrm = 9 << FormShift,
95 LdStMulFrm = 10 << FormShift,
96
Johnny Chen81f04d52010-03-19 17:39:00 +000097 LdStExFrm = 11 << FormShift,
Jim Grosbach5278eb82009-12-11 01:42:04 +000098
David Goodwin334c2642009-07-08 16:09:28 +000099 // Miscellaneous arithmetic instructions
Johnny Chen81f04d52010-03-19 17:39:00 +0000100 ArithMiscFrm = 12 << FormShift,
David Goodwin334c2642009-07-08 16:09:28 +0000101
102 // Extend instructions
Johnny Chen81f04d52010-03-19 17:39:00 +0000103 ExtFrm = 13 << FormShift,
David Goodwin334c2642009-07-08 16:09:28 +0000104
105 // VFP formats
Johnny Chen81f04d52010-03-19 17:39:00 +0000106 VFPUnaryFrm = 14 << FormShift,
107 VFPBinaryFrm = 15 << FormShift,
108 VFPConv1Frm = 16 << FormShift,
109 VFPConv2Frm = 17 << FormShift,
110 VFPConv3Frm = 18 << FormShift,
111 VFPConv4Frm = 19 << FormShift,
112 VFPConv5Frm = 20 << FormShift,
113 VFPLdStFrm = 21 << FormShift,
114 VFPLdStMulFrm = 22 << FormShift,
115 VFPMiscFrm = 23 << FormShift,
David Goodwin334c2642009-07-08 16:09:28 +0000116
117 // Thumb format
Johnny Chen81f04d52010-03-19 17:39:00 +0000118 ThumbFrm = 24 << FormShift,
David Goodwin334c2642009-07-08 16:09:28 +0000119
Bob Wilson26532632010-06-25 23:45:37 +0000120 // Miscelleaneous format
121 MiscFrm = 25 << FormShift,
122
Bob Wilson1a913ed2010-06-11 21:34:50 +0000123 // NEON formats
Bob Wilson184723d2010-06-25 23:56:05 +0000124 NGetLnFrm = 26 << FormShift,
125 NSetLnFrm = 27 << FormShift,
126 NDupFrm = 28 << FormShift,
Bob Wilson80d9bc02010-06-26 00:05:09 +0000127 NLdStFrm = 29 << FormShift,
128 N1RegModImmFrm= 30 << FormShift,
129 N2RegFrm = 31 << FormShift,
130 NVCVTFrm = 32 << FormShift,
131 NVDupLnFrm = 33 << FormShift,
132 N2RegVShLFrm = 34 << FormShift,
133 N2RegVShRFrm = 35 << FormShift,
134 N3RegFrm = 36 << FormShift,
135 N3RegVShFrm = 37 << FormShift,
136 NVExtFrm = 38 << FormShift,
137 NVMulSLFrm = 39 << FormShift,
138 NVTBLFrm = 40 << FormShift,
David Goodwin334c2642009-07-08 16:09:28 +0000139
140 //===------------------------------------------------------------------===//
141 // Misc flags.
142
143 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
144 // it doesn't have a Rn operand.
145 UnaryDP = 1 << 15,
146
147 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
148 // a 16-bit Thumb instruction if certain conditions are met.
149 Xform16Bit = 1 << 16,
150
151 //===------------------------------------------------------------------===//
Anton Korobeynikovf95215f2009-11-02 00:10:38 +0000152 // Code domain.
153 DomainShift = 17,
154 DomainMask = 3 << DomainShift,
155 DomainGeneral = 0 << DomainShift,
156 DomainVFP = 1 << DomainShift,
157 DomainNEON = 2 << DomainShift,
158
159 //===------------------------------------------------------------------===//
David Goodwin334c2642009-07-08 16:09:28 +0000160 // Field shifts - such shifts are used to set field while generating
161 // machine instructions.
162 M_BitShift = 5,
163 ShiftImmShift = 5,
164 ShiftShift = 7,
165 N_BitShift = 7,
166 ImmHiShift = 8,
167 SoRotImmShift = 8,
168 RegRsShift = 8,
169 ExtRotImmShift = 10,
170 RegRdLoShift = 12,
171 RegRdShift = 12,
172 RegRdHiShift = 16,
173 RegRnShift = 16,
174 S_BitShift = 20,
175 W_BitShift = 21,
176 AM3_I_BitShift = 22,
177 D_BitShift = 22,
178 U_BitShift = 23,
179 P_BitShift = 24,
180 I_BitShift = 25,
181 CondShift = 28
182 };
Anton Korobeynikov5cdc3a92009-11-24 00:44:37 +0000183
184 /// Target Operand Flag enum.
185 enum TOF {
186 //===------------------------------------------------------------------===//
187 // ARM Specific MachineOperand flags.
188
189 MO_NO_FLAG,
190
191 /// MO_LO16 - On a symbol operand, this represents a relocation containing
192 /// lower 16 bit of the address. Used only via movw instruction.
193 MO_LO16,
194
195 /// MO_HI16 - On a symbol operand, this represents a relocation containing
196 /// higher 16 bit of the address. Used only via movt instruction.
197 MO_HI16
198 };
Evan Chengb46aaa32009-07-19 19:16:46 +0000199}
200
David Goodwin334c2642009-07-08 16:09:28 +0000201class ARMBaseInstrInfo : public TargetInstrInfoImpl {
Chris Lattner4dbbe342010-07-20 21:17:29 +0000202 const ARMSubtarget &Subtarget;
David Goodwin334c2642009-07-08 16:09:28 +0000203protected:
204 // Can be only subclassed.
Anton Korobeynikovf95215f2009-11-02 00:10:38 +0000205 explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
David Goodwin334c2642009-07-08 16:09:28 +0000206public:
207 // Return the non-pre/post incrementing version of 'Opc'. Return 0
208 // if there is not such an opcode.
209 virtual unsigned getUnindexedOpcode(unsigned Opc) const =0;
210
David Goodwin334c2642009-07-08 16:09:28 +0000211 virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
212 MachineBasicBlock::iterator &MBBI,
213 LiveVariables *LV) const;
214
215 virtual const ARMBaseRegisterInfo &getRegisterInfo() const =0;
Anton Korobeynikovf95215f2009-11-02 00:10:38 +0000216 const ARMSubtarget &getSubtarget() const { return Subtarget; }
David Goodwin334c2642009-07-08 16:09:28 +0000217
Evan Cheng2457f2c2010-05-22 01:47:14 +0000218 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
219 MachineBasicBlock::iterator MI,
220 const std::vector<CalleeSavedInfo> &CSI,
221 const TargetRegisterInfo *TRI) const;
222
David Goodwin334c2642009-07-08 16:09:28 +0000223 // Branch analysis.
224 virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
225 MachineBasicBlock *&FBB,
226 SmallVectorImpl<MachineOperand> &Cond,
Chris Lattner20628752010-07-22 21:27:00 +0000227 bool AllowModify = false) const;
David Goodwin334c2642009-07-08 16:09:28 +0000228 virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
229 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
230 MachineBasicBlock *FBB,
Stuart Hastings3bf91252010-06-17 22:43:56 +0000231 const SmallVectorImpl<MachineOperand> &Cond,
232 DebugLoc DL) const;
David Goodwin334c2642009-07-08 16:09:28 +0000233
234 virtual
235 bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
236
237 // Predication support.
Evan Chengab331502009-07-10 01:38:27 +0000238 bool isPredicated(const MachineInstr *MI) const {
239 int PIdx = MI->findFirstPredOperandIdx();
240 return PIdx != -1 && MI->getOperand(PIdx).getImm() != ARMCC::AL;
241 }
David Goodwin334c2642009-07-08 16:09:28 +0000242
243 ARMCC::CondCodes getPredicate(const MachineInstr *MI) const {
244 int PIdx = MI->findFirstPredOperandIdx();
245 return PIdx != -1 ? (ARMCC::CondCodes)MI->getOperand(PIdx).getImm()
246 : ARMCC::AL;
247 }
248
249 virtual
250 bool PredicateInstruction(MachineInstr *MI,
251 const SmallVectorImpl<MachineOperand> &Pred) const;
252
253 virtual
254 bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
255 const SmallVectorImpl<MachineOperand> &Pred2) const;
256
257 virtual bool DefinesPredicate(MachineInstr *MI,
258 std::vector<MachineOperand> &Pred) const;
259
Evan Chengac0869d2009-11-21 06:21:52 +0000260 virtual bool isPredicable(MachineInstr *MI) const;
261
David Goodwin334c2642009-07-08 16:09:28 +0000262 /// GetInstSize - Returns the size of the specified MachineInstr.
263 ///
264 virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const;
265
David Goodwin334c2642009-07-08 16:09:28 +0000266 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
267 int &FrameIndex) const;
268 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
269 int &FrameIndex) const;
270
Jakob Stoklund Olesenac273662010-07-11 06:33:54 +0000271 virtual void copyPhysReg(MachineBasicBlock &MBB,
272 MachineBasicBlock::iterator I, DebugLoc DL,
273 unsigned DestReg, unsigned SrcReg,
274 bool KillSrc) const;
Evan Cheng5732ca02009-07-27 03:14:20 +0000275
David Goodwin334c2642009-07-08 16:09:28 +0000276 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
277 MachineBasicBlock::iterator MBBI,
278 unsigned SrcReg, bool isKill, int FrameIndex,
Evan Cheng746ad692010-05-06 19:06:44 +0000279 const TargetRegisterClass *RC,
280 const TargetRegisterInfo *TRI) const;
David Goodwin334c2642009-07-08 16:09:28 +0000281
David Goodwin334c2642009-07-08 16:09:28 +0000282 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
283 MachineBasicBlock::iterator MBBI,
284 unsigned DestReg, int FrameIndex,
Evan Cheng746ad692010-05-06 19:06:44 +0000285 const TargetRegisterClass *RC,
286 const TargetRegisterInfo *TRI) const;
David Goodwin334c2642009-07-08 16:09:28 +0000287
Evan Cheng62b50652010-04-26 07:39:25 +0000288 virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
Evan Cheng8601a3d2010-04-29 01:13:30 +0000289 int FrameIx,
Evan Cheng62b50652010-04-26 07:39:25 +0000290 uint64_t Offset,
291 const MDNode *MDPtr,
292 DebugLoc DL) const;
293
Evan Chengfdc83402009-11-08 00:15:23 +0000294 virtual void reMaterialize(MachineBasicBlock &MBB,
295 MachineBasicBlock::iterator MI,
296 unsigned DestReg, unsigned SubIdx,
Evan Chengd57cdd52009-11-14 02:55:43 +0000297 const MachineInstr *Orig,
Jakob Stoklund Olesen9edf7de2010-06-02 22:47:25 +0000298 const TargetRegisterInfo &TRI) const;
Evan Chengfdc83402009-11-08 00:15:23 +0000299
Jakob Stoklund Olesen30ac0462010-01-06 23:47:07 +0000300 MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
301
Evan Cheng506049f2010-03-03 01:44:33 +0000302 virtual bool produceSameValue(const MachineInstr *MI0,
303 const MachineInstr *MI1) const;
Evan Cheng86050dc2010-06-18 23:09:54 +0000304
Bill Wendling4b722102010-06-23 23:00:16 +0000305 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
306 /// determine if two loads are loading from the same base address. It should
307 /// only return true if the base pointers are the same and the only
308 /// differences between the two addresses is the offset. It also returns the
309 /// offsets by reference.
310 virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
311 int64_t &Offset1, int64_t &Offset2)const;
312
313 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
314 /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
315 /// be scheduled togther. On some targets if two loads are loading from
316 /// addresses in the same cache line, it's better if they are scheduled
317 /// together. This function takes two integers that represent the load offsets
318 /// from the common base address. It returns true if it decides it's desirable
319 /// to schedule the two loads together. "NumLoads" is the number of loads that
320 /// have already been scheduled after Load1.
321 virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
322 int64_t Offset1, int64_t Offset2,
323 unsigned NumLoads) const;
324
Evan Cheng86050dc2010-06-18 23:09:54 +0000325 virtual bool isSchedulingBoundary(const MachineInstr *MI,
326 const MachineBasicBlock *MBB,
327 const MachineFunction &MF) const;
Evan Cheng13151432010-06-25 22:42:03 +0000328
329 virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB,
330 unsigned NumInstrs) const;
331
332 virtual bool isProfitableToIfCvt(MachineBasicBlock &TMBB,unsigned NumT,
333 MachineBasicBlock &FMBB,unsigned NumF) const;
334
335 virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
336 unsigned NumInstrs) const {
337 return NumInstrs && NumInstrs == 1;
338 }
Bill Wendlinge4ddbdf2010-08-06 01:32:48 +0000339
340 /// isCompareInstr - If the machine instruction is a comparison instruction,
341 /// then return true. Also return the source register in SrcReg and the value
342 /// it compares against in CmpValue.
343 virtual bool isCompareInstr(const MachineInstr *MI, unsigned &SrcReg,
344 int &CmpValue) const;
345
346 /// convertToSetZeroFlag - Convert the instruction to set the zero flag so
347 /// that we can remove a "comparison with zero".
348 virtual bool convertToSetZeroFlag(MachineInstr *Instr,
349 MachineInstr *CmpInstr) const;
David Goodwin334c2642009-07-08 16:09:28 +0000350};
Evan Cheng6495f632009-07-28 05:48:47 +0000351
352static inline
353const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) {
354 return MIB.addImm((int64_t)ARMCC::AL).addReg(0);
David Goodwin334c2642009-07-08 16:09:28 +0000355}
356
Evan Cheng6495f632009-07-28 05:48:47 +0000357static inline
358const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) {
359 return MIB.addReg(0);
360}
361
362static inline
Evan Chenge8af1f92009-08-10 02:37:24 +0000363const MachineInstrBuilder &AddDefaultT1CC(const MachineInstrBuilder &MIB,
364 bool isDead = false) {
365 return MIB.addReg(ARM::CPSR, getDefRegState(true) | getDeadRegState(isDead));
Evan Cheng6495f632009-07-28 05:48:47 +0000366}
367
368static inline
Evan Chengbc9b7542009-08-15 07:59:10 +0000369const MachineInstrBuilder &AddNoT1CC(const MachineInstrBuilder &MIB) {
370 return MIB.addReg(0);
371}
372
373static inline
Evan Cheng6495f632009-07-28 05:48:47 +0000374bool isUncondBranchOpcode(int Opc) {
375 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
376}
377
378static inline
379bool isCondBranchOpcode(int Opc) {
380 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
381}
382
383static inline
384bool isJumpTableBranchOpcode(int Opc) {
385 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm || Opc == ARM::BR_JTadd ||
386 Opc == ARM::tBR_JTr || Opc == ARM::t2BR_JT;
387}
388
Bob Wilson8d4de5a2009-10-28 18:26:41 +0000389static inline
390bool isIndirectBranchOpcode(int Opc) {
Anton Korobeynikovce7bf1c2010-03-06 19:39:36 +0000391 return Opc == ARM::BRIND || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
Bob Wilson8d4de5a2009-10-28 18:26:41 +0000392}
393
Evan Cheng8fb90362009-08-08 03:20:32 +0000394/// getInstrPredicate - If instruction is predicated, returns its predicate
395/// condition, otherwise returns AL. It also returns the condition code
396/// register by reference.
Evan Cheng5adb66a2009-09-28 09:14:39 +0000397ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg);
Evan Cheng8fb90362009-08-08 03:20:32 +0000398
Evan Cheng6495f632009-07-28 05:48:47 +0000399int getMatchingCondBranchOpcode(int Opc);
400
401/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
402/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
403/// code.
404void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
405 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
406 unsigned DestReg, unsigned BaseReg, int NumBytes,
407 ARMCC::CondCodes Pred, unsigned PredReg,
408 const ARMBaseInstrInfo &TII);
409
410void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
411 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
412 unsigned DestReg, unsigned BaseReg, int NumBytes,
413 ARMCC::CondCodes Pred, unsigned PredReg,
414 const ARMBaseInstrInfo &TII);
415
416
Jim Grosbach764ab522009-08-11 15:33:49 +0000417/// rewriteARMFrameIndex / rewriteT2FrameIndex -
Evan Chengcdbb3f52009-08-27 01:23:50 +0000418/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
419/// offset could not be handled directly in MI, and return the left-over
420/// portion by reference.
421bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
422 unsigned FrameReg, int &Offset,
423 const ARMBaseInstrInfo &TII);
Evan Cheng6495f632009-07-28 05:48:47 +0000424
Evan Chengcdbb3f52009-08-27 01:23:50 +0000425bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
426 unsigned FrameReg, int &Offset,
427 const ARMBaseInstrInfo &TII);
Evan Cheng6495f632009-07-28 05:48:47 +0000428
429} // End llvm namespace
430
David Goodwin334c2642009-07-08 16:09:28 +0000431#endif