-//===-- R600ISelLowering.cpp - TODO: Add brief description -------===//
+//===-- R600ISelLowering.cpp - R600 DAG Lowering Implementation -----------===//
//
// The LLVM Compiler Infrastructure
//
//
//===----------------------------------------------------------------------===//
//
-// TODO: Add full description
+// Most of the DAG lowering is handled in AMDGPUISelLowering.cpp. This file
+// is mostly EmitInstrWithCustomInserter().
//
//===----------------------------------------------------------------------===//
#include "R600ISelLowering.h"
+#include "AMDGPUUtil.h"
#include "R600InstrInfo.h"
#include "R600MachineFunctionInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass);
addRegisterClass(MVT::v4i32, &AMDIL::R600_Reg128RegClass);
addRegisterClass(MVT::i32, &AMDIL::R600_Reg32RegClass);
+ computeRegisterProperties();
setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal);
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal);
+
+ setOperationAction(ISD::FSUB, MVT::f32, Expand);
+
}
MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
{
MachineFunction * MF = BB->getParent();
MachineRegisterInfo &MRI = MF->getRegInfo();
+ MachineBasicBlock::iterator I = *MI;
switch (MI->getOpcode()) {
default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
- /* XXX: Use helper function from AMDGPULowerShaderInstructions here */
case AMDIL::TGID_X:
addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X);
break;
case AMDIL::LOCAL_SIZE_Z:
lowerImplicitParameter(MI, *BB, MRI, 8);
break;
+
+ case AMDIL::CLAMP_R600:
+ MI->getOperand(0).addTargetFlag(MO_FLAG_CLAMP);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1));
+ break;
+
+ case AMDIL::FABS_R600:
+ MI->getOperand(1).addTargetFlag(MO_FLAG_ABS);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1));
+ break;
+
+ case AMDIL::FNEG_R600:
+ MI->getOperand(1).addTargetFlag(MO_FLAG_NEG);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1));
+ break;
+
+ case AMDIL::R600_LOAD_CONST:
+ {
+ int64_t RegIndex = MI->getOperand(1).getImm();
+ unsigned ConstantReg = AMDIL::R600_CReg32RegClass.getRegister(RegIndex);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::COPY))
+ .addOperand(MI->getOperand(0))
+ .addReg(ConstantReg);
+ break;
+ }
+
case AMDIL::LOAD_INPUT:
{
int64_t RegIndex = MI->getOperand(1).getImm();
addLiveIn(MI, MF, MRI, TII,
AMDIL::R600_TReg32RegClass.getRegister(RegIndex));
- MI->eraseFromParent();
break;
}
+
+ case AMDIL::MASK_WRITE:
+ {
+ unsigned maskedRegister = MI->getOperand(0).getReg();
+ assert(TargetRegisterInfo::isVirtualRegister(maskedRegister));
+ MachineInstr * defInstr = MRI.getVRegDef(maskedRegister);
+ MachineOperand * def = defInstr->findRegisterDefOperand(maskedRegister);
+ def->addTargetFlag(MO_FLAG_MASK);
+ // Return early so the instruction is not erased
+ return BB;
+ }
+
+ case AMDIL::RAT_WRITE_CACHELESS_eg:
+ {
+ // Convert to DWORD address
+ unsigned NewAddr = MRI.createVirtualRegister(
+ AMDIL::R600_TReg32_XRegisterClass);
+ unsigned ShiftValue = MRI.createVirtualRegister(
+ AMDIL::R600_TReg32RegisterClass);
+
+ // XXX In theory, we should be able to pass ShiftValue directly to
+ // the LSHR_eg instruction as an inline literal, but I tried doing it
+ // this way and it didn't produce the correct results.
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::MOV), ShiftValue)
+ .addReg(AMDIL::ALU_LITERAL_X)
+ .addImm(2);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::LSHR_eg), NewAddr)
+ .addOperand(MI->getOperand(1))
+ .addReg(ShiftValue);
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(MI->getOpcode()))
+ .addOperand(MI->getOperand(0))
+ .addReg(NewAddr);
+ break;
+ }
+
case AMDIL::STORE_OUTPUT:
{
- MachineBasicBlock::iterator I = *MI;
int64_t OutputIndex = MI->getOperand(1).getImm();
unsigned OutputReg = AMDIL::R600_TReg32RegClass.getRegister(OutputIndex);
if (!MRI.isLiveOut(OutputReg)) {
MRI.addLiveOut(OutputReg);
}
- MI->eraseFromParent();
break;
}
unsigned ReservedReg =
AMDIL::R600_TReg32RegClass.getRegister(ReservedIndex);
MFI->ReservedRegs.push_back(ReservedReg);
- MI->eraseFromParent();
break;
}
+
+ case AMDIL::TXD:
+ {
+ unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
+ unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
+
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0)
+ .addOperand(MI->getOperand(3))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5));
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1)
+ .addOperand(MI->getOperand(2))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5));
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_G))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5))
+ .addReg(t0, RegState::Implicit)
+ .addReg(t1, RegState::Implicit);
+ break;
+ }
+ case AMDIL::TXD_SHADOW:
+ {
+ unsigned t0 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
+ unsigned t1 = MRI.createVirtualRegister(AMDIL::R600_Reg128RegisterClass);
+
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_H), t0)
+ .addOperand(MI->getOperand(3))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5));
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SET_GRADIENTS_V), t1)
+ .addOperand(MI->getOperand(2))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5));
+ BuildMI(*BB, I, BB->findDebugLoc(I), TII->get(AMDIL::TEX_SAMPLE_C_G))
+ .addOperand(MI->getOperand(0))
+ .addOperand(MI->getOperand(1))
+ .addOperand(MI->getOperand(4))
+ .addOperand(MI->getOperand(5))
+ .addReg(t0, RegState::Implicit)
+ .addReg(t1, RegState::Implicit);
+ break;
+ }
+
+
}
+ MI->eraseFromParent();
return BB;
}
MachineRegisterInfo & MRI, unsigned dword_offset) const
{
MachineBasicBlock::iterator I = *MI;
- unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
+ unsigned PtrReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass);
- BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg)
+ BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), PtrReg)
.addReg(AMDIL::ALU_LITERAL_X)
.addImm(dword_offset * 4);
- BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg))
+ BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_PARAM_eg))
.addOperand(MI->getOperand(0))
- .addReg(offsetReg)
+ .addReg(PtrReg)
.addImm(0);
}