diff options
author | Tom Stellard <[email protected]> | 2012-07-25 08:30:32 -0400 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2012-07-27 17:08:08 +0000 |
commit | 50ff2dc0a4f553eb8d634d6f081fe5e4e25f6f48 (patch) | |
tree | acc1b4b0a305aff1f771399445614bf10302fd24 /src/gallium/drivers/radeon/SIISelLowering.cpp | |
parent | c424975572af2edd46863e5bb9fe3c51c96b4f9b (diff) |
radeon/llvm: Add special nodes for SALU operations on VCC
The VCC register is tricky because the SALU views it as 64-bit, but the
VALU views it as 1-bit. In order to deal with this we've added some
special bitcast and binary operations to help convert from the 64-bit
SALU view to the 1-bit VALU view and vice versa.
Diffstat (limited to 'src/gallium/drivers/radeon/SIISelLowering.cpp')
-rw-r--r-- | src/gallium/drivers/radeon/SIISelLowering.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/SIISelLowering.cpp b/src/gallium/drivers/radeon/SIISelLowering.cpp index 23eb4f8e239..e004562244d 100644 --- a/src/gallium/drivers/radeon/SIISelLowering.cpp +++ b/src/gallium/drivers/radeon/SIISelLowering.cpp @@ -35,6 +35,8 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) : computeRegisterProperties(); + setOperationAction(ISD::AND, MVT::i1, Custom); + setOperationAction(ISD::ADD, MVT::i64, Legal); setOperationAction(ISD::ADD, MVT::i32, Legal); @@ -216,9 +218,33 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); + case ISD::AND: return Loweri1ContextSwitch(Op, DAG, ISD::AND); } } +/// Loweri1ContextSwitch - The function is for lowering i1 operations on the +/// VCC register. In the VALU context, VCC is a one bit register, but in the +/// SALU context the VCC is a 64-bit register (1-bit per thread). Since only +/// the SALU can perform operations on the VCC register, we need to promote +/// the operand types from i1 to i64 in order for tablegen to be able to match +/// this operation to the correct SALU instruction. We do this promotion by +/// wrapping the operands in a CopyToReg node. +/// +SDValue SITargetLowering::Loweri1ContextSwitch(SDValue Op, + SelectionDAG &DAG, + unsigned VCCNode) const +{ + DebugLoc DL = Op.getDebugLoc(); + + SDValue OpNode = DAG.getNode(VCCNode, DL, MVT::i64, + DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i64, + Op.getOperand(0)), + DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i64, + Op.getOperand(1))); + + return DAG.getNode(SIISD::VCC_BITCAST, DL, MVT::i1, OpNode); +} + SDValue SITargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); @@ -256,3 +282,14 @@ SDValue SITargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const SDValue Cond = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, CC); return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False); } + +#define NODE_NAME_CASE(node) case SIISD::node: return #node; + +const char* SITargetLowering::getTargetNodeName(unsigned Opcode) const +{ + switch (Opcode) { + default: return AMDGPUTargetLowering::getTargetNodeName(Opcode); + NODE_NAME_CASE(VCC_AND) + NODE_NAME_CASE(VCC_BITCAST) + } +} |