diff options
author | Tom Stellard <[email protected]> | 2012-06-27 21:10:42 +0000 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-06-29 18:46:18 +0000 |
commit | b66ef1f48c946fdb0762e0092fa13a6f53e53e90 (patch) | |
tree | fe8614d1ff7a2239b33b168e7d245d8266bf742d /src | |
parent | c01199dfc0d30ad4c20cc4a2ebe3cdcbc74debb6 (diff) |
radeon/llvm: Handle floating point loads on R600
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/radeon/AMDGPUISelLowering.cpp | 30 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/AMDGPUISelLowering.h | 1 |
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; |