]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
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 LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
15 #define LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
17 #include "MCTargetDesc/ARMBaseInfo.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/SmallSet.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/Support/CodeGen.h"
22 #include "llvm/Target/TargetInstrInfo.h"
24 #define GET_INSTRINFO_HEADER
25 #include "ARMGenInstrInfo.inc"
29 class ARMBaseRegisterInfo
;
31 class ARMBaseInstrInfo
: public ARMGenInstrInfo
{
32 const ARMSubtarget
&Subtarget
;
35 // Can be only subclassed.
36 explicit ARMBaseInstrInfo(const ARMSubtarget
&STI
);
38 void expandLoadStackGuardBase(MachineBasicBlock::iterator MI
,
39 unsigned LoadImmOpc
, unsigned LoadOpc
,
40 Reloc::Model RM
) const;
42 /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
44 /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
45 /// the list is modeled as <Reg:SubReg, SubIdx>.
46 /// E.g., REG_SEQUENCE vreg1:sub1, sub0, vreg2, sub1 would produce
48 /// - vreg1:sub1, sub0
51 /// \returns true if it is possible to build such an input sequence
52 /// with the pair \p MI, \p DefIdx. False otherwise.
54 /// \pre MI.isRegSequenceLike().
55 bool getRegSequenceLikeInputs(
56 const MachineInstr
&MI
, unsigned DefIdx
,
57 SmallVectorImpl
<RegSubRegPairAndIdx
> &InputRegs
) const override
;
59 /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
61 /// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
62 /// E.g., EXTRACT_SUBREG vreg1:sub1, sub0, sub1 would produce:
63 /// - vreg1:sub1, sub0
65 /// \returns true if it is possible to build such an input sequence
66 /// with the pair \p MI, \p DefIdx. False otherwise.
68 /// \pre MI.isExtractSubregLike().
69 bool getExtractSubregLikeInputs(const MachineInstr
&MI
, unsigned DefIdx
,
70 RegSubRegPairAndIdx
&InputReg
) const override
;
72 /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
74 /// \p [out] BaseReg and \p [out] InsertedReg contain
75 /// the equivalent inputs of INSERT_SUBREG.
76 /// E.g., INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
77 /// - BaseReg: vreg0:sub0
78 /// - InsertedReg: vreg1:sub1, sub3
80 /// \returns true if it is possible to build such an input sequence
81 /// with the pair \p MI, \p DefIdx. False otherwise.
83 /// \pre MI.isInsertSubregLike().
85 getInsertSubregLikeInputs(const MachineInstr
&MI
, unsigned DefIdx
,
86 RegSubRegPair
&BaseReg
,
87 RegSubRegPairAndIdx
&InsertedReg
) const override
;
90 // Return whether the target has an explicit NOP encoding.
93 // Return the non-pre/post incrementing version of 'Opc'. Return 0
94 // if there is not such an opcode.
95 virtual unsigned getUnindexedOpcode(unsigned Opc
) const =0;
97 MachineInstr
*convertToThreeAddress(MachineFunction::iterator
&MFI
,
98 MachineBasicBlock::iterator
&MBBI
,
99 LiveVariables
*LV
) const override
;
101 virtual const ARMBaseRegisterInfo
&getRegisterInfo() const = 0;
102 const ARMSubtarget
&getSubtarget() const { return Subtarget
; }
104 ScheduleHazardRecognizer
*
105 CreateTargetHazardRecognizer(const TargetSubtargetInfo
*STI
,
106 const ScheduleDAG
*DAG
) const override
;
108 ScheduleHazardRecognizer
*
109 CreateTargetPostRAHazardRecognizer(const InstrItineraryData
*II
,
110 const ScheduleDAG
*DAG
) const override
;
113 bool AnalyzeBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*&TBB
,
114 MachineBasicBlock
*&FBB
,
115 SmallVectorImpl
<MachineOperand
> &Cond
,
116 bool AllowModify
= false) const override
;
117 unsigned RemoveBranch(MachineBasicBlock
&MBB
) const override
;
118 unsigned InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
119 MachineBasicBlock
*FBB
,
120 const SmallVectorImpl
<MachineOperand
> &Cond
,
121 DebugLoc DL
) const override
;
124 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const override
;
126 // Predication support.
127 bool isPredicated(const MachineInstr
*MI
) const override
;
129 ARMCC::CondCodes
getPredicate(const MachineInstr
*MI
) const {
130 int PIdx
= MI
->findFirstPredOperandIdx();
131 return PIdx
!= -1 ? (ARMCC::CondCodes
)MI
->getOperand(PIdx
).getImm()
135 bool PredicateInstruction(MachineInstr
*MI
,
136 const SmallVectorImpl
<MachineOperand
> &Pred
) const override
;
138 bool SubsumesPredicate(const SmallVectorImpl
<MachineOperand
> &Pred1
,
139 const SmallVectorImpl
<MachineOperand
> &Pred2
) const override
;
141 bool DefinesPredicate(MachineInstr
*MI
,
142 std::vector
<MachineOperand
> &Pred
) const override
;
144 bool isPredicable(MachineInstr
*MI
) const override
;
146 /// GetInstSize - Returns the size of the specified MachineInstr.
148 virtual unsigned GetInstSizeInBytes(const MachineInstr
* MI
) const;
150 unsigned isLoadFromStackSlot(const MachineInstr
*MI
,
151 int &FrameIndex
) const override
;
152 unsigned isStoreToStackSlot(const MachineInstr
*MI
,
153 int &FrameIndex
) const override
;
154 unsigned isLoadFromStackSlotPostFE(const MachineInstr
*MI
,
155 int &FrameIndex
) const override
;
156 unsigned isStoreToStackSlotPostFE(const MachineInstr
*MI
,
157 int &FrameIndex
) const override
;
159 void copyToCPSR(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
160 unsigned SrcReg
, bool KillSrc
,
161 const ARMSubtarget
&Subtarget
) const;
162 void copyFromCPSR(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
163 unsigned DestReg
, bool KillSrc
,
164 const ARMSubtarget
&Subtarget
) const;
166 void copyPhysReg(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
167 DebugLoc DL
, unsigned DestReg
, unsigned SrcReg
,
168 bool KillSrc
) const override
;
170 void storeRegToStackSlot(MachineBasicBlock
&MBB
,
171 MachineBasicBlock::iterator MBBI
,
172 unsigned SrcReg
, bool isKill
, int FrameIndex
,
173 const TargetRegisterClass
*RC
,
174 const TargetRegisterInfo
*TRI
) const override
;
176 void loadRegFromStackSlot(MachineBasicBlock
&MBB
,
177 MachineBasicBlock::iterator MBBI
,
178 unsigned DestReg
, int FrameIndex
,
179 const TargetRegisterClass
*RC
,
180 const TargetRegisterInfo
*TRI
) const override
;
182 bool expandPostRAPseudo(MachineBasicBlock::iterator MI
) const override
;
184 void reMaterialize(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MI
,
185 unsigned DestReg
, unsigned SubIdx
,
186 const MachineInstr
*Orig
,
187 const TargetRegisterInfo
&TRI
) const override
;
189 MachineInstr
*duplicate(MachineInstr
*Orig
,
190 MachineFunction
&MF
) const override
;
192 MachineInstr
*commuteInstruction(MachineInstr
*,
193 bool=false) const override
;
195 const MachineInstrBuilder
&AddDReg(MachineInstrBuilder
&MIB
, unsigned Reg
,
196 unsigned SubIdx
, unsigned State
,
197 const TargetRegisterInfo
*TRI
) const;
199 bool produceSameValue(const MachineInstr
*MI0
, const MachineInstr
*MI1
,
200 const MachineRegisterInfo
*MRI
) const override
;
202 /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
203 /// determine if two loads are loading from the same base address. It should
204 /// only return true if the base pointers are the same and the only
205 /// differences between the two addresses is the offset. It also returns the
206 /// offsets by reference.
207 bool areLoadsFromSameBasePtr(SDNode
*Load1
, SDNode
*Load2
, int64_t &Offset1
,
208 int64_t &Offset2
) const override
;
210 /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
211 /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
212 /// should be scheduled togther. On some targets if two loads are loading from
213 /// addresses in the same cache line, it's better if they are scheduled
214 /// together. This function takes two integers that represent the load offsets
215 /// from the common base address. It returns true if it decides it's desirable
216 /// to schedule the two loads together. "NumLoads" is the number of loads that
217 /// have already been scheduled after Load1.
218 bool shouldScheduleLoadsNear(SDNode
*Load1
, SDNode
*Load2
,
219 int64_t Offset1
, int64_t Offset2
,
220 unsigned NumLoads
) const override
;
222 bool isSchedulingBoundary(const MachineInstr
*MI
,
223 const MachineBasicBlock
*MBB
,
224 const MachineFunction
&MF
) const override
;
226 bool isProfitableToIfCvt(MachineBasicBlock
&MBB
,
227 unsigned NumCycles
, unsigned ExtraPredCycles
,
228 const BranchProbability
&Probability
) const override
;
230 bool isProfitableToIfCvt(MachineBasicBlock
&TMBB
, unsigned NumT
,
231 unsigned ExtraT
, MachineBasicBlock
&FMBB
,
232 unsigned NumF
, unsigned ExtraF
,
233 const BranchProbability
&Probability
) const override
;
235 bool isProfitableToDupForIfCvt(MachineBasicBlock
&MBB
, unsigned NumCycles
,
236 const BranchProbability
&Probability
) const override
{
237 return NumCycles
== 1;
240 bool isProfitableToUnpredicate(MachineBasicBlock
&TMBB
,
241 MachineBasicBlock
&FMBB
) const override
;
243 /// analyzeCompare - For a comparison instruction, return the source registers
244 /// in SrcReg and SrcReg2 if having two register operands, and the value it
245 /// compares against in CmpValue. Return true if the comparison instruction
247 bool analyzeCompare(const MachineInstr
*MI
, unsigned &SrcReg
,
248 unsigned &SrcReg2
, int &CmpMask
,
249 int &CmpValue
) const override
;
251 /// optimizeCompareInstr - Convert the instruction to set the zero flag so
252 /// that we can remove a "comparison with zero"; Remove a redundant CMP
253 /// instruction if the flags can be updated in the same way by an earlier
254 /// instruction such as SUB.
255 bool optimizeCompareInstr(MachineInstr
*CmpInstr
, unsigned SrcReg
,
256 unsigned SrcReg2
, int CmpMask
, int CmpValue
,
257 const MachineRegisterInfo
*MRI
) const override
;
259 bool analyzeSelect(const MachineInstr
*MI
,
260 SmallVectorImpl
<MachineOperand
> &Cond
,
261 unsigned &TrueOp
, unsigned &FalseOp
,
262 bool &Optimizable
) const override
;
264 MachineInstr
*optimizeSelect(MachineInstr
*MI
,
265 SmallPtrSetImpl
<MachineInstr
*> &SeenMIs
,
266 bool) const override
;
268 /// FoldImmediate - 'Reg' is known to be defined by a move immediate
269 /// instruction, try to fold the immediate into the use instruction.
270 bool FoldImmediate(MachineInstr
*UseMI
, MachineInstr
*DefMI
,
271 unsigned Reg
, MachineRegisterInfo
*MRI
) const override
;
273 unsigned getNumMicroOps(const InstrItineraryData
*ItinData
,
274 const MachineInstr
*MI
) const override
;
276 int getOperandLatency(const InstrItineraryData
*ItinData
,
277 const MachineInstr
*DefMI
, unsigned DefIdx
,
278 const MachineInstr
*UseMI
,
279 unsigned UseIdx
) const override
;
280 int getOperandLatency(const InstrItineraryData
*ItinData
,
281 SDNode
*DefNode
, unsigned DefIdx
,
282 SDNode
*UseNode
, unsigned UseIdx
) const override
;
284 /// VFP/NEON execution domains.
285 std::pair
<uint16_t, uint16_t>
286 getExecutionDomain(const MachineInstr
*MI
) const override
;
287 void setExecutionDomain(MachineInstr
*MI
, unsigned Domain
) const override
;
289 unsigned getPartialRegUpdateClearance(const MachineInstr
*, unsigned,
290 const TargetRegisterInfo
*) const override
;
291 void breakPartialRegDependency(MachineBasicBlock::iterator
, unsigned,
292 const TargetRegisterInfo
*TRI
) const override
;
294 /// Get the number of addresses by LDM or VLDM or zero for unknown.
295 unsigned getNumLDMAddresses(const MachineInstr
*MI
) const;
298 unsigned getInstBundleLength(const MachineInstr
*MI
) const;
300 int getVLDMDefCycle(const InstrItineraryData
*ItinData
,
301 const MCInstrDesc
&DefMCID
,
303 unsigned DefIdx
, unsigned DefAlign
) const;
304 int getLDMDefCycle(const InstrItineraryData
*ItinData
,
305 const MCInstrDesc
&DefMCID
,
307 unsigned DefIdx
, unsigned DefAlign
) const;
308 int getVSTMUseCycle(const InstrItineraryData
*ItinData
,
309 const MCInstrDesc
&UseMCID
,
311 unsigned UseIdx
, unsigned UseAlign
) const;
312 int getSTMUseCycle(const InstrItineraryData
*ItinData
,
313 const MCInstrDesc
&UseMCID
,
315 unsigned UseIdx
, unsigned UseAlign
) const;
316 int getOperandLatency(const InstrItineraryData
*ItinData
,
317 const MCInstrDesc
&DefMCID
,
318 unsigned DefIdx
, unsigned DefAlign
,
319 const MCInstrDesc
&UseMCID
,
320 unsigned UseIdx
, unsigned UseAlign
) const;
322 unsigned getPredicationCost(const MachineInstr
*MI
) const override
;
324 unsigned getInstrLatency(const InstrItineraryData
*ItinData
,
325 const MachineInstr
*MI
,
326 unsigned *PredCost
= nullptr) const override
;
328 int getInstrLatency(const InstrItineraryData
*ItinData
,
329 SDNode
*Node
) const override
;
331 bool hasHighOperandLatency(const InstrItineraryData
*ItinData
,
332 const MachineRegisterInfo
*MRI
,
333 const MachineInstr
*DefMI
, unsigned DefIdx
,
334 const MachineInstr
*UseMI
,
335 unsigned UseIdx
) const override
;
336 bool hasLowDefLatency(const InstrItineraryData
*ItinData
,
337 const MachineInstr
*DefMI
,
338 unsigned DefIdx
) const override
;
340 /// verifyInstruction - Perform target specific instruction verification.
341 bool verifyInstruction(const MachineInstr
*MI
,
342 StringRef
&ErrInfo
) const override
;
344 virtual void expandLoadStackGuard(MachineBasicBlock::iterator MI
,
345 Reloc::Model RM
) const = 0;
348 /// Modeling special VFP / NEON fp MLA / MLS hazards.
350 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
352 DenseMap
<unsigned, unsigned> MLxEntryMap
;
354 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
355 /// stalls when scheduled together with fp MLA / MLS opcodes.
356 SmallSet
<unsigned, 16> MLxHazardOpcodes
;
359 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
361 bool isFpMLxInstruction(unsigned Opcode
) const {
362 return MLxEntryMap
.count(Opcode
);
365 /// isFpMLxInstruction - This version also returns the multiply opcode and the
366 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
367 /// the MLX instructions with an extra lane operand.
368 bool isFpMLxInstruction(unsigned Opcode
, unsigned &MulOpc
,
369 unsigned &AddSubOpc
, bool &NegAcc
,
370 bool &HasLane
) const;
372 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
373 /// will cause stalls when scheduled after (within 4-cycle window) a fp
374 /// MLA / MLS instruction.
375 bool canCauseFpMLxStall(unsigned Opcode
) const {
376 return MLxHazardOpcodes
.count(Opcode
);
379 /// Returns true if the instruction has a shift by immediate that can be
380 /// executed in one cycle less.
381 bool isSwiftFastImmShift(const MachineInstr
*MI
) const;
385 const MachineInstrBuilder
&AddDefaultPred(const MachineInstrBuilder
&MIB
) {
386 return MIB
.addImm((int64_t)ARMCC::AL
).addReg(0);
390 const MachineInstrBuilder
&AddDefaultCC(const MachineInstrBuilder
&MIB
) {
391 return MIB
.addReg(0);
395 const MachineInstrBuilder
&AddDefaultT1CC(const MachineInstrBuilder
&MIB
,
396 bool isDead
= false) {
397 return MIB
.addReg(ARM::CPSR
, getDefRegState(true) | getDeadRegState(isDead
));
401 const MachineInstrBuilder
&AddNoT1CC(const MachineInstrBuilder
&MIB
) {
402 return MIB
.addReg(0);
406 bool isUncondBranchOpcode(int Opc
) {
407 return Opc
== ARM::B
|| Opc
== ARM::tB
|| Opc
== ARM::t2B
;
411 bool isCondBranchOpcode(int Opc
) {
412 return Opc
== ARM::Bcc
|| Opc
== ARM::tBcc
|| Opc
== ARM::t2Bcc
;
416 bool isJumpTableBranchOpcode(int Opc
) {
417 return Opc
== ARM::BR_JTr
|| Opc
== ARM::BR_JTm
|| Opc
== ARM::BR_JTadd
||
418 Opc
== ARM::tBR_JTr
|| Opc
== ARM::t2BR_JT
;
422 bool isIndirectBranchOpcode(int Opc
) {
423 return Opc
== ARM::BX
|| Opc
== ARM::MOVPCRX
|| Opc
== ARM::tBRIND
;
426 static inline bool isPopOpcode(int Opc
) {
427 return Opc
== ARM::tPOP_RET
|| Opc
== ARM::LDMIA_RET
||
428 Opc
== ARM::t2LDMIA_RET
|| Opc
== ARM::tPOP
|| Opc
== ARM::LDMIA_UPD
||
429 Opc
== ARM::t2LDMIA_UPD
|| Opc
== ARM::VLDMDIA_UPD
;
432 static inline bool isPushOpcode(int Opc
) {
433 return Opc
== ARM::tPUSH
|| Opc
== ARM::t2STMDB_UPD
||
434 Opc
== ARM::STMDB_UPD
|| Opc
== ARM::VSTMDDB_UPD
;
437 /// getInstrPredicate - If instruction is predicated, returns its predicate
438 /// condition, otherwise returns AL. It also returns the condition code
439 /// register by reference.
440 ARMCC::CondCodes
getInstrPredicate(const MachineInstr
*MI
, unsigned &PredReg
);
442 int getMatchingCondBranchOpcode(int Opc
);
444 /// Determine if MI can be folded into an ARM MOVCC instruction, and return the
445 /// opcode of the SSA instruction representing the conditional MI.
446 unsigned canFoldARMInstrIntoMOVCC(unsigned Reg
,
448 const MachineRegisterInfo
&MRI
);
450 /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether
451 /// the instruction is encoded with an 'S' bit is determined by the optional
452 /// CPSR def operand.
453 unsigned convertAddSubFlagsOpcode(unsigned OldOpc
);
455 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
456 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
458 void emitARMRegPlusImmediate(MachineBasicBlock
&MBB
,
459 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
460 unsigned DestReg
, unsigned BaseReg
, int NumBytes
,
461 ARMCC::CondCodes Pred
, unsigned PredReg
,
462 const ARMBaseInstrInfo
&TII
, unsigned MIFlags
= 0);
464 void emitT2RegPlusImmediate(MachineBasicBlock
&MBB
,
465 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
466 unsigned DestReg
, unsigned BaseReg
, int NumBytes
,
467 ARMCC::CondCodes Pred
, unsigned PredReg
,
468 const ARMBaseInstrInfo
&TII
, unsigned MIFlags
= 0);
469 void emitThumbRegPlusImmediate(MachineBasicBlock
&MBB
,
470 MachineBasicBlock::iterator
&MBBI
, DebugLoc dl
,
471 unsigned DestReg
, unsigned BaseReg
,
472 int NumBytes
, const TargetInstrInfo
&TII
,
473 const ARMBaseRegisterInfo
& MRI
,
474 unsigned MIFlags
= 0);
476 /// Tries to add registers to the reglist of a given base-updating
477 /// push/pop instruction to adjust the stack by an additional
478 /// NumBytes. This can save a few bytes per function in code-size, but
479 /// obviously generates more memory traffic. As such, it only takes
480 /// effect in functions being optimised for size.
481 bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget
&Subtarget
,
482 MachineFunction
&MF
, MachineInstr
*MI
,
485 /// rewriteARMFrameIndex / rewriteT2FrameIndex -
486 /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
487 /// offset could not be handled directly in MI, and return the left-over
488 /// portion by reference.
489 bool rewriteARMFrameIndex(MachineInstr
&MI
, unsigned FrameRegIdx
,
490 unsigned FrameReg
, int &Offset
,
491 const ARMBaseInstrInfo
&TII
);
493 bool rewriteT2FrameIndex(MachineInstr
&MI
, unsigned FrameRegIdx
,
494 unsigned FrameReg
, int &Offset
,
495 const ARMBaseInstrInfo
&TII
);
497 } // End llvm namespace