--- lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 1 + lib/Target/AMDGPU/AMDGPUISelLowering.h | 1 + lib/Target/AMDGPU/AMDGPUMCInstLower.cpp | 6 ++++ lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp | 49 ++++++++++++++++++++++++- lib/Target/AMDGPU/R600ISelLowering.cpp | 61 +++++++++++++++++++++++++++++--- lib/Target/AMDGPU/R600Instructions.td | 18 ++++++++++ 6 files changed, 130 insertions(+), 6 deletions(-)
diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp index 665cb59..4963ad7 100644 --- a/lib/Target/AMDGPU/AMDGPUISelLowering.cpp +++ b/lib/Target/AMDGPU/AMDGPUISelLowering.cpp @@ -398,6 +398,7 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(INTERP) NODE_NAME_CASE(INTERP_P0) NODE_NAME_CASE(EXPORT) + NODE_NAME_CASE(CONST_ADDRESS) NODE_NAME_CASE(REGISTER_LOAD) NODE_NAME_CASE(REGISTER_STORE) } diff --git a/lib/Target/AMDGPU/AMDGPUISelLowering.h b/lib/Target/AMDGPU/AMDGPUISelLowering.h index 602a933..4b3a066 100644 --- a/lib/Target/AMDGPU/AMDGPUISelLowering.h +++ b/lib/Target/AMDGPU/AMDGPUISelLowering.h @@ -122,6 +122,7 @@ enum { INTERP, INTERP_P0, EXPORT, + CONST_ADDRESS, REGISTER_LOAD, REGISTER_STORE, LAST_AMDGPU_ISD_NUMBER diff --git a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp index de4053e..fc40e94 100644 --- a/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp +++ b/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp @@ -50,6 +50,12 @@ void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { case MachineOperand::MO_Register: MCOp = MCOperand::CreateReg(MO.getReg()); break; + case MachineOperand::MO_GlobalAddress: { + unsigned Offset = MO.getOffset(); + + MCOp = MCOperand::CreateReg(AMDGPU::R600_KC0_CReg32RegClass.getRegister(Offset)); + } + break; } OutMI.addOperand(MCOp); } diff --git a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp index b3403e2..034d075 100644 --- a/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp +++ b/lib/Target/AMDGPU/AMDILISelDAGToDAG.cpp @@ -168,6 +168,27 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { } break; } + case AMDGPUISD::CONST_ADDRESS: { + EVT OpVT = N->getValueType(0); + unsigned int NewOpc = AMDGPU::CONST_COPY; + SDValue TZero = CurDAG->getTargetConstant(0, MVT::i32); + SDValue TOne = CurDAG->getTargetConstant(1, MVT::i32); + SDValue Args[11] = { + TOne, + TZero, + TZero, + TZero, + N->getOperand(0), + TZero, + TZero, + TZero, + TOne, + CurDAG->getRegister(AMDGPU::PRED_SEL_OFF, MVT::i32), + TZero + }; + + return CurDAG->SelectNodeTo(N, NewOpc, OpVT, Args, 11); + } case ISD::ConstantFP: case ISD::Constant: { const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); @@ -260,7 +281,33 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { break; } } - return SelectCode(N); + SDNode *Result = SelectCode(N); + + const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>(); + if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { + const R600InstrInfo *TII = static_cast<const R600InstrInfo*>(TM.getInstrInfo()); + if (Result && TII->isALUInstr(Result->getMachineOpcode())) { + std::vector<SDValue> Ops; + MachineSDNode *PotentialGlue = 0; + for(SDNode::op_iterator I = Result->op_begin(), E = Result->op_end(); + I != E; ++I) { + SDValue Value = *I; + if (Value.getOpcode() == AMDGPUISD::CONST_ADDRESS) { + if (!dyn_cast<ConstantSDNode>(Value.getOperand(1))) { + PotentialGlue = CurDAG->getMachineNode(AMDGPU::MOVA_INT, Value.getDebugLoc(), MVT::Glue, Value.getOperand(1)); + } + Ops.push_back(Value.getOperand(0)); + } else { + Ops.push_back(Value); + } + } + if (PotentialGlue) + Ops.push_back(SDValue(PotentialGlue, 0)); + CurDAG->MorphNodeTo(Result, Result->getOpcode(), Result->getVTList(), Ops.data(), Ops.size()); + } + } + + return Result; } bool AMDGPUDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) { diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp index 370bc5a..672397c 100644 --- a/lib/Target/AMDGPU/R600ISelLowering.cpp +++ b/lib/Target/AMDGPU/R600ISelLowering.cpp @@ -99,12 +99,12 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) : setOperationAction(ISD::VSELECT, MVT::v4i32, Expand); // Legalize loads and stores to the private address space. - setOperationAction(ISD::LOAD, MVT::f32, Custom); - setOperationAction(ISD::LOAD, MVT::i32, Custom); + setOperationAction(ISD::LOAD, MVT::v4f32, Custom); + /*setOperationAction(ISD::LOAD, MVT::i32, Custom); setOperationAction(ISD::LOAD, MVT::v2f32, Custom); setOperationAction(ISD::LOAD, MVT::v2i32, Custom); setOperationAction(ISD::LOAD, MVT::v4f32, Custom); - setOperationAction(ISD::LOAD, MVT::v4i32, Custom); + setOperationAction(ISD::LOAD, MVT::v4i32, Custom);*/ setLoadExtAction(ISD::EXTLOAD, MVT::v4i8, Custom); setLoadExtAction(ISD::EXTLOAD, MVT::i8, Custom); setLoadExtAction(ISD::ZEXTLOAD, MVT::v4i8, Custom); @@ -954,6 +954,39 @@ SDValue R600TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { return Cond; } +static +const GlobalValue *SelectAddr(SDValue Addr, unsigned &Offset, SDValue &BaseReg) { + switch (Addr.getOpcode()) { + case ISD::GlobalAddress: { + GlobalAddressSDNode * G = dyn_cast<GlobalAddressSDNode>(Addr); + Offset = G->getOffset(); + return G->getGlobal(); + } + case ISD::ADD: { + const GlobalValue *Result; + SDValue NoOpValue; + if (Result = SelectAddr(Addr.getOperand(0), Offset, NoOpValue)) { + ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); + if (Const) { + Offset += Const->getZExtValue(); + } else { + BaseReg = Addr.getOperand(1); + } + } else if (Result = SelectAddr(Addr.getOperand(1), Offset, NoOpValue)) { + ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Addr.getOperand(0)); + if (Const) { + Offset += Const->getZExtValue(); + } else { + BaseReg = Addr.getOperand(0); + } + } + return Result; + } + default: + return NULL; + } +} + SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const { EVT VT = Op.getValueType(); @@ -963,8 +996,26 @@ SDValue R600TargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const SDValue Ptr = Op.getOperand(1); SDValue LoweredLoad; - if (LoadNode->getAddressSpace() != AMDGPUAS::PRIVATE_ADDRESS) { - return SDValue(); + if (LoadNode->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) { + unsigned Offset; + SDValue BaseReg; + const GlobalValue *GV = SelectAddr(Op.getOperand(1), Offset, BaseReg); + if (BaseReg.getNode()) { + BaseReg = DAG.getNode(ISD::SRL, DL, MVT::i32, BaseReg, DAG.getConstant(2, MVT::i32)); + } else { + BaseReg = DAG.getConstant(0, MVT::i32); + } + SDValue Slots[4]; + for (unsigned i = 0; i < 4; i++) { + SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, MVT::f32, Offset / 4 + i); + Slots[i] = DAG.getNode(AMDGPUISD::CONST_ADDRESS, DL, MVT::f32, + TGA, BaseReg); + } + SDValue MergedValues[2] = { + DAG.getNode(ISD::BUILD_VECTOR, DL, MVT::v4f32, Slots, 4), + Chain + }; + return DAG.getMergeValues(MergedValues, 2, DL); } if (VT.isVector()) { diff --git a/lib/Target/AMDGPU/R600Instructions.td b/lib/Target/AMDGPU/R600Instructions.td index 6c0ed1d..6898439 100644 --- a/lib/Target/AMDGPU/R600Instructions.td +++ b/lib/Target/AMDGPU/R600Instructions.td @@ -439,6 +439,14 @@ def INTERP_P0: SDNode<"AMDGPUISD::INTERP_P0", SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisInt<1>]> >; +def CONST_ADDRESS: SDNode<"AMDGPUISD::CONST_ADDRESS", + SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisInt<1>, SDTCisInt<2>]>, + [SDNPMayLoad] +>; + +def MOVA_INT : InstR600 <0xCC, (outs), (ins R600_Reg32:$src0), "MOVA_INT", [], +AnyALU>; + //===----------------------------------------------------------------------===// // Interpolation Instructions //===----------------------------------------------------------------------===// @@ -1624,6 +1632,16 @@ let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in { "RETURN", [(IL_retflag)]>; } + +//===----------------------------------------------------------------------===// +// Constant Buffer Addressing Support +//===----------------------------------------------------------------------===// + +def CONST_COPY : R600_1OP <0x19, "CONST_COPY", []> +{ + let mayLoad = 1; +} + //===----------------------------------------------------------------------===// // ISel Patterns //===----------------------------------------------------------------------===// -- 1.8.0.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev