25#define DEBUG_TYPE "r600-expand-special-instrs"
44 return "R600 Expand special instructions pass";
51 "R600 Expand Special Instrs",
false,
false)
55char R600ExpandSpecialInstrsPass::
ID = 0;
60 return new R600ExpandSpecialInstrsPass();
63void R600ExpandSpecialInstrsPass::SetFlagInNewMI(
MachineInstr *NewMI,
69 TII->setImmOperand(*NewMI,
Op, Val);
73bool R600ExpandSpecialInstrsPass::runOnMachineFunction(MachineFunction &MF) {
75 TII =
ST.getInstrInfo();
77 const R600RegisterInfo &
TRI =
TII->getRegisterInfo();
79 for (MachineBasicBlock &
MBB : MF) {
82 MachineInstr &
MI = *
I;
86 if (
TII->isLDSRetInstr(
MI.getOpcode())) {
87 int DstIdx =
TII->getOperandIdx(
MI.getOpcode(), R600::OpName::dst);
89 MachineOperand &DstOp =
MI.getOperand(DstIdx);
90 MachineInstr *Mov =
TII->buildMovInstr(&
MBB,
I,
91 DstOp.
getReg(), R600::OQAP);
93 int LDSPredSelIdx =
TII->getOperandIdx(
MI.getOpcode(),
94 R600::OpName::pred_sel);
96 R600::OpName::pred_sel);
99 MI.getOperand(LDSPredSelIdx).getReg());
102 switch (
MI.getOpcode()) {
106 uint64_t
Flags =
MI.getOperand(3).getImm();
109 MachineInstr *PredSet =
TII->buildDefaultInstruction(
MBB,
I,
110 MI.getOperand(2).getImm(),
111 MI.getOperand(0).getReg(),
112 MI.getOperand(1).getReg(),
116 TII->setImmOperand(*PredSet, R600::OpName::update_exec_mask, 1);
118 TII->setImmOperand(*PredSet, R600::OpName::update_pred, 1);
120 MI.eraseFromParent();
125 const R600RegisterInfo &
TRI =
TII->getRegisterInfo();
130 for (
unsigned Chan = 0; Chan < 4; ++Chan) {
131 bool Mask = (Chan !=
TRI.getHWRegChan(DstReg));
133 R600::R600_TReg32RegClass.getRegister((DstBase * 4) + Chan);
135 TII->buildSlotOfVectorInstruction(
MBB, &
MI, Chan, SubDstReg);
148 BMI->
getOperand(
TII->getOperandIdx(Opcode, R600::OpName::src0))
151 BMI->
getOperand(
TII->getOperandIdx(Opcode, R600::OpName::src1))
155 if ((
TRI.getEncodingValue(Src0) & 0xff) < 127 &&
156 (
TRI.getEncodingValue(Src1) & 0xff) < 127)
157 assert(
TRI.getHWRegChan(Src0) ==
TRI.getHWRegChan(Src1));
159 MI.eraseFromParent();
164 bool IsReduction =
TII->isReductionOp(
MI.getOpcode());
165 bool IsVector =
TII->isVector(
MI);
166 bool IsCube =
TII->isCubeOp(
MI.getOpcode());
167 if (!IsReduction && !IsVector && !IsCube) {
196 for (
unsigned Chan = 0; Chan < 4; Chan++) {
198 MI.getOperand(
TII->getOperandIdx(
MI, R600::OpName::dst)).getReg();
200 MI.getOperand(
TII->getOperandIdx(
MI, R600::OpName::src0)).getReg();
205 int Src1Idx =
TII->getOperandIdx(
MI, R600::OpName::src1);
207 Src1 =
MI.getOperand(Src1Idx).getReg();
212 Src0 =
TRI.getSubReg(Src0, SubRegIndex);
213 Src1 =
TRI.getSubReg(Src1, SubRegIndex);
215 static const int CubeSrcSwz[] = {2, 2, 0, 1};
218 Src1 =
TRI.getSubReg(Src0, SubRegIndex1);
219 Src0 =
TRI.getSubReg(Src0, SubRegIndex0);
227 DstReg =
TRI.getSubReg(DstReg, SubRegIndex);
231 Mask = (Chan !=
TRI.getHWRegChan(DstReg));
233 DstReg = R600::R600_TReg32RegClass.getRegister((DstBase * 4) + Chan);
237 NotLast = (Chan != 3 );
240 unsigned Opcode =
MI.getOpcode();
242 case R600::CUBE_r600_pseudo:
243 Opcode = R600::CUBE_r600_real;
245 case R600::CUBE_eg_pseudo:
246 Opcode = R600::CUBE_eg_real;
252 MachineInstr *NewMI =
253 TII->buildDefaultInstruction(
MBB,
I, Opcode, DstReg, Src0, Src1);
263 SetFlagInNewMI(NewMI, &
MI, R600::OpName::clamp);
264 SetFlagInNewMI(NewMI, &
MI, R600::OpName::literal);
265 SetFlagInNewMI(NewMI, &
MI, R600::OpName::src0_abs);
266 SetFlagInNewMI(NewMI, &
MI, R600::OpName::src1_abs);
267 SetFlagInNewMI(NewMI, &
MI, R600::OpName::src0_neg);
268 SetFlagInNewMI(NewMI, &
MI, R600::OpName::src1_neg);
270 MI.eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
#define HW_REG_MASK
Defines for extracting register information from register encoding.
Provides R600 specific target descriptions.
AMDGPU R600 specific subclass of TargetSubtarget.
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void bundleWithPred()
Bundle this instruction with its predecessor.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
StringRef - Represent a constant reference to a string, i.e.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createR600ExpandSpecialInstrsPass()
LLVM_ABI bool finalizeBundles(MachineFunction &MF)
finalizeBundles - Finalize instruction bundles in the specified MachineFunction.
DWARFExpression::Operation Op
char & R600ExpandSpecialInstrsPassID
static unsigned getSubRegFromChannel(unsigned Channel)