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