summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.cpp30
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.h1
2 files changed, 31 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
index 544de0fa312..f14900450ae 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
@@ -33,6 +33,7 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
setOperationAction(ISD::FEXP2, MVT::f32, Legal);
setOperationAction(ISD::FRINT, MVT::f32, Legal);
+ setOperationAction(ISD::LOAD, MVT::f32, Custom);
setOperationAction(ISD::UDIV, MVT::i32, Expand);
setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
@@ -45,6 +46,7 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
switch (Op.getOpcode()) {
default: return AMDILTargetLowering::LowerOperation(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
+ case ISD::LOAD: return BitcastLOAD(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
}
@@ -127,6 +129,34 @@ SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
OneSubAC);
}
+/// BitcastLoad - Convert floating point loads to integer loads of the same
+/// type width and the bitcast the result back to a floating point type.
+SDValue AMDGPUTargetLowering::BitcastLOAD(SDValue Op, SelectionDAG &DAG) const
+{
+ DebugLoc DL = Op.getDebugLoc();
+ EVT VT = Op.getValueType();
+ EVT IntVT;
+
+ if (VT == MVT::f32) {
+ IntVT = MVT::i32;
+ } else {
+ return Op;
+ }
+ LoadSDNode * LD = dyn_cast<LoadSDNode>(Op);
+ assert(LD);
+
+ SDValue NewLoad = DAG.getLoad (LD->getAddressingMode(),
+ LD->getExtensionType(), IntVT, DL,
+ LD->getChain(), LD->getBasePtr(),
+ LD->getOffset(), IntVT,
+ LD->getMemOperand());
+
+ SDValue Bitcast = DAG.getNode(ISD::BITCAST, DL, VT, NewLoad);
+ DAG.ReplaceAllUsesWith(Op.getValue(0).getNode(), &Bitcast);
+
+ return Op;
+}
+
SDValue AMDGPUTargetLowering::LowerSELECT_CC(SDValue Op,
SelectionDAG &DAG) const
{
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
index 72342c99614..4d1a312ea5e 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
@@ -23,6 +23,7 @@ class AMDGPUTargetLowering : public AMDILTargetLowering
{
private:
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+ SDValue BitcastLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;