summaryrefslogtreecommitdiff
path: root/lib/Target/R600/AMDILISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/R600/AMDILISelDAGToDAG.cpp')
-rw-r--r--lib/Target/R600/AMDILISelDAGToDAG.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/Target/R600/AMDILISelDAGToDAG.cpp b/lib/Target/R600/AMDILISelDAGToDAG.cpp
index d15ed393c1..725a5e4f18 100644
--- a/lib/Target/R600/AMDILISelDAGToDAG.cpp
+++ b/lib/Target/R600/AMDILISelDAGToDAG.cpp
@@ -258,6 +258,87 @@ SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) {
}
break;
}
+
+ case ISD::INTRINSIC_WO_CHAIN: {
+ const AMDGPUSubtarget &ST = TM.getSubtarget<AMDGPUSubtarget>();
+ if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
+ unsigned IntrinsicID = N->getConstantOperandVal(0);
+ switch (IntrinsicID) {
+ case AMDGPUIntrinsic::AMDGPU_load_const: {
+ const R600InstrInfo *TII =
+ static_cast<const R600InstrInfo*>(CurDAG->getTarget().getInstrInfo());
+ int CSel = N->getConstantOperandVal(1);
+ std::vector<SDValue> Ops;
+
+ // We'll try to fold the const in the alu insts with native operands
+ for (SDNode::use_iterator Use = N->use_begin(), Next = llvm::next(Use);
+ Use != SDNode::use_end(); Use = Next) {
+ Next = llvm::next(Use);
+
+ if (!Use->isMachineOpcode())
+ continue;
+
+ unsigned Opcode = Use->getMachineOpcode();
+
+ const MCInstrDesc & MCDesc = TII->get(Opcode);
+ if (HAS_NATIVE_OPERANDS(MCDesc.TSFlags)) {
+
+ unsigned SrcNum = MCDesc.TSFlags & R600_InstFlag::OP3 ? 3 :
+ MCDesc.TSFlags & R600_InstFlag::OP2 ? 2 : 1;
+
+ const unsigned SrcOps[3][2] = {
+ {R600Operands::SRC0, R600Operands::SRC0_SEL},
+ {R600Operands::SRC1, R600Operands::SRC1_SEL},
+ {R600Operands::SRC2, R600Operands::SRC2_SEL}
+ };
+
+ Ops.clear();
+ for (unsigned i = 0; i < Use->getNumOperands(); ++i) {
+ Ops.push_back(Use->getOperand(i));
+ }
+
+ int RegOpIdx = Use.getOperandNo();
+ unsigned SrcIdx;
+
+ for (SrcIdx = 0; SrcIdx < SrcNum; ++SrcIdx) {
+ if (R600Operands::ALUOpTable[SrcNum-1][SrcOps[SrcIdx][0]] ==
+ RegOpIdx + 1)
+ break;
+ }
+
+ assert(SrcIdx < SrcNum && "ALU const folding: invalid operand");
+
+ int SelOpIdx =
+ R600Operands::ALUOpTable[SrcNum-1][SrcOps[SrcIdx][1]] - 1;
+
+ Ops[RegOpIdx] = CurDAG->getRegister(AMDGPU::ALU_CONST, MVT::f32);
+ Ops[SelOpIdx] = CurDAG->getTargetConstant(CSel, MVT::i32);
+
+ CurDAG->UpdateNodeOperands(*Use, Ops.data(), Use->getNumOperands());
+ }
+ }
+
+ Ops.clear();
+ Ops.push_back(CurDAG->getTargetConstant(1, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getRegister(AMDGPU::ALU_CONST, MVT::f32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(CSel, MVT::i32));
+ Ops.push_back(CurDAG->getTargetConstant(1, MVT::i32));
+ Ops.push_back(CurDAG->getRegister(AMDGPU::PRED_SEL_OFF, MVT::f32));
+ Ops.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+
+ return CurDAG->SelectNodeTo(N, AMDGPU::MOV, MVT::f32, Ops.data(),
+ Ops.size());
+
+ }
+ }
+ }
+ }
}
return SelectCode(N);
}