1 //===- ARMBaseInstrInfo.h - ARM Base Instruction Information ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Base ARM implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #ifndef ARMBASEINSTRUCTIONINFO_H
15 #define ARMBASEINSTRUCTIONINFO_H
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/Target/TargetInstrInfo.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallSet.h"
23 #define GET_INSTRINFO_HEADER
24 #include "ARMGenInstrInfo.inc"
28 class ARMBaseRegisterInfo
;
30 /// ARMII - This namespace holds all of the target specific flags that
31 /// instruction info tracks.
35 //===------------------------------------------------------------------===//
38 //===------------------------------------------------------------------===//
39 // This four-bit field describes the addressing mode used.
40 AddrModeMask
= 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
42 // Size* - Flags to keep track of the size of an instruction.
44 SizeMask
= 7 << SizeShift
,
45 SizeSpecial
= 1, // 0 byte pseudo or special case.
50 // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
51 // and store ops only. Generic "updating" flag is used for ld/st multiple.
52 // The index mode enums are declared in ARMBaseInfo.h
54 IndexModeMask
= 3 << IndexModeShift
,
56 //===------------------------------------------------------------------===//
57 // Instruction encoding formats.
60 FormMask
= 0x3f << FormShift
,
62 // Pseudo instructions
63 Pseudo
= 0 << FormShift
,
65 // Multiply instructions
66 MulFrm
= 1 << FormShift
,
68 // Branch instructions
69 BrFrm
= 2 << FormShift
,
70 BrMiscFrm
= 3 << FormShift
,
72 // Data Processing instructions
73 DPFrm
= 4 << FormShift
,
74 DPSoRegFrm
= 5 << FormShift
,
77 LdFrm
= 6 << FormShift
,
78 StFrm
= 7 << FormShift
,
79 LdMiscFrm
= 8 << FormShift
,
80 StMiscFrm
= 9 << FormShift
,
81 LdStMulFrm
= 10 << FormShift
,
83 LdStExFrm
= 11 << FormShift
,
85 // Miscellaneous arithmetic instructions
86 ArithMiscFrm
= 12 << FormShift
,
87 SatFrm
= 13 << FormShift
,
89 // Extend instructions
90 ExtFrm
= 14 << FormShift
,
93 VFPUnaryFrm
= 15 << FormShift
,
94 VFPBinaryFrm
= 16 << FormShift
,
95 VFPConv1Frm
= 17 << FormShift
,
96 VFPConv2Frm
= 18 << FormShift
,
97 VFPConv3Frm
= 19 << FormShift
,
98 VFPConv4Frm
= 20 << FormShift
,
99 VFPConv5Frm
= 21 << FormShift
,
100 VFPLdStFrm
= 22 << FormShift
,
101 VFPLdStMulFrm
= 23 << FormShift
,
102 VFPMiscFrm
= 24 << FormShift
,
105 ThumbFrm
= 25 << FormShift
,
107 // Miscelleaneous format
108 MiscFrm
= 26 << FormShift
,
111 NGetLnFrm
= 27 << FormShift
,
112 NSetLnFrm
= 28 << FormShift
,
113 NDupFrm
= 29 << FormShift
,
114 NLdStFrm
= 30 << FormShift
,
115 N1RegModImmFrm
= 31 << FormShift
,
116 N2RegFrm
= 32 << FormShift
,
117 NVCVTFrm
= 33 << FormShift
,
118 NVDupLnFrm
= 34 << FormShift
,
119 N2RegVShLFrm
= 35 << FormShift
,
120 N2RegVShRFrm
= 36 << FormShift
,
121 N3RegFrm
= 37 << FormShift
,
122 N3RegVShFrm
= 38 << FormShift
,
123 NVExtFrm
= 39 << FormShift
,
124 NVMulSLFrm
= 40 << FormShift
,
125 NVTBLFrm
= 41 << FormShift
,
127 //===------------------------------------------------------------------===//
130 // UnaryDP - Indicates this is a unary data processing instruction, i.e.
131 // it doesn't have a Rn operand.
134 // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
135 // a 16-bit Thumb instruction if certain conditions are met.
136 Xform16Bit
= 1 << 17,
138 //===------------------------------------------------------------------===//
141 DomainMask
= 7 << DomainShift
,
142 DomainGeneral
= 0 << DomainShift
,
143 DomainVFP
= 1 << DomainShift
,
144 DomainNEON
= 2 << DomainShift
,
145 DomainNEONA8
= 4 << DomainShift
,
147 //===------------------------------------------------------------------===//
148 // Field shifts - such shifts are used to set field while generating
149 // machine instructions.
151 // FIXME: This list will need adjusting/fixing as the MC code emitter
152 // takes shape and the ARMCodeEmitter.cpp bits go away.
178 class ARMBaseInstrInfo
: public ARMGenInstrInfo
{
179 const ARMSubtarget
&Subtarget
;
182 // Can be only subclassed.
183 explicit ARMBaseInstrInfo(const ARMSubtarget
&STI
);
186 // Return the non-pre/post incrementing version of 'Opc'. Return 0
187 // if there is not such an opcode.
188 virtual unsigned getUnindexedOpcode(unsigned Opc
) const =0;
190 virtual MachineInstr
*convertToThreeAddress(MachineFunction::iterator
&MFI
,
191 MachineBasicBlock::iterator
&MBBI
,
192 LiveVariables
*LV
) const;
194 virtual const ARMBaseRegisterInfo
&getRegisterInfo() const =0;
195 const ARMSubtarget
&getSubtarget() const { return Subtarget
; }
197 ScheduleHazardRecognizer
*
198 CreateTargetHazardRecognizer(const TargetMachine
*TM
,
199 const ScheduleDAG
*DAG
) const;
201 ScheduleHazardRecognizer
*
202 CreateTargetPostRAHazardRecognizer(const InstrItineraryData
*II
,
203 const ScheduleDAG
*DAG
) const;
206 virtual bool AnalyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
207 MachineBasicBlock
*&FBB
,
208 SmallVectorImpl
<MachineOperand
> &Cond
,
209 bool AllowModify
= false) const;
210 virtual unsigned RemoveBranch(MachineBasicBlock
&MBB
) const;
211 virtual unsigned InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
212 MachineBasicBlock
*FBB
,
213 const SmallVectorImpl
<MachineOperand
> &Cond
,
217 bool ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const;
219 // Predication support.
220 bool isPredicated(const MachineInstr
*MI
) const {
221 int PIdx
= MI
->findFirstPredOperandIdx();
222 return PIdx
!= -1 && MI
->getOperand(PIdx
).getImm() != ARMCC::AL
;
225 ARMCC::CondCodes
getPredicate(const MachineInstr
*MI
) const {
226 int PIdx
= MI
->findFirstPredOperandIdx();
227 return PIdx
!= -1 ? (ARMCC::CondCodes
)MI
->getOperand(PIdx
).getImm()
232 bool PredicateInstruction(MachineInstr
*MI
,
233 const SmallVectorImpl
<MachineOperand
> &Pred
) const;
236 bool SubsumesPredicate(const SmallVectorImpl
<MachineOperand
> &Pred1
,
237 const SmallVectorImpl
<MachineOperand
> &Pred2
) const;
239 virtual bool DefinesPredicate(MachineInstr
*MI
,
240 std::vector
<MachineOperand
> &Pred
) const;
242 virtual bool isPredicable(MachineInstr
*MI
) const;
244 /// GetInstSize - Returns the size of the specified MachineInstr.
246 virtual unsigned GetInstSizeInBytes(const MachineInstr
* MI
) const;
248 virtual unsigned isLoadFromStackSlot(const MachineInstr
*MI
,
249 int &FrameIndex
) const;
250 virtual unsigned isStoreToStackSlot(const MachineInstr
*MI
,
251 int &FrameIndex
) const;
253 virtual void copyPhysReg(MachineBasicBlock
&MBB
,
254 MachineBasicBlock::iterator I
, DebugLoc DL
,
255 unsigned DestReg
, unsigned SrcReg
,
258 virtual void storeRegToStackSlot(MachineBasicBlock
&MBB
,
259 MachineBasicBlock::iterator MBBI
,
260 unsigned SrcReg
, bool isKill
, int FrameIndex
,
261 const TargetRegisterClass
*RC
,
262 const TargetRegisterInfo
*TRI
) const;
264 virtual void loadRegFromStackSlot(MachineBasicBlock
&MBB
,
265 MachineBasicBlock::iterator MBBI
,
266 unsigned DestReg
, int FrameIndex
,
267 const TargetRegisterClass
*RC
,
268 const TargetRegisterInfo
*TRI
) const;
270 virtual MachineInstr
*emitFrameIndexDebugValue(MachineFunction
&MF
,
276 virtual void reMaterialize(MachineBasicBlock
&MBB
,
277 MachineBasicBlock::iterator MI
,
278 unsigned DestReg
, unsigned SubIdx
,
279 const MachineInstr
*Orig
,
280 const TargetRegisterInfo
&TRI
) const;
282 MachineInstr
*duplicate(MachineInstr
*Orig
, MachineFunction
&MF
) const;
284 virtual bool produceSameValue(const MachineInstr
*MI0
,
285 const MachineInstr
*MI1
,
286 const MachineRegisterInfo
*MRI
) const;
288 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
289 /// determine if two loads are loading from the same base address. It should
290 /// only return true if the base pointers are the same and the only
291 /// differences between the two addresses is the offset. It also returns the
292 /// offsets by reference.
293 virtual bool areLoadsFromSameBasePtr(SDNode
*Load1
, SDNode
*Load2
,
294 int64_t &Offset1
, int64_t &Offset2
)const;
296 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
297 /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
298 /// should be scheduled togther. On some targets if two loads are loading from
299 /// addresses in the same cache line, it's better if they are scheduled
300 /// together. This function takes two integers that represent the load offsets
301 /// from the common base address. It returns true if it decides it's desirable
302 /// to schedule the two loads together. "NumLoads" is the number of loads that
303 /// have already been scheduled after Load1.
304 virtual bool shouldScheduleLoadsNear(SDNode
*Load1
, SDNode
*Load2
,
305 int64_t Offset1
, int64_t Offset2
,
306 unsigned NumLoads
) const;
308 virtual bool isSchedulingBoundary(const MachineInstr
*MI
,
309 const MachineBasicBlock
*MBB
,
310 const MachineFunction
&MF
) const;
312 virtual bool isProfitableToIfCvt(MachineBasicBlock
&MBB
,
313 unsigned NumCycles
, unsigned ExtraPredCycles
,
314 const BranchProbability
&Probability
) const;
316 virtual bool isProfitableToIfCvt(MachineBasicBlock
&TMBB
,
317 unsigned NumT
, unsigned ExtraT
,
318 MachineBasicBlock
&FMBB
,
319 unsigned NumF
, unsigned ExtraF
,
320 const BranchProbability
&Probability
) const;
322 virtual bool isProfitableToDupForIfCvt(MachineBasicBlock
&MBB
,
324 const BranchProbability
325 &Probability
) const {
326 return NumCycles
== 1;
329 /// AnalyzeCompare - For a comparison instruction, return the source register
330 /// in SrcReg and the value it compares against in CmpValue. Return true if
331 /// the comparison instruction can be analyzed.
332 virtual bool AnalyzeCompare(const MachineInstr
*MI
, unsigned &SrcReg
,
333 int &CmpMask
, int &CmpValue
) const;
335 /// OptimizeCompareInstr - Convert the instruction to set the zero flag so
336 /// that we can remove a "comparison with zero".
337 virtual bool OptimizeCompareInstr(MachineInstr
*CmpInstr
, unsigned SrcReg
,
338 int CmpMask
, int CmpValue
,
339 const MachineRegisterInfo
*MRI
) const;
341 /// FoldImmediate - 'Reg' is known to be defined by a move immediate
342 /// instruction, try to fold the immediate into the use instruction.
343 virtual bool FoldImmediate(MachineInstr
*UseMI
, MachineInstr
*DefMI
,
344 unsigned Reg
, MachineRegisterInfo
*MRI
) const;
346 virtual unsigned getNumMicroOps(const InstrItineraryData
*ItinData
,
347 const MachineInstr
*MI
) const;
350 int getOperandLatency(const InstrItineraryData
*ItinData
,
351 const MachineInstr
*DefMI
, unsigned DefIdx
,
352 const MachineInstr
*UseMI
, unsigned UseIdx
) const;
354 int getOperandLatency(const InstrItineraryData
*ItinData
,
355 SDNode
*DefNode
, unsigned DefIdx
,
356 SDNode
*UseNode
, unsigned UseIdx
) const;
358 int getVLDMDefCycle(const InstrItineraryData
*ItinData
,
359 const MCInstrDesc
&DefMCID
,
361 unsigned DefIdx
, unsigned DefAlign
) const;
362 int getLDMDefCycle(const InstrItineraryData
*ItinData
,
363 const MCInstrDesc
&DefMCID
,
365 unsigned DefIdx
, unsigned DefAlign
) const;
366 int getVSTMUseCycle(const InstrItineraryData
*ItinData
,
367 const MCInstrDesc
&UseMCID
,
369 unsigned UseIdx
, unsigned UseAlign
) const;
370 int getSTMUseCycle(const InstrItineraryData
*ItinData
,
371 const MCInstrDesc
&UseMCID
,
373 unsigned UseIdx
, unsigned UseAlign
) const;
374 int getOperandLatency(const InstrItineraryData
*ItinData
,
375 const MCInstrDesc
&DefMCID
,
376 unsigned DefIdx
, unsigned DefAlign
,
377 const MCInstrDesc
&UseMCID
,
378 unsigned UseIdx
, unsigned UseAlign
) const;
380 int getInstrLatency(const InstrItineraryData
*ItinData
,
381 const MachineInstr
*MI
, unsigned *PredCost
= 0) const;
383 int getInstrLatency(const InstrItineraryData
*ItinData
,
386 bool hasHighOperandLatency(const InstrItineraryData
*ItinData
,
387 const MachineRegisterInfo
*MRI
,
388 const MachineInstr
*DefMI
, unsigned DefIdx
,
389 const MachineInstr
*UseMI
, unsigned UseIdx
) const;
390 bool hasLowDefLatency(const InstrItineraryData
*ItinData
,
391 const MachineInstr
*DefMI
, unsigned DefIdx
) const;
394 /// Modeling special VFP / NEON fp MLA / MLS hazards.
396 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
398 DenseMap
<unsigned, unsigned> MLxEntryMap
;
400 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
401 /// stalls when scheduled together with fp MLA / MLS opcodes.
402 SmallSet
<unsigned, 16> MLxHazardOpcodes
;
405 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
407 bool isFpMLxInstruction(unsigned Opcode
) const {
408 return MLxEntryMap
.count(Opcode
);
411 /// isFpMLxInstruction - This version also returns the multiply opcode and the
412 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
413 /// the MLX instructions with an extra lane operand.
414 bool isFpMLxInstruction(unsigned Opcode
, unsigned &MulOpc
,
415 unsigned &AddSubOpc
, bool &NegAcc
,
416 bool &HasLane
) const;
418 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
419 /// will cause stalls when scheduled after (within 4-cycle window) a fp
420 /// MLA / MLS instruction.
421 bool canCauseFpMLxStall(unsigned Opcode
) const {
422 return MLxHazardOpcodes
.count(Opcode
);
427 const MachineInstrBuilder
&AddDefaultPred(const MachineInstrBuilder
&MIB
) {
428 return MIB
.addImm((int64_t)ARMCC::AL
).addReg(0);
432 const MachineInstrBuilder
&AddDefaultCC(const MachineInstrBuilder
&MIB
) {
433 return MIB
.addReg(0);
437 const MachineInstrBuilder
&AddDefaultT1CC(const MachineInstrBuilder
&MIB
,
438 bool isDead
= false) {
439 return MIB
.addReg(ARM::CPSR
, getDefRegState(true) | getDeadRegState(isDead
));
443 const MachineInstrBuilder
&AddNoT1CC(const MachineInstrBuilder
&MIB
) {
444 return MIB
.addReg(0);
448 bool isUncondBranchOpcode(int Opc
) {
449 return Opc
== ARM::B
|| Opc
== ARM::tB
|| Opc
== ARM::t2B
;
453 bool isCondBranchOpcode(int Opc
) {
454 return Opc
== ARM::Bcc
|| Opc
== ARM::tBcc
|| Opc
== ARM::t2Bcc
;
458 bool isJumpTableBranchOpcode(int Opc
) {
459 return Opc
== ARM::BR_JTr
|| Opc
== ARM::BR_JTm
|| Opc
== ARM::BR_JTadd
||
460 Opc
== ARM::tBR_JTr
|| Opc
== ARM::t2BR_JT
;
464 bool isIndirectBranchOpcode(int Opc
) {
465 return Opc
== ARM::BX
|| Opc
== ARM::MOVPCRX
|| Opc
== ARM::tBRIND
;
468 /// getInstrPredicate - If instruction is predicated, returns its predicate
469 /// condition, otherwise returns AL. It also returns the condition code
470 /// register by reference.
471 ARMCC::CondCodes
getInstrPredicate(const MachineInstr
*MI
, unsigned &PredReg
);
473 int getMatchingCondBranchOpcode(int Opc
);
475 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
476 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
478 void emitARMRegPlusImmediate(MachineBasicBlock
&MBB
,
479 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
480 unsigned DestReg
, unsigned BaseReg
, int NumBytes
,
481 ARMCC::CondCodes Pred
, unsigned PredReg
,
482 const ARMBaseInstrInfo
&TII
, unsigned MIFlags
= 0);
484 void emitT2RegPlusImmediate(MachineBasicBlock
&MBB
,
485 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
486 unsigned DestReg
, unsigned BaseReg
, int NumBytes
,
487 ARMCC::CondCodes Pred
, unsigned PredReg
,
488 const ARMBaseInstrInfo
&TII
, unsigned MIFlags
= 0);
489 void emitThumbRegPlusImmediate(MachineBasicBlock
&MBB
,
490 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
491 unsigned DestReg
, unsigned BaseReg
,
492 int NumBytes
, const TargetInstrInfo
&TII
,
493 const ARMBaseRegisterInfo
& MRI
,
494 unsigned MIFlags
= 0);
497 /// rewriteARMFrameIndex / rewriteT2FrameIndex -
498 /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
499 /// offset could not be handled directly in MI, and return the left-over
500 /// portion by reference.
501 bool rewriteARMFrameIndex(MachineInstr
&MI
, unsigned FrameRegIdx
,
502 unsigned FrameReg
, int &Offset
,
503 const ARMBaseInstrInfo
&TII
);
505 bool rewriteT2FrameIndex(MachineInstr
&MI
, unsigned FrameRegIdx
,
506 unsigned FrameReg
, int &Offset
,
507 const ARMBaseInstrInfo
&TII
);
509 } // End llvm namespace