diff options
author | Tom Stellard <[email protected]> | 2012-06-01 14:49:03 -0400 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-06-01 16:52:26 -0400 |
commit | 0ebf2318b3d5e60adfc43e477b19acdc3cd4cc07 (patch) | |
tree | 0fc1f6ded65fc97e095420b7d3750f32098c0eb5 /src/gallium/drivers | |
parent | c108831d4451f624167d2c433282c6ac63541a79 (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')
-rw-r--r-- | src/gallium/drivers/radeon/AMDILISelDAGToDAG.cpp | 29 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600CodeEmitter.cpp | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/R600Instructions.td | 6 |
3 files changed, 33 insertions, 4 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 || diff --git a/src/gallium/drivers/radeon/R600CodeEmitter.cpp b/src/gallium/drivers/radeon/R600CodeEmitter.cpp index 8715f1133e8..f75c2f51bdc 100644 --- a/src/gallium/drivers/radeon/R600CodeEmitter.cpp +++ b/src/gallium/drivers/radeon/R600CodeEmitter.cpp @@ -255,7 +255,7 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) { emitByte(0); // offset - emitTwoBytes(0); + emitTwoBytes(MI.getOperand(2).getImm()); // endian emitByte(0); diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td index e12ebab60c9..921d5650060 100644 --- a/src/gallium/drivers/radeon/R600Instructions.td +++ b/src/gallium/drivers/radeon/R600Instructions.td @@ -51,6 +51,7 @@ def MEMrr : Operand<iPTR> { def ADDRParam : ComplexPattern<i32, 2, "SelectADDRParam", [], []>; def ADDRDWord : ComplexPattern<i32, 1, "SelectADDRDWord", [], []>; +def ADDRVTX_READ : ComplexPattern<i32, 2, "SelectADDRVTX_READ", [], []>; class R600_ALU { @@ -225,7 +226,6 @@ def store_global : PatFrag<(ops node:$value, node:$ptr), def load_param : PatFrag<(ops node:$ptr), (load node:$ptr), [{ - return true; const Value *Src = cast<LoadSDNode>(N)->getSrcValue(); if (Src) { PointerType * PT = dyn_cast<PointerType>(Src->getType()); @@ -804,11 +804,11 @@ class VTX_READ_eg <int buffer_id, list<dag> pattern> : InstR600ISA < >; def VTX_READ_PARAM_eg : VTX_READ_eg <0, - [(set (i32 R600_TReg32_X:$dst), (load_param ADDRParam:$ptr))] + [(set (i32 R600_TReg32_X:$dst), (load_param ADDRVTX_READ:$ptr))] >; def VTX_READ_GLOBAL_eg : VTX_READ_eg <1, - [(set (i32 R600_TReg32_X:$dst), (global_load ADDRParam:$ptr))] + [(set (i32 R600_TReg32_X:$dst), (global_load ADDRVTX_READ:$ptr))] >; } // End isEG Predicate |