llvm/llvm/lib/Target/AArch64/AArch64InstrInfo.h

//===- 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