NVPTXISelDAGToDAG.cpp revision 0b8c9a80f20772c3793201ab5b251d3520b9cea3
149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file defines an instruction selector for the NVPTX target. 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXISelDAGToDAG.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalValue.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CommandLine.h" 1949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/Debug.h" 2049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/ErrorHandling.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h" 2249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetIntrinsicInfo.h" 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#undef DEBUG_TYPE 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#define DEBUG_TYPE "nvptx-isel" 2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm; 2849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic cl::opt<bool> 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiUseFMADInstruction("nvptx-mad-enable", 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::ZeroOrMore, 3349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::desc("NVPTX Specific: Enable generating FMAD instructions"), 3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::init(false)); 3549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic cl::opt<int> 3749683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiFMAContractLevel("nvptx-fma-level", 3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::ZeroOrMore, 3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::desc("NVPTX Specific: FMA contraction (0: don't do it" 4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski " 1: do it 2: do it aggressively"), 4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::init(2)); 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic cl::opt<int> 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiUsePrecDivF32("nvptx-prec-divf32", 4649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::ZeroOrMore, 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use" 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski " IEEE Compliant F32 div.rnd if avaiable."), 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cl::init(2)); 5049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// createNVPTXISelDag - This pass converts a legalized DAG into a 5249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// NVPTX-specific DAG, ready for instruction scheduling. 5349683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiFunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM, 5449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski llvm::CodeGenOpt::Level OptLevel) { 5549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return new NVPTXDAGToDAGISel(TM, OptLevel); 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiNVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski CodeGenOpt::Level OptLevel) 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski: SelectionDAGISel(tm, OptLevel), 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Subtarget(tm.getSubtarget<NVPTXSubtarget>()) 6349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski{ 6449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Always do fma.f32 fpcontract if the target supports the instruction. 6549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Always do fma.f64 fpcontract if the target supports the instruction. 6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Do mad.f32 is nvptx-mad-enable is specified and the target does not 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // support fma.f32. 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32(); 7049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && 7149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (FMAContractLevel>=1); 7249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && 7349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (FMAContractLevel>=1); 7449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doFMAF32AGG = (OptLevel > 0) && Subtarget.hasFMAF32() && 7549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (FMAContractLevel==2); 7649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doFMAF64AGG = (OptLevel > 0) && Subtarget.hasFMAF64() && 7749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski (FMAContractLevel==2); 7849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction; 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 81af878315192a9fa5b534364e327c24aeb8d73b5aBenjamin Kramer UseF32FTZ = false; 82af878315192a9fa5b534364e327c24aeb8d73b5aBenjamin Kramer 8349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski doMulWide = (OptLevel > 0); 8449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Decide how to translate f32 div 8649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski do_DIVF32_PREC = UsePrecDivF32; 8749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // sm less than sm_20 does not support div.rnd. Use div.full. 8849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20()) 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski do_DIVF32_PREC = 1; 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 9249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// Select - Select instructions not customized! Used for 9449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// expanded, promoted and normal instructions. 9549683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiSDNode* NVPTXDAGToDAGISel::Select(SDNode *N) { 9649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N->isMachineOpcode()) 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; // Already selected. 9949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode *ResNode = NULL; 10149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (N->getOpcode()) { 10249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case ISD::LOAD: 10349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski ResNode = SelectLoad(N); 10449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski break; 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case ISD::STORE: 10649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski ResNode = SelectStore(N); 10749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski break; 10849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 10949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (ResNode) 11049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return ResNode; 11149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return SelectCode(N); 11249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 11349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskistatic unsigned int 11649683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskigetCodeAddrSpace(MemSDNode *N, const NVPTXSubtarget &Subtarget) 11749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski{ 11849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Value *Src = N->getSrcValue(); 11949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!Src) 12049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTX::PTXLdStInstCode::LOCAL; 12149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 12249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) { 12349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (PT->getAddressSpace()) { 12449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL; 12549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL; 12649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED; 12749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_CONST_NOT_GEN: 12849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTX::PTXLdStInstCode::CONSTANT; 12949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC; 13049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM; 13149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case llvm::ADDRESS_SPACE_CONST: 13249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If the arch supports generic address space, translate it to GLOBAL 13349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // for correctness. 13449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If the arch does not support generic address space, then the arch 13549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // does not really support ADDRESS_SPACE_CONST, translate it to 13649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // to CONSTANT for better performance. 13749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Subtarget.hasGenericLdSt()) 13849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTX::PTXLdStInstCode::GLOBAL; 13949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 14049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTX::PTXLdStInstCode::CONSTANT; 14149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: break; 14249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 14349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 14449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTX::PTXLdStInstCode::LOCAL; 14549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 14649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 14749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 14849683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiSDNode* NVPTXDAGToDAGISel::SelectLoad(SDNode *N) { 14949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski DebugLoc dl = N->getDebugLoc(); 15049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski LoadSDNode *LD = cast<LoadSDNode>(N); 15149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski EVT LoadedVT = LD->getMemoryVT(); 15249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode *NVPTXLD= NULL; 15349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 15449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // do not support pre/post inc/dec 15549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (LD->isIndexed()) 15649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 15749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 15849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!LoadedVT.isSimple()) 15949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 16049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 16149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Address Space Setting 16249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget); 16349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 16449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Volatile Setting 16549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // - .volatile is only availalble for .global and .shared 16649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isVolatile = LD->isVolatile(); 16749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL && 16849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED && 16949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC) 17049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isVolatile = false; 17149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 17249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Vector Setting 17349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT SimpleVT = LoadedVT.getSimpleVT(); 17449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned vecType = NVPTX::PTXLdStInstCode::Scalar; 17549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SimpleVT.isVector()) { 17649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned num = SimpleVT.getVectorNumElements(); 17749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (num == 2) 17849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski vecType = NVPTX::PTXLdStInstCode::V2; 17949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (num == 4) 18049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski vecType = NVPTX::PTXLdStInstCode::V4; 18149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 18249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 18349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 18449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 18549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Type Setting: fromType + fromTypeWidth 18649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 18749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Sign : ISD::SEXTLOAD 18849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the 18949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // type is integer 19049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float 19149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT ScalarVT = SimpleVT.getScalarType(); 19249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned fromTypeWidth = ScalarVT.getSizeInBits(); 19349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int fromType; 19449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if ((LD->getExtensionType() == ISD::SEXTLOAD)) 19549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski fromType = NVPTX::PTXLdStInstCode::Signed; 19649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (ScalarVT.isFloatingPoint()) 19749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski fromType = NVPTX::PTXLdStInstCode::Float; 19849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 19949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski fromType = NVPTX::PTXLdStInstCode::Unsigned; 20049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 20149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Create the machine instruction DAG 20249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Chain = N->getOperand(0); 20349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue N1 = N->getOperand(1); 20449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Addr; 20549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Offset, Base; 20649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned Opcode; 20749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy; 20849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 20949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectDirectAddr(N1, Addr)) { 21049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (TargetVT) { 21149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::LD_i8_avar; break; 21249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::LD_i16_avar; break; 21349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::LD_i32_avar; break; 21449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::LD_i64_avar; break; 21549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::LD_f32_avar; break; 21649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::LD_f64_avar; break; 21749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::LD_v2i8_avar; break; 21849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::LD_v2i16_avar; break; 21949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::LD_v2i32_avar; break; 22049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::LD_v2i64_avar; break; 22149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::LD_v2f32_avar; break; 22249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::LD_v2f64_avar; break; 22349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::LD_v4i8_avar; break; 22449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::LD_v4i16_avar; break; 22549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::LD_v4i32_avar; break; 22649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::LD_v4f32_avar; break; 22749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 22849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 22949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { getI32Imm(isVolatile), 23049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 23149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 23249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromType), 23349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromTypeWidth), 23449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Addr, Chain }; 23549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, 23649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 7); 23749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (Subtarget.is64Bit()? 23849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRsi64(N1.getNode(), N1, Base, Offset): 23949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRsi(N1.getNode(), N1, Base, Offset)) { 24049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (TargetVT) { 24149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::LD_i8_asi; break; 24249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::LD_i16_asi; break; 24349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::LD_i32_asi; break; 24449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::LD_i64_asi; break; 24549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::LD_f32_asi; break; 24649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::LD_f64_asi; break; 24749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::LD_v2i8_asi; break; 24849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::LD_v2i16_asi; break; 24949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::LD_v2i32_asi; break; 25049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::LD_v2i64_asi; break; 25149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::LD_v2f32_asi; break; 25249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::LD_v2f64_asi; break; 25349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::LD_v4i8_asi; break; 25449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::LD_v4i16_asi; break; 25549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::LD_v4i32_asi; break; 25649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::LD_v4f32_asi; break; 25749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 25849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 25949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { getI32Imm(isVolatile), 26049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 26149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 26249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromType), 26349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromTypeWidth), 26449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base, Offset, Chain }; 26549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, 26649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 8); 26749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (Subtarget.is64Bit()? 26849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRri64(N1.getNode(), N1, Base, Offset): 26949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRri(N1.getNode(), N1, Base, Offset)) { 27049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (TargetVT) { 27149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::LD_i8_ari; break; 27249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::LD_i16_ari; break; 27349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::LD_i32_ari; break; 27449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::LD_i64_ari; break; 27549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::LD_f32_ari; break; 27649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::LD_f64_ari; break; 27749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::LD_v2i8_ari; break; 27849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::LD_v2i16_ari; break; 27949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::LD_v2i32_ari; break; 28049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::LD_v2i64_ari; break; 28149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::LD_v2f32_ari; break; 28249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::LD_v2f64_ari; break; 28349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::LD_v4i8_ari; break; 28449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::LD_v4i16_ari; break; 28549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::LD_v4i32_ari; break; 28649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::LD_v4f32_ari; break; 28749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 28849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 28949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { getI32Imm(isVolatile), 29049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 29149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 29249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromType), 29349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromTypeWidth), 29449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base, Offset, Chain }; 29549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, 29649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 8); 29749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 29849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else { 29949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (TargetVT) { 30049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::LD_i8_areg; break; 30149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::LD_i16_areg; break; 30249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::LD_i32_areg; break; 30349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::LD_i64_areg; break; 30449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::LD_f32_areg; break; 30549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::LD_f64_areg; break; 30649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::LD_v2i8_areg; break; 30749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::LD_v2i16_areg; break; 30849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::LD_v2i32_areg; break; 30949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::LD_v2i64_areg; break; 31049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::LD_v2f32_areg; break; 31149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::LD_v2f64_areg; break; 31249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::LD_v4i8_areg; break; 31349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::LD_v4i16_areg; break; 31449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::LD_v4i32_areg; break; 31549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::LD_v4f32_areg; break; 31649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 31749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 31849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { getI32Imm(isVolatile), 31949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 32049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 32149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromType), 32249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(fromTypeWidth), 32349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski N1, Chain }; 32449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, 32549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 7); 32649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 32749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 32849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (NVPTXLD != NULL) { 32949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 33049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand(); 33149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1); 33249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 33349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 33449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTXLD; 33549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 33649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 33749683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiSDNode* NVPTXDAGToDAGISel::SelectStore(SDNode *N) { 33849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski DebugLoc dl = N->getDebugLoc(); 33949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski StoreSDNode *ST = cast<StoreSDNode>(N); 34049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski EVT StoreVT = ST->getMemoryVT(); 34149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode *NVPTXST = NULL; 34249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 34349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // do not support pre/post inc/dec 34449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (ST->isIndexed()) 34549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 34649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 34749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!StoreVT.isSimple()) 34849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 34949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 35049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Address Space Setting 35149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget); 35249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 35349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Volatile Setting 35449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // - .volatile is only availalble for .global and .shared 35549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool isVolatile = ST->isVolatile(); 35649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL && 35749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED && 35849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC) 35949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski isVolatile = false; 36049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 36149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Vector Setting 36249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT SimpleVT = StoreVT.getSimpleVT(); 36349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned vecType = NVPTX::PTXLdStInstCode::Scalar; 36449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SimpleVT.isVector()) { 36549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned num = SimpleVT.getVectorNumElements(); 36649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (num == 2) 36749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski vecType = NVPTX::PTXLdStInstCode::V2; 36849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (num == 4) 36949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski vecType = NVPTX::PTXLdStInstCode::V4; 37049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 37149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NULL; 37249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 37349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 37449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Type Setting: toType + toTypeWidth 37549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // - for integer type, always use 'u' 37649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 37749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT ScalarVT = SimpleVT.getScalarType(); 37849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned toTypeWidth = ScalarVT.getSizeInBits(); 37949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int toType; 38049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (ScalarVT.isFloatingPoint()) 38149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski toType = NVPTX::PTXLdStInstCode::Float; 38249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 38349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski toType = NVPTX::PTXLdStInstCode::Unsigned; 38449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 38549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Create the machine instruction DAG 38649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Chain = N->getOperand(0); 38749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue N1 = N->getOperand(1); 38849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue N2 = N->getOperand(2); 38949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Addr; 39049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Offset, Base; 39149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned Opcode; 39249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::SimpleValueType SourceVT = 39349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski N1.getNode()->getValueType(0).getSimpleVT().SimpleTy; 39449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 39549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectDirectAddr(N2, Addr)) { 39649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (SourceVT) { 39749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::ST_i8_avar; break; 39849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::ST_i16_avar; break; 39949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::ST_i32_avar; break; 40049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::ST_i64_avar; break; 40149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::ST_f32_avar; break; 40249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::ST_f64_avar; break; 40349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::ST_v2i8_avar; break; 40449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::ST_v2i16_avar; break; 40549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::ST_v2i32_avar; break; 40649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::ST_v2i64_avar; break; 40749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::ST_v2f32_avar; break; 40849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::ST_v2f64_avar; break; 40949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::ST_v4i8_avar; break; 41049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::ST_v4i16_avar; break; 41149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::ST_v4i32_avar; break; 41249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::ST_v4f32_avar; break; 41349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 41449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 41549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { N1, 41649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(isVolatile), 41749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 41849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 41949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toType), 42049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toTypeWidth), 42149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Addr, Chain }; 42249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXST = CurDAG->getMachineNode(Opcode, dl, 42349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 8); 42449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (Subtarget.is64Bit()? 42549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRsi64(N2.getNode(), N2, Base, Offset): 42649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRsi(N2.getNode(), N2, Base, Offset)) { 42749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (SourceVT) { 42849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::ST_i8_asi; break; 42949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::ST_i16_asi; break; 43049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::ST_i32_asi; break; 43149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::ST_i64_asi; break; 43249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::ST_f32_asi; break; 43349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::ST_f64_asi; break; 43449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::ST_v2i8_asi; break; 43549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::ST_v2i16_asi; break; 43649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::ST_v2i32_asi; break; 43749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::ST_v2i64_asi; break; 43849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::ST_v2f32_asi; break; 43949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::ST_v2f64_asi; break; 44049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::ST_v4i8_asi; break; 44149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::ST_v4i16_asi; break; 44249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::ST_v4i32_asi; break; 44349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::ST_v4f32_asi; break; 44449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 44549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 44649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { N1, 44749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(isVolatile), 44849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 44949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 45049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toType), 45149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toTypeWidth), 45249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base, Offset, Chain }; 45349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXST = CurDAG->getMachineNode(Opcode, dl, 45449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 9); 45549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else if (Subtarget.is64Bit()? 45649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRri64(N2.getNode(), N2, Base, Offset): 45749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SelectADDRri(N2.getNode(), N2, Base, Offset)) { 45849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (SourceVT) { 45949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::ST_i8_ari; break; 46049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::ST_i16_ari; break; 46149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::ST_i32_ari; break; 46249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::ST_i64_ari; break; 46349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::ST_f32_ari; break; 46449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::ST_f64_ari; break; 46549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::ST_v2i8_ari; break; 46649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::ST_v2i16_ari; break; 46749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::ST_v2i32_ari; break; 46849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::ST_v2i64_ari; break; 46949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::ST_v2f32_ari; break; 47049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::ST_v2f64_ari; break; 47149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::ST_v4i8_ari; break; 47249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::ST_v4i16_ari; break; 47349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::ST_v4i32_ari; break; 47449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::ST_v4f32_ari; break; 47549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 47649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 47749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { N1, 47849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(isVolatile), 47949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 48049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 48149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toType), 48249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toTypeWidth), 48349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base, Offset, Chain }; 48449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXST = CurDAG->getMachineNode(Opcode, dl, 48549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 9); 48649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } else { 48749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (SourceVT) { 48849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i8: Opcode = NVPTX::ST_i8_areg; break; 48949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i16: Opcode = NVPTX::ST_i16_areg; break; 49049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i32: Opcode = NVPTX::ST_i32_areg; break; 49149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::i64: Opcode = NVPTX::ST_i64_areg; break; 49249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f32: Opcode = NVPTX::ST_f32_areg; break; 49349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::f64: Opcode = NVPTX::ST_f64_areg; break; 49449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i8: Opcode = NVPTX::ST_v2i8_areg; break; 49549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i16: Opcode = NVPTX::ST_v2i16_areg; break; 49649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i32: Opcode = NVPTX::ST_v2i32_areg; break; 49749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2i64: Opcode = NVPTX::ST_v2i64_areg; break; 49849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f32: Opcode = NVPTX::ST_v2f32_areg; break; 49949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v2f64: Opcode = NVPTX::ST_v2f64_areg; break; 50049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i8: Opcode = NVPTX::ST_v4i8_areg; break; 50149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i16: Opcode = NVPTX::ST_v4i16_areg; break; 50249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4i32: Opcode = NVPTX::ST_v4i32_areg; break; 50349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case MVT::v4f32: Opcode = NVPTX::ST_v4f32_areg; break; 50449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return NULL; 50549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 50649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Ops[] = { N1, 50749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(isVolatile), 50849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(codeAddrSpace), 50949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(vecType), 51049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toType), 51149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski getI32Imm(toTypeWidth), 51249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski N2, Chain }; 51349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXST = CurDAG->getMachineNode(Opcode, dl, 51449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT::Other, Ops, 8); 51549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 51649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 51749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (NVPTXST != NULL) { 51849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 51949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand(); 52049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1); 52149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 52249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 52349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return NVPTXST; 52449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 52549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 52649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// SelectDirectAddr - Match a direct address for DAG. 52749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// A direct address could be a globaladdress or externalsymbol. 52849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) { 52949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Return true if TGA or ES. 53049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N.getOpcode() == ISD::TargetGlobalAddress 53149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski || N.getOpcode() == ISD::TargetExternalSymbol) { 53249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Address = N; 53349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 53449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 53549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N.getOpcode() == NVPTXISD::Wrapper) { 53649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Address = N.getOperand(0); 53749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 53849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 53949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) { 54049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue(); 54149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (IID == Intrinsic::nvvm_ptr_gen_to_param) 54249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam) 54349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address)); 54449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 54549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 54649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 54749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 54849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// symbol+offset 54949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRsi_imp(SDNode *OpNode, SDValue Addr, 55049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset, 55149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT mvt) { 55249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Addr.getOpcode() == ISD::ADD) { 55349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 55449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue base=Addr.getOperand(0); 55549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectDirectAddr(base, Base)) { 55649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt); 55749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 55849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 55949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 56049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 56149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 56249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 56349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 56449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// symbol+offset 56549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr, 56649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset) { 56749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32); 56849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 56949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 57049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// symbol+offset 57149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr, 57249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset) { 57349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64); 57449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 57549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 57649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// register+offset 57749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRri_imp(SDNode *OpNode, SDValue Addr, 57849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset, 57949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski MVT mvt) { 58049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 58149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt); 58249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Offset = CurDAG->getTargetConstant(0, mvt); 58349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 58449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 58549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Addr.getOpcode() == ISD::TargetExternalSymbol || 58649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Addr.getOpcode() == ISD::TargetGlobalAddress) 58749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; // direct calls. 58849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 58949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (Addr.getOpcode() == ISD::ADD) { 59049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectDirectAddr(Addr.getOperand(0), Addr)) { 59149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 59249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 59349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 59449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (FrameIndexSDNode *FIN = 59549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) 59649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Constant offset from frame ref. 59749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt); 59849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else 59949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Base = Addr.getOperand(0); 60049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt); 60149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 60249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 60349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 60449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 60549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 60649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 60749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// register+offset 60849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr, 60949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset) { 61049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32); 61149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 61249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 61349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// register+offset 61449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr, 61549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Base, SDValue &Offset) { 61649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64); 61749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 61849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 61949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N, 62049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned int spN) const { 62149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const Value *Src = NULL; 62249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Even though MemIntrinsicSDNode is a subclas of MemSDNode, 62349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // the classof() for MemSDNode does not include MemIntrinsicSDNode 62449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // (See SelectionDAGNodes.h). So we need to check for both. 62549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) { 62649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Src = mN->getSrcValue(); 62749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 62849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) { 62949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Src = mN->getSrcValue(); 63049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 63149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!Src) 63249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 63349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) 63449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return (PT->getAddressSpace() == spN); 63549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 63649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 63749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 63849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 63949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski/// inline asm expressions. 64049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op, 64149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski char ConstraintCode, 64249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<SDValue> &OutOps) { 64349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue Op0, Op1; 64449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski switch (ConstraintCode) { 64549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski default: return true; 64649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski case 'm': // memory 64749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectDirectAddr(Op, Op0)) { 64849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski OutOps.push_back(Op0); 64949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); 65049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 65149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 65249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) { 65349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski OutOps.push_back(Op0); 65449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski OutOps.push_back(Op1); 65549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 65649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 65749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski break; 65849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 65949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 66049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 66149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 66249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Return true if N is a undef or a constant. 66349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// If N was undef, return a (i8imm 0) in Retval 66449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// If N was imm, convert it to i8imm and return in Retval 66549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Note: The convert to i8imm is required, otherwise the 66649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// pattern matcher inserts a bunch of IMOVi8rr to convert 66749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// the imm to i8imm, and this causes instruction selection 66849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// to fail. 66949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, 67049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Retval) { 67149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (!(N.getOpcode() == ISD::UNDEF) && 67249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski !(N.getOpcode() == ISD::Constant)) 67349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 67449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 67549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski if (N.getOpcode() == ISD::UNDEF) 67649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Retval = CurDAG->getTargetConstant(0, MVT::i8); 67749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski else { 67849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode()); 67949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski unsigned retval = cn->getZExtValue(); 68049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski Retval = CurDAG->getTargetConstant(retval, MVT::i8); 68149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 68249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return true; 68349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 684