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 "llvm/IR/IntrinsicInst.h" 25 #include "llvm/IR/IntrinsicsARM.h" 26 #include <array> 27 #include <cstdint> 28 29 #define GET_INSTRINFO_HEADER 30 #include "ARMGenInstrInfo.inc" 31 32 namespace llvm { 33 34 class ARMBaseRegisterInfo; 35 class ARMSubtarget; 36 37 class ARMBaseInstrInfo : public ARMGenInstrInfo { 38 const ARMSubtarget &Subtarget; 39 40 protected: 41 // Can be only subclassed. 42 explicit ARMBaseInstrInfo(const ARMSubtarget &STI); 43 44 void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, 45 unsigned LoadImmOpc, unsigned LoadOpc) const; 46 47 /// Build the equivalent inputs of a REG_SEQUENCE for the given \p MI 48 /// and \p DefIdx. 49 /// \p [out] InputRegs of the equivalent REG_SEQUENCE. Each element of 50 /// the list is modeled as <Reg:SubReg, SubIdx>. 51 /// E.g., REG_SEQUENCE %1:sub1, sub0, %2, sub1 would produce 52 /// two elements: 53 /// - %1:sub1, sub0 54 /// - %2<:0>, sub1 55 /// 56 /// \returns true if it is possible to build such an input sequence 57 /// with the pair \p MI, \p DefIdx. False otherwise. 58 /// 59 /// \pre MI.isRegSequenceLike(). 60 bool getRegSequenceLikeInputs( 61 const MachineInstr &MI, unsigned DefIdx, 62 SmallVectorImpl<RegSubRegPairAndIdx> &InputRegs) const override; 63 64 /// Build the equivalent inputs of a EXTRACT_SUBREG for the given \p MI 65 /// and \p DefIdx. 66 /// \p [out] InputReg of the equivalent EXTRACT_SUBREG. 67 /// E.g., EXTRACT_SUBREG %1:sub1, sub0, sub1 would produce: 68 /// - %1:sub1, sub0 69 /// 70 /// \returns true if it is possible to build such an input sequence 71 /// with the pair \p MI, \p DefIdx. False otherwise. 72 /// 73 /// \pre MI.isExtractSubregLike(). 74 bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, 75 RegSubRegPairAndIdx &InputReg) const override; 76 77 /// Build the equivalent inputs of a INSERT_SUBREG for the given \p MI 78 /// and \p DefIdx. 79 /// \p [out] BaseReg and \p [out] InsertedReg contain 80 /// the equivalent inputs of INSERT_SUBREG. 81 /// E.g., INSERT_SUBREG %0:sub0, %1:sub1, sub3 would produce: 82 /// - BaseReg: %0:sub0 83 /// - InsertedReg: %1:sub1, sub3 84 /// 85 /// \returns true if it is possible to build such an input sequence 86 /// with the pair \p MI, \p DefIdx. False otherwise. 87 /// 88 /// \pre MI.isInsertSubregLike(). 89 bool 90 getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, 91 RegSubRegPair &BaseReg, 92 RegSubRegPairAndIdx &InsertedReg) const override; 93 94 /// Commutes the operands in the given instruction. 95 /// The commutable operands are specified by their indices OpIdx1 and OpIdx2. 96 /// 97 /// Do not call this method for a non-commutable instruction or for 98 /// non-commutable pair of operand indices OpIdx1 and OpIdx2. 99 /// Even though the instruction is commutable, the method may still 100 /// fail to commute the operands, null pointer is returned in such cases. 101 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 102 unsigned OpIdx1, 103 unsigned OpIdx2) const override; 104 /// If the specific machine instruction is an instruction that moves/copies 105 /// value from one register to another register return destination and source 106 /// registers as machine operands. 107 Optional<DestSourcePair> 108 isCopyInstrImpl(const MachineInstr &MI) const override; 109 110 /// Specialization of \ref TargetInstrInfo::describeLoadedValue, used to 111 /// enhance debug entry value descriptions for ARM targets. 112 Optional<ParamLoadedValue> describeLoadedValue(const MachineInstr &MI, 113 Register Reg) const override; 114 115 public: 116 // Return whether the target has an explicit NOP encoding. 117 bool hasNOP() const; 118 119 // Return the non-pre/post incrementing version of 'Opc'. Return 0 120 // if there is not such an opcode. 121 virtual unsigned getUnindexedOpcode(unsigned Opc) const = 0; 122 123 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI, 124 MachineInstr &MI, 125 LiveVariables *LV) const override; 126 127 virtual const ARMBaseRegisterInfo &getRegisterInfo() const = 0; 128 const ARMSubtarget &getSubtarget() const { return Subtarget; } 129 130 ScheduleHazardRecognizer * 131 CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, 132 const ScheduleDAG *DAG) const override; 133 134 ScheduleHazardRecognizer * 135 CreateTargetMIHazardRecognizer(const InstrItineraryData *II, 136 const ScheduleDAGMI *DAG) const override; 137 138 ScheduleHazardRecognizer * 139 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 140 const ScheduleDAG *DAG) const override; 141 142 // Branch analysis. 143 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 144 MachineBasicBlock *&FBB, 145 SmallVectorImpl<MachineOperand> &Cond, 146 bool AllowModify = false) const override; 147 unsigned removeBranch(MachineBasicBlock &MBB, 148 int *BytesRemoved = nullptr) const override; 149 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 150 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 151 const DebugLoc &DL, 152 int *BytesAdded = nullptr) const override; 153 154 bool 155 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 156 157 // Predication support. 158 bool isPredicated(const MachineInstr &MI) const override; 159 160 // MIR printer helper function to annotate Operands with a comment. 161 std::string 162 createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, 163 unsigned OpIdx, 164 const TargetRegisterInfo *TRI) const override; 165 166 ARMCC::CondCodes getPredicate(const MachineInstr &MI) const { 167 int PIdx = MI.findFirstPredOperandIdx(); 168 return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm() 169 : ARMCC::AL; 170 } 171 172 bool PredicateInstruction(MachineInstr &MI, 173 ArrayRef<MachineOperand> Pred) const override; 174 175 bool SubsumesPredicate(ArrayRef<MachineOperand> Pred1, 176 ArrayRef<MachineOperand> Pred2) const override; 177 178 bool ClobbersPredicate(MachineInstr &MI, std::vector<MachineOperand> &Pred, 179 bool SkipDead) const override; 180 181 bool isPredicable(const MachineInstr &MI) const override; 182 183 // CPSR defined in instruction 184 static bool isCPSRDefined(const MachineInstr &MI); 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, MCRegister DestReg, MCRegister SrcReg, 208 bool KillSrc) const override; 209 210 void storeRegToStackSlot(MachineBasicBlock &MBB, 211 MachineBasicBlock::iterator MBBI, 212 Register 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 Register 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 Register 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 bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, 276 BranchProbability Probability) const override { 277 return NumCycles == 1; 278 } 279 280 unsigned extraSizeToPredicateInstructions(const MachineFunction &MF, 281 unsigned NumInsts) const override; 282 unsigned predictBranchSizeForIfCvt(MachineInstr &MI) const override; 283 284 bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, 285 MachineBasicBlock &FMBB) const override; 286 287 /// analyzeCompare - For a comparison instruction, return the source registers 288 /// in SrcReg and SrcReg2 if having two register operands, and the value it 289 /// compares against in CmpValue. Return true if the comparison instruction 290 /// can be analyzed. 291 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, 292 Register &SrcReg2, int &CmpMask, 293 int &CmpValue) const override; 294 295 /// optimizeCompareInstr - Convert the instruction to set the zero flag so 296 /// that we can remove a "comparison with zero"; Remove a redundant CMP 297 /// instruction if the flags can be updated in the same way by an earlier 298 /// instruction such as SUB. 299 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, 300 Register SrcReg2, int CmpMask, int CmpValue, 301 const MachineRegisterInfo *MRI) const override; 302 303 bool analyzeSelect(const MachineInstr &MI, 304 SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp, 305 unsigned &FalseOp, bool &Optimizable) const override; 306 307 MachineInstr *optimizeSelect(MachineInstr &MI, 308 SmallPtrSetImpl<MachineInstr *> &SeenMIs, 309 bool) const override; 310 311 /// FoldImmediate - 'Reg' is known to be defined by a move immediate 312 /// instruction, try to fold the immediate into the use instruction. 313 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, 314 MachineRegisterInfo *MRI) const override; 315 316 unsigned getNumMicroOps(const InstrItineraryData *ItinData, 317 const MachineInstr &MI) const override; 318 319 int getOperandLatency(const InstrItineraryData *ItinData, 320 const MachineInstr &DefMI, unsigned DefIdx, 321 const MachineInstr &UseMI, 322 unsigned UseIdx) const override; 323 int getOperandLatency(const InstrItineraryData *ItinData, 324 SDNode *DefNode, unsigned DefIdx, 325 SDNode *UseNode, unsigned UseIdx) const override; 326 327 /// VFP/NEON execution domains. 328 std::pair<uint16_t, uint16_t> 329 getExecutionDomain(const MachineInstr &MI) const override; 330 void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override; 331 332 unsigned 333 getPartialRegUpdateClearance(const MachineInstr &, unsigned, 334 const TargetRegisterInfo *) const override; 335 void breakPartialRegDependency(MachineInstr &, unsigned, 336 const TargetRegisterInfo *TRI) const override; 337 338 /// Get the number of addresses by LDM or VLDM or zero for unknown. 339 unsigned getNumLDMAddresses(const MachineInstr &MI) const; 340 341 std::pair<unsigned, unsigned> 342 decomposeMachineOperandsTargetFlags(unsigned TF) const override; 343 ArrayRef<std::pair<unsigned, const char *>> 344 getSerializableDirectMachineOperandTargetFlags() const override; 345 ArrayRef<std::pair<unsigned, const char *>> 346 getSerializableBitmaskMachineOperandTargetFlags() const override; 347 348 /// ARM supports the MachineOutliner. 349 bool isFunctionSafeToOutlineFrom(MachineFunction &MF, 350 bool OutlineFromLinkOnceODRs) const override; 351 outliner::OutlinedFunction getOutliningCandidateInfo( 352 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const override; 353 outliner::InstrType getOutliningType(MachineBasicBlock::iterator &MIT, 354 unsigned Flags) const override; 355 bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 356 unsigned &Flags) const override; 357 void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, 358 const outliner::OutlinedFunction &OF) const override; 359 MachineBasicBlock::iterator 360 insertOutlinedCall(Module &M, MachineBasicBlock &MBB, 361 MachineBasicBlock::iterator &It, MachineFunction &MF, 362 const outliner::Candidate &C) const override; 363 364 /// Enable outlining by default at -Oz. 365 bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; 366 367 bool isUnspillableTerminatorImpl(const MachineInstr *MI) const override { 368 return MI->getOpcode() == ARM::t2LoopEndDec || 369 MI->getOpcode() == ARM::t2DoLoopStartTP || 370 MI->getOpcode() == ARM::t2WhileLoopStartLR; 371 } 372 373 private: 374 /// Returns an unused general-purpose register which can be used for 375 /// constructing an outlined call if one exists. Returns 0 otherwise. 376 unsigned findRegisterToSaveLRTo(const outliner::Candidate &C) const; 377 378 // Adds an instruction which saves the link register on top of the stack into 379 /// the MachineBasicBlock \p MBB at position \p It. 380 void saveLROnStack(MachineBasicBlock &MBB, 381 MachineBasicBlock::iterator It) const; 382 383 /// Adds an instruction which restores the link register from the top the 384 /// stack into the MachineBasicBlock \p MBB at position \p It. 385 void restoreLRFromStack(MachineBasicBlock &MBB, 386 MachineBasicBlock::iterator It) const; 387 388 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 389 /// for the case when the LR is saved on the stack. 390 void emitCFIForLRSaveOnStack(MachineBasicBlock &MBB, 391 MachineBasicBlock::iterator It) const; 392 393 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 394 /// for the case when the LR is saved in the register \p Reg. 395 void emitCFIForLRSaveToReg(MachineBasicBlock &MBB, 396 MachineBasicBlock::iterator It, 397 Register Reg) const; 398 399 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 400 /// after the LR is was restored from the stack. 401 void emitCFIForLRRestoreFromStack(MachineBasicBlock &MBB, 402 MachineBasicBlock::iterator It) const; 403 404 /// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It, 405 /// after the LR is was restored from a register. 406 void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB, 407 MachineBasicBlock::iterator It) const; 408 /// \brief Sets the offsets on outlined instructions in \p MBB which use SP 409 /// so that they will be valid post-outlining. 410 /// 411 /// \param MBB A \p MachineBasicBlock in an outlined function. 412 void fixupPostOutline(MachineBasicBlock &MBB) const; 413 414 /// Returns true if the machine instruction offset can handle the stack fixup 415 /// and updates it if requested. 416 bool checkAndUpdateStackOffset(MachineInstr *MI, int64_t Fixup, 417 bool Updt) const; 418 419 unsigned getInstBundleLength(const MachineInstr &MI) const; 420 421 int getVLDMDefCycle(const InstrItineraryData *ItinData, 422 const MCInstrDesc &DefMCID, 423 unsigned DefClass, 424 unsigned DefIdx, unsigned DefAlign) const; 425 int getLDMDefCycle(const InstrItineraryData *ItinData, 426 const MCInstrDesc &DefMCID, 427 unsigned DefClass, 428 unsigned DefIdx, unsigned DefAlign) const; 429 int getVSTMUseCycle(const InstrItineraryData *ItinData, 430 const MCInstrDesc &UseMCID, 431 unsigned UseClass, 432 unsigned UseIdx, unsigned UseAlign) const; 433 int getSTMUseCycle(const InstrItineraryData *ItinData, 434 const MCInstrDesc &UseMCID, 435 unsigned UseClass, 436 unsigned UseIdx, unsigned UseAlign) const; 437 int getOperandLatency(const InstrItineraryData *ItinData, 438 const MCInstrDesc &DefMCID, 439 unsigned DefIdx, unsigned DefAlign, 440 const MCInstrDesc &UseMCID, 441 unsigned UseIdx, unsigned UseAlign) const; 442 443 int getOperandLatencyImpl(const InstrItineraryData *ItinData, 444 const MachineInstr &DefMI, unsigned DefIdx, 445 const MCInstrDesc &DefMCID, unsigned DefAdj, 446 const MachineOperand &DefMO, unsigned Reg, 447 const MachineInstr &UseMI, unsigned UseIdx, 448 const MCInstrDesc &UseMCID, unsigned UseAdj) const; 449 450 unsigned getPredicationCost(const MachineInstr &MI) const override; 451 452 unsigned getInstrLatency(const InstrItineraryData *ItinData, 453 const MachineInstr &MI, 454 unsigned *PredCost = nullptr) const override; 455 456 int getInstrLatency(const InstrItineraryData *ItinData, 457 SDNode *Node) const override; 458 459 bool hasHighOperandLatency(const TargetSchedModel &SchedModel, 460 const MachineRegisterInfo *MRI, 461 const MachineInstr &DefMI, unsigned DefIdx, 462 const MachineInstr &UseMI, 463 unsigned UseIdx) const override; 464 bool hasLowDefLatency(const TargetSchedModel &SchedModel, 465 const MachineInstr &DefMI, 466 unsigned DefIdx) const override; 467 468 /// verifyInstruction - Perform target specific instruction verification. 469 bool verifyInstruction(const MachineInstr &MI, 470 StringRef &ErrInfo) const override; 471 472 virtual void expandLoadStackGuard(MachineBasicBlock::iterator MI) const = 0; 473 474 void expandMEMCPY(MachineBasicBlock::iterator) const; 475 476 /// Identify instructions that can be folded into a MOVCC instruction, and 477 /// return the defining instruction. 478 MachineInstr *canFoldIntoMOVCC(Register Reg, const MachineRegisterInfo &MRI, 479 const TargetInstrInfo *TII) const; 480 481 bool isReallyTriviallyReMaterializable(const MachineInstr &MI, 482 AAResults *AA) const override; 483 484 private: 485 /// Modeling special VFP / NEON fp MLA / MLS hazards. 486 487 /// MLxEntryMap - Map fp MLA / MLS to the corresponding entry in the internal 488 /// MLx table. 489 DenseMap<unsigned, unsigned> MLxEntryMap; 490 491 /// MLxHazardOpcodes - Set of add / sub and multiply opcodes that would cause 492 /// stalls when scheduled together with fp MLA / MLS opcodes. 493 SmallSet<unsigned, 16> MLxHazardOpcodes; 494 495 public: 496 /// isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS 497 /// instruction. 498 bool isFpMLxInstruction(unsigned Opcode) const { 499 return MLxEntryMap.count(Opcode); 500 } 501 502 /// isFpMLxInstruction - This version also returns the multiply opcode and the 503 /// addition / subtraction opcode to expand to. Return true for 'HasLane' for 504 /// the MLX instructions with an extra lane operand. 505 bool isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, 506 unsigned &AddSubOpc, bool &NegAcc, 507 bool &HasLane) const; 508 509 /// canCauseFpMLxStall - Return true if an instruction of the specified opcode 510 /// will cause stalls when scheduled after (within 4-cycle window) a fp 511 /// MLA / MLS instruction. 512 bool canCauseFpMLxStall(unsigned Opcode) const { 513 return MLxHazardOpcodes.count(Opcode); 514 } 515 516 /// Returns true if the instruction has a shift by immediate that can be 517 /// executed in one cycle less. 518 bool isSwiftFastImmShift(const MachineInstr *MI) const; 519 520 /// Returns predicate register associated with the given frame instruction. 521 unsigned getFramePred(const MachineInstr &MI) const { 522 assert(isFrameInstr(MI)); 523 // Operands of ADJCALLSTACKDOWN/ADJCALLSTACKUP: 524 // - argument declared in the pattern: 525 // 0 - frame size 526 // 1 - arg of CALLSEQ_START/CALLSEQ_END 527 // 2 - predicate code (like ARMCC::AL) 528 // - added by predOps: 529 // 3 - predicate reg 530 return MI.getOperand(3).getReg(); 531 } 532 533 Optional<RegImmPair> isAddImmediate(const MachineInstr &MI, 534 Register Reg) const override; 535 }; 536 537 /// Get the operands corresponding to the given \p Pred value. By default, the 538 /// predicate register is assumed to be 0 (no register), but you can pass in a 539 /// \p PredReg if that is not the case. 540 static inline std::array<MachineOperand, 2> predOps(ARMCC::CondCodes Pred, 541 unsigned PredReg = 0) { 542 return {{MachineOperand::CreateImm(static_cast<int64_t>(Pred)), 543 MachineOperand::CreateReg(PredReg, false)}}; 544 } 545 546 /// Get the operand corresponding to the conditional code result. By default, 547 /// this is 0 (no register). 548 static inline MachineOperand condCodeOp(unsigned CCReg = 0) { 549 return MachineOperand::CreateReg(CCReg, false); 550 } 551 552 /// Get the operand corresponding to the conditional code result for Thumb1. 553 /// This operand will always refer to CPSR and it will have the Define flag set. 554 /// You can optionally set the Dead flag by means of \p isDead. 555 static inline MachineOperand t1CondCodeOp(bool isDead = false) { 556 return MachineOperand::CreateReg(ARM::CPSR, 557 /*Define*/ true, /*Implicit*/ false, 558 /*Kill*/ false, isDead); 559 } 560 561 static inline 562 bool isUncondBranchOpcode(int Opc) { 563 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B; 564 } 565 566 // This table shows the VPT instruction variants, i.e. the different 567 // mask field encodings, see also B5.6. Predication/conditional execution in 568 // the ArmARM. 569 static inline bool isVPTOpcode(int Opc) { 570 return Opc == ARM::MVE_VPTv16i8 || Opc == ARM::MVE_VPTv16u8 || 571 Opc == ARM::MVE_VPTv16s8 || Opc == ARM::MVE_VPTv8i16 || 572 Opc == ARM::MVE_VPTv8u16 || Opc == ARM::MVE_VPTv8s16 || 573 Opc == ARM::MVE_VPTv4i32 || Opc == ARM::MVE_VPTv4u32 || 574 Opc == ARM::MVE_VPTv4s32 || Opc == ARM::MVE_VPTv4f32 || 575 Opc == ARM::MVE_VPTv8f16 || Opc == ARM::MVE_VPTv16i8r || 576 Opc == ARM::MVE_VPTv16u8r || Opc == ARM::MVE_VPTv16s8r || 577 Opc == ARM::MVE_VPTv8i16r || Opc == ARM::MVE_VPTv8u16r || 578 Opc == ARM::MVE_VPTv8s16r || Opc == ARM::MVE_VPTv4i32r || 579 Opc == ARM::MVE_VPTv4u32r || Opc == ARM::MVE_VPTv4s32r || 580 Opc == ARM::MVE_VPTv4f32r || Opc == ARM::MVE_VPTv8f16r || 581 Opc == ARM::MVE_VPST; 582 } 583 584 static inline 585 unsigned VCMPOpcodeToVPT(unsigned Opcode) { 586 switch (Opcode) { 587 default: 588 return 0; 589 case ARM::MVE_VCMPf32: 590 return ARM::MVE_VPTv4f32; 591 case ARM::MVE_VCMPf16: 592 return ARM::MVE_VPTv8f16; 593 case ARM::MVE_VCMPi8: 594 return ARM::MVE_VPTv16i8; 595 case ARM::MVE_VCMPi16: 596 return ARM::MVE_VPTv8i16; 597 case ARM::MVE_VCMPi32: 598 return ARM::MVE_VPTv4i32; 599 case ARM::MVE_VCMPu8: 600 return ARM::MVE_VPTv16u8; 601 case ARM::MVE_VCMPu16: 602 return ARM::MVE_VPTv8u16; 603 case ARM::MVE_VCMPu32: 604 return ARM::MVE_VPTv4u32; 605 case ARM::MVE_VCMPs8: 606 return ARM::MVE_VPTv16s8; 607 case ARM::MVE_VCMPs16: 608 return ARM::MVE_VPTv8s16; 609 case ARM::MVE_VCMPs32: 610 return ARM::MVE_VPTv4s32; 611 612 case ARM::MVE_VCMPf32r: 613 return ARM::MVE_VPTv4f32r; 614 case ARM::MVE_VCMPf16r: 615 return ARM::MVE_VPTv8f16r; 616 case ARM::MVE_VCMPi8r: 617 return ARM::MVE_VPTv16i8r; 618 case ARM::MVE_VCMPi16r: 619 return ARM::MVE_VPTv8i16r; 620 case ARM::MVE_VCMPi32r: 621 return ARM::MVE_VPTv4i32r; 622 case ARM::MVE_VCMPu8r: 623 return ARM::MVE_VPTv16u8r; 624 case ARM::MVE_VCMPu16r: 625 return ARM::MVE_VPTv8u16r; 626 case ARM::MVE_VCMPu32r: 627 return ARM::MVE_VPTv4u32r; 628 case ARM::MVE_VCMPs8r: 629 return ARM::MVE_VPTv16s8r; 630 case ARM::MVE_VCMPs16r: 631 return ARM::MVE_VPTv8s16r; 632 case ARM::MVE_VCMPs32r: 633 return ARM::MVE_VPTv4s32r; 634 } 635 } 636 637 static inline 638 bool isCondBranchOpcode(int Opc) { 639 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc; 640 } 641 642 static inline bool isJumpTableBranchOpcode(int Opc) { 643 return Opc == ARM::BR_JTr || Opc == ARM::BR_JTm_i12 || 644 Opc == ARM::BR_JTm_rs || Opc == ARM::BR_JTadd || Opc == ARM::tBR_JTr || 645 Opc == ARM::t2BR_JT; 646 } 647 648 static inline bool isLowOverheadTerminatorOpcode(int Opc) { 649 return Opc == ARM::t2DoLoopStartTP || Opc == ARM::t2WhileLoopStart || 650 Opc == ARM::t2WhileLoopStartLR || Opc == ARM::t2LoopEnd || 651 Opc == ARM::t2LoopEndDec; 652 } 653 654 static inline 655 bool isIndirectBranchOpcode(int Opc) { 656 return Opc == ARM::BX || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; 657 } 658 659 static inline bool isIndirectCall(const MachineInstr &MI) { 660 int Opc = MI.getOpcode(); 661 switch (Opc) { 662 // indirect calls: 663 case ARM::BLX: 664 case ARM::BLX_noip: 665 case ARM::BLX_pred: 666 case ARM::BLX_pred_noip: 667 case ARM::BX_CALL: 668 case ARM::BMOVPCRX_CALL: 669 case ARM::TCRETURNri: 670 case ARM::TAILJMPr: 671 case ARM::TAILJMPr4: 672 case ARM::tBLXr: 673 case ARM::tBLXr_noip: 674 case ARM::tBLXNSr: 675 case ARM::tBLXNS_CALL: 676 case ARM::tBX_CALL: 677 case ARM::tTAILJMPr: 678 assert(MI.isCall(MachineInstr::IgnoreBundle)); 679 return true; 680 // direct calls: 681 case ARM::BL: 682 case ARM::BL_pred: 683 case ARM::BMOVPCB_CALL: 684 case ARM::BL_PUSHLR: 685 case ARM::BLXi: 686 case ARM::TCRETURNdi: 687 case ARM::TAILJMPd: 688 case ARM::SVC: 689 case ARM::HVC: 690 case ARM::TPsoft: 691 case ARM::tTAILJMPd: 692 case ARM::t2SMC: 693 case ARM::t2HVC: 694 case ARM::tBL: 695 case ARM::tBLXi: 696 case ARM::tBL_PUSHLR: 697 case ARM::tTAILJMPdND: 698 case ARM::tSVC: 699 case ARM::tTPsoft: 700 assert(MI.isCall(MachineInstr::IgnoreBundle)); 701 return false; 702 } 703 assert(!MI.isCall(MachineInstr::IgnoreBundle)); 704 return false; 705 } 706 707 static inline bool isIndirectControlFlowNotComingBack(const MachineInstr &MI) { 708 int opc = MI.getOpcode(); 709 return MI.isReturn() || isIndirectBranchOpcode(MI.getOpcode()) || 710 isJumpTableBranchOpcode(opc); 711 } 712 713 static inline bool isSpeculationBarrierEndBBOpcode(int Opc) { 714 return Opc == ARM::SpeculationBarrierISBDSBEndBB || 715 Opc == ARM::SpeculationBarrierSBEndBB || 716 Opc == ARM::t2SpeculationBarrierISBDSBEndBB || 717 Opc == ARM::t2SpeculationBarrierSBEndBB; 718 } 719 720 static inline bool isPopOpcode(int Opc) { 721 return Opc == ARM::tPOP_RET || Opc == ARM::LDMIA_RET || 722 Opc == ARM::t2LDMIA_RET || Opc == ARM::tPOP || Opc == ARM::LDMIA_UPD || 723 Opc == ARM::t2LDMIA_UPD || Opc == ARM::VLDMDIA_UPD; 724 } 725 726 static inline bool isPushOpcode(int Opc) { 727 return Opc == ARM::tPUSH || Opc == ARM::t2STMDB_UPD || 728 Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD; 729 } 730 731 static inline bool isSubImmOpcode(int Opc) { 732 return Opc == ARM::SUBri || 733 Opc == ARM::tSUBi3 || Opc == ARM::tSUBi8 || 734 Opc == ARM::tSUBSi3 || Opc == ARM::tSUBSi8 || 735 Opc == ARM::t2SUBri || Opc == ARM::t2SUBri12 || Opc == ARM::t2SUBSri; 736 } 737 738 static inline bool isMovRegOpcode(int Opc) { 739 return Opc == ARM::MOVr || Opc == ARM::tMOVr || Opc == ARM::t2MOVr; 740 } 741 /// isValidCoprocessorNumber - decide whether an explicit coprocessor 742 /// number is legal in generic instructions like CDP. The answer can 743 /// vary with the subtarget. 744 static inline bool isValidCoprocessorNumber(unsigned Num, 745 const FeatureBitset& featureBits) { 746 // In Armv7 and Armv8-M CP10 and CP11 clash with VFP/NEON, however, the 747 // coprocessor is still valid for CDP/MCR/MRC and friends. Allowing it is 748 // useful for code which is shared with older architectures which do not know 749 // the new VFP/NEON mnemonics. 750 751 // Armv8-A disallows everything *other* than 111x (CP14 and CP15). 752 if (featureBits[ARM::HasV8Ops] && (Num & 0xE) != 0xE) 753 return false; 754 755 // Armv8.1-M disallows 100x (CP8,CP9) and 111x (CP14,CP15) 756 // which clash with MVE. 757 if (featureBits[ARM::HasV8_1MMainlineOps] && 758 ((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE)) 759 return false; 760 761 return true; 762 } 763 764 /// getInstrPredicate - If instruction is predicated, returns its predicate 765 /// condition, otherwise returns AL. It also returns the condition code 766 /// register by reference. 767 ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg); 768 769 unsigned getMatchingCondBranchOpcode(unsigned Opc); 770 771 /// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether 772 /// the instruction is encoded with an 'S' bit is determined by the optional 773 /// CPSR def operand. 774 unsigned convertAddSubFlagsOpcode(unsigned OldOpc); 775 776 /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of 777 /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 778 /// code. 779 void emitARMRegPlusImmediate(MachineBasicBlock &MBB, 780 MachineBasicBlock::iterator &MBBI, 781 const DebugLoc &dl, Register DestReg, 782 Register BaseReg, int NumBytes, 783 ARMCC::CondCodes Pred, Register PredReg, 784 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 785 786 void emitT2RegPlusImmediate(MachineBasicBlock &MBB, 787 MachineBasicBlock::iterator &MBBI, 788 const DebugLoc &dl, Register DestReg, 789 Register BaseReg, int NumBytes, 790 ARMCC::CondCodes Pred, Register PredReg, 791 const ARMBaseInstrInfo &TII, unsigned MIFlags = 0); 792 void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, 793 MachineBasicBlock::iterator &MBBI, 794 const DebugLoc &dl, Register DestReg, 795 Register BaseReg, int NumBytes, 796 const TargetInstrInfo &TII, 797 const ARMBaseRegisterInfo &MRI, 798 unsigned MIFlags = 0); 799 800 /// Tries to add registers to the reglist of a given base-updating 801 /// push/pop instruction to adjust the stack by an additional 802 /// NumBytes. This can save a few bytes per function in code-size, but 803 /// obviously generates more memory traffic. As such, it only takes 804 /// effect in functions being optimised for size. 805 bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, 806 MachineFunction &MF, MachineInstr *MI, 807 unsigned NumBytes); 808 809 /// rewriteARMFrameIndex / rewriteT2FrameIndex - 810 /// Rewrite MI to access 'Offset' bytes from the FP. Return false if the 811 /// offset could not be handled directly in MI, and return the left-over 812 /// portion by reference. 813 bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 814 Register FrameReg, int &Offset, 815 const ARMBaseInstrInfo &TII); 816 817 bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 818 Register FrameReg, int &Offset, 819 const ARMBaseInstrInfo &TII, 820 const TargetRegisterInfo *TRI); 821 822 /// Return true if Reg is defd between From and To 823 bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From, 824 MachineBasicBlock::iterator To, 825 const TargetRegisterInfo *TRI); 826 827 /// Search backwards from a tBcc to find a tCMPi8 against 0, meaning 828 /// we can convert them to a tCBZ or tCBNZ. Return nullptr if not found. 829 MachineInstr *findCMPToFoldIntoCBZ(MachineInstr *Br, 830 const TargetRegisterInfo *TRI); 831 832 void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB); 833 void addUnpredicatedMveVpredROp(MachineInstrBuilder &MIB, Register DestReg); 834 835 void addPredicatedMveVpredNOp(MachineInstrBuilder &MIB, unsigned Cond); 836 void addPredicatedMveVpredROp(MachineInstrBuilder &MIB, unsigned Cond, 837 unsigned Inactive); 838 839 /// Returns the number of instructions required to materialize the given 840 /// constant in a register, or 3 if a literal pool load is needed. 841 /// If ForCodesize is specified, an approximate cost in bytes is returned. 842 unsigned ConstantMaterializationCost(unsigned Val, 843 const ARMSubtarget *Subtarget, 844 bool ForCodesize = false); 845 846 /// Returns true if Val1 has a lower Constant Materialization Cost than Val2. 847 /// Uses the cost from ConstantMaterializationCost, first with ForCodesize as 848 /// specified. If the scores are equal, return the comparison for !ForCodesize. 849 bool HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2, 850 const ARMSubtarget *Subtarget, 851 bool ForCodesize = false); 852 853 // Return the immediate if this is ADDri or SUBri, scaled as appropriate. 854 // Returns 0 for unknown instructions. 855 inline int getAddSubImmediate(MachineInstr &MI) { 856 int Scale = 1; 857 unsigned ImmOp; 858 switch (MI.getOpcode()) { 859 case ARM::t2ADDri: 860 ImmOp = 2; 861 break; 862 case ARM::t2SUBri: 863 case ARM::t2SUBri12: 864 ImmOp = 2; 865 Scale = -1; 866 break; 867 case ARM::tSUBi3: 868 case ARM::tSUBi8: 869 ImmOp = 3; 870 Scale = -1; 871 break; 872 default: 873 return 0; 874 } 875 return Scale * MI.getOperand(ImmOp).getImm(); 876 } 877 878 // Given a memory access Opcode, check that the give Imm would be a valid Offset 879 // for this instruction using its addressing mode. 880 inline bool isLegalAddressImm(unsigned Opcode, int Imm, 881 const TargetInstrInfo *TII) { 882 const MCInstrDesc &Desc = TII->get(Opcode); 883 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); 884 switch (AddrMode) { 885 case ARMII::AddrModeT2_i7: 886 return std::abs(Imm) < (((1 << 7) * 1) - 1); 887 case ARMII::AddrModeT2_i7s2: 888 return std::abs(Imm) < (((1 << 7) * 2) - 1) && Imm % 2 == 0; 889 case ARMII::AddrModeT2_i7s4: 890 return std::abs(Imm) < (((1 << 7) * 4) - 1) && Imm % 4 == 0; 891 case ARMII::AddrModeT2_i8: 892 return std::abs(Imm) < (((1 << 8) * 1) - 1); 893 case ARMII::AddrMode2: 894 return std::abs(Imm) < (((1 << 12) * 1) - 1); 895 case ARMII::AddrModeT2_i12: 896 return Imm >= 0 && Imm < (((1 << 12) * 1) - 1); 897 case ARMII::AddrModeT2_i8s4: 898 return std::abs(Imm) < (((1 << 8) * 4) - 1) && Imm % 4 == 0; 899 default: 900 llvm_unreachable("Unhandled Addressing mode"); 901 } 902 } 903 904 // Return true if the given intrinsic is a gather 905 inline bool isGather(IntrinsicInst *IntInst) { 906 if (IntInst == nullptr) 907 return false; 908 unsigned IntrinsicID = IntInst->getIntrinsicID(); 909 return (IntrinsicID == Intrinsic::masked_gather || 910 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base || 911 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_predicated || 912 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb || 913 IntrinsicID == Intrinsic::arm_mve_vldr_gather_base_wb_predicated || 914 IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset || 915 IntrinsicID == Intrinsic::arm_mve_vldr_gather_offset_predicated); 916 } 917 918 // Return true if the given intrinsic is a scatter 919 inline bool isScatter(IntrinsicInst *IntInst) { 920 if (IntInst == nullptr) 921 return false; 922 unsigned IntrinsicID = IntInst->getIntrinsicID(); 923 return (IntrinsicID == Intrinsic::masked_scatter || 924 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base || 925 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_predicated || 926 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_wb || 927 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_base_wb_predicated || 928 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_offset || 929 IntrinsicID == Intrinsic::arm_mve_vstr_scatter_offset_predicated); 930 } 931 932 // Return true if the given intrinsic is a gather or scatter 933 inline bool isGatherScatter(IntrinsicInst *IntInst) { 934 if (IntInst == nullptr) 935 return false; 936 return isGather(IntInst) || isScatter(IntInst); 937 } 938 939 unsigned getBLXOpcode(const MachineFunction &MF); 940 unsigned gettBLXrOpcode(const MachineFunction &MF); 941 unsigned getBLXpredOpcode(const MachineFunction &MF); 942 943 } // end namespace llvm 944 945 #endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H 946