1//===-- ARMBaseInstrInfo.h - ARM Base Instruction Information ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the Base ARM implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
14#define LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
15
16#include "MCTargetDesc/ARMBaseInfo.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/SmallSet.h"
19#include "llvm/CodeGen/MachineBasicBlock.h"
20#include "llvm/CodeGen/MachineInstr.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
22#include "llvm/CodeGen/MachineOperand.h"
23#include "llvm/CodeGen/TargetInstrInfo.h"
24#include <array>
25#include <cstdint>
26
27#define GET_INSTRINFO_HEADER
28#include "ARMGenInstrInfo.inc"
29
30namespace llvm {
31
32class ARMBaseRegisterInfo;
33class ARMSubtarget;
34
35class ARMBaseInstrInfo : public ARMGenInstrInfo {
36  const ARMSubtarget &Subtarget;
37
38protected:
39  // Can be only subclassed.
40  explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
41
42  void expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
43                                unsigned LoadImmOpc, unsigned LoadOpc) const;
44
45  /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI
46  /// and \p DefIdx.
47  /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of
48  /// the list is modeled as <Reg:SubReg, SubIdx>.
49  /// E.g., REG_SEQUENCE %1:sub1, sub0, %2, sub1 would produce
50  /// two elements:
51  /// - %1:sub1, sub0
52  /// - %2<:0>, sub1
53  ///
54  /// \returns true if it is possible to build such an input sequence
55  /// with the pair \p MI, \p DefIdx. False otherwise.
56  ///
57  /// \pre MI.isRegSequenceLike().
58  bool getRegSequenceLikeInputs(
59      const MachineInstr &MI, unsigned DefIdx,
60      SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override;
61
62  /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI
63  /// and \p DefIdx.
64  /// \p [out] InputReg of the equivalent EXTRACT_SUBREG.
65  /// E.g., EXTRACT_SUBREG %1:sub1, sub0, sub1 would produce:
66  /// - %1:sub1, sub0
67  ///
68  /// \returns true if it is possible to build such an input sequence
69  /// with the pair \p MI, \p DefIdx. False otherwise.
70  ///
71  /// \pre MI.isExtractSubregLike().
72  bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
73                                  RegSubRegPairAndIdx &InputReg) const override;
74
75  /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI
76  /// and \p DefIdx.
77  /// \p [out] BaseReg and \p [out] InsertedReg contain
78  /// the equivalent inputs of INSERT_SUBREG.
79  /// E.g., INSERT_SUBREG %0:sub0, %1:sub1, sub3 would produce:
80  /// - BaseReg: %0:sub0
81  /// - InsertedReg: %1:sub1, sub3
82  ///
83  /// \returns true if it is possible to build such an input sequence
84  /// with the pair \p MI, \p DefIdx. False otherwise.
85  ///
86  /// \pre MI.isInsertSubregLike().
87  bool
88  getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx,
89                            RegSubRegPair &BaseReg,
90                            RegSubRegPairAndIdx &InsertedReg) const override;
91
92  /// Commutes the operands in the given instruction.
93  /// The commutable operands are specified by their indices OpIdx1 and OpIdx2.
94  ///
95  /// Do not call this method for a non-commutable instruction or for
96  /// non-commutable pair of operand indices OpIdx1 and OpIdx2.
97  /// Even though the instruction is commutable, the method may still
98  /// fail to commute the operands, null pointer is returned in such cases.
99  MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
100                                       unsigned OpIdx1,
101                                       unsigned OpIdx2) const override;
102  /// If the specific machine instruction is an instruction that moves/copies
103  /// value from one register to another register return destination and source
104  /// registers as machine operands.
105  Optional<DestSourcePair>
106  isCopyInstrImpl(const MachineInstr &MI) const override;
107
108public:
109  // Return whether the target has an explicit NOP encoding.
110  bool hasNOP() const;
111
112  // Return the non-pre/post incrementing version of 'Opc'. Return 0
113  // if there is not such an opcode.
114  virtual unsigned getUnindexedOpcode(unsigned Opc) const = 0;
115
116  MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
117                                      MachineInstr &MI,
118                                      LiveVariables *LV) const override;
119
120  virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0;
121  const ARMSubtarget &getSubtarget() const { return Subtarget; }
122
123  ScheduleHazardRecognizer *
124  CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
125                               const ScheduleDAG *DAG) const override;
126
127  ScheduleHazardRecognizer *
128  CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
129                                     const ScheduleDAG *DAG) const override;
130
131  // Branch analysis.
132  bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
133                     MachineBasicBlock *&FBB,
134                     SmallVectorImpl<MachineOperand> &Cond,
135                     bool AllowModify = false) const override;
136  unsigned removeBranch(MachineBasicBlock &MBB,
137                        int *BytesRemoved = nullptr) const override;
138  unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
139                        MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
140                        const DebugLoc &DL,
141                        int *BytesAdded = nullptr) const override;
142
143  bool
144  reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
145
146  // Predication support.
147  bool isPredicated(const MachineInstr &MI) const override;
148
149  ARMCC::CondCodes getPredicate(const MachineInstr &MI) const {
150    int PIdx = MI.findFirstPredOperandIdx();
151    return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm()
152                      : ARMCC::AL;
153  }
154
155  bool PredicateInstruction(MachineInstr &MI,
156                            ArrayRef<MachineOperand> Pred) const override;
157
158  bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
159                         ArrayRef<MachineOperand> Pred2) const override;
160
161  bool DefinesPredicate(MachineInstr &MI,
162                        std::vector<MachineOperand> &Pred) const override;
163
164  bool isPredicable(const MachineInstr &MI) const override;
165
166  // CPSR defined in instruction
167  static bool isCPSRDefined(const MachineInstr &MI);
168  bool isAddrMode3OpImm(const MachineInstr &MI, unsigned Op) const;
169  bool isAddrMode3OpMinusReg(const MachineInstr &MI, unsigned Op) const;
170
171  // Load, scaled register offset
172  bool isLdstScaledReg(const MachineInstr &MI, unsigned Op) const;
173  // Load, scaled register offset, not plus LSL2
174  bool isLdstScaledRegNotPlusLsl2(const MachineInstr &MI, unsigned Op) const;
175  // Minus reg for ldstso addr mode
176  bool isLdstSoMinusReg(const MachineInstr &MI, unsigned Op) const;
177  // Scaled register offset in address mode 2
178  bool isAm2ScaledReg(const MachineInstr &MI, unsigned Op) const;
179  // Load multiple, base reg in list
180  bool isLDMBaseRegInList(const MachineInstr &MI) const;
181  // get LDM variable defs size
182  unsigned getLDMVariableDefsSize(const MachineInstr &MI) const;
183
184  /// GetInstSize - Returns the size of the specified MachineInstr.
185  ///
186  unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
187
188  unsigned isLoadFromStackSlot(const MachineInstr &MI,
189                               int &FrameIndex) const override;
190  unsigned isStoreToStackSlot(const MachineInstr &MI,
191                              int &FrameIndex) const override;
192  unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI,
193                                     int &FrameIndex) const override;
194  unsigned isStoreToStackSlotPostFE(const MachineInstr &MI,
195                                    int &FrameIndex) const override;
196
197  void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
198                  unsigned SrcReg, bool KillSrc,
199                  const ARMSubtarget &Subtarget) const;
200  void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
201                    unsigned DestReg, bool KillSrc,
202                    const ARMSubtarget &Subtarget) const;
203
204  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
205                   const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
206                   bool KillSrc) const override;
207
208  void storeRegToStackSlot(MachineBasicBlock &MBB,
209                           MachineBasicBlock::iterator MBBI,
210                           unsigned SrcReg, bool isKill, int FrameIndex,
211                           const TargetRegisterClass *RC,
212                           const TargetRegisterInfo *TRI) const override;
213
214  void loadRegFromStackSlot(MachineBasicBlock &MBB,
215                            MachineBasicBlock::iterator MBBI,
216                            unsigned DestReg, int FrameIndex,
217                            const TargetRegisterClass *RC,
218                            const TargetRegisterInfo *TRI) const override;
219
220  bool expandPostRAPseudo(MachineInstr &MI) const override;
221
222  bool shouldSink(const MachineInstr &MI) const override;
223
224  void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
225                     unsigned DestReg, unsigned SubIdx,
226                     const MachineInstr &Orig,
227                     const TargetRegisterInfo &TRI) const override;
228
229  MachineInstr &
230  duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore,
231            const MachineInstr &Orig) const override;
232
233  const MachineInstrBuilder &AddDReg(MachineInstrBuilder &MIB, unsigned Reg,
234                                     unsigned SubIdx, unsigned State,
235                                     const TargetRegisterInfo *TRI) const;
236
237  bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1,
238                        const MachineRegisterInfo *MRI) const override;
239
240  /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to
241  /// determine if two loads are loading from the same base address. It should
242  /// only return true if the base pointers are the same and the only
243  /// differences between the two addresses is the offset. It also returns the
244  /// offsets by reference.
245  bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1,
246                               int64_t &Offset2) const override;
247
248  /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
249  /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads
250  /// should be scheduled togther. On some targets if two loads are loading from
251  /// addresses in the same cache line, it's better if they are scheduled
252  /// together. This function takes two integers that represent the load offsets
253  /// from the common base address. It returns true if it decides it's desirable
254  /// to schedule the two loads together. "NumLoads" is the number of loads that
255  /// have already been scheduled after Load1.
256  bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
257                               int64_t Offset1, int64_t Offset2,
258                               unsigned NumLoads) const override;
259
260  bool isSchedulingBoundary(const MachineInstr &MI,
261                            const MachineBasicBlock *MBB,
262                            const MachineFunction &MF) const override;
263
264  bool isProfitableToIfCvt(MachineBasicBlock &MBB,
265                           unsigned NumCycles, unsigned ExtraPredCycles,
266                           BranchProbability Probability) const override;
267
268  bool isProfitableToIfCvt(MachineBasicBlock &TMBB, unsigned NumT,
269                           unsigned ExtraT, MachineBasicBlock &FMBB,
270                           unsigned NumF, unsigned ExtraF,
271                           BranchProbability Probability) const override;
272
273  bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
274                                 BranchProbability Probability) const override {
275    return NumCycles == 1;
276  }
277
278  unsigned extraSizeToPredicateInstructions(const MachineFunction &MF,
279                                            unsigned NumInsts) const override;
280  unsigned predictBranchSizeForIfCvt(MachineInstr &MI) const override;
281
282  bool isProfitableToUnpredicate(MachineBasicBlock &TMBB,
283                                 MachineBasicBlock &FMBB) const override;
284
285  /// analyzeCompare - For a comparison instruction, return the source registers
286  /// in SrcReg and SrcReg2 if having two register operands, and the value it
287  /// compares against in CmpValue. Return true if the comparison instruction
288  /// can be analyzed.
289  bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
290                      unsigned &SrcReg2, int &CmpMask,
291                      int &CmpValue) const override;
292
293  /// optimizeCompareInstr - Convert the instruction to set the zero flag so
294  /// that we can remove a "comparison with zero"; Remove a redundant CMP
295  /// instruction if the flags can be updated in the same way by an earlier
296  /// instruction such as SUB.
297  bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
298                            unsigned SrcReg2, int CmpMask, int CmpValue,
299                            const MachineRegisterInfo *MRI) const override;
300
301  bool analyzeSelect(const MachineInstr &MI,
302                     SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
303                     unsigned &FalseOp, bool &Optimizable) const override;
304
305  MachineInstr *optimizeSelect(MachineInstr &MI,
306                               SmallPtrSetImpl<MachineInstr *> &SeenMIs,
307                               bool) const override;
308
309  /// FoldImmediate - 'Reg' is known to be defined by a move immediate
310  /// instruction, try to fold the immediate into the use instruction.
311  bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
312                     MachineRegisterInfo *MRI) const override;
313
314  unsigned getNumMicroOps(const InstrItineraryData *ItinData,
315                          const MachineInstr &MI) const override;
316
317  int getOperandLatency(const InstrItineraryData *ItinData,
318                        const MachineInstr &DefMI, unsigned DefIdx,
319                        const MachineInstr &UseMI,
320                        unsigned UseIdx) const override;
321  int getOperandLatency(const InstrItineraryData *ItinData,
322                        SDNode *DefNode, unsigned DefIdx,
323                        SDNode *UseNode, unsigned UseIdx) const override;
324
325  /// VFP/NEON execution domains.
326  std::pair<uint16_t, uint16_t>
327  getExecutionDomain(const MachineInstr &MI) const override;
328  void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override;
329
330  unsigned
331  getPartialRegUpdateClearance(const MachineInstr &, unsigned,
332                               const TargetRegisterInfo *) const override;
333  void breakPartialRegDependency(MachineInstr &, unsigned,
334                                 const TargetRegisterInfo *TRI) const override;
335
336  /// Get the number of addresses by LDM or VLDM or zero for unknown.
337  unsigned getNumLDMAddresses(const MachineInstr &MI) const;
338
339  std::pair<unsigned, unsigned>
340  decomposeMachineOperandsTargetFlags(unsigned TF) const override;
341  ArrayRef<std::pair<unsigned, const char *>>
342  getSerializableDirectMachineOperandTargetFlags() const override;
343  ArrayRef<std::pair<unsigned, const char *>>
344  getSerializableBitmaskMachineOperandTargetFlags() const override;
345
346private:
347  unsigned getInstBundleLength(const MachineInstr &MI) const;
348
349  int getVLDMDefCycle(const InstrItineraryData *ItinData,
350                      const MCInstrDesc &DefMCID,
351                      unsigned DefClass,
352                      unsigned DefIdx, unsigned DefAlign) const;
353  int getLDMDefCycle(const InstrItineraryData *ItinData,
354                     const MCInstrDesc &DefMCID,
355                     unsigned DefClass,
356                     unsigned DefIdx, unsigned DefAlign) const;
357  int getVSTMUseCycle(const InstrItineraryData *ItinData,
358                      const MCInstrDesc &UseMCID,
359                      unsigned UseClass,
360                      unsigned UseIdx, unsigned UseAlign) const;
361  int getSTMUseCycle(const InstrItineraryData *ItinData,
362                     const MCInstrDesc &UseMCID,
363                     unsigned UseClass,
364                     unsigned UseIdx, unsigned UseAlign) const;
365  int getOperandLatency(const InstrItineraryData *ItinData,
366                        const MCInstrDesc &DefMCID,
367                        unsigned DefIdx, unsigned DefAlign,
368                        const MCInstrDesc &UseMCID,
369                        unsigned UseIdx, unsigned UseAlign) const;
370
371  int getOperandLatencyImpl(const InstrItineraryData *ItinData,
372                            const MachineInstr &DefMI, unsigned DefIdx,
373                            const MCInstrDesc &DefMCID, unsigned DefAdj,
374                            const MachineOperand &DefMO, unsigned Reg,
375                            const MachineInstr &UseMI, unsigned UseIdx,
376                            const MCInstrDesc &UseMCID, unsigned UseAdj) const;
377
378  unsigned getPredicationCost(const MachineInstr &MI) const override;
379
380  unsigned getInstrLatency(const InstrItineraryData *ItinData,
381                           const MachineInstr &MI,
382                           unsigned *PredCost = nullptr) const override;
383
384  int getInstrLatency(const InstrItineraryData *ItinData,
385                      SDNode *Node) const override;
386
387  bool hasHighOperandLatency(const TargetSchedModel &SchedModel,
388                             const MachineRegisterInfo *MRI,
389                             const MachineInstr &DefMI, unsigned DefIdx,
390                             const MachineInstr &UseMI,
391                             unsigned UseIdx) const override;
392  bool hasLowDefLatency(const TargetSchedModel &SchedModel,
393                        const MachineInstr &DefMI,
394                        unsigned DefIdx) const override;
395
396  /// verifyInstruction - Perform target specific instruction verification.
397  bool verifyInstruction(const MachineInstr &MI,
398                         StringRef &ErrInfo) const override;
399
400  virtual void expandLoadStackGuard(MachineBasicBlock::iterator MI) const = 0;
401
402  void expandMEMCPY(MachineBasicBlock::iterator) const;
403
404  /// Identify instructions that can be folded into a MOVCC instruction, and
405  /// return the defining instruction.
406  MachineInstr *canFoldIntoMOVCC(unsigned Reg, const MachineRegisterInfo &MRI,
407                                 const TargetInstrInfo *TII) const;
408
409private:
410  /// Modeling special VFP / NEON fp MLA / MLS hazards.
411
412  /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal
413  /// MLx table.
414  DenseMap<unsigned, unsigned> MLxEntryMap;
415
416  /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause
417  /// stalls when scheduled together with fp MLA / MLS opcodes.
418  SmallSet<unsigned, 16> MLxHazardOpcodes;
419
420public:
421  /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS
422  /// instruction.
423  bool isFpMLxInstruction(unsigned Opcode) const {
424    return MLxEntryMap.count(Opcode);
425  }
426
427  /// isFpMLxInstruction - This version also returns the multiply opcode and the
428  /// addition / subtraction opcode to expand to. Return true for 'HasLane' for
429  /// the MLX instructions with an extra lane operand.
430  bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
431                          unsigned &AddSubOpc, bool &NegAcc,
432                          bool &HasLane) const;
433
434  /// canCauseFpMLxStall - Return true if an instruction of the specified opcode
435  /// will cause stalls when scheduled after (within 4-cycle window) a fp
436  /// MLA / MLS instruction.
437  bool canCauseFpMLxStall(unsigned Opcode) const {
438    return MLxHazardOpcodes.count(Opcode);
439  }
440
441  /// Returns true if the instruction has a shift by immediate that can be
442  /// executed in one cycle less.
443  bool isSwiftFastImmShift(const MachineInstr *MI) const;
444
445  /// Returns predicate register associated with the given frame instruction.
446  unsigned getFramePred(const MachineInstr &MI) const {
447    assert(isFrameInstr(MI));
448    // Operands of ADJCALLSTACKDOWN/ADJCALLSTACKUP:
449    // - argument declared in the pattern:
450    // 0 - frame size
451    // 1 - arg of CALLSEQ_START/CALLSEQ_END
452    // 2 - predicate code (like ARMCC::AL)
453    // - added by predOps:
454    // 3 - predicate reg
455    return MI.getOperand(3).getReg();
456  }
457
458  Optional<RegImmPair> isAddImmediate(const MachineInstr &MI,
459                                      Register Reg) const override;
460};
461
462/// Get the operands corresponding to the given \p Pred value. By default, the
463/// predicate register is assumed to be 0 (no register), but you can pass in a
464/// \p PredReg if that is not the case.
465static inline std::array<MachineOperand, 2> predOps(ARMCC::CondCodes Pred,
466                                                    unsigned PredReg = 0) {
467  return {{MachineOperand::CreateImm(static_cast<int64_t>(Pred)),
468           MachineOperand::CreateReg(PredReg, false)}};
469}
470
471/// Get the operand corresponding to the conditional code result. By default,
472/// this is 0 (no register).
473static inline MachineOperand condCodeOp(unsigned CCReg = 0) {
474  return MachineOperand::CreateReg(CCReg, false);
475}
476
477/// Get the operand corresponding to the conditional code result for Thumb1.
478/// This operand will always refer to CPSR and it will have the Define flag set.
479/// You can optionally set the Dead flag by means of \p isDead.
480static inline MachineOperand t1CondCodeOp(bool isDead = false) {
481  return MachineOperand::CreateReg(ARM::CPSR,
482                                   /*Define*/ true, /*Implicit*/ false,
483                                   /*Kill*/ false, isDead);
484}
485
486static inline
487bool isUncondBranchOpcode(int Opc) {
488  return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
489}
490
491// This table shows the VPT instruction variants, i.e. the different
492// mask field encodings, see also B5.6. Predication/conditional execution in
493// the ArmARM.
494enum VPTMaskValue {
495  T     =  8, // 0b1000
496  TT    =  4, // 0b0100
497  TE    = 12, // 0b1100
498  TTT   =  2, // 0b0010
499  TTE   =  6, // 0b0110
500  TEE   = 10, // 0b1010
501  TET   = 14, // 0b1110
502  TTTT  =  1, // 0b0001
503  TTTE  =  3, // 0b0011
504  TTEE  =  5, // 0b0101
505  TTET  =  7, // 0b0111
506  TEEE  =  9, // 0b1001
507  TEET  = 11, // 0b1011
508  TETT  = 13, // 0b1101
509  TETE  = 15  // 0b1111
510};
511
512static inline bool isVPTOpcode(int Opc) {
513  return Opc == ARM::MVE_VPTv16i8 || Opc == ARM::MVE_VPTv16u8 ||
514         Opc == ARM::MVE_VPTv16s8 || Opc == ARM::MVE_VPTv8i16 ||
515         Opc == ARM::MVE_VPTv8u16 || Opc == ARM::MVE_VPTv8s16 ||
516         Opc == ARM::MVE_VPTv4i32 || Opc == ARM::MVE_VPTv4u32 ||
517         Opc == ARM::MVE_VPTv4s32 || Opc == ARM::MVE_VPTv4f32 ||
518         Opc == ARM::MVE_VPTv8f16 || Opc == ARM::MVE_VPTv16i8r ||
519         Opc == ARM::MVE_VPTv16u8r || Opc == ARM::MVE_VPTv16s8r ||
520         Opc == ARM::MVE_VPTv8i16r || Opc == ARM::MVE_VPTv8u16r ||
521         Opc == ARM::MVE_VPTv8s16r || Opc == ARM::MVE_VPTv4i32r ||
522         Opc == ARM::MVE_VPTv4u32r || Opc == ARM::MVE_VPTv4s32r ||
523         Opc == ARM::MVE_VPTv4f32r || Opc == ARM::MVE_VPTv8f16r ||
524         Opc == ARM::MVE_VPST;
525}
526
527static inline
528unsigned VCMPOpcodeToVPT(unsigned Opcode) {
529  switch (Opcode) {
530  default:
531    return 0;
532  case ARM::MVE_VCMPf32:
533    return ARM::MVE_VPTv4f32;
534  case ARM::MVE_VCMPf16:
535    return ARM::MVE_VPTv8f16;
536  case ARM::MVE_VCMPi8:
537    return ARM::MVE_VPTv16i8;
538  case ARM::MVE_VCMPi16:
539    return ARM::MVE_VPTv8i16;
540  case ARM::MVE_VCMPi32:
541    return ARM::MVE_VPTv4i32;
542  case ARM::MVE_VCMPu8:
543    return ARM::MVE_VPTv16u8;
544  case ARM::MVE_VCMPu16:
545    return ARM::MVE_VPTv8u16;
546  case ARM::MVE_VCMPu32:
547    return ARM::MVE_VPTv4u32;
548  case ARM::MVE_VCMPs8:
549    return ARM::MVE_VPTv16s8;
550  case ARM::MVE_VCMPs16:
551    return ARM::MVE_VPTv8s16;
552  case ARM::MVE_VCMPs32:
553    return ARM::MVE_VPTv4s32;
554
555  case ARM::MVE_VCMPf32r:
556    return ARM::MVE_VPTv4f32r;
557  case ARM::MVE_VCMPf16r:
558    return ARM::MVE_VPTv8f16r;
559  case ARM::MVE_VCMPi8r:
560    return ARM::MVE_VPTv16i8r;
561  case ARM::MVE_VCMPi16r:
562    return ARM::MVE_VPTv8i16r;
563  case ARM::MVE_VCMPi32r:
564    return ARM::MVE_VPTv4i32r;
565  case ARM::MVE_VCMPu8r:
566    return ARM::MVE_VPTv16u8r;
567  case ARM::MVE_VCMPu16r:
568    return ARM::MVE_VPTv8u16r;
569  case ARM::MVE_VCMPu32r:
570    return ARM::MVE_VPTv4u32r;
571  case ARM::MVE_VCMPs8r:
572    return ARM::MVE_VPTv16s8r;
573  case ARM::MVE_VCMPs16r:
574    return ARM::MVE_VPTv8s16r;
575  case ARM::MVE_VCMPs32r:
576    return ARM::MVE_VPTv4s32r;
577  }
578}
579
580static inline
581unsigned VCTPOpcodeToLSTP(unsigned Opcode, bool IsDoLoop) {
582  switch (Opcode) {
583  default:
584    llvm_unreachable("unhandled vctp opcode");
585    break;
586  case ARM::MVE_VCTP8:
587    return IsDoLoop ? ARM::MVE_DLSTP_8 : ARM::MVE_WLSTP_8;
588  case ARM::MVE_VCTP16:
589    return IsDoLoop ? ARM::MVE_DLSTP_16 : ARM::MVE_WLSTP_16;
590  case ARM::MVE_VCTP32:
591    return IsDoLoop ? ARM::MVE_DLSTP_32 : ARM::MVE_WLSTP_32;
592  case ARM::MVE_VCTP64:
593    return IsDoLoop ? ARM::MVE_DLSTP_64 : ARM::MVE_WLSTP_64;
594  }
595  return 0;
596}
597
598static inline
599bool isVCTP(MachineInstr *MI) {
600  switch (MI->getOpcode()) {
601  default:
602    break;
603  case ARM::MVE_VCTP8:
604  case ARM::MVE_VCTP16:
605  case ARM::MVE_VCTP32:
606  case ARM::MVE_VCTP64:
607    return true;
608  }
609  return false;
610}
611
612static inline
613bool isLoopStart(MachineInstr &MI) {
614  return MI.getOpcode() == ARM::t2DoLoopStart ||
615         MI.getOpcode() == ARM::t2WhileLoopStart;
616}
617
618static inline
619bool isCondBranchOpcode(int Opc) {
620  return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
621}
622
623static inline bool isJumpTableBranchOpcode(int Opc) {
624  return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm_i12 ||
625         Opc == ARM::BR_JTm_rs || Opc == ARM::BR_JTadd || Opc == ARM::tBR_JTr ||
626         Opc == ARM::t2BR_JT;
627}
628
629static inline
630bool isIndirectBranchOpcode(int Opc) {
631  return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND;
632}
633
634static inline bool isPopOpcode(int Opc) {
635  return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET ||
636         Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD ||
637         Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD;
638}
639
640static inline bool isPushOpcode(int Opc) {
641  return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD ||
642         Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD;
643}
644
645/// isValidCoprocessorNumber - decide whether an explicit coprocessor
646/// number is legal in generic instructions like CDP. The answer can
647/// vary with the subtarget.
648static inline bool isValidCoprocessorNumber(unsigned Num,
649                                            const FeatureBitset& featureBits) {
650  // Armv8-A disallows everything *other* than 111x (CP14 and CP15).
651  if (featureBits[ARM::HasV8Ops] && (Num & 0xE) != 0xE)
652    return false;
653
654  // Armv7 disallows 101x (CP10 and CP11), which clash with VFP/NEON.
655  if (featureBits[ARM::HasV7Ops] && (Num & 0xE) == 0xA)
656    return false;
657
658  // Armv8.1-M also disallows 100x (CP8,CP9) and 111x (CP14,CP15)
659  // which clash with MVE.
660  if (featureBits[ARM::HasV8_1MMainlineOps] &&
661      ((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE))
662    return false;
663
664  return true;
665}
666
667/// getInstrPredicate - If instruction is predicated, returns its predicate
668/// condition, otherwise returns AL. It also returns the condition code
669/// register by reference.
670ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg);
671
672unsigned getMatchingCondBranchOpcode(unsigned Opc);
673
674/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether
675/// the instruction is encoded with an 'S' bit is determined by the optional
676/// CPSR def operand.
677unsigned convertAddSubFlagsOpcode(unsigned OldOpc);
678
679/// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of
680/// instructions to materializea destreg = basereg + immediate in ARM / Thumb2
681/// code.
682void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
683                             MachineBasicBlock::iterator &MBBI,
684                             const DebugLoc &dl, unsigned DestReg,
685                             unsigned BaseReg, int NumBytes,
686                             ARMCC::CondCodes Pred, unsigned PredReg,
687                             const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
688
689void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
690                            MachineBasicBlock::iterator &MBBI,
691                            const DebugLoc &dl, unsigned DestReg,
692                            unsigned BaseReg, int NumBytes,
693                            ARMCC::CondCodes Pred, unsigned PredReg,
694                            const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
695void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
696                               MachineBasicBlock::iterator &MBBI,
697                               const DebugLoc &dl, unsigned DestReg,
698                               unsigned BaseReg, int NumBytes,
699                               const TargetInstrInfo &TII,
700                               const ARMBaseRegisterInfo &MRI,
701                               unsigned MIFlags = 0);
702
703/// Tries to add registers to the reglist of a given base-updating
704/// push/pop instruction to adjust the stack by an additional
705/// NumBytes. This can save a few bytes per function in code-size, but
706/// obviously generates more memory traffic. As such, it only takes
707/// effect in functions being optimised for size.
708bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget,
709                                MachineFunction &MF, MachineInstr *MI,
710                                unsigned NumBytes);
711
712/// rewriteARMFrameIndex / rewriteT2FrameIndex -
713/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
714/// offset could not be handled directly in MI, and return the left-over
715/// portion by reference.
716bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
717                          unsigned FrameReg, int &Offset,
718                          const ARMBaseInstrInfo &TII);
719
720bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
721                         unsigned FrameReg, int &Offset,
722                         const ARMBaseInstrInfo &TII,
723                         const TargetRegisterInfo *TRI);
724
725/// Return true if Reg is defd between From and To
726bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From,
727                            MachineBasicBlock::iterator To,
728                            const TargetRegisterInfo *TRI);
729
730/// Search backwards from a tBcc to find a tCMPi8 against 0, meaning
731/// we can convert them to a tCBZ or tCBNZ. Return nullptr if not found.
732MachineInstr *findCMPToFoldIntoCBZ(MachineInstr *Br,
733                                   const TargetRegisterInfo *TRI);
734
735void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB);
736void addUnpredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned DestReg);
737
738void addPredicatedMveVpredNOp(MachineInstrBuilder &MIB, unsigned Cond);
739void addPredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned Cond,
740                              unsigned Inactive);
741
742/// Returns the number of instructions required to materialize the given
743/// constant in a register, or 3 if a literal pool load is needed.
744/// If ForCodesize is specified, an approximate cost in bytes is returned.
745unsigned ConstantMaterializationCost(unsigned Val,
746                                     const ARMSubtarget *Subtarget,
747                                     bool ForCodesize = false);
748
749/// Returns true if Val1 has a lower Constant Materialization Cost than Val2.
750/// Uses the cost from ConstantMaterializationCost, first with ForCodesize as
751/// specified. If the scores are equal, return the comparison for !ForCodesize.
752bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2,
753                                         const ARMSubtarget *Subtarget,
754                                         bool ForCodesize = false);
755
756} // end namespace llvm
757
758#endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H
759