41 unsigned DestReg,
unsigned SrcReg,
47 assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC);
49 static const int16_t Sub0_15[] = {
50 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
51 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
52 AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
53 AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0
56 static const int16_t Sub0_7[] = {
57 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
58 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0
61 static const int16_t Sub0_3[] = {
62 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
65 static const int16_t Sub0_2[] = {
66 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
69 static const int16_t Sub0_1[] = {
70 AMDGPU::sub0, AMDGPU::sub1, 0
74 const int16_t *SubIndices;
76 if (AMDGPU::M0 == DestReg) {
81 if (!
I->definesRegister(AMDGPU::M0))
84 unsigned Opc =
I->getOpcode();
88 if (!
I->readsRegister(SrcReg))
96 if (AMDGPU::SReg_32RegClass.contains(DestReg)) {
97 assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
98 BuildMI(MBB, MI, DL,
get(AMDGPU::S_MOV_B32), DestReg)
102 }
else if (AMDGPU::SReg_64RegClass.contains(DestReg)) {
103 assert(AMDGPU::SReg_64RegClass.contains(SrcReg));
104 BuildMI(MBB, MI, DL,
get(AMDGPU::S_MOV_B64), DestReg)
108 }
else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
109 assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
110 Opcode = AMDGPU::S_MOV_B32;
113 }
else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
114 assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
115 Opcode = AMDGPU::S_MOV_B32;
118 }
else if (AMDGPU::SReg_512RegClass.contains(DestReg)) {
119 assert(AMDGPU::SReg_512RegClass.contains(SrcReg));
120 Opcode = AMDGPU::S_MOV_B32;
121 SubIndices = Sub0_15;
123 }
else if (AMDGPU::VReg_32RegClass.contains(DestReg)) {
124 assert(AMDGPU::VReg_32RegClass.contains(SrcReg) ||
125 AMDGPU::SReg_32RegClass.contains(SrcReg));
126 BuildMI(MBB, MI, DL,
get(AMDGPU::V_MOV_B32_e32), DestReg)
130 }
else if (AMDGPU::VReg_64RegClass.contains(DestReg)) {
131 assert(AMDGPU::VReg_64RegClass.contains(SrcReg) ||
132 AMDGPU::SReg_64RegClass.contains(SrcReg));
133 Opcode = AMDGPU::V_MOV_B32_e32;
136 }
else if (AMDGPU::VReg_96RegClass.contains(DestReg)) {
137 assert(AMDGPU::VReg_96RegClass.contains(SrcReg));
138 Opcode = AMDGPU::V_MOV_B32_e32;
141 }
else if (AMDGPU::VReg_128RegClass.contains(DestReg)) {
142 assert(AMDGPU::VReg_128RegClass.contains(SrcReg) ||
143 AMDGPU::SReg_128RegClass.contains(SrcReg));
144 Opcode = AMDGPU::V_MOV_B32_e32;
147 }
else if (AMDGPU::VReg_256RegClass.contains(DestReg)) {
148 assert(AMDGPU::VReg_256RegClass.contains(SrcReg) ||
149 AMDGPU::SReg_256RegClass.contains(SrcReg));
150 Opcode = AMDGPU::V_MOV_B32_e32;
153 }
else if (AMDGPU::VReg_512RegClass.contains(DestReg)) {
154 assert(AMDGPU::VReg_512RegClass.contains(SrcReg) ||
155 AMDGPU::SReg_512RegClass.contains(SrcReg));
156 Opcode = AMDGPU::V_MOV_B32_e32;
157 SubIndices = Sub0_15;
163 while (
unsigned SubIdx = *SubIndices++) {
165 get(Opcode), RI.getSubReg(DestReg, SubIdx));
212 AMDGPU::OpName::neg)).
getImm()))
231 unsigned SrcReg)
const {
238 default:
return false;
239 case AMDGPU::S_MOV_B32:
240 case AMDGPU::S_MOV_B64:
241 case AMDGPU::V_MOV_B32_e32:
242 case AMDGPU::V_MOV_B32_e64:
249 return RC != &AMDGPU::EXECRegRegClass;
311 unsigned ConstantBusCount = 0;
312 unsigned SGPRUsed = AMDGPU::NoRegister;
323 if (MO.
getReg() == AMDGPU::M0 || MO.
getReg() == AMDGPU::VCC ||
325 (AMDGPU::SGPR_32RegClass.contains(MO.
getReg()) ||
326 AMDGPU::SGPR_64RegClass.contains(MO.
getReg())))) {
327 if (SGPRUsed != MO.
getReg()) {
337 if (ConstantBusCount > 1) {
338 ErrInfo =
"VOP* instruction uses the constant bus more than once";
344 if (Src1Idx != -1 && (
isVOP2(Opcode) ||
isVOPC(Opcode))) {
347 ErrInfo =
"VOP[2C] src1 cannot be an immediate.";
355 ErrInfo =
"VOP3 src0 cannot be a literal constant.";
359 ErrInfo =
"VOP3 src1 cannot be a literal constant.";
363 ErrInfo =
"VOP3 src2 cannot be a literal constant.";
372 default:
return AMDGPU::INSTRUCTION_LIST_END;
376 case AMDGPU::S_ADD_I32:
return AMDGPU::V_ADD_I32_e32;
377 case AMDGPU::S_ADDC_U32:
return AMDGPU::V_ADDC_U32_e32;
378 case AMDGPU::S_SUB_I32:
return AMDGPU::V_SUB_I32_e32;
379 case AMDGPU::S_SUBB_U32:
return AMDGPU::V_SUBB_U32_e32;
380 case AMDGPU::S_ASHR_I32:
return AMDGPU::V_ASHR_I32_e32;
381 case AMDGPU::S_ASHR_I64:
return AMDGPU::V_ASHR_I64;
382 case AMDGPU::S_LSHL_B32:
return AMDGPU::V_LSHL_B32_e32;
383 case AMDGPU::S_LSHL_B64:
return AMDGPU::V_LSHL_B64;
384 case AMDGPU::S_LSHR_B32:
return AMDGPU::V_LSHR_B32_e32;
385 case AMDGPU::S_LSHR_B64:
return AMDGPU::V_LSHR_B64;
390 return getVALUOp(MI) != AMDGPU::INSTRUCTION_LIST_END;
394 unsigned OpNo)
const {
402 return RI.getRegClass(RCID);
419 unsigned RCID =
get(MI->
getOpcode()).OpInfo[OpIdx].RegClass;
421 unsigned Opcode = AMDGPU::V_MOV_B32_e32;
425 Opcode = AMDGPU::S_MOV_B32;
438 AMDGPU::OpName::src0);
440 AMDGPU::OpName::src1);
442 AMDGPU::OpName::src2);
452 if (ReadsVCC && Src0.
isReg() &&
458 if (ReadsVCC && Src1.
isReg() &&
479 int VOP3Idx[3] = {Src0Idx, Src1Idx, Src2Idx};
480 unsigned SGPRReg = AMDGPU::NoRegister;
481 for (
unsigned i = 0; i < 3; ++i) {
482 int Idx = VOP3Idx[i];
491 assert(MO.
getReg() != AMDGPU::SCC &&
"SCC operand to VOP3 instruction");
493 if (SGPRReg == AMDGPU::NoRegister || SGPRReg == MO.
getReg()) {
558 while (!Worklist.
empty()) {
561 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
636 unsigned Channel)
const {
637 assert(Channel == 0);
642 return &AMDGPU::VReg_32RegClass;
649 unsigned Address,
unsigned OffsetReg)
const {
651 unsigned IndirectBaseReg = AMDGPU::VReg_32RegClass.getRegister(
654 return BuildMI(*MBB, I, DL,
get(AMDGPU::SI_INDIRECT_DST_V1))
657 .addReg(IndirectBaseReg)
667 unsigned Address,
unsigned OffsetReg)
const {
669 unsigned IndirectBaseReg = AMDGPU::VReg_32RegClass.getRegister(
672 return BuildMI(*MBB, I, DL,
get(AMDGPU::SI_INDIRECT_SRC))
674 .addOperand(I->getOperand(1))
675 .addReg(IndirectBaseReg)
690 for (
int Index = Begin; Index <= End; ++Index)
691 Reserved.
set(AMDGPU::VReg_32RegClass.getRegister(Index));
693 for (
int Index = std::max(0, Begin - 1); Index <= End; ++Index)
694 Reserved.
set(AMDGPU::VReg_64RegClass.getRegister(Index));
696 for (
int Index = std::max(0, Begin - 2); Index <= End; ++Index)
697 Reserved.
set(AMDGPU::VReg_96RegClass.getRegister(Index));
699 for (
int Index = std::max(0, Begin - 3); Index <= End; ++Index)
700 Reserved.
set(AMDGPU::VReg_128RegClass.getRegister(Index));
702 for (
int Index = std::max(0, Begin - 7); Index <= End; ++Index)
703 Reserved.
set(AMDGPU::VReg_256RegClass.getRegister(Index));
705 for (
int Index = std::max(0, Begin - 15); Index <= End; ++Index)
706 Reserved.
set(AMDGPU::VReg_512RegClass.getRegister(Index));
void push_back(const T &Elt)
const MachineFunction * getParent() const
const ConstantFP * getFPImm() const
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
static bool isVirtualRegister(unsigned Reg)
void moveToVALU(MachineInstr &MI) const
Replace this instruction's opcode with the equivalent VALU opcode. This function will also move the u...
bool hasVGPRs(const TargetRegisterClass *RC) const
virtual bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const
bool isLiteralConstant(const MachineOperand &MO) const
virtual MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned ValueReg, unsigned Address, unsigned OffsetReg) const
Build instruction(s) for an indirect register read.
static use_iterator use_end()
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const TargetRegisterClass * getRegClass(unsigned Reg) const
int getCommuteOrig(uint16_t Opcode)
const uint16_t * ImplicitUses
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
void RemoveOperand(unsigned i)
SIInstrInfo(AMDGPUTargetMachine &tm)
int isMIMG(uint16_t Opcode) const
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const
virtual MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const
virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const
virtual bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const
virtual MachineInstr * commuteInstruction(MachineInstr *MI, bool NewMI=false) const
unsigned getKillRegState(bool B)
void ChangeToImmediate(int64_t ImmVal)
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
bool isSALUInstr(const MachineInstr &MI) const
virtual const TargetRegisterClass * getIndirectAddrRegClass() const
virtual unsigned calculateIndirectAddress(unsigned RegIndex, unsigned Channel) const
Calculate the "Indirect Address" for the given RegIndex and Channel.
bool isVariadic(QueryType Type=IgnoreBundle) const
The AMDGPU TargetMachine interface definition for hw codgen targets.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
const TargetRegisterClass * getEquivalentVGPRClass(const TargetRegisterClass *SRC) const
DebugLoc findDebugLoc(instr_iterator MBBI)
void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const
Legalize the OpIndex operand of this instruction by inserting a MOV. For example: ADD_I32_e32 VGPR0...
virtual bool isMov(unsigned Opcode) const
void setDesc(const MCInstrDesc &tid)
MachineInstr * buildMovInstr(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned DstReg, unsigned SrcReg) const
Build a MOV instruction.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
bool isSGPRClass(const TargetRegisterClass *RC) const
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
bool isVOP1(uint16_t Opcode) const
void replaceRegWith(unsigned FromReg, unsigned ToReg)
bool isVOP3(uint16_t Opcode) const
void reserveIndirectRegisters(BitVector &Reserved, const MachineFunction &MF) const
virtual int getIndirectIndexEnd(const MachineFunction &MF) const
unsigned commuteOpcode(unsigned Opcode) const
bool isVOPC(uint16_t Opcode) const
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
void legalizeOperands(MachineInstr *MI) const
Legalize all operands in this instruction. This function may create new instruction and insert them b...
use_iterator use_begin(unsigned RegNo) const
void setReg(unsigned Reg)
int getCommuteRev(uint16_t Opcode)
const SIRegisterInfo & getRegisterInfo() const
static unsigned getVALUOp(const MachineInstr &MI)
bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const
bool isExactlyValue(const APFloat &V) const
unsigned getReg() const
getReg - Returns the register number.
bool isCommutable(QueryType Type=IgnoreBundle) const
const uint16_t * ImplicitDefs
virtual MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, unsigned ValueReg, unsigned Address, unsigned OffsetReg) const
Build instruction(s) for an indirect register write.
std::reverse_iterator< iterator > reverse_iterator
virtual int getIndirectIndexBegin(const MachineFunction &MF) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
const MCOperandInfo * OpInfo
bool isInlineConstant(const MachineOperand &MO) const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
const TargetRegisterClass * getOpRegClass(const MachineInstr &MI, unsigned OpNo) const
Return the correct register class for OpNo. For target-specific instructions, this will return the re...
const MCRegisterInfo & MRI
int isSMRD(uint16_t Opcode) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
bool isVOP2(uint16_t Opcode) const
DebugLoc getDebugLoc() const