diff options
| author | Justin Holewinski <jholewinski@nvidia.com> | 2014-03-24 11:17:53 +0000 |
|---|---|---|
| committer | Justin Holewinski <jholewinski@nvidia.com> | 2014-03-24 11:17:53 +0000 |
| commit | ba2fa6de4fcd30ca8a2ee07d07a1f37b9444ffa4 (patch) | |
| tree | c556b4530d179be4e952f69e26aa1395859541f2 /llvm/lib | |
| parent | f7af2e6de853ff7515974f6def4cedac4c9ebbe6 (diff) | |
| download | bcm5719-llvm-ba2fa6de4fcd30ca8a2ee07d07a1f37b9444ffa4.tar.gz bcm5719-llvm-ba2fa6de4fcd30ca8a2ee07d07a1f37b9444ffa4.zip | |
[NVPTX] Add isel patterns for addrspacecast
llvm-svn: 204600
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 63 | ||||
| -rw-r--r-- | llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h | 1 |
2 files changed, 64 insertions, 0 deletions
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp index 6d1c160374e..bd08d2d8ad9 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp @@ -162,6 +162,9 @@ SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) { case NVPTXISD::StoreParamU32: ResNode = SelectStoreParam(N); break; + case ISD::ADDRSPACECAST: + ResNode = SelectAddrSpaceCast(N); + break; default: break; } @@ -191,6 +194,66 @@ static unsigned int getCodeAddrSpace(MemSDNode *N, return NVPTX::PTXLdStInstCode::GENERIC; } +SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) { + SDValue Src = N->getOperand(0); + AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N); + unsigned SrcAddrSpace = CastN->getSrcAddressSpace(); + unsigned DstAddrSpace = CastN->getDestAddressSpace(); + + assert(SrcAddrSpace != DstAddrSpace && + "addrspacecast must be between different address spaces"); + + if (DstAddrSpace == ADDRESS_SPACE_GENERIC) { + // Specific to generic + unsigned Opc; + switch (SrcAddrSpace) { + default: report_fatal_error("Bad address space in addrspacecast"); + case ADDRESS_SPACE_GLOBAL: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64 + : NVPTX::cvta_global_yes; + break; + case ADDRESS_SPACE_SHARED: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64 + : NVPTX::cvta_shared_yes; + break; + case ADDRESS_SPACE_CONST: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64 + : NVPTX::cvta_const_yes; + break; + case ADDRESS_SPACE_LOCAL: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64 + : NVPTX::cvta_local_yes; + break; + } + return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src); + } else { + // Generic to specific + if (SrcAddrSpace != 0) + report_fatal_error("Cannot cast between two non-generic address spaces"); + unsigned Opc; + switch (DstAddrSpace) { + default: report_fatal_error("Bad address space in addrspacecast"); + case ADDRESS_SPACE_GLOBAL: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64 + : NVPTX::cvta_to_global_yes; + break; + case ADDRESS_SPACE_SHARED: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64 + : NVPTX::cvta_to_shared_yes; + break; + case ADDRESS_SPACE_CONST: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64 + : NVPTX::cvta_to_const_yes; + break; + case ADDRESS_SPACE_LOCAL: + Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64 + : NVPTX::cvta_to_local_yes; + break; + } + return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src); + } +} + SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) { SDLoc dl(N); LoadSDNode *LD = cast<LoadSDNode>(N); diff --git a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h index a4a5abeb76c..93ad16911b5 100644 --- a/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h +++ b/llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h @@ -67,6 +67,7 @@ private: SDNode *SelectLoadParam(SDNode *N); SDNode *SelectStoreRetval(SDNode *N); SDNode *SelectStoreParam(SDNode *N); + SDNode *SelectAddrSpaceCast(SDNode *N); inline SDValue getI32Imm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, MVT::i32); |

