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