blob: ada4c223876e6943318714955ac73357e8bcc727 [file] [log] [blame]
Justin Holewinskiae556d32012-05-04 20:18:50 +00001//===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the NVPTX target.
11//
12//===----------------------------------------------------------------------===//
13
Justin Holewinskiae556d32012-05-04 20:18:50 +000014#include "NVPTXISelDAGToDAG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000015#include "llvm/IR/GlobalValue.h"
16#include "llvm/IR/Instructions.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/Support/CommandLine.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000018#include "llvm/Support/Debug.h"
19#include "llvm/Support/ErrorHandling.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/Support/raw_ostream.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000021#include "llvm/Target/TargetIntrinsicInfo.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000022
Justin Holewinskiae556d32012-05-04 20:18:50 +000023using namespace llvm;
24
Chandler Carruth84e68b22014-04-22 02:41:26 +000025#define DEBUG_TYPE "nvptx-isel"
26
Justin Holewinskiae556d32012-05-04 20:18:50 +000027static cl::opt<int>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000028FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskiae556d32012-05-04 20:18:50 +000029 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
Justin Holewinski0497ab12013-03-30 14:29:21 +000030 " 1: do it 2: do it aggressively"),
31 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000032
Justin Holewinski0497ab12013-03-30 14:29:21 +000033static cl::opt<int> UsePrecDivF32(
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000034 "nvptx-prec-divf32", cl::ZeroOrMore, cl::Hidden,
Justin Holewinski0497ab12013-03-30 14:29:21 +000035 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
36 " IEEE Compliant F32 div.rnd if avaiable."),
37 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000038
Justin Holewinski48f4ad32013-05-21 16:51:30 +000039static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000040UsePrecSqrtF32("nvptx-prec-sqrtf32", cl::Hidden,
Justin Holewinski48f4ad32013-05-21 16:51:30 +000041 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
42 cl::init(true));
43
Justin Holewinskicd069e62013-07-22 12:18:04 +000044static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000045FtzEnabled("nvptx-f32ftz", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskicd069e62013-07-22 12:18:04 +000046 cl::desc("NVPTX Specific: Flush f32 subnormals to sign-preserving zero."),
47 cl::init(false));
48
49
Justin Holewinskiae556d32012-05-04 20:18:50 +000050/// createNVPTXISelDag - This pass converts a legalized DAG into a
51/// NVPTX-specific DAG, ready for instruction scheduling.
52FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
53 llvm::CodeGenOpt::Level OptLevel) {
54 return new NVPTXDAGToDAGISel(TM, OptLevel);
55}
56
Justin Holewinskiae556d32012-05-04 20:18:50 +000057NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
58 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000059 : SelectionDAGISel(tm, OptLevel),
60 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000061
Justin Holewinski0497ab12013-03-30 14:29:21 +000062 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
63 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
64 doFMAF32AGG =
65 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
66 doFMAF64AGG =
67 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000068
Justin Holewinskicd069e62013-07-22 12:18:04 +000069 allowFMA = (FMAContractLevel >= 1);
Benjamin Kramera25a61b2012-05-05 11:22:02 +000070
Justin Holewinskiae556d32012-05-04 20:18:50 +000071 doMulWide = (OptLevel > 0);
Justin Holewinskicd069e62013-07-22 12:18:04 +000072}
Justin Holewinskiae556d32012-05-04 20:18:50 +000073
Justin Holewinskicd069e62013-07-22 12:18:04 +000074int NVPTXDAGToDAGISel::getDivF32Level() const {
75 if (UsePrecDivF32.getNumOccurrences() > 0) {
76 // If nvptx-prec-div32=N is used on the command-line, always honor it
77 return UsePrecDivF32;
78 } else {
79 // Otherwise, use div.approx if fast math is enabled
80 if (TM.Options.UnsafeFPMath)
81 return 0;
82 else
83 return 2;
84 }
85}
Justin Holewinskiae556d32012-05-04 20:18:50 +000086
Justin Holewinskicd069e62013-07-22 12:18:04 +000087bool NVPTXDAGToDAGISel::usePrecSqrtF32() const {
88 if (UsePrecSqrtF32.getNumOccurrences() > 0) {
89 // If nvptx-prec-sqrtf32 is used on the command-line, always honor it
90 return UsePrecSqrtF32;
91 } else {
92 // Otherwise, use sqrt.approx if fast math is enabled
93 if (TM.Options.UnsafeFPMath)
94 return false;
95 else
96 return true;
97 }
98}
99
100bool NVPTXDAGToDAGISel::useF32FTZ() const {
101 if (FtzEnabled.getNumOccurrences() > 0) {
102 // If nvptx-f32ftz is used on the command-line, always honor it
103 return FtzEnabled;
104 } else {
105 const Function *F = MF->getFunction();
106 // Otherwise, check for an nvptx-f32ftz attribute on the function
107 if (F->hasFnAttribute("nvptx-f32ftz"))
108 return (F->getAttributes().getAttribute(AttributeSet::FunctionIndex,
109 "nvptx-f32ftz")
110 .getValueAsString() == "true");
111 else
112 return false;
113 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000114}
115
116/// Select - Select instructions not customized! Used for
117/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +0000118SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000119
Tim Northover31d093c2013-09-22 08:21:56 +0000120 if (N->isMachineOpcode()) {
121 N->setNodeId(-1);
Craig Topper062a2ba2014-04-25 05:30:21 +0000122 return nullptr; // Already selected.
Tim Northover31d093c2013-09-22 08:21:56 +0000123 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000124
Craig Topper062a2ba2014-04-25 05:30:21 +0000125 SDNode *ResNode = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000126 switch (N->getOpcode()) {
127 case ISD::LOAD:
128 ResNode = SelectLoad(N);
129 break;
130 case ISD::STORE:
131 ResNode = SelectStore(N);
132 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000133 case NVPTXISD::LoadV2:
134 case NVPTXISD::LoadV4:
135 ResNode = SelectLoadVector(N);
136 break;
137 case NVPTXISD::LDGV2:
138 case NVPTXISD::LDGV4:
139 case NVPTXISD::LDUV2:
140 case NVPTXISD::LDUV4:
141 ResNode = SelectLDGLDUVector(N);
142 break;
143 case NVPTXISD::StoreV2:
144 case NVPTXISD::StoreV4:
145 ResNode = SelectStoreVector(N);
146 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000147 case NVPTXISD::LoadParam:
148 case NVPTXISD::LoadParamV2:
149 case NVPTXISD::LoadParamV4:
150 ResNode = SelectLoadParam(N);
151 break;
152 case NVPTXISD::StoreRetval:
153 case NVPTXISD::StoreRetvalV2:
154 case NVPTXISD::StoreRetvalV4:
155 ResNode = SelectStoreRetval(N);
156 break;
157 case NVPTXISD::StoreParam:
158 case NVPTXISD::StoreParamV2:
159 case NVPTXISD::StoreParamV4:
160 case NVPTXISD::StoreParamS32:
161 case NVPTXISD::StoreParamU32:
162 ResNode = SelectStoreParam(N);
163 break;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000164 case ISD::INTRINSIC_WO_CHAIN:
165 ResNode = SelectIntrinsicNoChain(N);
166 break;
167 case NVPTXISD::Tex1DFloatI32:
168 case NVPTXISD::Tex1DFloatFloat:
169 case NVPTXISD::Tex1DFloatFloatLevel:
170 case NVPTXISD::Tex1DFloatFloatGrad:
171 case NVPTXISD::Tex1DI32I32:
172 case NVPTXISD::Tex1DI32Float:
173 case NVPTXISD::Tex1DI32FloatLevel:
174 case NVPTXISD::Tex1DI32FloatGrad:
175 case NVPTXISD::Tex1DArrayFloatI32:
176 case NVPTXISD::Tex1DArrayFloatFloat:
177 case NVPTXISD::Tex1DArrayFloatFloatLevel:
178 case NVPTXISD::Tex1DArrayFloatFloatGrad:
179 case NVPTXISD::Tex1DArrayI32I32:
180 case NVPTXISD::Tex1DArrayI32Float:
181 case NVPTXISD::Tex1DArrayI32FloatLevel:
182 case NVPTXISD::Tex1DArrayI32FloatGrad:
183 case NVPTXISD::Tex2DFloatI32:
184 case NVPTXISD::Tex2DFloatFloat:
185 case NVPTXISD::Tex2DFloatFloatLevel:
186 case NVPTXISD::Tex2DFloatFloatGrad:
187 case NVPTXISD::Tex2DI32I32:
188 case NVPTXISD::Tex2DI32Float:
189 case NVPTXISD::Tex2DI32FloatLevel:
190 case NVPTXISD::Tex2DI32FloatGrad:
191 case NVPTXISD::Tex2DArrayFloatI32:
192 case NVPTXISD::Tex2DArrayFloatFloat:
193 case NVPTXISD::Tex2DArrayFloatFloatLevel:
194 case NVPTXISD::Tex2DArrayFloatFloatGrad:
195 case NVPTXISD::Tex2DArrayI32I32:
196 case NVPTXISD::Tex2DArrayI32Float:
197 case NVPTXISD::Tex2DArrayI32FloatLevel:
198 case NVPTXISD::Tex2DArrayI32FloatGrad:
199 case NVPTXISD::Tex3DFloatI32:
200 case NVPTXISD::Tex3DFloatFloat:
201 case NVPTXISD::Tex3DFloatFloatLevel:
202 case NVPTXISD::Tex3DFloatFloatGrad:
203 case NVPTXISD::Tex3DI32I32:
204 case NVPTXISD::Tex3DI32Float:
205 case NVPTXISD::Tex3DI32FloatLevel:
206 case NVPTXISD::Tex3DI32FloatGrad:
207 ResNode = SelectTextureIntrinsic(N);
208 break;
209 case NVPTXISD::Suld1DI8Trap:
210 case NVPTXISD::Suld1DI16Trap:
211 case NVPTXISD::Suld1DI32Trap:
212 case NVPTXISD::Suld1DV2I8Trap:
213 case NVPTXISD::Suld1DV2I16Trap:
214 case NVPTXISD::Suld1DV2I32Trap:
215 case NVPTXISD::Suld1DV4I8Trap:
216 case NVPTXISD::Suld1DV4I16Trap:
217 case NVPTXISD::Suld1DV4I32Trap:
218 case NVPTXISD::Suld1DArrayI8Trap:
219 case NVPTXISD::Suld1DArrayI16Trap:
220 case NVPTXISD::Suld1DArrayI32Trap:
221 case NVPTXISD::Suld1DArrayV2I8Trap:
222 case NVPTXISD::Suld1DArrayV2I16Trap:
223 case NVPTXISD::Suld1DArrayV2I32Trap:
224 case NVPTXISD::Suld1DArrayV4I8Trap:
225 case NVPTXISD::Suld1DArrayV4I16Trap:
226 case NVPTXISD::Suld1DArrayV4I32Trap:
227 case NVPTXISD::Suld2DI8Trap:
228 case NVPTXISD::Suld2DI16Trap:
229 case NVPTXISD::Suld2DI32Trap:
230 case NVPTXISD::Suld2DV2I8Trap:
231 case NVPTXISD::Suld2DV2I16Trap:
232 case NVPTXISD::Suld2DV2I32Trap:
233 case NVPTXISD::Suld2DV4I8Trap:
234 case NVPTXISD::Suld2DV4I16Trap:
235 case NVPTXISD::Suld2DV4I32Trap:
236 case NVPTXISD::Suld2DArrayI8Trap:
237 case NVPTXISD::Suld2DArrayI16Trap:
238 case NVPTXISD::Suld2DArrayI32Trap:
239 case NVPTXISD::Suld2DArrayV2I8Trap:
240 case NVPTXISD::Suld2DArrayV2I16Trap:
241 case NVPTXISD::Suld2DArrayV2I32Trap:
242 case NVPTXISD::Suld2DArrayV4I8Trap:
243 case NVPTXISD::Suld2DArrayV4I16Trap:
244 case NVPTXISD::Suld2DArrayV4I32Trap:
245 case NVPTXISD::Suld3DI8Trap:
246 case NVPTXISD::Suld3DI16Trap:
247 case NVPTXISD::Suld3DI32Trap:
248 case NVPTXISD::Suld3DV2I8Trap:
249 case NVPTXISD::Suld3DV2I16Trap:
250 case NVPTXISD::Suld3DV2I32Trap:
251 case NVPTXISD::Suld3DV4I8Trap:
252 case NVPTXISD::Suld3DV4I16Trap:
253 case NVPTXISD::Suld3DV4I32Trap:
254 ResNode = SelectSurfaceIntrinsic(N);
255 break;
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000256 case ISD::ADDRSPACECAST:
257 ResNode = SelectAddrSpaceCast(N);
258 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000259 default:
260 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000261 }
262 if (ResNode)
263 return ResNode;
264 return SelectCode(N);
265}
266
Justin Holewinski0497ab12013-03-30 14:29:21 +0000267static unsigned int getCodeAddrSpace(MemSDNode *N,
268 const NVPTXSubtarget &Subtarget) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000269 const Value *Src = N->getMemOperand()->getValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000270
Justin Holewinskiae556d32012-05-04 20:18:50 +0000271 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000272 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000273
274 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
275 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000276 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
277 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
278 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
279 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
280 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
281 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
282 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000283 }
284 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000285 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000286}
287
Justin Holewinski30d56a72014-04-09 15:39:15 +0000288SDNode *NVPTXDAGToDAGISel::SelectIntrinsicNoChain(SDNode *N) {
289 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
290 switch (IID) {
291 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000292 return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000293 case Intrinsic::nvvm_texsurf_handle_internal:
294 return SelectTexSurfHandle(N);
295 }
296}
297
298SDNode *NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
299 // Op 0 is the intrinsic ID
300 SDValue Wrapper = N->getOperand(1);
301 SDValue GlobalVal = Wrapper.getOperand(0);
302 return CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N), MVT::i64,
303 GlobalVal);
304}
305
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000306SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
307 SDValue Src = N->getOperand(0);
308 AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
309 unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
310 unsigned DstAddrSpace = CastN->getDestAddressSpace();
311
312 assert(SrcAddrSpace != DstAddrSpace &&
313 "addrspacecast must be between different address spaces");
314
315 if (DstAddrSpace == ADDRESS_SPACE_GENERIC) {
316 // Specific to generic
317 unsigned Opc;
318 switch (SrcAddrSpace) {
319 default: report_fatal_error("Bad address space in addrspacecast");
320 case ADDRESS_SPACE_GLOBAL:
321 Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64
322 : NVPTX::cvta_global_yes;
323 break;
324 case ADDRESS_SPACE_SHARED:
325 Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64
326 : NVPTX::cvta_shared_yes;
327 break;
328 case ADDRESS_SPACE_CONST:
329 Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64
330 : NVPTX::cvta_const_yes;
331 break;
332 case ADDRESS_SPACE_LOCAL:
333 Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64
334 : NVPTX::cvta_local_yes;
335 break;
336 }
337 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
338 } else {
339 // Generic to specific
340 if (SrcAddrSpace != 0)
341 report_fatal_error("Cannot cast between two non-generic address spaces");
342 unsigned Opc;
343 switch (DstAddrSpace) {
344 default: report_fatal_error("Bad address space in addrspacecast");
345 case ADDRESS_SPACE_GLOBAL:
346 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64
347 : NVPTX::cvta_to_global_yes;
348 break;
349 case ADDRESS_SPACE_SHARED:
350 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64
351 : NVPTX::cvta_to_shared_yes;
352 break;
353 case ADDRESS_SPACE_CONST:
354 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64
355 : NVPTX::cvta_to_const_yes;
356 break;
357 case ADDRESS_SPACE_LOCAL:
358 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64
359 : NVPTX::cvta_to_local_yes;
360 break;
361 }
362 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
363 }
364}
365
Justin Holewinski0497ab12013-03-30 14:29:21 +0000366SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000367 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000368 LoadSDNode *LD = cast<LoadSDNode>(N);
369 EVT LoadedVT = LD->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +0000370 SDNode *NVPTXLD = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000371
372 // do not support pre/post inc/dec
373 if (LD->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +0000374 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000375
376 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000377 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000378
379 // Address Space Setting
380 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
381
382 // Volatile Setting
383 // - .volatile is only availalble for .global and .shared
384 bool isVolatile = LD->isVolatile();
385 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
386 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
387 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
388 isVolatile = false;
389
390 // Vector Setting
391 MVT SimpleVT = LoadedVT.getSimpleVT();
392 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
393 if (SimpleVT.isVector()) {
394 unsigned num = SimpleVT.getVectorNumElements();
395 if (num == 2)
396 vecType = NVPTX::PTXLdStInstCode::V2;
397 else if (num == 4)
398 vecType = NVPTX::PTXLdStInstCode::V4;
399 else
Craig Topper062a2ba2014-04-25 05:30:21 +0000400 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000401 }
402
403 // Type Setting: fromType + fromTypeWidth
404 //
405 // Sign : ISD::SEXTLOAD
406 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
407 // type is integer
408 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
409 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000410 // Read at least 8 bits (predicates are stored as 8-bit values)
411 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000412 unsigned int fromType;
413 if ((LD->getExtensionType() == ISD::SEXTLOAD))
414 fromType = NVPTX::PTXLdStInstCode::Signed;
415 else if (ScalarVT.isFloatingPoint())
416 fromType = NVPTX::PTXLdStInstCode::Float;
417 else
418 fromType = NVPTX::PTXLdStInstCode::Unsigned;
419
420 // Create the machine instruction DAG
421 SDValue Chain = N->getOperand(0);
422 SDValue N1 = N->getOperand(1);
423 SDValue Addr;
424 SDValue Offset, Base;
425 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000426 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000427
428 if (SelectDirectAddr(N1, Addr)) {
429 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000430 case MVT::i8:
431 Opcode = NVPTX::LD_i8_avar;
432 break;
433 case MVT::i16:
434 Opcode = NVPTX::LD_i16_avar;
435 break;
436 case MVT::i32:
437 Opcode = NVPTX::LD_i32_avar;
438 break;
439 case MVT::i64:
440 Opcode = NVPTX::LD_i64_avar;
441 break;
442 case MVT::f32:
443 Opcode = NVPTX::LD_f32_avar;
444 break;
445 case MVT::f64:
446 Opcode = NVPTX::LD_f64_avar;
447 break;
448 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000449 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000450 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000451 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
452 getI32Imm(vecType), getI32Imm(fromType),
453 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000454 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000455 } else if (Subtarget.is64Bit()
456 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
457 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000458 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000459 case MVT::i8:
460 Opcode = NVPTX::LD_i8_asi;
461 break;
462 case MVT::i16:
463 Opcode = NVPTX::LD_i16_asi;
464 break;
465 case MVT::i32:
466 Opcode = NVPTX::LD_i32_asi;
467 break;
468 case MVT::i64:
469 Opcode = NVPTX::LD_i64_asi;
470 break;
471 case MVT::f32:
472 Opcode = NVPTX::LD_f32_asi;
473 break;
474 case MVT::f64:
475 Opcode = NVPTX::LD_f64_asi;
476 break;
477 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000478 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000479 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000480 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
481 getI32Imm(vecType), getI32Imm(fromType),
482 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000483 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000484 } else if (Subtarget.is64Bit()
485 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
486 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000487 if (Subtarget.is64Bit()) {
488 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000489 case MVT::i8:
490 Opcode = NVPTX::LD_i8_ari_64;
491 break;
492 case MVT::i16:
493 Opcode = NVPTX::LD_i16_ari_64;
494 break;
495 case MVT::i32:
496 Opcode = NVPTX::LD_i32_ari_64;
497 break;
498 case MVT::i64:
499 Opcode = NVPTX::LD_i64_ari_64;
500 break;
501 case MVT::f32:
502 Opcode = NVPTX::LD_f32_ari_64;
503 break;
504 case MVT::f64:
505 Opcode = NVPTX::LD_f64_ari_64;
506 break;
507 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000508 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000509 }
510 } else {
511 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000512 case MVT::i8:
513 Opcode = NVPTX::LD_i8_ari;
514 break;
515 case MVT::i16:
516 Opcode = NVPTX::LD_i16_ari;
517 break;
518 case MVT::i32:
519 Opcode = NVPTX::LD_i32_ari;
520 break;
521 case MVT::i64:
522 Opcode = NVPTX::LD_i64_ari;
523 break;
524 case MVT::f32:
525 Opcode = NVPTX::LD_f32_ari;
526 break;
527 case MVT::f64:
528 Opcode = NVPTX::LD_f64_ari;
529 break;
530 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000531 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000532 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000533 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000534 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
535 getI32Imm(vecType), getI32Imm(fromType),
536 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000537 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000538 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000539 if (Subtarget.is64Bit()) {
540 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000541 case MVT::i8:
542 Opcode = NVPTX::LD_i8_areg_64;
543 break;
544 case MVT::i16:
545 Opcode = NVPTX::LD_i16_areg_64;
546 break;
547 case MVT::i32:
548 Opcode = NVPTX::LD_i32_areg_64;
549 break;
550 case MVT::i64:
551 Opcode = NVPTX::LD_i64_areg_64;
552 break;
553 case MVT::f32:
554 Opcode = NVPTX::LD_f32_areg_64;
555 break;
556 case MVT::f64:
557 Opcode = NVPTX::LD_f64_areg_64;
558 break;
559 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000560 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000561 }
562 } else {
563 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000564 case MVT::i8:
565 Opcode = NVPTX::LD_i8_areg;
566 break;
567 case MVT::i16:
568 Opcode = NVPTX::LD_i16_areg;
569 break;
570 case MVT::i32:
571 Opcode = NVPTX::LD_i32_areg;
572 break;
573 case MVT::i64:
574 Opcode = NVPTX::LD_i64_areg;
575 break;
576 case MVT::f32:
577 Opcode = NVPTX::LD_f32_areg;
578 break;
579 case MVT::f64:
580 Opcode = NVPTX::LD_f64_areg;
581 break;
582 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000583 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000584 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000585 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000586 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
587 getI32Imm(vecType), getI32Imm(fromType),
588 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000589 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000590 }
591
Craig Topper062a2ba2014-04-25 05:30:21 +0000592 if (NVPTXLD) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000593 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
594 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
595 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
596 }
597
598 return NVPTXLD;
599}
600
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000601SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
602
603 SDValue Chain = N->getOperand(0);
604 SDValue Op1 = N->getOperand(1);
605 SDValue Addr, Offset, Base;
606 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000607 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000608 SDNode *LD;
609 MemSDNode *MemSD = cast<MemSDNode>(N);
610 EVT LoadedVT = MemSD->getMemoryVT();
611
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000612 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000613 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000614
615 // Address Space Setting
616 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
617
618 // Volatile Setting
619 // - .volatile is only availalble for .global and .shared
620 bool IsVolatile = MemSD->isVolatile();
621 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
622 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
623 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
624 IsVolatile = false;
625
626 // Vector Setting
627 MVT SimpleVT = LoadedVT.getSimpleVT();
628
629 // Type Setting: fromType + fromTypeWidth
630 //
631 // Sign : ISD::SEXTLOAD
632 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
633 // type is integer
634 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
635 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000636 // Read at least 8 bits (predicates are stored as 8-bit values)
637 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000638 unsigned int FromType;
639 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000640 unsigned ExtensionType = cast<ConstantSDNode>(
641 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000642 if (ExtensionType == ISD::SEXTLOAD)
643 FromType = NVPTX::PTXLdStInstCode::Signed;
644 else if (ScalarVT.isFloatingPoint())
645 FromType = NVPTX::PTXLdStInstCode::Float;
646 else
647 FromType = NVPTX::PTXLdStInstCode::Unsigned;
648
649 unsigned VecType;
650
651 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000652 case NVPTXISD::LoadV2:
653 VecType = NVPTX::PTXLdStInstCode::V2;
654 break;
655 case NVPTXISD::LoadV4:
656 VecType = NVPTX::PTXLdStInstCode::V4;
657 break;
658 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000659 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000660 }
661
662 EVT EltVT = N->getValueType(0);
663
664 if (SelectDirectAddr(Op1, Addr)) {
665 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000666 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000667 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000668 case NVPTXISD::LoadV2:
669 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000670 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000671 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000672 case MVT::i8:
673 Opcode = NVPTX::LDV_i8_v2_avar;
674 break;
675 case MVT::i16:
676 Opcode = NVPTX::LDV_i16_v2_avar;
677 break;
678 case MVT::i32:
679 Opcode = NVPTX::LDV_i32_v2_avar;
680 break;
681 case MVT::i64:
682 Opcode = NVPTX::LDV_i64_v2_avar;
683 break;
684 case MVT::f32:
685 Opcode = NVPTX::LDV_f32_v2_avar;
686 break;
687 case MVT::f64:
688 Opcode = NVPTX::LDV_f64_v2_avar;
689 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000690 }
691 break;
692 case NVPTXISD::LoadV4:
693 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000694 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000695 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000696 case MVT::i8:
697 Opcode = NVPTX::LDV_i8_v4_avar;
698 break;
699 case MVT::i16:
700 Opcode = NVPTX::LDV_i16_v4_avar;
701 break;
702 case MVT::i32:
703 Opcode = NVPTX::LDV_i32_v4_avar;
704 break;
705 case MVT::f32:
706 Opcode = NVPTX::LDV_f32_v4_avar;
707 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000708 }
709 break;
710 }
711
Justin Holewinski0497ab12013-03-30 14:29:21 +0000712 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
713 getI32Imm(VecType), getI32Imm(FromType),
714 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000715 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000716 } else if (Subtarget.is64Bit()
717 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
718 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000719 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000720 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000721 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000722 case NVPTXISD::LoadV2:
723 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000724 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000725 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000726 case MVT::i8:
727 Opcode = NVPTX::LDV_i8_v2_asi;
728 break;
729 case MVT::i16:
730 Opcode = NVPTX::LDV_i16_v2_asi;
731 break;
732 case MVT::i32:
733 Opcode = NVPTX::LDV_i32_v2_asi;
734 break;
735 case MVT::i64:
736 Opcode = NVPTX::LDV_i64_v2_asi;
737 break;
738 case MVT::f32:
739 Opcode = NVPTX::LDV_f32_v2_asi;
740 break;
741 case MVT::f64:
742 Opcode = NVPTX::LDV_f64_v2_asi;
743 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000744 }
745 break;
746 case NVPTXISD::LoadV4:
747 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000748 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000749 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000750 case MVT::i8:
751 Opcode = NVPTX::LDV_i8_v4_asi;
752 break;
753 case MVT::i16:
754 Opcode = NVPTX::LDV_i16_v4_asi;
755 break;
756 case MVT::i32:
757 Opcode = NVPTX::LDV_i32_v4_asi;
758 break;
759 case MVT::f32:
760 Opcode = NVPTX::LDV_f32_v4_asi;
761 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000762 }
763 break;
764 }
765
Justin Holewinski0497ab12013-03-30 14:29:21 +0000766 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
767 getI32Imm(VecType), getI32Imm(FromType),
768 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000769 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000770 } else if (Subtarget.is64Bit()
771 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
772 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000773 if (Subtarget.is64Bit()) {
774 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000775 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000776 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000777 case NVPTXISD::LoadV2:
778 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000779 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000780 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000781 case MVT::i8:
782 Opcode = NVPTX::LDV_i8_v2_ari_64;
783 break;
784 case MVT::i16:
785 Opcode = NVPTX::LDV_i16_v2_ari_64;
786 break;
787 case MVT::i32:
788 Opcode = NVPTX::LDV_i32_v2_ari_64;
789 break;
790 case MVT::i64:
791 Opcode = NVPTX::LDV_i64_v2_ari_64;
792 break;
793 case MVT::f32:
794 Opcode = NVPTX::LDV_f32_v2_ari_64;
795 break;
796 case MVT::f64:
797 Opcode = NVPTX::LDV_f64_v2_ari_64;
798 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000799 }
800 break;
801 case NVPTXISD::LoadV4:
802 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000803 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000804 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000805 case MVT::i8:
806 Opcode = NVPTX::LDV_i8_v4_ari_64;
807 break;
808 case MVT::i16:
809 Opcode = NVPTX::LDV_i16_v4_ari_64;
810 break;
811 case MVT::i32:
812 Opcode = NVPTX::LDV_i32_v4_ari_64;
813 break;
814 case MVT::f32:
815 Opcode = NVPTX::LDV_f32_v4_ari_64;
816 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000817 }
818 break;
819 }
820 } else {
821 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000822 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000823 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000824 case NVPTXISD::LoadV2:
825 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000826 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000827 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000828 case MVT::i8:
829 Opcode = NVPTX::LDV_i8_v2_ari;
830 break;
831 case MVT::i16:
832 Opcode = NVPTX::LDV_i16_v2_ari;
833 break;
834 case MVT::i32:
835 Opcode = NVPTX::LDV_i32_v2_ari;
836 break;
837 case MVT::i64:
838 Opcode = NVPTX::LDV_i64_v2_ari;
839 break;
840 case MVT::f32:
841 Opcode = NVPTX::LDV_f32_v2_ari;
842 break;
843 case MVT::f64:
844 Opcode = NVPTX::LDV_f64_v2_ari;
845 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000846 }
847 break;
848 case NVPTXISD::LoadV4:
849 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000850 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000851 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000852 case MVT::i8:
853 Opcode = NVPTX::LDV_i8_v4_ari;
854 break;
855 case MVT::i16:
856 Opcode = NVPTX::LDV_i16_v4_ari;
857 break;
858 case MVT::i32:
859 Opcode = NVPTX::LDV_i32_v4_ari;
860 break;
861 case MVT::f32:
862 Opcode = NVPTX::LDV_f32_v4_ari;
863 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000864 }
865 break;
866 }
867 }
868
Justin Holewinski0497ab12013-03-30 14:29:21 +0000869 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
870 getI32Imm(VecType), getI32Imm(FromType),
871 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000872
Michael Liaob53d8962013-04-19 22:22:57 +0000873 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000874 } else {
875 if (Subtarget.is64Bit()) {
876 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000877 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000878 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000879 case NVPTXISD::LoadV2:
880 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000881 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000882 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000883 case MVT::i8:
884 Opcode = NVPTX::LDV_i8_v2_areg_64;
885 break;
886 case MVT::i16:
887 Opcode = NVPTX::LDV_i16_v2_areg_64;
888 break;
889 case MVT::i32:
890 Opcode = NVPTX::LDV_i32_v2_areg_64;
891 break;
892 case MVT::i64:
893 Opcode = NVPTX::LDV_i64_v2_areg_64;
894 break;
895 case MVT::f32:
896 Opcode = NVPTX::LDV_f32_v2_areg_64;
897 break;
898 case MVT::f64:
899 Opcode = NVPTX::LDV_f64_v2_areg_64;
900 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000901 }
902 break;
903 case NVPTXISD::LoadV4:
904 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000905 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000906 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000907 case MVT::i8:
908 Opcode = NVPTX::LDV_i8_v4_areg_64;
909 break;
910 case MVT::i16:
911 Opcode = NVPTX::LDV_i16_v4_areg_64;
912 break;
913 case MVT::i32:
914 Opcode = NVPTX::LDV_i32_v4_areg_64;
915 break;
916 case MVT::f32:
917 Opcode = NVPTX::LDV_f32_v4_areg_64;
918 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000919 }
920 break;
921 }
922 } else {
923 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000924 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000925 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000926 case NVPTXISD::LoadV2:
927 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000928 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000929 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000930 case MVT::i8:
931 Opcode = NVPTX::LDV_i8_v2_areg;
932 break;
933 case MVT::i16:
934 Opcode = NVPTX::LDV_i16_v2_areg;
935 break;
936 case MVT::i32:
937 Opcode = NVPTX::LDV_i32_v2_areg;
938 break;
939 case MVT::i64:
940 Opcode = NVPTX::LDV_i64_v2_areg;
941 break;
942 case MVT::f32:
943 Opcode = NVPTX::LDV_f32_v2_areg;
944 break;
945 case MVT::f64:
946 Opcode = NVPTX::LDV_f64_v2_areg;
947 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000948 }
949 break;
950 case NVPTXISD::LoadV4:
951 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000952 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000953 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000954 case MVT::i8:
955 Opcode = NVPTX::LDV_i8_v4_areg;
956 break;
957 case MVT::i16:
958 Opcode = NVPTX::LDV_i16_v4_areg;
959 break;
960 case MVT::i32:
961 Opcode = NVPTX::LDV_i32_v4_areg;
962 break;
963 case MVT::f32:
964 Opcode = NVPTX::LDV_f32_v4_areg;
965 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000966 }
967 break;
968 }
969 }
970
Justin Holewinski0497ab12013-03-30 14:29:21 +0000971 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
972 getI32Imm(VecType), getI32Imm(FromType),
973 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000974 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000975 }
976
977 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
978 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
979 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
980
981 return LD;
982}
983
984SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
985
986 SDValue Chain = N->getOperand(0);
987 SDValue Op1 = N->getOperand(1);
988 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000989 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000990 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000991 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000992 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000993
Justin Holewinskie40e9292013-07-01 12:58:52 +0000994 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000995
Justin Holewinskie40e9292013-07-01 12:58:52 +0000996 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000997 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000998 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000999 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001000 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001001 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001002 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001003 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001004 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001005 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001006 break;
1007 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001008 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001009 break;
1010 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001011 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001012 break;
1013 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001014 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001015 break;
1016 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001017 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001018 break;
1019 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001020 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001021 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001022 }
1023 break;
1024 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001025 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001026 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001027 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001028 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001029 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001030 break;
1031 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001032 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001033 break;
1034 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001035 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001036 break;
1037 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001038 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001039 break;
1040 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001041 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001042 break;
1043 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001044 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
1045 break;
1046 }
1047 break;
1048 case NVPTXISD::LDGV4:
1049 switch (EltVT.getSimpleVT().SimpleTy) {
1050 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001051 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001052 case MVT::i8:
1053 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
1054 break;
1055 case MVT::i16:
1056 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
1057 break;
1058 case MVT::i32:
1059 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
1060 break;
1061 case MVT::f32:
1062 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001063 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001064 }
1065 break;
1066 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001067 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001068 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001069 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001070 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001071 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001072 break;
1073 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001074 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001075 break;
1076 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001077 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001078 break;
1079 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001080 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001081 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001082 }
1083 break;
1084 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001085
1086 SDValue Ops[] = { Addr, Chain };
1087 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1088 ArrayRef<SDValue>(Ops, 2));
1089 } else if (Subtarget.is64Bit()
1090 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
1091 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
1092 if (Subtarget.is64Bit()) {
1093 switch (N->getOpcode()) {
1094 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001095 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001096 case NVPTXISD::LDGV2:
1097 switch (EltVT.getSimpleVT().SimpleTy) {
1098 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001099 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001100 case MVT::i8:
1101 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
1102 break;
1103 case MVT::i16:
1104 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
1105 break;
1106 case MVT::i32:
1107 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
1108 break;
1109 case MVT::i64:
1110 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
1111 break;
1112 case MVT::f32:
1113 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
1114 break;
1115 case MVT::f64:
1116 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
1117 break;
1118 }
1119 break;
1120 case NVPTXISD::LDUV2:
1121 switch (EltVT.getSimpleVT().SimpleTy) {
1122 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001123 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001124 case MVT::i8:
1125 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
1126 break;
1127 case MVT::i16:
1128 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
1129 break;
1130 case MVT::i32:
1131 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
1132 break;
1133 case MVT::i64:
1134 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
1135 break;
1136 case MVT::f32:
1137 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
1138 break;
1139 case MVT::f64:
1140 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
1141 break;
1142 }
1143 break;
1144 case NVPTXISD::LDGV4:
1145 switch (EltVT.getSimpleVT().SimpleTy) {
1146 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001147 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001148 case MVT::i8:
1149 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
1150 break;
1151 case MVT::i16:
1152 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
1153 break;
1154 case MVT::i32:
1155 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
1156 break;
1157 case MVT::f32:
1158 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
1159 break;
1160 }
1161 break;
1162 case NVPTXISD::LDUV4:
1163 switch (EltVT.getSimpleVT().SimpleTy) {
1164 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001165 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001166 case MVT::i8:
1167 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
1168 break;
1169 case MVT::i16:
1170 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
1171 break;
1172 case MVT::i32:
1173 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1174 break;
1175 case MVT::f32:
1176 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1177 break;
1178 }
1179 break;
1180 }
1181 } else {
1182 switch (N->getOpcode()) {
1183 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001184 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001185 case NVPTXISD::LDGV2:
1186 switch (EltVT.getSimpleVT().SimpleTy) {
1187 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001188 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001189 case MVT::i8:
1190 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1191 break;
1192 case MVT::i16:
1193 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1194 break;
1195 case MVT::i32:
1196 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1197 break;
1198 case MVT::i64:
1199 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1200 break;
1201 case MVT::f32:
1202 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1203 break;
1204 case MVT::f64:
1205 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1206 break;
1207 }
1208 break;
1209 case NVPTXISD::LDUV2:
1210 switch (EltVT.getSimpleVT().SimpleTy) {
1211 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001212 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001213 case MVT::i8:
1214 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1215 break;
1216 case MVT::i16:
1217 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1218 break;
1219 case MVT::i32:
1220 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1221 break;
1222 case MVT::i64:
1223 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1224 break;
1225 case MVT::f32:
1226 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1227 break;
1228 case MVT::f64:
1229 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1230 break;
1231 }
1232 break;
1233 case NVPTXISD::LDGV4:
1234 switch (EltVT.getSimpleVT().SimpleTy) {
1235 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001236 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001237 case MVT::i8:
1238 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1239 break;
1240 case MVT::i16:
1241 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1242 break;
1243 case MVT::i32:
1244 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1245 break;
1246 case MVT::f32:
1247 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1248 break;
1249 }
1250 break;
1251 case NVPTXISD::LDUV4:
1252 switch (EltVT.getSimpleVT().SimpleTy) {
1253 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001254 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001255 case MVT::i8:
1256 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1257 break;
1258 case MVT::i16:
1259 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1260 break;
1261 case MVT::i32:
1262 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1263 break;
1264 case MVT::f32:
1265 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1266 break;
1267 }
1268 break;
1269 }
1270 }
1271
1272 SDValue Ops[] = { Base, Offset, Chain };
1273
1274 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1275 ArrayRef<SDValue>(Ops, 3));
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001276 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001277 if (Subtarget.is64Bit()) {
1278 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001279 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001280 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001281 case NVPTXISD::LDGV2:
1282 switch (EltVT.getSimpleVT().SimpleTy) {
1283 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001284 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001285 case MVT::i8:
1286 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1287 break;
1288 case MVT::i16:
1289 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1290 break;
1291 case MVT::i32:
1292 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1293 break;
1294 case MVT::i64:
1295 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1296 break;
1297 case MVT::f32:
1298 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1299 break;
1300 case MVT::f64:
1301 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1302 break;
1303 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001304 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001305 case NVPTXISD::LDUV2:
1306 switch (EltVT.getSimpleVT().SimpleTy) {
1307 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001308 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001309 case MVT::i8:
1310 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1311 break;
1312 case MVT::i16:
1313 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1314 break;
1315 case MVT::i32:
1316 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1317 break;
1318 case MVT::i64:
1319 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1320 break;
1321 case MVT::f32:
1322 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1323 break;
1324 case MVT::f64:
1325 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1326 break;
1327 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001328 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001329 case NVPTXISD::LDGV4:
1330 switch (EltVT.getSimpleVT().SimpleTy) {
1331 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001332 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001333 case MVT::i8:
1334 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1335 break;
1336 case MVT::i16:
1337 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1338 break;
1339 case MVT::i32:
1340 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1341 break;
1342 case MVT::f32:
1343 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1344 break;
1345 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001346 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001347 case NVPTXISD::LDUV4:
1348 switch (EltVT.getSimpleVT().SimpleTy) {
1349 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001350 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001351 case MVT::i8:
1352 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1353 break;
1354 case MVT::i16:
1355 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1356 break;
1357 case MVT::i32:
1358 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1359 break;
1360 case MVT::f32:
1361 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1362 break;
1363 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001364 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001365 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001366 } else {
1367 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001368 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001369 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001370 case NVPTXISD::LDGV2:
1371 switch (EltVT.getSimpleVT().SimpleTy) {
1372 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001373 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001374 case MVT::i8:
1375 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1376 break;
1377 case MVT::i16:
1378 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1379 break;
1380 case MVT::i32:
1381 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1382 break;
1383 case MVT::i64:
1384 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1385 break;
1386 case MVT::f32:
1387 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1388 break;
1389 case MVT::f64:
1390 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1391 break;
1392 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001393 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001394 case NVPTXISD::LDUV2:
1395 switch (EltVT.getSimpleVT().SimpleTy) {
1396 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001397 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001398 case MVT::i8:
1399 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1400 break;
1401 case MVT::i16:
1402 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1403 break;
1404 case MVT::i32:
1405 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1406 break;
1407 case MVT::i64:
1408 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1409 break;
1410 case MVT::f32:
1411 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1412 break;
1413 case MVT::f64:
1414 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1415 break;
1416 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001417 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001418 case NVPTXISD::LDGV4:
1419 switch (EltVT.getSimpleVT().SimpleTy) {
1420 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001421 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001422 case MVT::i8:
1423 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1424 break;
1425 case MVT::i16:
1426 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1427 break;
1428 case MVT::i32:
1429 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1430 break;
1431 case MVT::f32:
1432 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1433 break;
1434 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001435 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001436 case NVPTXISD::LDUV4:
1437 switch (EltVT.getSimpleVT().SimpleTy) {
1438 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001439 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001440 case MVT::i8:
1441 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1442 break;
1443 case MVT::i16:
1444 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1445 break;
1446 case MVT::i32:
1447 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1448 break;
1449 case MVT::f32:
1450 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1451 break;
1452 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001453 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001454 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001455 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001456
Justin Holewinskie40e9292013-07-01 12:58:52 +00001457 SDValue Ops[] = { Op1, Chain };
1458 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1459 ArrayRef<SDValue>(Ops, 2));
1460 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001461
1462 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1463 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1464 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1465
1466 return LD;
1467}
1468
Justin Holewinski0497ab12013-03-30 14:29:21 +00001469SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001470 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001471 StoreSDNode *ST = cast<StoreSDNode>(N);
1472 EVT StoreVT = ST->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +00001473 SDNode *NVPTXST = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001474
1475 // do not support pre/post inc/dec
1476 if (ST->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +00001477 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001478
1479 if (!StoreVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +00001480 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001481
1482 // Address Space Setting
1483 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1484
1485 // Volatile Setting
1486 // - .volatile is only availalble for .global and .shared
1487 bool isVolatile = ST->isVolatile();
1488 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1489 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1490 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1491 isVolatile = false;
1492
1493 // Vector Setting
1494 MVT SimpleVT = StoreVT.getSimpleVT();
1495 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1496 if (SimpleVT.isVector()) {
1497 unsigned num = SimpleVT.getVectorNumElements();
1498 if (num == 2)
1499 vecType = NVPTX::PTXLdStInstCode::V2;
1500 else if (num == 4)
1501 vecType = NVPTX::PTXLdStInstCode::V4;
1502 else
Craig Topper062a2ba2014-04-25 05:30:21 +00001503 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001504 }
1505
1506 // Type Setting: toType + toTypeWidth
1507 // - for integer type, always use 'u'
1508 //
1509 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001510 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001511 unsigned int toType;
1512 if (ScalarVT.isFloatingPoint())
1513 toType = NVPTX::PTXLdStInstCode::Float;
1514 else
1515 toType = NVPTX::PTXLdStInstCode::Unsigned;
1516
1517 // Create the machine instruction DAG
1518 SDValue Chain = N->getOperand(0);
1519 SDValue N1 = N->getOperand(1);
1520 SDValue N2 = N->getOperand(2);
1521 SDValue Addr;
1522 SDValue Offset, Base;
1523 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001524 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001525
1526 if (SelectDirectAddr(N2, Addr)) {
1527 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001528 case MVT::i8:
1529 Opcode = NVPTX::ST_i8_avar;
1530 break;
1531 case MVT::i16:
1532 Opcode = NVPTX::ST_i16_avar;
1533 break;
1534 case MVT::i32:
1535 Opcode = NVPTX::ST_i32_avar;
1536 break;
1537 case MVT::i64:
1538 Opcode = NVPTX::ST_i64_avar;
1539 break;
1540 case MVT::f32:
1541 Opcode = NVPTX::ST_f32_avar;
1542 break;
1543 case MVT::f64:
1544 Opcode = NVPTX::ST_f64_avar;
1545 break;
1546 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001547 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001548 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001549 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1550 getI32Imm(vecType), getI32Imm(toType),
1551 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001552 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001553 } else if (Subtarget.is64Bit()
1554 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1555 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001556 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001557 case MVT::i8:
1558 Opcode = NVPTX::ST_i8_asi;
1559 break;
1560 case MVT::i16:
1561 Opcode = NVPTX::ST_i16_asi;
1562 break;
1563 case MVT::i32:
1564 Opcode = NVPTX::ST_i32_asi;
1565 break;
1566 case MVT::i64:
1567 Opcode = NVPTX::ST_i64_asi;
1568 break;
1569 case MVT::f32:
1570 Opcode = NVPTX::ST_f32_asi;
1571 break;
1572 case MVT::f64:
1573 Opcode = NVPTX::ST_f64_asi;
1574 break;
1575 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001576 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001577 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001578 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1579 getI32Imm(vecType), getI32Imm(toType),
1580 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001581 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001582 } else if (Subtarget.is64Bit()
1583 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1584 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001585 if (Subtarget.is64Bit()) {
1586 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001587 case MVT::i8:
1588 Opcode = NVPTX::ST_i8_ari_64;
1589 break;
1590 case MVT::i16:
1591 Opcode = NVPTX::ST_i16_ari_64;
1592 break;
1593 case MVT::i32:
1594 Opcode = NVPTX::ST_i32_ari_64;
1595 break;
1596 case MVT::i64:
1597 Opcode = NVPTX::ST_i64_ari_64;
1598 break;
1599 case MVT::f32:
1600 Opcode = NVPTX::ST_f32_ari_64;
1601 break;
1602 case MVT::f64:
1603 Opcode = NVPTX::ST_f64_ari_64;
1604 break;
1605 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001606 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001607 }
1608 } else {
1609 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001610 case MVT::i8:
1611 Opcode = NVPTX::ST_i8_ari;
1612 break;
1613 case MVT::i16:
1614 Opcode = NVPTX::ST_i16_ari;
1615 break;
1616 case MVT::i32:
1617 Opcode = NVPTX::ST_i32_ari;
1618 break;
1619 case MVT::i64:
1620 Opcode = NVPTX::ST_i64_ari;
1621 break;
1622 case MVT::f32:
1623 Opcode = NVPTX::ST_f32_ari;
1624 break;
1625 case MVT::f64:
1626 Opcode = NVPTX::ST_f64_ari;
1627 break;
1628 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001629 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001630 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001631 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001632 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1633 getI32Imm(vecType), getI32Imm(toType),
1634 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001635 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001636 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001637 if (Subtarget.is64Bit()) {
1638 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001639 case MVT::i8:
1640 Opcode = NVPTX::ST_i8_areg_64;
1641 break;
1642 case MVT::i16:
1643 Opcode = NVPTX::ST_i16_areg_64;
1644 break;
1645 case MVT::i32:
1646 Opcode = NVPTX::ST_i32_areg_64;
1647 break;
1648 case MVT::i64:
1649 Opcode = NVPTX::ST_i64_areg_64;
1650 break;
1651 case MVT::f32:
1652 Opcode = NVPTX::ST_f32_areg_64;
1653 break;
1654 case MVT::f64:
1655 Opcode = NVPTX::ST_f64_areg_64;
1656 break;
1657 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001658 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001659 }
1660 } else {
1661 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001662 case MVT::i8:
1663 Opcode = NVPTX::ST_i8_areg;
1664 break;
1665 case MVT::i16:
1666 Opcode = NVPTX::ST_i16_areg;
1667 break;
1668 case MVT::i32:
1669 Opcode = NVPTX::ST_i32_areg;
1670 break;
1671 case MVT::i64:
1672 Opcode = NVPTX::ST_i64_areg;
1673 break;
1674 case MVT::f32:
1675 Opcode = NVPTX::ST_f32_areg;
1676 break;
1677 case MVT::f64:
1678 Opcode = NVPTX::ST_f64_areg;
1679 break;
1680 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001681 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001682 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001683 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001684 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1685 getI32Imm(vecType), getI32Imm(toType),
1686 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001687 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001688 }
1689
Craig Topper062a2ba2014-04-25 05:30:21 +00001690 if (NVPTXST) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001691 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1692 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1693 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1694 }
1695
1696 return NVPTXST;
1697}
1698
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001699SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1700 SDValue Chain = N->getOperand(0);
1701 SDValue Op1 = N->getOperand(1);
1702 SDValue Addr, Offset, Base;
1703 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001704 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001705 SDNode *ST;
1706 EVT EltVT = Op1.getValueType();
1707 MemSDNode *MemSD = cast<MemSDNode>(N);
1708 EVT StoreVT = MemSD->getMemoryVT();
1709
1710 // Address Space Setting
1711 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1712
1713 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1714 report_fatal_error("Cannot store to pointer that points to constant "
1715 "memory space");
1716 }
1717
1718 // Volatile Setting
1719 // - .volatile is only availalble for .global and .shared
1720 bool IsVolatile = MemSD->isVolatile();
1721 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1722 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1723 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1724 IsVolatile = false;
1725
1726 // Type Setting: toType + toTypeWidth
1727 // - for integer type, always use 'u'
1728 assert(StoreVT.isSimple() && "Store value is not simple");
1729 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001730 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001731 unsigned ToType;
1732 if (ScalarVT.isFloatingPoint())
1733 ToType = NVPTX::PTXLdStInstCode::Float;
1734 else
1735 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1736
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001737 SmallVector<SDValue, 12> StOps;
1738 SDValue N2;
1739 unsigned VecType;
1740
1741 switch (N->getOpcode()) {
1742 case NVPTXISD::StoreV2:
1743 VecType = NVPTX::PTXLdStInstCode::V2;
1744 StOps.push_back(N->getOperand(1));
1745 StOps.push_back(N->getOperand(2));
1746 N2 = N->getOperand(3);
1747 break;
1748 case NVPTXISD::StoreV4:
1749 VecType = NVPTX::PTXLdStInstCode::V4;
1750 StOps.push_back(N->getOperand(1));
1751 StOps.push_back(N->getOperand(2));
1752 StOps.push_back(N->getOperand(3));
1753 StOps.push_back(N->getOperand(4));
1754 N2 = N->getOperand(5);
1755 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001756 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001757 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001758 }
1759
1760 StOps.push_back(getI32Imm(IsVolatile));
1761 StOps.push_back(getI32Imm(CodeAddrSpace));
1762 StOps.push_back(getI32Imm(VecType));
1763 StOps.push_back(getI32Imm(ToType));
1764 StOps.push_back(getI32Imm(ToTypeWidth));
1765
1766 if (SelectDirectAddr(N2, Addr)) {
1767 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001768 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001769 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001770 case NVPTXISD::StoreV2:
1771 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001772 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001773 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001774 case MVT::i8:
1775 Opcode = NVPTX::STV_i8_v2_avar;
1776 break;
1777 case MVT::i16:
1778 Opcode = NVPTX::STV_i16_v2_avar;
1779 break;
1780 case MVT::i32:
1781 Opcode = NVPTX::STV_i32_v2_avar;
1782 break;
1783 case MVT::i64:
1784 Opcode = NVPTX::STV_i64_v2_avar;
1785 break;
1786 case MVT::f32:
1787 Opcode = NVPTX::STV_f32_v2_avar;
1788 break;
1789 case MVT::f64:
1790 Opcode = NVPTX::STV_f64_v2_avar;
1791 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001792 }
1793 break;
1794 case NVPTXISD::StoreV4:
1795 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001796 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001797 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001798 case MVT::i8:
1799 Opcode = NVPTX::STV_i8_v4_avar;
1800 break;
1801 case MVT::i16:
1802 Opcode = NVPTX::STV_i16_v4_avar;
1803 break;
1804 case MVT::i32:
1805 Opcode = NVPTX::STV_i32_v4_avar;
1806 break;
1807 case MVT::f32:
1808 Opcode = NVPTX::STV_f32_v4_avar;
1809 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001810 }
1811 break;
1812 }
1813 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001814 } else if (Subtarget.is64Bit()
1815 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1816 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001817 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001818 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001819 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001820 case NVPTXISD::StoreV2:
1821 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001822 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001823 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001824 case MVT::i8:
1825 Opcode = NVPTX::STV_i8_v2_asi;
1826 break;
1827 case MVT::i16:
1828 Opcode = NVPTX::STV_i16_v2_asi;
1829 break;
1830 case MVT::i32:
1831 Opcode = NVPTX::STV_i32_v2_asi;
1832 break;
1833 case MVT::i64:
1834 Opcode = NVPTX::STV_i64_v2_asi;
1835 break;
1836 case MVT::f32:
1837 Opcode = NVPTX::STV_f32_v2_asi;
1838 break;
1839 case MVT::f64:
1840 Opcode = NVPTX::STV_f64_v2_asi;
1841 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001842 }
1843 break;
1844 case NVPTXISD::StoreV4:
1845 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001846 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001847 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001848 case MVT::i8:
1849 Opcode = NVPTX::STV_i8_v4_asi;
1850 break;
1851 case MVT::i16:
1852 Opcode = NVPTX::STV_i16_v4_asi;
1853 break;
1854 case MVT::i32:
1855 Opcode = NVPTX::STV_i32_v4_asi;
1856 break;
1857 case MVT::f32:
1858 Opcode = NVPTX::STV_f32_v4_asi;
1859 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001860 }
1861 break;
1862 }
1863 StOps.push_back(Base);
1864 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001865 } else if (Subtarget.is64Bit()
1866 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1867 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001868 if (Subtarget.is64Bit()) {
1869 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001870 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001871 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001872 case NVPTXISD::StoreV2:
1873 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001874 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001875 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001876 case MVT::i8:
1877 Opcode = NVPTX::STV_i8_v2_ari_64;
1878 break;
1879 case MVT::i16:
1880 Opcode = NVPTX::STV_i16_v2_ari_64;
1881 break;
1882 case MVT::i32:
1883 Opcode = NVPTX::STV_i32_v2_ari_64;
1884 break;
1885 case MVT::i64:
1886 Opcode = NVPTX::STV_i64_v2_ari_64;
1887 break;
1888 case MVT::f32:
1889 Opcode = NVPTX::STV_f32_v2_ari_64;
1890 break;
1891 case MVT::f64:
1892 Opcode = NVPTX::STV_f64_v2_ari_64;
1893 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001894 }
1895 break;
1896 case NVPTXISD::StoreV4:
1897 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001898 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001899 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001900 case MVT::i8:
1901 Opcode = NVPTX::STV_i8_v4_ari_64;
1902 break;
1903 case MVT::i16:
1904 Opcode = NVPTX::STV_i16_v4_ari_64;
1905 break;
1906 case MVT::i32:
1907 Opcode = NVPTX::STV_i32_v4_ari_64;
1908 break;
1909 case MVT::f32:
1910 Opcode = NVPTX::STV_f32_v4_ari_64;
1911 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001912 }
1913 break;
1914 }
1915 } else {
1916 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001917 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001918 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001919 case NVPTXISD::StoreV2:
1920 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001921 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001922 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001923 case MVT::i8:
1924 Opcode = NVPTX::STV_i8_v2_ari;
1925 break;
1926 case MVT::i16:
1927 Opcode = NVPTX::STV_i16_v2_ari;
1928 break;
1929 case MVT::i32:
1930 Opcode = NVPTX::STV_i32_v2_ari;
1931 break;
1932 case MVT::i64:
1933 Opcode = NVPTX::STV_i64_v2_ari;
1934 break;
1935 case MVT::f32:
1936 Opcode = NVPTX::STV_f32_v2_ari;
1937 break;
1938 case MVT::f64:
1939 Opcode = NVPTX::STV_f64_v2_ari;
1940 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001941 }
1942 break;
1943 case NVPTXISD::StoreV4:
1944 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001945 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001946 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001947 case MVT::i8:
1948 Opcode = NVPTX::STV_i8_v4_ari;
1949 break;
1950 case MVT::i16:
1951 Opcode = NVPTX::STV_i16_v4_ari;
1952 break;
1953 case MVT::i32:
1954 Opcode = NVPTX::STV_i32_v4_ari;
1955 break;
1956 case MVT::f32:
1957 Opcode = NVPTX::STV_f32_v4_ari;
1958 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001959 }
1960 break;
1961 }
1962 }
1963 StOps.push_back(Base);
1964 StOps.push_back(Offset);
1965 } else {
1966 if (Subtarget.is64Bit()) {
1967 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001968 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001969 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001970 case NVPTXISD::StoreV2:
1971 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001972 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001973 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001974 case MVT::i8:
1975 Opcode = NVPTX::STV_i8_v2_areg_64;
1976 break;
1977 case MVT::i16:
1978 Opcode = NVPTX::STV_i16_v2_areg_64;
1979 break;
1980 case MVT::i32:
1981 Opcode = NVPTX::STV_i32_v2_areg_64;
1982 break;
1983 case MVT::i64:
1984 Opcode = NVPTX::STV_i64_v2_areg_64;
1985 break;
1986 case MVT::f32:
1987 Opcode = NVPTX::STV_f32_v2_areg_64;
1988 break;
1989 case MVT::f64:
1990 Opcode = NVPTX::STV_f64_v2_areg_64;
1991 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001992 }
1993 break;
1994 case NVPTXISD::StoreV4:
1995 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001996 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001997 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001998 case MVT::i8:
1999 Opcode = NVPTX::STV_i8_v4_areg_64;
2000 break;
2001 case MVT::i16:
2002 Opcode = NVPTX::STV_i16_v4_areg_64;
2003 break;
2004 case MVT::i32:
2005 Opcode = NVPTX::STV_i32_v4_areg_64;
2006 break;
2007 case MVT::f32:
2008 Opcode = NVPTX::STV_f32_v4_areg_64;
2009 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002010 }
2011 break;
2012 }
2013 } else {
2014 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002015 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002016 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002017 case NVPTXISD::StoreV2:
2018 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002019 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002020 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002021 case MVT::i8:
2022 Opcode = NVPTX::STV_i8_v2_areg;
2023 break;
2024 case MVT::i16:
2025 Opcode = NVPTX::STV_i16_v2_areg;
2026 break;
2027 case MVT::i32:
2028 Opcode = NVPTX::STV_i32_v2_areg;
2029 break;
2030 case MVT::i64:
2031 Opcode = NVPTX::STV_i64_v2_areg;
2032 break;
2033 case MVT::f32:
2034 Opcode = NVPTX::STV_f32_v2_areg;
2035 break;
2036 case MVT::f64:
2037 Opcode = NVPTX::STV_f64_v2_areg;
2038 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002039 }
2040 break;
2041 case NVPTXISD::StoreV4:
2042 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002043 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002044 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002045 case MVT::i8:
2046 Opcode = NVPTX::STV_i8_v4_areg;
2047 break;
2048 case MVT::i16:
2049 Opcode = NVPTX::STV_i16_v4_areg;
2050 break;
2051 case MVT::i32:
2052 Opcode = NVPTX::STV_i32_v4_areg;
2053 break;
2054 case MVT::f32:
2055 Opcode = NVPTX::STV_f32_v4_areg;
2056 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002057 }
2058 break;
2059 }
2060 }
2061 StOps.push_back(N2);
2062 }
2063
2064 StOps.push_back(Chain);
2065
Michael Liaob53d8962013-04-19 22:22:57 +00002066 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002067
2068 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2069 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2070 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
2071
2072 return ST;
2073}
2074
Justin Holewinskif8f70912013-06-28 17:57:59 +00002075SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
2076 SDValue Chain = Node->getOperand(0);
2077 SDValue Offset = Node->getOperand(2);
2078 SDValue Flag = Node->getOperand(3);
2079 SDLoc DL(Node);
2080 MemSDNode *Mem = cast<MemSDNode>(Node);
2081
2082 unsigned VecSize;
2083 switch (Node->getOpcode()) {
2084 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002085 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002086 case NVPTXISD::LoadParam:
2087 VecSize = 1;
2088 break;
2089 case NVPTXISD::LoadParamV2:
2090 VecSize = 2;
2091 break;
2092 case NVPTXISD::LoadParamV4:
2093 VecSize = 4;
2094 break;
2095 }
2096
2097 EVT EltVT = Node->getValueType(0);
2098 EVT MemVT = Mem->getMemoryVT();
2099
2100 unsigned Opc = 0;
2101
2102 switch (VecSize) {
2103 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002104 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002105 case 1:
2106 switch (MemVT.getSimpleVT().SimpleTy) {
2107 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002108 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002109 case MVT::i1:
2110 Opc = NVPTX::LoadParamMemI8;
2111 break;
2112 case MVT::i8:
2113 Opc = NVPTX::LoadParamMemI8;
2114 break;
2115 case MVT::i16:
2116 Opc = NVPTX::LoadParamMemI16;
2117 break;
2118 case MVT::i32:
2119 Opc = NVPTX::LoadParamMemI32;
2120 break;
2121 case MVT::i64:
2122 Opc = NVPTX::LoadParamMemI64;
2123 break;
2124 case MVT::f32:
2125 Opc = NVPTX::LoadParamMemF32;
2126 break;
2127 case MVT::f64:
2128 Opc = NVPTX::LoadParamMemF64;
2129 break;
2130 }
2131 break;
2132 case 2:
2133 switch (MemVT.getSimpleVT().SimpleTy) {
2134 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002135 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002136 case MVT::i1:
2137 Opc = NVPTX::LoadParamMemV2I8;
2138 break;
2139 case MVT::i8:
2140 Opc = NVPTX::LoadParamMemV2I8;
2141 break;
2142 case MVT::i16:
2143 Opc = NVPTX::LoadParamMemV2I16;
2144 break;
2145 case MVT::i32:
2146 Opc = NVPTX::LoadParamMemV2I32;
2147 break;
2148 case MVT::i64:
2149 Opc = NVPTX::LoadParamMemV2I64;
2150 break;
2151 case MVT::f32:
2152 Opc = NVPTX::LoadParamMemV2F32;
2153 break;
2154 case MVT::f64:
2155 Opc = NVPTX::LoadParamMemV2F64;
2156 break;
2157 }
2158 break;
2159 case 4:
2160 switch (MemVT.getSimpleVT().SimpleTy) {
2161 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002162 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002163 case MVT::i1:
2164 Opc = NVPTX::LoadParamMemV4I8;
2165 break;
2166 case MVT::i8:
2167 Opc = NVPTX::LoadParamMemV4I8;
2168 break;
2169 case MVT::i16:
2170 Opc = NVPTX::LoadParamMemV4I16;
2171 break;
2172 case MVT::i32:
2173 Opc = NVPTX::LoadParamMemV4I32;
2174 break;
2175 case MVT::f32:
2176 Opc = NVPTX::LoadParamMemV4F32;
2177 break;
2178 }
2179 break;
2180 }
2181
2182 SDVTList VTs;
2183 if (VecSize == 1) {
2184 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2185 } else if (VecSize == 2) {
2186 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2187 } else {
2188 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
Craig Topperabb4ac72014-04-16 06:10:51 +00002189 VTs = CurDAG->getVTList(EVTs);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002190 }
2191
2192 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2193
2194 SmallVector<SDValue, 2> Ops;
2195 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2196 Ops.push_back(Chain);
2197 Ops.push_back(Flag);
2198
2199 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002200 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002201 return Ret;
2202}
2203
2204SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2205 SDLoc DL(N);
2206 SDValue Chain = N->getOperand(0);
2207 SDValue Offset = N->getOperand(1);
2208 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2209 MemSDNode *Mem = cast<MemSDNode>(N);
2210
2211 // How many elements do we have?
2212 unsigned NumElts = 1;
2213 switch (N->getOpcode()) {
2214 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002215 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002216 case NVPTXISD::StoreRetval:
2217 NumElts = 1;
2218 break;
2219 case NVPTXISD::StoreRetvalV2:
2220 NumElts = 2;
2221 break;
2222 case NVPTXISD::StoreRetvalV4:
2223 NumElts = 4;
2224 break;
2225 }
2226
2227 // Build vector of operands
2228 SmallVector<SDValue, 6> Ops;
2229 for (unsigned i = 0; i < NumElts; ++i)
2230 Ops.push_back(N->getOperand(i + 2));
2231 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2232 Ops.push_back(Chain);
2233
2234 // Determine target opcode
2235 // If we have an i1, use an 8-bit store. The lowering code in
2236 // NVPTXISelLowering will have already emitted an upcast.
2237 unsigned Opcode = 0;
2238 switch (NumElts) {
2239 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002240 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002241 case 1:
2242 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2243 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002244 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002245 case MVT::i1:
2246 Opcode = NVPTX::StoreRetvalI8;
2247 break;
2248 case MVT::i8:
2249 Opcode = NVPTX::StoreRetvalI8;
2250 break;
2251 case MVT::i16:
2252 Opcode = NVPTX::StoreRetvalI16;
2253 break;
2254 case MVT::i32:
2255 Opcode = NVPTX::StoreRetvalI32;
2256 break;
2257 case MVT::i64:
2258 Opcode = NVPTX::StoreRetvalI64;
2259 break;
2260 case MVT::f32:
2261 Opcode = NVPTX::StoreRetvalF32;
2262 break;
2263 case MVT::f64:
2264 Opcode = NVPTX::StoreRetvalF64;
2265 break;
2266 }
2267 break;
2268 case 2:
2269 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2270 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002271 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002272 case MVT::i1:
2273 Opcode = NVPTX::StoreRetvalV2I8;
2274 break;
2275 case MVT::i8:
2276 Opcode = NVPTX::StoreRetvalV2I8;
2277 break;
2278 case MVT::i16:
2279 Opcode = NVPTX::StoreRetvalV2I16;
2280 break;
2281 case MVT::i32:
2282 Opcode = NVPTX::StoreRetvalV2I32;
2283 break;
2284 case MVT::i64:
2285 Opcode = NVPTX::StoreRetvalV2I64;
2286 break;
2287 case MVT::f32:
2288 Opcode = NVPTX::StoreRetvalV2F32;
2289 break;
2290 case MVT::f64:
2291 Opcode = NVPTX::StoreRetvalV2F64;
2292 break;
2293 }
2294 break;
2295 case 4:
2296 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2297 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002298 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002299 case MVT::i1:
2300 Opcode = NVPTX::StoreRetvalV4I8;
2301 break;
2302 case MVT::i8:
2303 Opcode = NVPTX::StoreRetvalV4I8;
2304 break;
2305 case MVT::i16:
2306 Opcode = NVPTX::StoreRetvalV4I16;
2307 break;
2308 case MVT::i32:
2309 Opcode = NVPTX::StoreRetvalV4I32;
2310 break;
2311 case MVT::f32:
2312 Opcode = NVPTX::StoreRetvalV4F32;
2313 break;
2314 }
2315 break;
2316 }
2317
2318 SDNode *Ret =
2319 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2320 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2321 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2322 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2323
2324 return Ret;
2325}
2326
2327SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2328 SDLoc DL(N);
2329 SDValue Chain = N->getOperand(0);
2330 SDValue Param = N->getOperand(1);
2331 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2332 SDValue Offset = N->getOperand(2);
2333 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2334 MemSDNode *Mem = cast<MemSDNode>(N);
2335 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2336
2337 // How many elements do we have?
2338 unsigned NumElts = 1;
2339 switch (N->getOpcode()) {
2340 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002341 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002342 case NVPTXISD::StoreParamU32:
2343 case NVPTXISD::StoreParamS32:
2344 case NVPTXISD::StoreParam:
2345 NumElts = 1;
2346 break;
2347 case NVPTXISD::StoreParamV2:
2348 NumElts = 2;
2349 break;
2350 case NVPTXISD::StoreParamV4:
2351 NumElts = 4;
2352 break;
2353 }
2354
2355 // Build vector of operands
2356 SmallVector<SDValue, 8> Ops;
2357 for (unsigned i = 0; i < NumElts; ++i)
2358 Ops.push_back(N->getOperand(i + 3));
2359 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2360 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2361 Ops.push_back(Chain);
2362 Ops.push_back(Flag);
2363
2364 // Determine target opcode
2365 // If we have an i1, use an 8-bit store. The lowering code in
2366 // NVPTXISelLowering will have already emitted an upcast.
2367 unsigned Opcode = 0;
2368 switch (N->getOpcode()) {
2369 default:
2370 switch (NumElts) {
2371 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002372 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002373 case 1:
2374 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2375 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002376 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002377 case MVT::i1:
2378 Opcode = NVPTX::StoreParamI8;
2379 break;
2380 case MVT::i8:
2381 Opcode = NVPTX::StoreParamI8;
2382 break;
2383 case MVT::i16:
2384 Opcode = NVPTX::StoreParamI16;
2385 break;
2386 case MVT::i32:
2387 Opcode = NVPTX::StoreParamI32;
2388 break;
2389 case MVT::i64:
2390 Opcode = NVPTX::StoreParamI64;
2391 break;
2392 case MVT::f32:
2393 Opcode = NVPTX::StoreParamF32;
2394 break;
2395 case MVT::f64:
2396 Opcode = NVPTX::StoreParamF64;
2397 break;
2398 }
2399 break;
2400 case 2:
2401 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2402 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002403 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002404 case MVT::i1:
2405 Opcode = NVPTX::StoreParamV2I8;
2406 break;
2407 case MVT::i8:
2408 Opcode = NVPTX::StoreParamV2I8;
2409 break;
2410 case MVT::i16:
2411 Opcode = NVPTX::StoreParamV2I16;
2412 break;
2413 case MVT::i32:
2414 Opcode = NVPTX::StoreParamV2I32;
2415 break;
2416 case MVT::i64:
2417 Opcode = NVPTX::StoreParamV2I64;
2418 break;
2419 case MVT::f32:
2420 Opcode = NVPTX::StoreParamV2F32;
2421 break;
2422 case MVT::f64:
2423 Opcode = NVPTX::StoreParamV2F64;
2424 break;
2425 }
2426 break;
2427 case 4:
2428 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2429 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002430 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002431 case MVT::i1:
2432 Opcode = NVPTX::StoreParamV4I8;
2433 break;
2434 case MVT::i8:
2435 Opcode = NVPTX::StoreParamV4I8;
2436 break;
2437 case MVT::i16:
2438 Opcode = NVPTX::StoreParamV4I16;
2439 break;
2440 case MVT::i32:
2441 Opcode = NVPTX::StoreParamV4I32;
2442 break;
2443 case MVT::f32:
2444 Opcode = NVPTX::StoreParamV4F32;
2445 break;
2446 }
2447 break;
2448 }
2449 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002450 // Special case: if we have a sign-extend/zero-extend node, insert the
2451 // conversion instruction first, and use that as the value operand to
2452 // the selected StoreParam node.
2453 case NVPTXISD::StoreParamU32: {
2454 Opcode = NVPTX::StoreParamI32;
2455 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2456 MVT::i32);
2457 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2458 MVT::i32, Ops[0], CvtNone);
2459 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002460 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002461 }
2462 case NVPTXISD::StoreParamS32: {
2463 Opcode = NVPTX::StoreParamI32;
2464 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2465 MVT::i32);
2466 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2467 MVT::i32, Ops[0], CvtNone);
2468 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002469 break;
2470 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002471 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002472
Justin Holewinskidff28d22013-07-01 12:59:01 +00002473 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002474 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002475 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002476 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2477 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2478 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2479
2480 return Ret;
2481}
2482
Justin Holewinski30d56a72014-04-09 15:39:15 +00002483SDNode *NVPTXDAGToDAGISel::SelectTextureIntrinsic(SDNode *N) {
2484 SDValue Chain = N->getOperand(0);
2485 SDValue TexRef = N->getOperand(1);
2486 SDValue SampRef = N->getOperand(2);
Craig Topper062a2ba2014-04-25 05:30:21 +00002487 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002488 unsigned Opc = 0;
2489 SmallVector<SDValue, 8> Ops;
2490
2491 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002492 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002493 case NVPTXISD::Tex1DFloatI32:
2494 Opc = NVPTX::TEX_1D_F32_I32;
2495 break;
2496 case NVPTXISD::Tex1DFloatFloat:
2497 Opc = NVPTX::TEX_1D_F32_F32;
2498 break;
2499 case NVPTXISD::Tex1DFloatFloatLevel:
2500 Opc = NVPTX::TEX_1D_F32_F32_LEVEL;
2501 break;
2502 case NVPTXISD::Tex1DFloatFloatGrad:
2503 Opc = NVPTX::TEX_1D_F32_F32_GRAD;
2504 break;
2505 case NVPTXISD::Tex1DI32I32:
2506 Opc = NVPTX::TEX_1D_I32_I32;
2507 break;
2508 case NVPTXISD::Tex1DI32Float:
2509 Opc = NVPTX::TEX_1D_I32_F32;
2510 break;
2511 case NVPTXISD::Tex1DI32FloatLevel:
2512 Opc = NVPTX::TEX_1D_I32_F32_LEVEL;
2513 break;
2514 case NVPTXISD::Tex1DI32FloatGrad:
2515 Opc = NVPTX::TEX_1D_I32_F32_GRAD;
2516 break;
2517 case NVPTXISD::Tex1DArrayFloatI32:
2518 Opc = NVPTX::TEX_1D_ARRAY_F32_I32;
2519 break;
2520 case NVPTXISD::Tex1DArrayFloatFloat:
2521 Opc = NVPTX::TEX_1D_ARRAY_F32_F32;
2522 break;
2523 case NVPTXISD::Tex1DArrayFloatFloatLevel:
2524 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_LEVEL;
2525 break;
2526 case NVPTXISD::Tex1DArrayFloatFloatGrad:
2527 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_GRAD;
2528 break;
2529 case NVPTXISD::Tex1DArrayI32I32:
2530 Opc = NVPTX::TEX_1D_ARRAY_I32_I32;
2531 break;
2532 case NVPTXISD::Tex1DArrayI32Float:
2533 Opc = NVPTX::TEX_1D_ARRAY_I32_F32;
2534 break;
2535 case NVPTXISD::Tex1DArrayI32FloatLevel:
2536 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_LEVEL;
2537 break;
2538 case NVPTXISD::Tex1DArrayI32FloatGrad:
2539 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_GRAD;
2540 break;
2541 case NVPTXISD::Tex2DFloatI32:
2542 Opc = NVPTX::TEX_2D_F32_I32;
2543 break;
2544 case NVPTXISD::Tex2DFloatFloat:
2545 Opc = NVPTX::TEX_2D_F32_F32;
2546 break;
2547 case NVPTXISD::Tex2DFloatFloatLevel:
2548 Opc = NVPTX::TEX_2D_F32_F32_LEVEL;
2549 break;
2550 case NVPTXISD::Tex2DFloatFloatGrad:
2551 Opc = NVPTX::TEX_2D_F32_F32_GRAD;
2552 break;
2553 case NVPTXISD::Tex2DI32I32:
2554 Opc = NVPTX::TEX_2D_I32_I32;
2555 break;
2556 case NVPTXISD::Tex2DI32Float:
2557 Opc = NVPTX::TEX_2D_I32_F32;
2558 break;
2559 case NVPTXISD::Tex2DI32FloatLevel:
2560 Opc = NVPTX::TEX_2D_I32_F32_LEVEL;
2561 break;
2562 case NVPTXISD::Tex2DI32FloatGrad:
2563 Opc = NVPTX::TEX_2D_I32_F32_GRAD;
2564 break;
2565 case NVPTXISD::Tex2DArrayFloatI32:
2566 Opc = NVPTX::TEX_2D_ARRAY_F32_I32;
2567 break;
2568 case NVPTXISD::Tex2DArrayFloatFloat:
2569 Opc = NVPTX::TEX_2D_ARRAY_F32_F32;
2570 break;
2571 case NVPTXISD::Tex2DArrayFloatFloatLevel:
2572 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_LEVEL;
2573 break;
2574 case NVPTXISD::Tex2DArrayFloatFloatGrad:
2575 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_GRAD;
2576 break;
2577 case NVPTXISD::Tex2DArrayI32I32:
2578 Opc = NVPTX::TEX_2D_ARRAY_I32_I32;
2579 break;
2580 case NVPTXISD::Tex2DArrayI32Float:
2581 Opc = NVPTX::TEX_2D_ARRAY_I32_F32;
2582 break;
2583 case NVPTXISD::Tex2DArrayI32FloatLevel:
2584 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_LEVEL;
2585 break;
2586 case NVPTXISD::Tex2DArrayI32FloatGrad:
2587 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_GRAD;
2588 break;
2589 case NVPTXISD::Tex3DFloatI32:
2590 Opc = NVPTX::TEX_3D_F32_I32;
2591 break;
2592 case NVPTXISD::Tex3DFloatFloat:
2593 Opc = NVPTX::TEX_3D_F32_F32;
2594 break;
2595 case NVPTXISD::Tex3DFloatFloatLevel:
2596 Opc = NVPTX::TEX_3D_F32_F32_LEVEL;
2597 break;
2598 case NVPTXISD::Tex3DFloatFloatGrad:
2599 Opc = NVPTX::TEX_3D_F32_F32_GRAD;
2600 break;
2601 case NVPTXISD::Tex3DI32I32:
2602 Opc = NVPTX::TEX_3D_I32_I32;
2603 break;
2604 case NVPTXISD::Tex3DI32Float:
2605 Opc = NVPTX::TEX_3D_I32_F32;
2606 break;
2607 case NVPTXISD::Tex3DI32FloatLevel:
2608 Opc = NVPTX::TEX_3D_I32_F32_LEVEL;
2609 break;
2610 case NVPTXISD::Tex3DI32FloatGrad:
2611 Opc = NVPTX::TEX_3D_I32_F32_GRAD;
2612 break;
2613 }
2614
2615 Ops.push_back(TexRef);
2616 Ops.push_back(SampRef);
2617
2618 // Copy over indices
2619 for (unsigned i = 3; i < N->getNumOperands(); ++i) {
2620 Ops.push_back(N->getOperand(i));
2621 }
2622
2623 Ops.push_back(Chain);
2624 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2625 return Ret;
2626}
2627
2628SDNode *NVPTXDAGToDAGISel::SelectSurfaceIntrinsic(SDNode *N) {
2629 SDValue Chain = N->getOperand(0);
2630 SDValue TexHandle = N->getOperand(1);
Craig Topper062a2ba2014-04-25 05:30:21 +00002631 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002632 unsigned Opc = 0;
2633 SmallVector<SDValue, 8> Ops;
2634 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002635 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002636 case NVPTXISD::Suld1DI8Trap:
2637 Opc = NVPTX::SULD_1D_I8_TRAP;
2638 Ops.push_back(TexHandle);
2639 Ops.push_back(N->getOperand(2));
2640 Ops.push_back(Chain);
2641 break;
2642 case NVPTXISD::Suld1DI16Trap:
2643 Opc = NVPTX::SULD_1D_I16_TRAP;
2644 Ops.push_back(TexHandle);
2645 Ops.push_back(N->getOperand(2));
2646 Ops.push_back(Chain);
2647 break;
2648 case NVPTXISD::Suld1DI32Trap:
2649 Opc = NVPTX::SULD_1D_I32_TRAP;
2650 Ops.push_back(TexHandle);
2651 Ops.push_back(N->getOperand(2));
2652 Ops.push_back(Chain);
2653 break;
2654 case NVPTXISD::Suld1DV2I8Trap:
2655 Opc = NVPTX::SULD_1D_V2I8_TRAP;
2656 Ops.push_back(TexHandle);
2657 Ops.push_back(N->getOperand(2));
2658 Ops.push_back(Chain);
2659 break;
2660 case NVPTXISD::Suld1DV2I16Trap:
2661 Opc = NVPTX::SULD_1D_V2I16_TRAP;
2662 Ops.push_back(TexHandle);
2663 Ops.push_back(N->getOperand(2));
2664 Ops.push_back(Chain);
2665 break;
2666 case NVPTXISD::Suld1DV2I32Trap:
2667 Opc = NVPTX::SULD_1D_V2I32_TRAP;
2668 Ops.push_back(TexHandle);
2669 Ops.push_back(N->getOperand(2));
2670 Ops.push_back(Chain);
2671 break;
2672 case NVPTXISD::Suld1DV4I8Trap:
2673 Opc = NVPTX::SULD_1D_V4I8_TRAP;
2674 Ops.push_back(TexHandle);
2675 Ops.push_back(N->getOperand(2));
2676 Ops.push_back(Chain);
2677 break;
2678 case NVPTXISD::Suld1DV4I16Trap:
2679 Opc = NVPTX::SULD_1D_V4I16_TRAP;
2680 Ops.push_back(TexHandle);
2681 Ops.push_back(N->getOperand(2));
2682 Ops.push_back(Chain);
2683 break;
2684 case NVPTXISD::Suld1DV4I32Trap:
2685 Opc = NVPTX::SULD_1D_V4I32_TRAP;
2686 Ops.push_back(TexHandle);
2687 Ops.push_back(N->getOperand(2));
2688 Ops.push_back(Chain);
2689 break;
2690 case NVPTXISD::Suld1DArrayI8Trap:
2691 Opc = NVPTX::SULD_1D_ARRAY_I8_TRAP;
2692 Ops.push_back(TexHandle);
2693 Ops.push_back(N->getOperand(2));
2694 Ops.push_back(N->getOperand(3));
2695 Ops.push_back(Chain);
2696 break;
2697 case NVPTXISD::Suld1DArrayI16Trap:
2698 Opc = NVPTX::SULD_1D_ARRAY_I16_TRAP;
2699 Ops.push_back(TexHandle);
2700 Ops.push_back(N->getOperand(2));
2701 Ops.push_back(N->getOperand(3));
2702 Ops.push_back(Chain);
2703 break;
2704 case NVPTXISD::Suld1DArrayI32Trap:
2705 Opc = NVPTX::SULD_1D_ARRAY_I32_TRAP;
2706 Ops.push_back(TexHandle);
2707 Ops.push_back(N->getOperand(2));
2708 Ops.push_back(N->getOperand(3));
2709 Ops.push_back(Chain);
2710 break;
2711 case NVPTXISD::Suld1DArrayV2I8Trap:
2712 Opc = NVPTX::SULD_1D_ARRAY_V2I8_TRAP;
2713 Ops.push_back(TexHandle);
2714 Ops.push_back(N->getOperand(2));
2715 Ops.push_back(N->getOperand(3));
2716 Ops.push_back(Chain);
2717 break;
2718 case NVPTXISD::Suld1DArrayV2I16Trap:
2719 Opc = NVPTX::SULD_1D_ARRAY_V2I16_TRAP;
2720 Ops.push_back(TexHandle);
2721 Ops.push_back(N->getOperand(2));
2722 Ops.push_back(N->getOperand(3));
2723 Ops.push_back(Chain);
2724 break;
2725 case NVPTXISD::Suld1DArrayV2I32Trap:
2726 Opc = NVPTX::SULD_1D_ARRAY_V2I32_TRAP;
2727 Ops.push_back(TexHandle);
2728 Ops.push_back(N->getOperand(2));
2729 Ops.push_back(N->getOperand(3));
2730 Ops.push_back(Chain);
2731 break;
2732 case NVPTXISD::Suld1DArrayV4I8Trap:
2733 Opc = NVPTX::SULD_1D_ARRAY_V4I8_TRAP;
2734 Ops.push_back(TexHandle);
2735 Ops.push_back(N->getOperand(2));
2736 Ops.push_back(N->getOperand(3));
2737 Ops.push_back(Chain);
2738 break;
2739 case NVPTXISD::Suld1DArrayV4I16Trap:
2740 Opc = NVPTX::SULD_1D_ARRAY_V4I16_TRAP;
2741 Ops.push_back(TexHandle);
2742 Ops.push_back(N->getOperand(2));
2743 Ops.push_back(N->getOperand(3));
2744 Ops.push_back(Chain);
2745 break;
2746 case NVPTXISD::Suld1DArrayV4I32Trap:
2747 Opc = NVPTX::SULD_1D_ARRAY_V4I32_TRAP;
2748 Ops.push_back(TexHandle);
2749 Ops.push_back(N->getOperand(2));
2750 Ops.push_back(N->getOperand(3));
2751 Ops.push_back(Chain);
2752 break;
2753 case NVPTXISD::Suld2DI8Trap:
2754 Opc = NVPTX::SULD_2D_I8_TRAP;
2755 Ops.push_back(TexHandle);
2756 Ops.push_back(N->getOperand(2));
2757 Ops.push_back(N->getOperand(3));
2758 Ops.push_back(Chain);
2759 break;
2760 case NVPTXISD::Suld2DI16Trap:
2761 Opc = NVPTX::SULD_2D_I16_TRAP;
2762 Ops.push_back(TexHandle);
2763 Ops.push_back(N->getOperand(2));
2764 Ops.push_back(N->getOperand(3));
2765 Ops.push_back(Chain);
2766 break;
2767 case NVPTXISD::Suld2DI32Trap:
2768 Opc = NVPTX::SULD_2D_I32_TRAP;
2769 Ops.push_back(TexHandle);
2770 Ops.push_back(N->getOperand(2));
2771 Ops.push_back(N->getOperand(3));
2772 Ops.push_back(Chain);
2773 break;
2774 case NVPTXISD::Suld2DV2I8Trap:
2775 Opc = NVPTX::SULD_2D_V2I8_TRAP;
2776 Ops.push_back(TexHandle);
2777 Ops.push_back(N->getOperand(2));
2778 Ops.push_back(N->getOperand(3));
2779 Ops.push_back(Chain);
2780 break;
2781 case NVPTXISD::Suld2DV2I16Trap:
2782 Opc = NVPTX::SULD_2D_V2I16_TRAP;
2783 Ops.push_back(TexHandle);
2784 Ops.push_back(N->getOperand(2));
2785 Ops.push_back(N->getOperand(3));
2786 Ops.push_back(Chain);
2787 break;
2788 case NVPTXISD::Suld2DV2I32Trap:
2789 Opc = NVPTX::SULD_2D_V2I32_TRAP;
2790 Ops.push_back(TexHandle);
2791 Ops.push_back(N->getOperand(2));
2792 Ops.push_back(N->getOperand(3));
2793 Ops.push_back(Chain);
2794 break;
2795 case NVPTXISD::Suld2DV4I8Trap:
2796 Opc = NVPTX::SULD_2D_V4I8_TRAP;
2797 Ops.push_back(TexHandle);
2798 Ops.push_back(N->getOperand(2));
2799 Ops.push_back(N->getOperand(3));
2800 Ops.push_back(Chain);
2801 break;
2802 case NVPTXISD::Suld2DV4I16Trap:
2803 Opc = NVPTX::SULD_2D_V4I16_TRAP;
2804 Ops.push_back(TexHandle);
2805 Ops.push_back(N->getOperand(2));
2806 Ops.push_back(N->getOperand(3));
2807 Ops.push_back(Chain);
2808 break;
2809 case NVPTXISD::Suld2DV4I32Trap:
2810 Opc = NVPTX::SULD_2D_V4I32_TRAP;
2811 Ops.push_back(TexHandle);
2812 Ops.push_back(N->getOperand(2));
2813 Ops.push_back(N->getOperand(3));
2814 Ops.push_back(Chain);
2815 break;
2816 case NVPTXISD::Suld2DArrayI8Trap:
2817 Opc = NVPTX::SULD_2D_ARRAY_I8_TRAP;
2818 Ops.push_back(TexHandle);
2819 Ops.push_back(N->getOperand(2));
2820 Ops.push_back(N->getOperand(3));
2821 Ops.push_back(N->getOperand(4));
2822 Ops.push_back(Chain);
2823 break;
2824 case NVPTXISD::Suld2DArrayI16Trap:
2825 Opc = NVPTX::SULD_2D_ARRAY_I16_TRAP;
2826 Ops.push_back(TexHandle);
2827 Ops.push_back(N->getOperand(2));
2828 Ops.push_back(N->getOperand(3));
2829 Ops.push_back(N->getOperand(4));
2830 Ops.push_back(Chain);
2831 break;
2832 case NVPTXISD::Suld2DArrayI32Trap:
2833 Opc = NVPTX::SULD_2D_ARRAY_I32_TRAP;
2834 Ops.push_back(TexHandle);
2835 Ops.push_back(N->getOperand(2));
2836 Ops.push_back(N->getOperand(3));
2837 Ops.push_back(N->getOperand(4));
2838 Ops.push_back(Chain);
2839 break;
2840 case NVPTXISD::Suld2DArrayV2I8Trap:
2841 Opc = NVPTX::SULD_2D_ARRAY_V2I8_TRAP;
2842 Ops.push_back(TexHandle);
2843 Ops.push_back(N->getOperand(2));
2844 Ops.push_back(N->getOperand(3));
2845 Ops.push_back(N->getOperand(4));
2846 Ops.push_back(Chain);
2847 break;
2848 case NVPTXISD::Suld2DArrayV2I16Trap:
2849 Opc = NVPTX::SULD_2D_ARRAY_V2I16_TRAP;
2850 Ops.push_back(TexHandle);
2851 Ops.push_back(N->getOperand(2));
2852 Ops.push_back(N->getOperand(3));
2853 Ops.push_back(N->getOperand(4));
2854 Ops.push_back(Chain);
2855 break;
2856 case NVPTXISD::Suld2DArrayV2I32Trap:
2857 Opc = NVPTX::SULD_2D_ARRAY_V2I32_TRAP;
2858 Ops.push_back(TexHandle);
2859 Ops.push_back(N->getOperand(2));
2860 Ops.push_back(N->getOperand(3));
2861 Ops.push_back(N->getOperand(4));
2862 Ops.push_back(Chain);
2863 break;
2864 case NVPTXISD::Suld2DArrayV4I8Trap:
2865 Opc = NVPTX::SULD_2D_ARRAY_V4I8_TRAP;
2866 Ops.push_back(TexHandle);
2867 Ops.push_back(N->getOperand(2));
2868 Ops.push_back(N->getOperand(3));
2869 Ops.push_back(N->getOperand(4));
2870 Ops.push_back(Chain);
2871 break;
2872 case NVPTXISD::Suld2DArrayV4I16Trap:
2873 Opc = NVPTX::SULD_2D_ARRAY_V4I16_TRAP;
2874 Ops.push_back(TexHandle);
2875 Ops.push_back(N->getOperand(2));
2876 Ops.push_back(N->getOperand(3));
2877 Ops.push_back(N->getOperand(4));
2878 Ops.push_back(Chain);
2879 break;
2880 case NVPTXISD::Suld2DArrayV4I32Trap:
2881 Opc = NVPTX::SULD_2D_ARRAY_V4I32_TRAP;
2882 Ops.push_back(TexHandle);
2883 Ops.push_back(N->getOperand(2));
2884 Ops.push_back(N->getOperand(3));
2885 Ops.push_back(N->getOperand(4));
2886 Ops.push_back(Chain);
2887 break;
2888 case NVPTXISD::Suld3DI8Trap:
2889 Opc = NVPTX::SULD_3D_I8_TRAP;
2890 Ops.push_back(TexHandle);
2891 Ops.push_back(N->getOperand(2));
2892 Ops.push_back(N->getOperand(3));
2893 Ops.push_back(N->getOperand(4));
2894 Ops.push_back(Chain);
2895 break;
2896 case NVPTXISD::Suld3DI16Trap:
2897 Opc = NVPTX::SULD_3D_I16_TRAP;
2898 Ops.push_back(TexHandle);
2899 Ops.push_back(N->getOperand(2));
2900 Ops.push_back(N->getOperand(3));
2901 Ops.push_back(N->getOperand(4));
2902 Ops.push_back(Chain);
2903 break;
2904 case NVPTXISD::Suld3DI32Trap:
2905 Opc = NVPTX::SULD_3D_I32_TRAP;
2906 Ops.push_back(TexHandle);
2907 Ops.push_back(N->getOperand(2));
2908 Ops.push_back(N->getOperand(3));
2909 Ops.push_back(N->getOperand(4));
2910 Ops.push_back(Chain);
2911 break;
2912 case NVPTXISD::Suld3DV2I8Trap:
2913 Opc = NVPTX::SULD_3D_V2I8_TRAP;
2914 Ops.push_back(TexHandle);
2915 Ops.push_back(N->getOperand(2));
2916 Ops.push_back(N->getOperand(3));
2917 Ops.push_back(N->getOperand(4));
2918 Ops.push_back(Chain);
2919 break;
2920 case NVPTXISD::Suld3DV2I16Trap:
2921 Opc = NVPTX::SULD_3D_V2I16_TRAP;
2922 Ops.push_back(TexHandle);
2923 Ops.push_back(N->getOperand(2));
2924 Ops.push_back(N->getOperand(3));
2925 Ops.push_back(N->getOperand(4));
2926 Ops.push_back(Chain);
2927 break;
2928 case NVPTXISD::Suld3DV2I32Trap:
2929 Opc = NVPTX::SULD_3D_V2I32_TRAP;
2930 Ops.push_back(TexHandle);
2931 Ops.push_back(N->getOperand(2));
2932 Ops.push_back(N->getOperand(3));
2933 Ops.push_back(N->getOperand(4));
2934 Ops.push_back(Chain);
2935 break;
2936 case NVPTXISD::Suld3DV4I8Trap:
2937 Opc = NVPTX::SULD_3D_V4I8_TRAP;
2938 Ops.push_back(TexHandle);
2939 Ops.push_back(N->getOperand(2));
2940 Ops.push_back(N->getOperand(3));
2941 Ops.push_back(N->getOperand(4));
2942 Ops.push_back(Chain);
2943 break;
2944 case NVPTXISD::Suld3DV4I16Trap:
2945 Opc = NVPTX::SULD_3D_V4I16_TRAP;
2946 Ops.push_back(TexHandle);
2947 Ops.push_back(N->getOperand(2));
2948 Ops.push_back(N->getOperand(3));
2949 Ops.push_back(N->getOperand(4));
2950 Ops.push_back(Chain);
2951 break;
2952 case NVPTXISD::Suld3DV4I32Trap:
2953 Opc = NVPTX::SULD_3D_V4I32_TRAP;
2954 Ops.push_back(TexHandle);
2955 Ops.push_back(N->getOperand(2));
2956 Ops.push_back(N->getOperand(3));
2957 Ops.push_back(N->getOperand(4));
2958 Ops.push_back(Chain);
2959 break;
2960 }
2961 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2962 return Ret;
2963}
2964
Justin Holewinskiae556d32012-05-04 20:18:50 +00002965// SelectDirectAddr - Match a direct address for DAG.
2966// A direct address could be a globaladdress or externalsymbol.
2967bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2968 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002969 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2970 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002971 Address = N;
2972 return true;
2973 }
2974 if (N.getOpcode() == NVPTXISD::Wrapper) {
2975 Address = N.getOperand(0);
2976 return true;
2977 }
2978 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2979 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2980 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2981 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2982 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2983 }
2984 return false;
2985}
2986
2987// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002988bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2989 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002990 if (Addr.getOpcode() == ISD::ADD) {
2991 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002992 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002993 if (SelectDirectAddr(base, Base)) {
2994 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2995 return true;
2996 }
2997 }
2998 }
2999 return false;
3000}
3001
3002// symbol+offset
3003bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
3004 SDValue &Base, SDValue &Offset) {
3005 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
3006}
3007
3008// symbol+offset
3009bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
3010 SDValue &Base, SDValue &Offset) {
3011 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
3012}
3013
3014// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003015bool NVPTXDAGToDAGISel::SelectADDRri_imp(
3016 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003017 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
3018 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3019 Offset = CurDAG->getTargetConstant(0, mvt);
3020 return true;
3021 }
3022 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
3023 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00003024 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00003025
3026 if (Addr.getOpcode() == ISD::ADD) {
3027 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
3028 return false;
3029 }
3030 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
3031 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00003032 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00003033 // Constant offset from frame ref.
3034 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3035 else
3036 Base = Addr.getOperand(0);
3037 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3038 return true;
3039 }
3040 }
3041 return false;
3042}
3043
3044// register+offset
3045bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
3046 SDValue &Base, SDValue &Offset) {
3047 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
3048}
3049
3050// register+offset
3051bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
3052 SDValue &Base, SDValue &Offset) {
3053 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
3054}
3055
3056bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
3057 unsigned int spN) const {
Craig Topper062a2ba2014-04-25 05:30:21 +00003058 const Value *Src = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00003059 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
3060 // the classof() for MemSDNode does not include MemIntrinsicSDNode
3061 // (See SelectionDAGNodes.h). So we need to check for both.
3062 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003063 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3064 return true;
3065 Src = mN->getMemOperand()->getValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00003066 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003067 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3068 return true;
3069 Src = mN->getMemOperand()->getValue();
Justin Holewinskiae556d32012-05-04 20:18:50 +00003070 }
3071 if (!Src)
3072 return false;
3073 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
3074 return (PT->getAddressSpace() == spN);
3075 return false;
3076}
3077
3078/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3079/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003080bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
3081 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003082 SDValue Op0, Op1;
3083 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003084 default:
3085 return true;
3086 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00003087 if (SelectDirectAddr(Op, Op0)) {
3088 OutOps.push_back(Op0);
3089 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
3090 return false;
3091 }
3092 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
3093 OutOps.push_back(Op0);
3094 OutOps.push_back(Op1);
3095 return false;
3096 }
3097 break;
3098 }
3099 return true;
3100}