#ifndef LLVM_LIB_TARGET_R600_SIINSTRINFO_H
#define LLVM_LIB_TARGET_R600_SIINSTRINFO_H
#include "AMDGPUInstrInfo.h"
#include "SIDefines.h"
#include "SIRegisterInfo.h"
namespace llvm {
class SIInstrInfo : public AMDGPUInstrInfo {
private:
const SIRegisterInfo RI;
unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
MachineRegisterInfo &MRI,
MachineOperand &SuperReg,
const TargetRegisterClass *SuperRC,
unsigned SubIdx,
const TargetRegisterClass *SubRC) const;
MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
MachineRegisterInfo &MRI,
MachineOperand &SuperReg,
const TargetRegisterClass *SuperRC,
unsigned SubIdx,
const TargetRegisterClass *SubRC) const;
unsigned split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist,
MachineBasicBlock::iterator MI,
MachineRegisterInfo &MRI,
const TargetRegisterClass *RC,
const MachineOperand &Op) const;
void swapOperands(MachineBasicBlock::iterator Inst) const;
void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
MachineInstr *Inst, unsigned Opcode) const;
void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
MachineInstr *Inst, unsigned Opcode) const;
void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
MachineInstr *Inst) const;
void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
MachineInstr *Inst) const;
void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const;
bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
MachineInstr *MIb) const;
unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
public:
explicit SIInstrInfo(const AMDGPUSubtarget &st);
const SIRegisterInfo &getRegisterInfo() const override {
return RI;
}
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
int64_t &Offset1,
int64_t &Offset2) const override;
bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
unsigned &BaseReg, unsigned &Offset,
const TargetRegisterInfo *TRI) const final;
bool shouldClusterLoads(MachineInstr *FirstLdSt,
MachineInstr *SecondLdSt,
unsigned NumLoads) const final;
void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const override;
unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
RegScavenger *RS,
unsigned TmpReg,
unsigned Offset,
unsigned Size) const;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
unsigned commuteOpcode(unsigned Opcode) const;
MachineInstr *commuteInstruction(MachineInstr *MI,
bool NewMI = false) const override;
bool findCommutedOpIndices(MachineInstr *MI,
unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const override;
bool isTriviallyReMaterializable(const MachineInstr *MI,
AliasAnalysis *AA = nullptr) const;
bool areMemAccessesTriviallyDisjoint(
MachineInstr *MIa, MachineInstr *MIb,
AliasAnalysis *AA = nullptr) const override;
MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned DstReg, unsigned SrcReg) const override;
bool isMov(unsigned Opcode) const override;
bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override;
bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
unsigned Reg, MachineRegisterInfo *MRI) const final;
bool isSALU(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SALU;
}
bool isVALU(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::VALU;
}
bool isSOP1(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SOP1;
}
bool isSOP2(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SOP2;
}
bool isSOPC(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SOPC;
}
bool isSOPK(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SOPK;
}
bool isSOPP(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SOPP;
}
bool isVOP1(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::VOP1;
}
bool isVOP2(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::VOP2;
}
bool isVOP3(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::VOP3;
}
bool isVOPC(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::VOPC;
}
bool isMUBUF(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
}
bool isMTBUF(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
}
bool isSMRD(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::SMRD;
}
bool isDS(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::DS;
}
bool isMIMG(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::MIMG;
}
bool isFLAT(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::FLAT;
}
bool isWQM(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::WQM;
}
bool isInlineConstant(const APInt &Imm) const;
bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
const MachineOperand &MO) const;
bool hasVALU32BitEncoding(unsigned Opcode) const;
bool usesConstantBus(const MachineRegisterInfo &MRI,
const MachineOperand &MO,
unsigned OpSize) const;
bool hasModifiers(unsigned Opcode) const;
bool hasModifiersSet(const MachineInstr &MI,
unsigned OpName) const;
bool verifyInstruction(const MachineInstr *MI,
StringRef &ErrInfo) const override;
static unsigned getVALUOp(const MachineInstr &MI);
bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
unsigned OpNo) const;
unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
if (OpInfo.RegClass == -1) {
assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
return 4;
}
return RI.getRegClass(OpInfo.RegClass)->getSize();
}
unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
return getOpRegClass(MI, OpNo)->getSize();
}
bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
const MachineOperand *MO = nullptr) const;
void legalizeOperands(MachineInstr *MI) const;
void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC,
unsigned HalfImmOp, unsigned HalfSGPROp,
MachineInstr *&Lo, MachineInstr *&Hi) const;
void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) const;
void moveToVALU(MachineInstr &MI) const;
unsigned calculateIndirectAddress(unsigned RegIndex,
unsigned Channel) const override;
const TargetRegisterClass *getIndirectAddrRegClass() const override;
MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg,
unsigned Address,
unsigned OffsetReg) const override;
MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
MachineBasicBlock::iterator I,
unsigned ValueReg,
unsigned Address,
unsigned OffsetReg) const override;
void reserveIndirectRegisters(BitVector &Reserved,
const MachineFunction &MF) const;
void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
unsigned SavReg, unsigned IndexReg) const;
void insertNOPs(MachineBasicBlock::iterator MI, int Count) const;
MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
const MachineOperand *getNamedOperand(const MachineInstr &MI,
unsigned OpName) const {
return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
}
uint64_t getDefaultRsrcDataFormat() const;
};
namespace AMDGPU {
int getVOPe64(uint16_t Opcode);
int getVOPe32(uint16_t Opcode);
int getCommuteRev(uint16_t Opcode);
int getCommuteOrig(uint16_t Opcode);
int getAddr64Inst(uint16_t Opcode);
int getAtomicRetOp(uint16_t Opcode);
int getAtomicNoRetOp(uint16_t Opcode);
const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
const uint64_t RSRC_TID_ENABLE = 1LL << 55;
}
namespace SI {
namespace KernelInputOffsets {
enum Offsets {
NGROUPS_X = 0,
NGROUPS_Y = 4,
NGROUPS_Z = 8,
GLOBAL_SIZE_X = 12,
GLOBAL_SIZE_Y = 16,
GLOBAL_SIZE_Z = 20,
LOCAL_SIZE_X = 24,
LOCAL_SIZE_Y = 28,
LOCAL_SIZE_Z = 32
};
} }
}
#endif