//===- AArch64InstrInfo.h - AArch64 Instruction Information -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains the AArch64 implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H #define LLVM_LIB_TARGET_AARCH64_AARCH64INSTRINFO_H #include "AArch64.h" #include "AArch64RegisterInfo.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/Support/TypeSize.h" #include <optional> #define GET_INSTRINFO_HEADER #include "AArch64GenInstrInfo.inc" namespace llvm { class AArch64Subtarget; static const MachineMemOperand::Flags MOSuppressPair = …; static const MachineMemOperand::Flags MOStridedAccess = …; #define FALKOR_STRIDED_ACCESS_MD … // AArch64 MachineCombiner patterns enum AArch64MachineCombinerPattern : unsigned { … }; class AArch64InstrInfo final : public AArch64GenInstrInfo { … }; struct UsedNZCV { … }; /// \returns Conditions flags used after \p CmpInstr in its MachineBB if NZCV /// flags are not alive in successors of the same \p CmpInstr and \p MI parent. /// \returns std::nullopt otherwise. /// /// Collect instructions using that flags in \p CCUseInstrs if provided. std::optional<UsedNZCV> examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl<MachineInstr *> *CCUseInstrs = nullptr); /// Return true if there is an instruction /after/ \p DefMI and before \p UseMI /// which either reads or clobbers NZCV. bool isNZCVTouchedInInstructionRange(const MachineInstr &DefMI, const MachineInstr &UseMI, const TargetRegisterInfo *TRI); MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg, unsigned Reg, const StackOffset &Offset, bool LastAdjustmentWasScalable = true); MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg, const StackOffset &OffsetFromDefCFA); /// emitFrameOffset - Emit instructions as needed to set DestReg to SrcReg /// plus Offset. This is intended to be used from within the prolog/epilog /// insertion (PEI) pass, where a virtual scratch register may be allocated /// if necessary, to be replaced by the scavenger at the end of PEI. void emitFrameOffset(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, StackOffset Offset, const TargetInstrInfo *TII, MachineInstr::MIFlag = MachineInstr::NoFlags, bool SetNZCV = false, bool NeedsWinCFI = false, bool *HasWinCFI = nullptr, bool EmitCFAOffset = false, StackOffset InitialOffset = { … }; /// rewriteAArch64FrameIndex - Rewrite MI to access 'Offset' bytes from the /// FP. Return false if the offset could not be handled directly in MI, and /// return the left-over portion by reference. bool rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, StackOffset &Offset, const AArch64InstrInfo *TII); /// Use to report the frame offset status in isAArch64FrameOffsetLegal. enum AArch64FrameOffsetStatus { … }; /// Check if the @p Offset is a valid frame offset for @p MI. /// The returned value reports the validity of the frame offset for @p MI. /// It uses the values defined by AArch64FrameOffsetStatus for that. /// If result == AArch64FrameOffsetCannotUpdate, @p MI cannot be updated to /// use an offset.eq /// If result & AArch64FrameOffsetIsLegal, @p Offset can completely be /// rewritten in @p MI. /// If result & AArch64FrameOffsetCanUpdate, @p Offset contains the /// amount that is off the limit of the legal offset. /// If set, @p OutUseUnscaledOp will contain the whether @p MI should be /// turned into an unscaled operator, which opcode is in @p OutUnscaledOp. /// If set, @p EmittableOffset contains the amount that can be set in @p MI /// (possibly with @p OutUnscaledOp if OutUseUnscaledOp is true) and that /// is a legal offset. int isAArch64FrameOffsetLegal(const MachineInstr &MI, StackOffset &Offset, bool *OutUseUnscaledOp = nullptr, unsigned *OutUnscaledOp = nullptr, int64_t *EmittableOffset = nullptr); static inline bool isUncondBranchOpcode(int Opc) { … } static inline bool isCondBranchOpcode(int Opc) { … } static inline bool isIndirectBranchOpcode(int Opc) { … } static inline bool isPTrueOpcode(unsigned Opc) { … } /// Return opcode to be used for indirect calls. unsigned getBLRCallOpcode(const MachineFunction &MF); /// Return XPAC opcode to be used for a ptrauth strip using the given key. static inline unsigned getXPACOpcodeForKey(AArch64PACKey::ID K) { … } /// Return AUT opcode to be used for a ptrauth auth using the given key, or its /// AUT*Z variant that doesn't take a discriminator operand, using zero instead. static inline unsigned getAUTOpcodeForKey(AArch64PACKey::ID K, bool Zero) { … } /// Return PAC opcode to be used for a ptrauth sign using the given key, or its /// PAC*Z variant that doesn't take a discriminator operand, using zero instead. static inline unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero) { … } // struct TSFlags { #define TSFLAG_ELEMENT_SIZE_TYPE … #define TSFLAG_DESTRUCTIVE_INST_TYPE … #define TSFLAG_FALSE_LANE_TYPE … #define TSFLAG_INSTR_FLAGS … #define TSFLAG_SME_MATRIX_TYPE … // } AArch64 } // end namespace llvm #endif