From 0ebf2318b3d5e60adfc43e477b19acdc3cd4cc07 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 1 Jun 2012 14:49:03 -0400 Subject: [PATCH] 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. --- .../drivers/radeon/AMDILISelDAGToDAG.cpp | 29 +++++++++++++++++++ .../drivers/radeon/R600CodeEmitter.cpp | 2 +- .../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(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(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 { def ADDRParam : ComplexPattern; def ADDRDWord : ComplexPattern; +def ADDRVTX_READ : ComplexPattern; 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(N)->getSrcValue(); if (Src) { PointerType * PT = dyn_cast(Src->getType()); @@ -804,11 +804,11 @@ class VTX_READ_eg 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