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 30 namespace llvm { 31 32 class ARMBaseRegisterInfo; 33 class ARMSubtarget; 34 35 class ARMBaseInstrInfo : public ARMGenInstrInfo { 36 const ARMSubtarget &Subtarget; 37 38 protected: 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 108 public: 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 346 private: 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 409 private: 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 420 public: 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. 465 static 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). 473 static 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. 480 static inline MachineOperand t1CondCodeOp(bool isDead = false) { 481 return MachineOperand::CreateReg(ARM::CPSR, 482 /*Define*/ true, /*Implicit*/ false, 483 /*Kill*/ false, isDead); 484 } 485 486 static inline 487 bool 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. 494 enum 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 512 static 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 527 static inline 528 unsigned 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 580 static inline 581 unsigned 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 598 static inline 599 bool 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 612 static inline 613 bool isLoopStart(MachineInstr &MI) { 614 return MI.getOpcode() == ARM::t2DoLoopStart || 615 MI.getOpcode() == ARM::t2WhileLoopStart; 616 } 617 618 static inline 619 bool isCondBranchOpcode(int Opc) { 620 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 621 } 622 623 static 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 629 static inline 630 bool isIndirectBranchOpcode(int Opc) { 631 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 632 } 633 634 static 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 640 static 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. 648 static 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. 670 ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg); 671 672 unsigned 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. 677 unsigned convertAddSubFlagsOpcode(unsigned OldOpc); 678 679 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 680 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 681 /// code. 682 void 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 689 void 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); 695 void 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. 708 bool 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. 716 bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 717 unsigned FrameReg, int &Offset, 718 const ARMBaseInstrInfo &TII); 719 720 bool 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 726 bool 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. 732 MachineInstr *findCMPToFoldIntoCBZ(MachineInstr *Br, 733 const TargetRegisterInfo *TRI); 734 735 void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB); 736 void addUnpredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned DestReg); 737 738 void addPredicatedMveVpredNOp(MachineInstrBuilder &MIB, unsigned Cond); 739 void 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. 745 unsigned 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. 752 bool 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