#ifndef LLVM_TARGET_ARM64INSTRINFO_H
#define LLVM_TARGET_ARM64INSTRINFO_H
#include "ARM64.h"
#include "ARM64RegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "ARM64GenInstrInfo.inc"
namespace llvm {
class ARM64Subtarget;
class ARM64TargetMachine;
class ARM64InstrInfo : public ARM64GenInstrInfo {
enum TargetMemOperandFlags {
MOSuppressPair = 1
};
const ARM64RegisterInfo RI;
const ARM64Subtarget &Subtarget;
public:
explicit ARM64InstrInfo(const ARM64Subtarget &STI);
virtual const ARM64RegisterInfo &getRegisterInfo() const { return RI; }
unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
virtual bool isCoalescableExtInstr(const MachineInstr &MI,
unsigned &SrcReg, unsigned &DstReg,
unsigned &SubIdx) const;
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
unsigned isGPRZero(const MachineInstr *MI) const;
unsigned isGPRCopy(const MachineInstr *MI) const;
unsigned isFPRCopy(const MachineInstr *MI) const;
bool isScaledAddr(const MachineInstr *MI) const;
bool isLdStPairSuppressed(const MachineInstr *MI) const;
void suppressLdStPair(MachineInstr *MI) const;
virtual bool getLdStBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
unsigned &Offset,
const TargetRegisterInfo *TRI) const;
virtual bool enableClusterLoads() const { return true; }
virtual bool shouldClusterLoads(MachineInstr *FirstLdSt,
MachineInstr *SecondLdSt,
unsigned NumLoads) const;
virtual bool shouldScheduleAdjacent(MachineInstr* First,
MachineInstr *Second) const;
MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF,
int FrameIx, uint64_t Offset,
const MDNode *MDPtr,
DebugLoc DL) const;
void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
DebugLoc DL, unsigned DestReg, unsigned SrcReg,
bool KillSrc, unsigned Opcode,
llvm::ArrayRef<unsigned> Indices) const;
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const;
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
MachineInstr* MI,
const SmallVectorImpl<unsigned> &Ops,
int FrameIndex) const;
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify = false) const;
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const;
virtual bool
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
virtual bool canInsertSelect(const MachineBasicBlock&,
const SmallVectorImpl<MachineOperand> &Cond,
unsigned, unsigned, int&, int&, int&) const;
virtual void insertSelect(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
unsigned DstReg,
const SmallVectorImpl<MachineOperand> &Cond,
unsigned TrueReg, unsigned FalseReg) const;
virtual void getNoopForMachoTarget(MCInst &NopInst) const;
virtual bool analyzeCompare(const MachineInstr *MI, unsigned &SrcReg,
unsigned &SrcReg2, int &CmpMask,
int &CmpValue) const;
virtual bool optimizeCompareInstr(MachineInstr *CmpInstr, unsigned SrcReg,
unsigned SrcReg2, int CmpMask, int CmpValue,
const MachineRegisterInfo *MRI) const;
private:
void instantiateCondBranch(MachineBasicBlock &MBB, DebugLoc DL,
MachineBasicBlock *TBB,
const SmallVectorImpl<MachineOperand> &Cond) const;
};
void emitFrameOffset(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, DebugLoc DL,
unsigned DestReg, unsigned SrcReg, int Offset,
const ARM64InstrInfo *TII,
MachineInstr::MIFlag = MachineInstr::NoFlags,
bool SetCPSR = false);
bool rewriteARM64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
unsigned FrameReg, int &Offset,
const ARM64InstrInfo *TII);
enum ARM64FrameOffsetStatus {
ARM64FrameOffsetCannotUpdate = 0x0, ARM64FrameOffsetIsLegal = 0x1, ARM64FrameOffsetCanUpdate = 0x2 };
int isARM64FrameOffsetLegal(const MachineInstr &MI, int &Offset,
bool *OutUseUnscaledOp = NULL,
unsigned *OutUnscaledOp = NULL,
int *EmittableOffset = NULL);
static inline bool isUncondBranchOpcode(int Opc) {
return Opc == ARM64::B;
}
static inline bool isCondBranchOpcode(int Opc) {
switch (Opc) {
case ARM64::Bcc:
case ARM64::CBZW:
case ARM64::CBZX:
case ARM64::CBNZW:
case ARM64::CBNZX:
case ARM64::TBZ:
case ARM64::TBNZ:
return true;
default:
return false;
}
}
static inline bool isIndirectBranchOpcode(int Opc) {
return Opc == ARM64::BR;
}
}
#endif