summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-06-01 14:49:03 -0400
committerTom Stellard <[email protected]>2012-06-01 16:52:26 -0400
commit0ebf2318b3d5e60adfc43e477b19acdc3cd4cc07 (patch)
tree0fc1f6ded65fc97e095420b7d3750f32098c0eb5 /src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
parentc108831d4451f624167d2c433282c6ac63541a79 (diff)
radeon/llvm: Fix VTX_READ patterns
The VTX_READ instructions were using the ADDRParam ComplexPattern which allows a load instruction's offset to be a register, but VTX_READ instructions can only handle an immediate offset. Also, the load_param pattern fragment had an erroneous return true; statement that was causing it to match the wrong load instructions.
Diffstat (limited to 'src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp')
-rw-r--r--src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
index b14a360c3cc..d7b08b0aa77 100644
--- a/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
+++ b/src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp
@@ -69,6 +69,7 @@ private:
bool SelectADDR8BitOffset(SDValue Addr, SDValue& Base, SDValue& Offset);
bool SelectADDRReg(SDValue Addr, SDValue& Base, SDValue& Offset);
+ bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
// Include the pieces autogenerated from the target description.
#include "AMDGPUGenDAGISel.inc"
@@ -556,6 +557,34 @@ bool AMDILDAGToDAGISel::SelectADDR8BitOffset(SDValue Addr, SDValue& Base,
return true;
}
+bool AMDILDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
+ SDValue &Offset)
+{
+ ConstantSDNode * IMMOffset;
+
+ if (Addr.getOpcode() == ISD::ADD
+ && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
+ && isInt<16>(IMMOffset->getZExtValue())) {
+
+ Base = Addr.getOperand(0);
+ Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
+ return true;
+ // If the pointer address is constant, we can move it to the offset field.
+ } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
+ && isInt<16>(IMMOffset->getZExtValue())) {
+ Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+ CurDAG->getEntryNode().getDebugLoc(),
+ AMDIL::ZERO, MVT::i32);
+ Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
+ return true;
+ }
+
+ // Default case, no offset
+ Base = Addr;
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+ return true;
+}
+
bool AMDILDAGToDAGISel::SelectADDRReg(SDValue Addr, SDValue& Base,
SDValue& Offset) {
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||