NVPTXISelDAGToDAG.cpp revision 0b8c9a80f20772c3793201ab5b251d3520b9cea3
19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===//
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//                     The LLVM Compiler Infrastructure
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// This file is distributed under the University of Illinois Open Source
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// License. See LICENSE.TXT for details.
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//===----------------------------------------------------------------------===//
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// This file defines an instruction selector for the NVPTX target.
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//===----------------------------------------------------------------------===//
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "NVPTXISelDAGToDAG.h"
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/IR/GlobalValue.h"
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/IR/Instructions.h"
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/Support/CommandLine.h"
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/Support/Debug.h"
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/Support/ErrorHandling.h"
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/Support/raw_ostream.h"
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include "llvm/Target/TargetIntrinsicInfo.h"
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#undef DEBUG_TYPE
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#define DEBUG_TYPE "nvptx-isel"
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonusing namespace llvm;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonstatic cl::opt<bool>
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonUseFMADInstruction("nvptx-mad-enable",
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   cl::ZeroOrMore,
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                cl::desc("NVPTX Specific: Enable generating FMAD instructions"),
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   cl::init(false));
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonstatic cl::opt<int>
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonFMAContractLevel("nvptx-fma-level",
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 cl::ZeroOrMore,
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                     " 1: do it  2: do it aggressively"),
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                     cl::init(2));
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonstatic cl::opt<int>
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonUsePrecDivF32("nvptx-prec-divf32",
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              cl::ZeroOrMore,
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  " IEEE Compliant F32 div.rnd if avaiable."),
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  cl::init(2));
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// createNVPTXISelDag - This pass converts a legalized DAG into a
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// NVPTX-specific DAG, ready for instruction scheduling.
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonFunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                       llvm::CodeGenOpt::Level OptLevel) {
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return new NVPTXDAGToDAGISel(TM, OptLevel);
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonNVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     CodeGenOpt::Level OptLevel)
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson: SelectionDAGISel(tm, OptLevel),
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  Subtarget(tm.getSubtarget<NVPTXSubtarget>())
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Always do fma.f32 fpcontract if the target supports the instruction.
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Always do fma.f64 fpcontract if the target supports the instruction.
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Do mad.f32 is nvptx-mad-enable is specified and the target does not
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // support fma.f32.
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32();
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doFMAF32 =  (OptLevel > 0) && Subtarget.hasFMAF32() &&
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (FMAContractLevel>=1);
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doFMAF64 =  (OptLevel > 0) && Subtarget.hasFMAF64() &&
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (FMAContractLevel>=1);
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doFMAF32AGG =  (OptLevel > 0) && Subtarget.hasFMAF32() &&
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (FMAContractLevel==2);
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doFMAF64AGG =  (OptLevel > 0) && Subtarget.hasFMAF64() &&
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (FMAContractLevel==2);
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction;
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  UseF32FTZ = false;
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  doMulWide = (OptLevel > 0);
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Decide how to translate f32 div
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  do_DIVF32_PREC = UsePrecDivF32;
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // sm less than sm_20 does not support div.rnd. Use div.full.
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    do_DIVF32_PREC = 1;
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// Select - Select instructions not customized! Used for
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// expanded, promoted and normal instructions.
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonSDNode* NVPTXDAGToDAGISel::Select(SDNode *N) {
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (N->isMachineOpcode())
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NULL;   // Already selected.
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDNode *ResNode = NULL;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (N->getOpcode()) {
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  case ISD::LOAD:
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ResNode = SelectLoad(N);
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  case ISD::STORE:
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ResNode = SelectStore(N);
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (ResNode)
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ResNode;
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return SelectCode(N);
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonstatic unsigned int
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsongetCodeAddrSpace(MemSDNode *N, const NVPTXSubtarget &Subtarget)
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  const Value *Src = N->getSrcValue();
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (!Src)
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NVPTX::PTXLdStInstCode::LOCAL;
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (PT->getAddressSpace()) {
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_CONST_NOT_GEN:
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NVPTX::PTXLdStInstCode::CONSTANT;
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case llvm::ADDRESS_SPACE_CONST:
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // If the arch supports generic address space, translate it to GLOBAL
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // for correctness.
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // If the arch does not support generic address space, then the arch
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // does not really support ADDRESS_SPACE_CONST, translate it to
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // to CONSTANT for better performance.
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (Subtarget.hasGenericLdSt())
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NVPTX::PTXLdStInstCode::GLOBAL;
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return NVPTX::PTXLdStInstCode::CONSTANT;
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: break;
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return NVPTX::PTXLdStInstCode::LOCAL;
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonSDNode* NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  DebugLoc dl = N->getDebugLoc();
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  LoadSDNode *LD = cast<LoadSDNode>(N);
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  EVT LoadedVT = LD->getMemoryVT();
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDNode *NVPTXLD= NULL;
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // do not support pre/post inc/dec
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (LD->isIndexed())
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NULL;
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (!LoadedVT.isSimple())
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NULL;
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Address Space Setting
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Volatile Setting
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // - .volatile is only availalble for .global and .shared
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  bool isVolatile = LD->isVolatile();
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    isVolatile = false;
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Vector Setting
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT SimpleVT = LoadedVT.getSimpleVT();
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (SimpleVT.isVector()) {
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    unsigned num = SimpleVT.getVectorNumElements();
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (num == 2)
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vecType = NVPTX::PTXLdStInstCode::V2;
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (num == 4)
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vecType = NVPTX::PTXLdStInstCode::V4;
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Type Setting: fromType + fromTypeWidth
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Sign   : ISD::SEXTLOAD
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //          type is integer
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Float  : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT ScalarVT = SimpleVT.getScalarType();
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned fromTypeWidth =  ScalarVT.getSizeInBits();
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned int fromType;
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if ((LD->getExtensionType() == ISD::SEXTLOAD))
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    fromType = NVPTX::PTXLdStInstCode::Signed;
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else if (ScalarVT.isFloatingPoint())
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    fromType = NVPTX::PTXLdStInstCode::Float;
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    fromType = NVPTX::PTXLdStInstCode::Unsigned;
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Create the machine instruction DAG
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Chain = N->getOperand(0);
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue N1 = N->getOperand(1);
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Addr;
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Offset, Base;
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned Opcode;
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (SelectDirectAddr(N1, Addr)) {
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (TargetVT) {
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::LD_i8_avar; break;
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::LD_i16_avar; break;
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::LD_i32_avar; break;
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::LD_i64_avar; break;
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::LD_f32_avar; break;
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::LD_f64_avar; break;
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::LD_v2i8_avar; break;
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::LD_v2i16_avar; break;
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::LD_v2i32_avar; break;
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::LD_v2i64_avar; break;
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::LD_v2f32_avar; break;
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::LD_v2f64_avar; break;
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::LD_v4i8_avar; break;
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::LD_v4i16_avar; break;
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::LD_v4i32_avar; break;
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::LD_v4f32_avar; break;
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { getI32Imm(isVolatile),
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromType),
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromTypeWidth),
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Addr, Chain };
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT,
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 7);
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (Subtarget.is64Bit()?
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRsi64(N1.getNode(), N1, Base, Offset):
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (TargetVT) {
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::LD_i8_asi; break;
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::LD_i16_asi; break;
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::LD_i32_asi; break;
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::LD_i64_asi; break;
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::LD_f32_asi; break;
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::LD_f64_asi; break;
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::LD_v2i8_asi; break;
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::LD_v2i16_asi; break;
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::LD_v2i32_asi; break;
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::LD_v2i64_asi; break;
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::LD_v2f32_asi; break;
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::LD_v2f64_asi; break;
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::LD_v4i8_asi; break;
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::LD_v4i16_asi; break;
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::LD_v4i32_asi; break;
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::LD_v4f32_asi; break;
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { getI32Imm(isVolatile),
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromType),
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromTypeWidth),
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Base, Offset, Chain };
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT,
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 8);
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (Subtarget.is64Bit()?
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRri64(N1.getNode(), N1, Base, Offset):
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRri(N1.getNode(), N1, Base, Offset)) {
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (TargetVT) {
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::LD_i8_ari; break;
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::LD_i16_ari; break;
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::LD_i32_ari; break;
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::LD_i64_ari; break;
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::LD_f32_ari; break;
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::LD_f64_ari; break;
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::LD_v2i8_ari; break;
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::LD_v2i16_ari; break;
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::LD_v2i32_ari; break;
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::LD_v2i64_ari; break;
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::LD_v2f32_ari; break;
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::LD_v2f64_ari; break;
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::LD_v4i8_ari; break;
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::LD_v4i16_ari; break;
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::LD_v4i32_ari; break;
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::LD_v4f32_ari; break;
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { getI32Imm(isVolatile),
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromType),
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromTypeWidth),
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Base, Offset, Chain };
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT,
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 8);
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else {
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (TargetVT) {
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::LD_i8_areg; break;
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::LD_i16_areg; break;
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::LD_i32_areg; break;
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::LD_i64_areg; break;
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::LD_f32_areg; break;
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::LD_f64_areg; break;
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::LD_v2i8_areg; break;
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::LD_v2i16_areg; break;
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::LD_v2i32_areg; break;
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::LD_v2i64_areg; break;
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::LD_v2f32_areg; break;
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::LD_v2f64_areg; break;
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::LD_v4i8_areg; break;
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::LD_v4i16_areg; break;
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::LD_v4i32_areg; break;
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::LD_v4f32_areg; break;
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { getI32Imm(isVolatile),
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromType),
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(fromTypeWidth),
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      N1, Chain };
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT,
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 7);
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (NVPTXLD != NULL) {
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return NVPTXLD;
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonSDNode* NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  DebugLoc dl = N->getDebugLoc();
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  StoreSDNode *ST = cast<StoreSDNode>(N);
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  EVT StoreVT = ST->getMemoryVT();
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDNode *NVPTXST = NULL;
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // do not support pre/post inc/dec
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (ST->isIndexed())
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NULL;
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (!StoreVT.isSimple())
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return NULL;
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Address Space Setting
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Volatile Setting
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // - .volatile is only availalble for .global and .shared
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  bool isVolatile = ST->isVolatile();
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    isVolatile = false;
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Vector Setting
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT SimpleVT = StoreVT.getSimpleVT();
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (SimpleVT.isVector()) {
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    unsigned num = SimpleVT.getVectorNumElements();
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (num == 2)
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vecType = NVPTX::PTXLdStInstCode::V2;
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (num == 4)
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      vecType = NVPTX::PTXLdStInstCode::V4;
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return NULL;
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Type Setting: toType + toTypeWidth
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // - for integer type, always use 'u'
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  //
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT ScalarVT = SimpleVT.getScalarType();
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned toTypeWidth =  ScalarVT.getSizeInBits();
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned int toType;
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (ScalarVT.isFloatingPoint())
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    toType = NVPTX::PTXLdStInstCode::Float;
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    toType = NVPTX::PTXLdStInstCode::Unsigned;
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Create the machine instruction DAG
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Chain = N->getOperand(0);
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue N1 = N->getOperand(1);
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue N2 = N->getOperand(2);
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Addr;
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Offset, Base;
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  unsigned Opcode;
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  MVT::SimpleValueType SourceVT =
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (SelectDirectAddr(N2, Addr)) {
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (SourceVT) {
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::ST_i8_avar; break;
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::ST_i16_avar; break;
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::ST_i32_avar; break;
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::ST_i64_avar; break;
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::ST_f32_avar; break;
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::ST_f64_avar; break;
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::ST_v2i8_avar; break;
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::ST_v2i16_avar; break;
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::ST_v2i32_avar; break;
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::ST_v2i64_avar; break;
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::ST_v2f32_avar; break;
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::ST_v2f64_avar; break;
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::ST_v4i8_avar; break;
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::ST_v4i16_avar; break;
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::ST_v4i32_avar; break;
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::ST_v4f32_avar; break;
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { N1,
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(isVolatile),
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toType),
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toTypeWidth),
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Addr, Chain };
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXST = CurDAG->getMachineNode(Opcode, dl,
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 8);
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (Subtarget.is64Bit()?
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRsi64(N2.getNode(), N2, Base, Offset):
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (SourceVT) {
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::ST_i8_asi; break;
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::ST_i16_asi; break;
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::ST_i32_asi; break;
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::ST_i64_asi; break;
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::ST_f32_asi; break;
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::ST_f64_asi; break;
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::ST_v2i8_asi; break;
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::ST_v2i16_asi; break;
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::ST_v2i32_asi; break;
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::ST_v2i64_asi; break;
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::ST_v2f32_asi; break;
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::ST_v2f64_asi; break;
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::ST_v4i8_asi; break;
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::ST_v4i16_asi; break;
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::ST_v4i32_asi; break;
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::ST_v4f32_asi; break;
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { N1,
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(isVolatile),
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toType),
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toTypeWidth),
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Base, Offset, Chain };
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXST = CurDAG->getMachineNode(Opcode, dl,
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 9);
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (Subtarget.is64Bit()?
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRri64(N2.getNode(), N2, Base, Offset):
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SelectADDRri(N2.getNode(), N2, Base, Offset)) {
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (SourceVT) {
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::ST_i8_ari; break;
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::ST_i16_ari; break;
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::ST_i32_ari; break;
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::ST_i64_ari; break;
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::ST_f32_ari; break;
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::ST_f64_ari; break;
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::ST_v2i8_ari; break;
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::ST_v2i16_ari; break;
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::ST_v2i32_ari; break;
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::ST_v2i64_ari; break;
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::ST_v2f32_ari; break;
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::ST_v2f64_ari; break;
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::ST_v4i8_ari; break;
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::ST_v4i16_ari; break;
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::ST_v4i32_ari; break;
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::ST_v4f32_ari; break;
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { N1,
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(isVolatile),
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toType),
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toTypeWidth),
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      Base, Offset, Chain };
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXST = CurDAG->getMachineNode(Opcode, dl,
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 9);
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (SourceVT) {
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i8:    Opcode = NVPTX::ST_i8_areg; break;
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i16:   Opcode = NVPTX::ST_i16_areg; break;
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i32:   Opcode = NVPTX::ST_i32_areg; break;
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::i64:   Opcode = NVPTX::ST_i64_areg; break;
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f32:   Opcode = NVPTX::ST_f32_areg; break;
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::f64:   Opcode = NVPTX::ST_f64_areg; break;
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i8:  Opcode = NVPTX::ST_v2i8_areg; break;
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i16: Opcode = NVPTX::ST_v2i16_areg; break;
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i32: Opcode = NVPTX::ST_v2i32_areg; break;
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2i64: Opcode = NVPTX::ST_v2i64_areg; break;
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f32: Opcode = NVPTX::ST_v2f32_areg; break;
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v2f64: Opcode = NVPTX::ST_v2f64_areg; break;
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i8:  Opcode = NVPTX::ST_v4i8_areg; break;
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i16: Opcode = NVPTX::ST_v4i16_areg; break;
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4i32: Opcode = NVPTX::ST_v4i32_areg; break;
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case MVT::v4f32: Opcode = NVPTX::ST_v4f32_areg; break;
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default: return NULL;
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    SDValue Ops[] = { N1,
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(isVolatile),
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(codeAddrSpace),
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(vecType),
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toType),
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      getI32Imm(toTypeWidth),
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                      N2, Chain };
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NVPTXST = CurDAG->getMachineNode(Opcode, dl,
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     MVT::Other, Ops, 8);
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (NVPTXST != NULL) {
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return NVPTXST;
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// SelectDirectAddr - Match a direct address for DAG.
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// A direct address could be a globaladdress or externalsymbol.
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Return true if TGA or ES.
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (N.getOpcode() == ISD::TargetGlobalAddress
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      || N.getOpcode() == ISD::TargetExternalSymbol) {
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Address = N;
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (N.getOpcode() == NVPTXISD::Wrapper) {
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Address = N.getOperand(0);
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (IID == Intrinsic::nvvm_ptr_gen_to_param)
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// symbol+offset
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRsi_imp(SDNode *OpNode, SDValue Addr,
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         SDValue &Base, SDValue &Offset,
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         MVT mvt) {
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (Addr.getOpcode() == ISD::ADD) {
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      SDValue base=Addr.getOperand(0);
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (SelectDirectAddr(base, Base)) {
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// symbol+offset
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     SDValue &Base, SDValue &Offset) {
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// symbol+offset
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                       SDValue &Base, SDValue &Offset) {
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// register+offset
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRri_imp(SDNode *OpNode, SDValue Addr,
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         SDValue &Base, SDValue &Offset,
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                         MVT mvt) {
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Offset = CurDAG->getTargetConstant(0, mvt);
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Addr.getOpcode() == ISD::TargetGlobalAddress)
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;  // direct calls.
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (Addr.getOpcode() == ISD::ADD) {
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (FrameIndexSDNode *FIN =
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Constant offset from frame ref.
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        Base = Addr.getOperand(0);
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// register+offset
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                     SDValue &Base, SDValue &Offset) {
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// register+offset
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                       SDValue &Base, SDValue &Offset) {
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                 unsigned int spN) const {
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  const Value *Src = NULL;
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // the classof() for MemSDNode does not include MemIntrinsicSDNode
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // (See SelectionDAGNodes.h). So we need to check for both.
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Src = mN->getSrcValue();
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Src = mN->getSrcValue();
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (!Src)
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (PT->getAddressSpace() == spN);
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/// inline asm expressions.
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                     char ConstraintCode,
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                 std::vector<SDValue> &OutOps) {
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SDValue Op0, Op1;
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (ConstraintCode) {
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  default: return true;
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  case 'm':   // memory
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (SelectDirectAddr(Op, Op0)) {
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      OutOps.push_back(Op0);
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      OutOps.push_back(Op0);
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      OutOps.push_back(Op1);
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    break;
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return true;
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Return true if N is a undef or a constant.
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// If N was undef, return a (i8imm 0) in Retval
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// If N was imm, convert it to i8imm and return in Retval
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Note: The convert to i8imm is required, otherwise the
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// pattern matcher inserts a bunch of IMOVi8rr to convert
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// the imm to i8imm, and this causes instruction selection
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// to fail.
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N,
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   SDValue &Retval) {
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (!(N.getOpcode() == ISD::UNDEF) &&
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      !(N.getOpcode() == ISD::Constant))
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (N.getOpcode() == ISD::UNDEF)
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Retval = CurDAG->getTargetConstant(0, MVT::i8);
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  else {
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    unsigned retval = cn->getZExtValue();
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Retval = CurDAG->getTargetConstant(retval, MVT::i8);
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return true;
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson