Line data Source code
1 : //===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file contains the Base ARM implementation of the TargetInstrInfo class.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
15 : #define LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
16 :
17 : #include "MCTargetDesc/ARMBaseInfo.h"
18 : #include "llvm/ADT/DenseMap.h"
19 : #include "llvm/ADT/SmallSet.h"
20 : #include "llvm/CodeGen/MachineBasicBlock.h"
21 : #include "llvm/CodeGen/MachineInstr.h"
22 : #include "llvm/CodeGen/MachineInstrBuilder.h"
23 : #include "llvm/CodeGen/MachineOperand.h"
24 : #include "llvm/CodeGen/TargetInstrInfo.h"
25 : #include <array>
26 : #include <cstdint>
27 :
28 : #define GET_INSTRINFO_HEADER
29 : #include "ARMGenInstrInfo.inc"
30 :
31 : namespace llvm {
32 :
33 : class ARMBaseRegisterInfo;
34 : class ARMSubtarget;
35 :
36 : class ARMBaseInstrInfo : public ARMGenInstrInfo {
37 : const ARMSubtarget &Subtarget;
38 :
39 : protected:
40 : // Can be only subclassed.
41 : explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
42 :
43 : void expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
44 : unsigned LoadImmOpc, unsigned LoadOpc) const;
45 :
46 : /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
47 : /// and \p DefIdx.
48 : /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
49 : /// the list is modeled as <Reg:SubReg, SubIdx>.
50 : /// E.g., REG_SEQUENCE %1:sub1, sub0, %2, sub1 would produce
51 : /// two elements:
52 : /// - %1:sub1, sub0
53 : /// - %2<:0>, sub1
54 : ///
55 : /// \returns true if it is possible to build such an input sequence
56 : /// with the pair \p MI, \p DefIdx. False otherwise.
57 : ///
58 : /// \pre MI.isRegSequenceLike().
59 : bool getRegSequenceLikeInputs(
60 : const MachineInstr &MI, unsigned DefIdx,
61 : SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override;
62 :
63 : /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
64 : /// and \p DefIdx.
65 : /// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
66 : /// E.g., EXTRACT_SUBREG %1:sub1, sub0, sub1 would produce:
67 : /// - %1:sub1, sub0
68 : ///
69 : /// \returns true if it is possible to build such an input sequence
70 : /// with the pair \p MI, \p DefIdx. False otherwise.
71 : ///
72 : /// \pre MI.isExtractSubregLike().
73 : bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
74 : RegSubRegPairAndIdx &InputReg) const override;
75 :
76 : /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
77 : /// and \p DefIdx.
78 : /// \p [out] BaseReg and \p [out] InsertedReg contain
79 : /// the equivalent inputs of INSERT_SUBREG.
80 : /// E.g., INSERT_SUBREG %0:sub0, %1:sub1, sub3 would produce:
81 : /// - BaseReg: %0:sub0
82 : /// - InsertedReg: %1:sub1, sub3
83 : ///
84 : /// \returns true if it is possible to build such an input sequence
85 : /// with the pair \p MI, \p DefIdx. False otherwise.
86 : ///
87 : /// \pre MI.isInsertSubregLike().
88 : bool
89 : getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
90 : RegSubRegPair &BaseReg,
91 : RegSubRegPairAndIdx &InsertedReg) const override;
92 :
93 : /// Commutes the operands in the given instruction.
94 : /// The commutable operands are specified by their indices OpIdx1 and OpIdx2.
95 : ///
96 : /// Do not call this method for a non-commutable instruction or for
97 : /// non-commutable pair of operand indices OpIdx1 and OpIdx2.
98 : /// Even though the instruction is commutable, the method may still
99 : /// fail to commute the operands, null pointer is returned in such cases.
100 : MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
101 : unsigned OpIdx1,
102 : unsigned OpIdx2) const override;
103 :
104 : /// If the specific machine instruction is a instruction that moves/copies
105 : /// value from one register to another register return true along with
106 : /// @Source machine operand and @Destination machine operand.
107 : bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source,
108 : const MachineOperand *&Destination) const override;
109 :
110 : public:
111 : // Return whether the target has an explicit NOP encoding.
112 : bool hasNOP() const;
113 :
114 : // Return the non-pre/post incrementing version of 'Opc'. Return 0
115 : // if there is not such an opcode.
116 : virtual unsigned getUnindexedOpcode(unsigned Opc) const = 0;
117 :
118 : MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
119 : MachineInstr &MI,
120 : LiveVariables *LV) const override;
121 :
122 : virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0;
123 0 : const ARMSubtarget &getSubtarget() const { return Subtarget; }
124 :
125 : ScheduleHazardRecognizer *
126 : CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
127 : const ScheduleDAG *DAG) const override;
128 :
129 : ScheduleHazardRecognizer *
130 : CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
131 : const ScheduleDAG *DAG) const override;
132 :
133 : // Branch analysis.
134 : bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
135 : MachineBasicBlock *&FBB,
136 : SmallVectorImpl<MachineOperand> &Cond,
137 : bool AllowModify = false) const override;
138 : unsigned removeBranch(MachineBasicBlock &MBB,
139 : int *BytesRemoved = nullptr) const override;
140 : unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
141 : MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
142 : const DebugLoc &DL,
143 : int *BytesAdded = nullptr) const override;
144 :
145 : bool
146 : reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
147 :
148 : // Predication support.
149 : bool isPredicated(const MachineInstr &MI) const override;
150 :
151 : ARMCC::CondCodes getPredicate(const MachineInstr &MI) const {
152 : int PIdx = MI.findFirstPredOperandIdx();
153 : return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm()
154 : : ARMCC::AL;
155 : }
156 :
157 : bool PredicateInstruction(MachineInstr &MI,
158 : ArrayRef<MachineOperand> Pred) const override;
159 :
160 : bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
161 : ArrayRef<MachineOperand> Pred2) const override;
162 :
163 : bool DefinesPredicate(MachineInstr &MI,
164 : std::vector<MachineOperand> &Pred) const override;
165 :
166 : bool isPredicable(const MachineInstr &MI) const override;
167 :
168 : // CPSR defined in instruction
169 : static bool isCPSRDefined(const MachineInstr &MI);
170 : bool isAddrMode3OpImm(const MachineInstr &MI, unsigned Op) const;
171 : bool isAddrMode3OpMinusReg(const MachineInstr &MI, unsigned Op) const;
172 :
173 : // Load, scaled register offset
174 : bool isLdstScaledReg(const MachineInstr &MI, unsigned Op) const;
175 : // Load, scaled register offset, not plus LSL2
176 : bool isLdstScaledRegNotPlusLsl2(const MachineInstr &MI, unsigned Op) const;
177 : // Minus reg for ldstso addr mode
178 : bool isLdstSoMinusReg(const MachineInstr &MI, unsigned Op) const;
179 : // Scaled register offset in address mode 2
180 : bool isAm2ScaledReg(const MachineInstr &MI, unsigned Op) const;
181 : // Load multiple, base reg in list
182 : bool isLDMBaseRegInList(const MachineInstr &MI) const;
183 : // get LDM variable defs size
184 : unsigned getLDMVariableDefsSize(const MachineInstr &MI) const;
185 :
186 : /// GetInstSize - Returns the size of the specified MachineInstr.
187 : ///
188 : unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
189 :
190 : unsigned isLoadFromStackSlot(const MachineInstr &MI,
191 : int &FrameIndex) const override;
192 : unsigned isStoreToStackSlot(const MachineInstr &MI,
193 : int &FrameIndex) const override;
194 : unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI,
195 : int &FrameIndex) const override;
196 : unsigned isStoreToStackSlotPostFE(const MachineInstr &MI,
197 : int &FrameIndex) const override;
198 :
199 : void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
200 : unsigned SrcReg, bool KillSrc,
201 : const ARMSubtarget &Subtarget) const;
202 : void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
203 : unsigned DestReg, bool KillSrc,
204 : const ARMSubtarget &Subtarget) const;
205 :
206 : void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
207 : const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
208 : bool KillSrc) const override;
209 :
210 : void storeRegToStackSlot(MachineBasicBlock &MBB,
211 : MachineBasicBlock::iterator MBBI,
212 : unsigned SrcReg, bool isKill, int FrameIndex,
213 : const TargetRegisterClass *RC,
214 : const TargetRegisterInfo *TRI) const override;
215 :
216 : void loadRegFromStackSlot(MachineBasicBlock &MBB,
217 : MachineBasicBlock::iterator MBBI,
218 : unsigned DestReg, int FrameIndex,
219 : const TargetRegisterClass *RC,
220 : const TargetRegisterInfo *TRI) const override;
221 :
222 : bool expandPostRAPseudo(MachineInstr &MI) const override;
223 :
224 : bool shouldSink(const MachineInstr &MI) const override;
225 :
226 : void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
227 : unsigned DestReg, unsigned SubIdx,
228 : const MachineInstr &Orig,
229 : const TargetRegisterInfo &TRI) const override;
230 :
231 : MachineInstr &
232 : duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
233 : const MachineInstr &Orig) const override;
234 :
235 : const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg,
236 : unsigned SubIdx, unsigned State,
237 : const TargetRegisterInfo *TRI) const;
238 :
239 : bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1,
240 : const MachineRegisterInfo *MRI) const override;
241 :
242 : /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
243 : /// determine if two loads are loading from the same base address. It should
244 : /// only return true if the base pointers are the same and the only
245 : /// differences between the two addresses is the offset. It also returns the
246 : /// offsets by reference.
247 : bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1,
248 : int64_t &Offset2) const override;
249 :
250 : /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
251 : /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
252 : /// should be scheduled togther. On some targets if two loads are loading from
253 : /// addresses in the same cache line, it's better if they are scheduled
254 : /// together. This function takes two integers that represent the load offsets
255 : /// from the common base address. It returns true if it decides it's desirable
256 : /// to schedule the two loads together. "NumLoads" is the number of loads that
257 : /// have already been scheduled after Load1.
258 : bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
259 : int64_t Offset1, int64_t Offset2,
260 : unsigned NumLoads) const override;
261 :
262 : bool isSchedulingBoundary(const MachineInstr &MI,
263 : const MachineBasicBlock *MBB,
264 : const MachineFunction &MF) const override;
265 :
266 : bool isProfitableToIfCvt(MachineBasicBlock &MBB,
267 : unsigned NumCycles, unsigned ExtraPredCycles,
268 : BranchProbability Probability) const override;
269 :
270 : bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
271 : unsigned ExtraT, MachineBasicBlock &FMBB,
272 : unsigned NumF, unsigned ExtraF,
273 : BranchProbability Probability) const override;
274 :
275 2015 : bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
276 : BranchProbability Probability) const override {
277 2015 : return NumCycles == 1;
278 : }
279 :
280 : bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
281 : MachineBasicBlock &FMBB) const override;
282 :
283 : /// analyzeCompare - For a comparison instruction, return the source registers
284 : /// in SrcReg and SrcReg2 if having two register operands, and the value it
285 : /// compares against in CmpValue. Return true if the comparison instruction
286 : /// can be analyzed.
287 : bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
288 : unsigned &SrcReg2, int &CmpMask,
289 : int &CmpValue) const override;
290 :
291 : /// optimizeCompareInstr - Convert the instruction to set the zero flag so
292 : /// that we can remove a "comparison with zero"; Remove a redundant CMP
293 : /// instruction if the flags can be updated in the same way by an earlier
294 : /// instruction such as SUB.
295 : bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
296 : unsigned SrcReg2, int CmpMask, int CmpValue,
297 : const MachineRegisterInfo *MRI) const override;
298 :
299 : bool analyzeSelect(const MachineInstr &MI,
300 : SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
301 : unsigned &FalseOp, bool &Optimizable) const override;
302 :
303 : MachineInstr *optimizeSelect(MachineInstr &MI,
304 : SmallPtrSetImpl<MachineInstr *> &SeenMIs,
305 : bool) const override;
306 :
307 : /// FoldImmediate - 'Reg' is known to be defined by a move immediate
308 : /// instruction, try to fold the immediate into the use instruction.
309 : bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
310 : MachineRegisterInfo *MRI) const override;
311 :
312 : unsigned getNumMicroOps(const InstrItineraryData *ItinData,
313 : const MachineInstr &MI) const override;
314 :
315 : int getOperandLatency(const InstrItineraryData *ItinData,
316 : const MachineInstr &DefMI, unsigned DefIdx,
317 : const MachineInstr &UseMI,
318 : unsigned UseIdx) const override;
319 : int getOperandLatency(const InstrItineraryData *ItinData,
320 : SDNode *DefNode, unsigned DefIdx,
321 : SDNode *UseNode, unsigned UseIdx) const override;
322 :
323 : /// VFP/NEON execution domains.
324 : std::pair<uint16_t, uint16_t>
325 : getExecutionDomain(const MachineInstr &MI) const override;
326 : void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override;
327 :
328 : unsigned
329 : getPartialRegUpdateClearance(const MachineInstr &, unsigned,
330 : const TargetRegisterInfo *) const override;
331 : void breakPartialRegDependency(MachineInstr &, unsigned,
332 : const TargetRegisterInfo *TRI) const override;
333 :
334 : /// Get the number of addresses by LDM or VLDM or zero for unknown.
335 : unsigned getNumLDMAddresses(const MachineInstr &MI) const;
336 :
337 : std::pair<unsigned, unsigned>
338 : decomposeMachineOperandsTargetFlags(unsigned TF) const override;
339 : ArrayRef<std::pair<unsigned, const char *>>
340 : getSerializableDirectMachineOperandTargetFlags() const override;
341 : ArrayRef<std::pair<unsigned, const char *>>
342 : getSerializableBitmaskMachineOperandTargetFlags() const override;
343 :
344 : private:
345 : unsigned getInstBundleLength(const MachineInstr &MI) const;
346 :
347 : int getVLDMDefCycle(const InstrItineraryData *ItinData,
348 : const MCInstrDesc &DefMCID,
349 : unsigned DefClass,
350 : unsigned DefIdx, unsigned DefAlign) const;
351 : int getLDMDefCycle(const InstrItineraryData *ItinData,
352 : const MCInstrDesc &DefMCID,
353 : unsigned DefClass,
354 : unsigned DefIdx, unsigned DefAlign) const;
355 : int getVSTMUseCycle(const InstrItineraryData *ItinData,
356 : const MCInstrDesc &UseMCID,
357 : unsigned UseClass,
358 : unsigned UseIdx, unsigned UseAlign) const;
359 : int getSTMUseCycle(const InstrItineraryData *ItinData,
360 : const MCInstrDesc &UseMCID,
361 : unsigned UseClass,
362 : unsigned UseIdx, unsigned UseAlign) const;
363 : int getOperandLatency(const InstrItineraryData *ItinData,
364 : const MCInstrDesc &DefMCID,
365 : unsigned DefIdx, unsigned DefAlign,
366 : const MCInstrDesc &UseMCID,
367 : unsigned UseIdx, unsigned UseAlign) const;
368 :
369 : int getOperandLatencyImpl(const InstrItineraryData *ItinData,
370 : const MachineInstr &DefMI, unsigned DefIdx,
371 : const MCInstrDesc &DefMCID, unsigned DefAdj,
372 : const MachineOperand &DefMO, unsigned Reg,
373 : const MachineInstr &UseMI, unsigned UseIdx,
374 : const MCInstrDesc &UseMCID, unsigned UseAdj) const;
375 :
376 : unsigned getPredicationCost(const MachineInstr &MI) const override;
377 :
378 : unsigned getInstrLatency(const InstrItineraryData *ItinData,
379 : const MachineInstr &MI,
380 : unsigned *PredCost = nullptr) const override;
381 :
382 : int getInstrLatency(const InstrItineraryData *ItinData,
383 : SDNode *Node) const override;
384 :
385 : bool hasHighOperandLatency(const TargetSchedModel &SchedModel,
386 : const MachineRegisterInfo *MRI,
387 : const MachineInstr &DefMI, unsigned DefIdx,
388 : const MachineInstr &UseMI,
389 : unsigned UseIdx) const override;
390 : bool hasLowDefLatency(const TargetSchedModel &SchedModel,
391 : const MachineInstr &DefMI,
392 : unsigned DefIdx) const override;
393 :
394 : /// verifyInstruction - Perform target specific instruction verification.
395 : bool verifyInstruction(const MachineInstr &MI,
396 : StringRef &ErrInfo) const override;
397 :
398 : virtual void expandLoadStackGuard(MachineBasicBlock::iterator MI) const = 0;
399 :
400 : void expandMEMCPY(MachineBasicBlock::iterator) const;
401 :
402 : private:
403 : /// Modeling special VFP / NEON fp MLA / MLS hazards.
404 :
405 : /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
406 : /// MLx table.
407 : DenseMap<unsigned, unsigned> MLxEntryMap;
408 :
409 : /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
410 : /// stalls when scheduled together with fp MLA / MLS opcodes.
411 : SmallSet<unsigned, 16> MLxHazardOpcodes;
412 :
413 : public:
414 : /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
415 : /// instruction.
416 : bool isFpMLxInstruction(unsigned Opcode) const {
417 38324 : return MLxEntryMap.count(Opcode);
418 : }
419 :
420 : /// isFpMLxInstruction - This version also returns the multiply opcode and the
421 : /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
422 : /// the MLX instructions with an extra lane operand.
423 : bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
424 : unsigned &AddSubOpc, bool &NegAcc,
425 : bool &HasLane) const;
426 :
427 : /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
428 : /// will cause stalls when scheduled after (within 4-cycle window) a fp
429 : /// MLA / MLS instruction.
430 : bool canCauseFpMLxStall(unsigned Opcode) const {
431 500 : return MLxHazardOpcodes.count(Opcode);
432 : }
433 :
434 : /// Returns true if the instruction has a shift by immediate that can be
435 : /// executed in one cycle less.
436 : bool isSwiftFastImmShift(const MachineInstr *MI) const;
437 :
438 : /// Returns predicate register associated with the given frame instruction.
439 0 : unsigned getFramePred(const MachineInstr &MI) const {
440 : assert(isFrameInstr(MI));
441 : // Operands of ADJCALLSTACKDOWN/ADJCALLSTACKUP:
442 : // - argument declared in the pattern:
443 : // 0 - frame size
444 : // 1 - arg of CALLSEQ_START/CALLSEQ_END
445 : // 2 - predicate code (like ARMCC::AL)
446 : // - added by predOps:
447 : // 3 - predicate reg
448 42 : return MI.getOperand(3).getReg();
449 : }
450 : };
451 :
452 : /// Get the operands corresponding to the given \p Pred value. By default, the
453 : /// predicate register is assumed to be 0 (no register), but you can pass in a
454 : /// \p PredReg if that is not the case.
455 : static inline std::array<MachineOperand, 2> predOps(ARMCC::CondCodes Pred,
456 : unsigned PredReg = 0) {
457 3514 : return {{MachineOperand::CreateImm(static_cast<int64_t>(Pred)),
458 : MachineOperand::CreateReg(PredReg, false)}};
459 : }
460 :
461 : /// Get the operand corresponding to the conditional code result. By default,
462 : /// this is 0 (no register).
463 : static inline MachineOperand condCodeOp(unsigned CCReg = 0) {
464 : return MachineOperand::CreateReg(CCReg, false);
465 : }
466 :
467 : /// Get the operand corresponding to the conditional code result for Thumb1.
468 : /// This operand will always refer to CPSR and it will have the Define flag set.
469 : /// You can optionally set the Dead flag by means of \p isDead.
470 : static inline MachineOperand t1CondCodeOp(bool isDead = false) {
471 : return MachineOperand::CreateReg(ARM::CPSR,
472 : /*Define*/ true, /*Implicit*/ false,
473 : /*Kill*/ false, isDead);
474 : }
475 :
476 : static inline
477 : bool isUncondBranchOpcode(int Opc) {
478 429004 : return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
479 : }
480 :
481 : static inline
482 : bool isCondBranchOpcode(int Opc) {
483 231840 : return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
484 : }
485 :
486 : static inline bool isJumpTableBranchOpcode(int Opc) {
487 388191 : return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm_i12 ||
488 388191 : Opc == ARM::BR_JTm_rs || Opc == ARM::BR_JTadd || Opc == ARM::tBR_JTr ||
489 386485 : Opc == ARM::t2BR_JT;
490 : }
491 :
492 : static inline
493 : bool isIndirectBranchOpcode(int Opc) {
494 390720 : return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
495 : }
496 :
497 : static inline bool isPopOpcode(int Opc) {
498 87 : return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET ||
499 76 : Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD ||
500 147 : Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD;
501 : }
502 :
503 : static inline bool isPushOpcode(int Opc) {
504 87 : return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD ||
505 87 : Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD;
506 : }
507 :
508 : /// getInstrPredicate - If instruction is predicated, returns its predicate
509 : /// condition, otherwise returns AL. It also returns the condition code
510 : /// register by reference.
511 : ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg);
512 :
513 : unsigned getMatchingCondBranchOpcode(unsigned Opc);
514 :
515 : /// Determine if MI can be folded into an ARM MOVCC instruction, and return the
516 : /// opcode of the SSA instruction representing the conditional MI.
517 : unsigned canFoldARMInstrIntoMOVCC(unsigned Reg,
518 : MachineInstr *&MI,
519 : const MachineRegisterInfo &MRI);
520 :
521 : /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether
522 : /// the instruction is encoded with an 'S' bit is determined by the optional
523 : /// CPSR def operand.
524 : unsigned convertAddSubFlagsOpcode(unsigned OldOpc);
525 :
526 : /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
527 : /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
528 : /// code.
529 : void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
530 : MachineBasicBlock::iterator &MBBI,
531 : const DebugLoc &dl, unsigned DestReg,
532 : unsigned BaseReg, int NumBytes,
533 : ARMCC::CondCodes Pred, unsigned PredReg,
534 : const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
535 :
536 : void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
537 : MachineBasicBlock::iterator &MBBI,
538 : const DebugLoc &dl, unsigned DestReg,
539 : unsigned BaseReg, int NumBytes,
540 : ARMCC::CondCodes Pred, unsigned PredReg,
541 : const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
542 : void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
543 : MachineBasicBlock::iterator &MBBI,
544 : const DebugLoc &dl, unsigned DestReg,
545 : unsigned BaseReg, int NumBytes,
546 : const TargetInstrInfo &TII,
547 : const ARMBaseRegisterInfo &MRI,
548 : unsigned MIFlags = 0);
549 :
550 : /// Tries to add registers to the reglist of a given base-updating
551 : /// push/pop instruction to adjust the stack by an additional
552 : /// NumBytes. This can save a few bytes per function in code-size, but
553 : /// obviously generates more memory traffic. As such, it only takes
554 : /// effect in functions being optimised for size.
555 : bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
556 : MachineFunction &MF, MachineInstr *MI,
557 : unsigned NumBytes);
558 :
559 : /// rewriteARMFrameIndex / rewriteT2FrameIndex -
560 : /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
561 : /// offset could not be handled directly in MI, and return the left-over
562 : /// portion by reference.
563 : bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
564 : unsigned FrameReg, int &Offset,
565 : const ARMBaseInstrInfo &TII);
566 :
567 : bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
568 : unsigned FrameReg, int &Offset,
569 : const ARMBaseInstrInfo &TII);
570 :
571 : } // end namespace llvm
572 :
573 : #endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
|