46 const char *getPassName()
const override {
47 return "R600 Expand special instructions pass";
56 return new R600ExpandSpecialInstrsPass(TM);
59 void R600ExpandSpecialInstrsPass::SetFlagInNewMI(
MachineInstr *NewMI,
61 int OpIdx =
TII->getOperandIdx(*OldMI, Op);
64 TII->setImmOperand(NewMI, Op, Val);
68 bool R600ExpandSpecialInstrsPass::runOnMachineFunction(
MachineFunction &MF) {
77 while (I != MBB.
end()) {
83 int DstIdx =
TII->getOperandIdx(MI.
getOpcode(), AMDGPU::OpName::dst);
87 DstOp.
getReg(), AMDGPU::OQAP);
88 DstOp.
setReg(AMDGPU::OQAP);
90 AMDGPU::OpName::pred_sel);
92 AMDGPU::OpName::pred_sel);
101 case AMDGPU::PRED_X: {
112 TII->setImmOperand(PredSet, AMDGPU::OpName::update_exec_mask, 1);
114 TII->setImmOperand(PredSet, AMDGPU::OpName::update_pred, 1);
120 case AMDGPU::INTERP_PAIR_XY: {
122 unsigned PReg = AMDGPU::R600_ArrayBaseRegClass.getRegister(
125 for (
unsigned Chan = 0; Chan < 4; ++Chan) {
131 DstReg = Chan == 2 ? AMDGPU::T0_Z : AMDGPU::T0_W;
133 BMI =
TII->buildDefaultInstruction(MBB, I, AMDGPU::INTERP_XY,
149 case AMDGPU::INTERP_PAIR_ZW: {
151 unsigned PReg = AMDGPU::R600_ArrayBaseRegClass.getRegister(
154 for (
unsigned Chan = 0; Chan < 4; ++Chan) {
158 DstReg = Chan == 0 ? AMDGPU::T0_X : AMDGPU::T0_Y;
162 BMI =
TII->buildDefaultInstruction(MBB, I, AMDGPU::INTERP_ZW,
178 case AMDGPU::INTERP_VEC_LOAD: {
181 unsigned PReg = AMDGPU::R600_ArrayBaseRegClass.getRegister(
185 for (
unsigned Chan = 0; Chan < 4; ++Chan) {
186 BMI =
TII->buildDefaultInstruction(MBB, I, AMDGPU::INTERP_LOAD_P0,
198 case AMDGPU::DOT_4: {
203 unsigned DstBase = TRI.getEncodingValue(DstReg) &
HW_REG_MASK;
205 for (
unsigned Chan = 0; Chan < 4; ++Chan) {
208 AMDGPU::R600_TReg32RegClass.getRegister((DstBase * 4) + Chan);
210 TII->buildSlotOfVectorInstruction(MBB, &MI, Chan, SubDstReg);
223 TII->getOperandIdx(Opcode, AMDGPU::OpName::src0))
226 TII->getOperandIdx(Opcode, AMDGPU::OpName::src1))
230 if ((TRI.getEncodingValue(Src0) & 0xff) < 127 &&
231 (TRI.getEncodingValue(Src1) & 0xff) < 127)
240 bool IsVector =
TII->isVector(MI);
242 if (!IsReduction && !IsVector && !IsCube) {
271 for (
unsigned Chan = 0; Chan < 4; Chan++) {
273 TII->getOperandIdx(MI, AMDGPU::OpName::dst)).
getReg();
275 TII->getOperandIdx(MI, AMDGPU::OpName::src0)).
getReg();
280 int Src1Idx =
TII->getOperandIdx(MI, AMDGPU::OpName::src1);
287 Src0 = TRI.getSubReg(Src0, SubRegIndex);
288 Src1 = TRI.getSubReg(Src1, SubRegIndex);
290 static const int CubeSrcSwz[] = {2, 2, 0, 1};
293 Src1 = TRI.getSubReg(Src0, SubRegIndex1);
294 Src0 = TRI.getSubReg(Src0, SubRegIndex0);
302 DstReg = TRI.getSubReg(DstReg, SubRegIndex);
307 unsigned DstBase = TRI.getEncodingValue(DstReg) &
HW_REG_MASK;
308 DstReg = AMDGPU::R600_TReg32RegClass.getRegister((DstBase * 4) + Chan);
312 NotLast = (Chan != 3 );
317 case AMDGPU::CUBE_r600_pseudo:
318 Opcode = AMDGPU::CUBE_r600_real;
320 case AMDGPU::CUBE_eg_pseudo:
321 Opcode = AMDGPU::CUBE_eg_real;
328 TII->buildDefaultInstruction(MBB, I, Opcode, DstReg, Src0, Src1);
338 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::clamp);
339 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::literal);
340 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::src0_abs);
341 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::src1_abs);
342 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::src0_neg);
343 SetFlagInNewMI(NewMI, &MI, AMDGPU::OpName::src1_neg);
void bundleWithPred()
Bundle this instruction with its predecessor.
AMDGPU specific subclass of TargetSubtarget.
Interface definition for R600InstrInfo.
unsigned getHWRegChan(unsigned reg) const
get the HW encoding for a register's channel.
Interface definition for R600RegisterInfo.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
FunctionPass * createR600ExpandSpecialInstrsPass(TargetMachine &tm)
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const HexagonRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define HW_REG_MASK
Defines for extracting register information from register encoding.
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineOperand & getOperand(unsigned i) const
unsigned getSubRegFromChannel(unsigned Channel) const
FunctionPass class - This class is used to implement most global optimizations.
MachineOperand class - Representation of each machine instruction operand.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Representation of each machine instruction.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.