summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.cpp7
-rw-r--r--src/gallium/drivers/radeon/AMDGPUISelLowering.h10
-rw-r--r--src/gallium/drivers/radeon/SIISelLowering.cpp69
-rw-r--r--src/gallium/drivers/radeon/SIISelLowering.h3
-rw-r--r--src/gallium/drivers/radeon/SIInstructions.td27
5 files changed, 50 insertions, 66 deletions
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
index 2e6782840f2..e22df8efb0e 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
@@ -311,13 +311,6 @@ bool AMDGPUTargetLowering::isHWFalseValue(SDValue Op) const
return false;
}
-void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
- MachineFunction * MF, MachineRegisterInfo & MRI,
- const TargetInstrInfo * TII, unsigned reg) const
-{
- AMDGPU::utilAddLiveIn(MF, MRI, TII, reg, MI->getOperand(0).getReg());
-}
-
SDValue AMDGPUTargetLowering::CreateLiveInRegister(SelectionDAG &DAG,
const TargetRegisterClass *RC,
unsigned Reg, EVT VT) const {
diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
index b05de384202..cd2f0c0789a 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
@@ -29,16 +29,6 @@ private:
protected:
- /// addLiveIn - This functions adds reg to the live in list of the entry block
- /// and emits a copy from reg to MI.getOperand(0).
- ///
- // Some registers are loaded with values before the program
- /// begins to execute. The loading of these values is modeled with pseudo
- /// instructions which are lowered using this function.
- void addLiveIn(MachineInstr * MI, MachineFunction * MF,
- MachineRegisterInfo & MRI, const TargetInstrInfo * TII,
- unsigned reg) const;
-
/// CreateLiveInRegister - Helper function that adds Reg to the LiveIn list
/// of the DAG's MachineFunction. This returns a Register SDNode representing
/// Reg.
diff --git a/src/gallium/drivers/radeon/SIISelLowering.cpp b/src/gallium/drivers/radeon/SIISelLowering.cpp
index 270e4a163b6..092c2fa67e2 100644
--- a/src/gallium/drivers/radeon/SIISelLowering.cpp
+++ b/src/gallium/drivers/radeon/SIISelLowering.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "SIISelLowering.h"
+#include "AMDIL.h"
#include "AMDILIntrinsicInfo.h"
#include "SIInstrInfo.h"
#include "SIRegisterInfo.h"
@@ -47,6 +48,11 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) :
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
+ // We need to custom lower loads from the USER_SGPR address space, so we can
+ // add the SGPRs as livein registers.
+ setOperationAction(ISD::LOAD, MVT::i32, Custom);
+ setOperationAction(ISD::LOAD, MVT::i64, Custom);
+
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
@@ -126,11 +132,6 @@ MachineBasicBlock * SITargetLowering::EmitInstrWithCustomInserter(
case AMDGPU::SI_V_CNDLT:
LowerSI_V_CNDLT(MI, *BB, I, MRI);
break;
- case AMDGPU::USE_SGPR_32:
- case AMDGPU::USE_SGPR_64:
- lowerUSE_SGPR(MI, BB->getParent(), MRI);
- MI->eraseFromParent();
- break;
}
return BB;
}
@@ -209,21 +210,6 @@ void SITargetLowering::LowerSI_V_CNDLT(MachineInstr *MI, MachineBasicBlock &BB,
MI->eraseFromParent();
}
-void SITargetLowering::lowerUSE_SGPR(MachineInstr *MI,
- MachineFunction * MF, MachineRegisterInfo & MRI) const
-{
- const TargetInstrInfo * TII = getTargetMachine().getInstrInfo();
- unsigned dstReg = MI->getOperand(0).getReg();
- int64_t newIndex = MI->getOperand(1).getImm();
- const TargetRegisterClass * dstClass = MRI.getRegClass(dstReg);
- unsigned DwordWidth = dstClass->getSize() / 4;
- assert(newIndex % DwordWidth == 0 && "USER_SGPR not properly aligned");
- newIndex = newIndex / DwordWidth;
-
- unsigned newReg = dstClass->getRegister(newIndex);
- addLiveIn(MI, MF, MRI, TII, newReg);
-}
-
EVT SITargetLowering::getSetCCResultType(EVT VT) const
{
return MVT::i1;
@@ -238,6 +224,7 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
switch (Op.getOpcode()) {
default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
+ case ISD::LOAD: return LowerLOAD(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
case ISD::AND: return Loweri1ContextSwitch(Op, DAG, ISD::AND);
case ISD::INTRINSIC_WO_CHAIN: {
@@ -303,6 +290,48 @@ SDValue SITargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
return Result;
}
+SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const
+{
+ EVT VT = Op.getValueType();
+ LoadSDNode *Ptr = dyn_cast<LoadSDNode>(Op);
+
+ assert(Ptr);
+
+ unsigned AddrSpace = Ptr->getPointerInfo().getAddrSpace();
+
+ // We only need to lower USER_SGPR address space loads
+ if (AddrSpace != AMDGPUAS::USER_SGPR_ADDRESS) {
+ return SDValue();
+ }
+
+ // Loads from the USER_SGPR address space can only have constant value
+ // pointers.
+ ConstantSDNode *BasePtr = dyn_cast<ConstantSDNode>(Ptr->getBasePtr());
+ assert(BasePtr);
+
+ unsigned TypeDwordWidth = VT.getSizeInBits() / 32;
+ const TargetRegisterClass * dstClass;
+ switch (TypeDwordWidth) {
+ default:
+ assert(!"USER_SGPR value size not implemented");
+ return SDValue();
+ case 1:
+ dstClass = &AMDGPU::SReg_32RegClass;
+ break;
+ case 2:
+ dstClass = &AMDGPU::SReg_64RegClass;
+ break;
+ }
+ uint64_t Index = BasePtr->getZExtValue();
+ assert(Index % TypeDwordWidth == 0 && "USER_SGPR not properly aligned");
+ unsigned SGPRIndex = Index / TypeDwordWidth;
+ unsigned Reg = dstClass->getRegister(SGPRIndex);
+
+ DAG.ReplaceAllUsesOfValueWith(Op, CreateLiveInRegister(DAG, dstClass, Reg,
+ VT));
+ return SDValue();
+}
+
SDValue SITargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
{
SDValue LHS = Op.getOperand(0);
diff --git a/src/gallium/drivers/radeon/SIISelLowering.h b/src/gallium/drivers/radeon/SIISelLowering.h
index d5454528de2..cf655a1dce7 100644
--- a/src/gallium/drivers/radeon/SIISelLowering.h
+++ b/src/gallium/drivers/radeon/SIISelLowering.h
@@ -35,12 +35,11 @@ class SITargetLowering : public AMDGPUTargetLowering
MachineBasicBlock::iterator I) const;
void LowerSI_V_CNDLT(MachineInstr *MI, MachineBasicBlock &BB,
MachineBasicBlock::iterator I, MachineRegisterInfo & MRI) const;
- void lowerUSE_SGPR(MachineInstr *MI, MachineFunction * MF,
- MachineRegisterInfo & MRI) const;
SDValue Loweri1ContextSwitch(SDValue Op, SelectionDAG &DAG,
unsigned VCCNode) const;
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
public:
diff --git a/src/gallium/drivers/radeon/SIInstructions.td b/src/gallium/drivers/radeon/SIInstructions.td
index aad2ade10ce..152d7356a91 100644
--- a/src/gallium/drivers/radeon/SIInstructions.td
+++ b/src/gallium/drivers/radeon/SIInstructions.td
@@ -7,19 +7,6 @@
//
//===----------------------------------------------------------------------===//
-def load_user_sgpr : PatFrag<(ops node:$ptr),
- (load node:$ptr),
- [{
- const Value *Src = cast<LoadSDNode>(N)->getSrcValue();
- if (Src) {
- PointerType * PT = dyn_cast<PointerType>(Src->getType());
- return PT && PT->getAddressSpace() == AMDGPUAS::USER_SGPR_ADDRESS;
- }
- return false;
- }]
->;
-
-
def isSI : Predicate<"Subtarget.device()"
"->getGeneration() == AMDGPUDeviceInfo::HD7XXX">;
@@ -956,20 +943,6 @@ def SI_INTERP_CONST : InstSI <
imm:$attr, SReg_32:$params))]
>;
-def USE_SGPR_32 : InstSI <
- (outs SReg_32:$dst),
- (ins i32imm:$src0),
- "USE_SGPR_32",
- [(set (i32 SReg_32:$dst), (load_user_sgpr imm:$src0))]
->;
-
-def USE_SGPR_64 : InstSI <
- (outs SReg_64:$dst),
- (ins i32imm:$src0),
- "USE_SGPR_64",
- [(set (i64 SReg_64:$dst), (load_user_sgpr imm:$src0))]
->;
-
} // end usesCustomInserter
// SI Psuedo branch instructions. These are used by the CFG structurizer pass