summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-06-27 21:10:42 +0000
committerTom Stellard <[email protected]>2012-06-29 18:46:18 +0000
commitb66ef1f48c946fdb0762e0092fa13a6f53e53e90 (patch)
treefe8614d1ff7a2239b33b168e7d245d8266bf742d /src/gallium
parentc01199dfc0d30ad4c20cc4a2ebe3cdcbc74debb6 (diff)
radeon/llvm: Handle floating point loads on R600
Diffstat (limited to 'src/gallium')
-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;