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