blob: 9fd4bb1c699ef797d6d73f9378cddf34a1d28374 [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
23#undef DEBUG_TYPE
24#define DEBUG_TYPE "nvptx-isel"
25
26using namespace llvm;
27
Justin Holewinskiae556d32012-05-04 20:18:50 +000028static cl::opt<int>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000029FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskiae556d32012-05-04 20:18:50 +000030 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
Justin Holewinski0497ab12013-03-30 14:29:21 +000031 " 1: do it 2: do it aggressively"),
32 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000033
Justin Holewinski0497ab12013-03-30 14:29:21 +000034static cl::opt<int> UsePrecDivF32(
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000035 "nvptx-prec-divf32", cl::ZeroOrMore, cl::Hidden,
Justin Holewinski0497ab12013-03-30 14:29:21 +000036 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
37 " IEEE Compliant F32 div.rnd if avaiable."),
38 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000039
Justin Holewinski48f4ad32013-05-21 16:51:30 +000040static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000041UsePrecSqrtF32("nvptx-prec-sqrtf32", cl::Hidden,
Justin Holewinski48f4ad32013-05-21 16:51:30 +000042 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
43 cl::init(true));
44
Justin Holewinskicd069e62013-07-22 12:18:04 +000045static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000046FtzEnabled("nvptx-f32ftz", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskicd069e62013-07-22 12:18:04 +000047 cl::desc("NVPTX Specific: Flush f32 subnormals to sign-preserving zero."),
48 cl::init(false));
49
50
Justin Holewinskiae556d32012-05-04 20:18:50 +000051/// createNVPTXISelDag - This pass converts a legalized DAG into a
52/// NVPTX-specific DAG, ready for instruction scheduling.
53FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
54 llvm::CodeGenOpt::Level OptLevel) {
55 return new NVPTXDAGToDAGISel(TM, OptLevel);
56}
57
Justin Holewinskiae556d32012-05-04 20:18:50 +000058NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
59 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000060 : SelectionDAGISel(tm, OptLevel),
61 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000062
Justin Holewinski0497ab12013-03-30 14:29:21 +000063 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
64 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
65 doFMAF32AGG =
66 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
67 doFMAF64AGG =
68 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000069
Justin Holewinskicd069e62013-07-22 12:18:04 +000070 allowFMA = (FMAContractLevel >= 1);
Benjamin Kramera25a61b2012-05-05 11:22:02 +000071
Justin Holewinskiae556d32012-05-04 20:18:50 +000072 doMulWide = (OptLevel > 0);
Justin Holewinskicd069e62013-07-22 12:18:04 +000073}
Justin Holewinskiae556d32012-05-04 20:18:50 +000074
Justin Holewinskicd069e62013-07-22 12:18:04 +000075int NVPTXDAGToDAGISel::getDivF32Level() const {
76 if (UsePrecDivF32.getNumOccurrences() > 0) {
77 // If nvptx-prec-div32=N is used on the command-line, always honor it
78 return UsePrecDivF32;
79 } else {
80 // Otherwise, use div.approx if fast math is enabled
81 if (TM.Options.UnsafeFPMath)
82 return 0;
83 else
84 return 2;
85 }
86}
Justin Holewinskiae556d32012-05-04 20:18:50 +000087
Justin Holewinskicd069e62013-07-22 12:18:04 +000088bool NVPTXDAGToDAGISel::usePrecSqrtF32() const {
89 if (UsePrecSqrtF32.getNumOccurrences() > 0) {
90 // If nvptx-prec-sqrtf32 is used on the command-line, always honor it
91 return UsePrecSqrtF32;
92 } else {
93 // Otherwise, use sqrt.approx if fast math is enabled
94 if (TM.Options.UnsafeFPMath)
95 return false;
96 else
97 return true;
98 }
99}
100
101bool NVPTXDAGToDAGISel::useF32FTZ() const {
102 if (FtzEnabled.getNumOccurrences() > 0) {
103 // If nvptx-f32ftz is used on the command-line, always honor it
104 return FtzEnabled;
105 } else {
106 const Function *F = MF->getFunction();
107 // Otherwise, check for an nvptx-f32ftz attribute on the function
108 if (F->hasFnAttribute("nvptx-f32ftz"))
109 return (F->getAttributes().getAttribute(AttributeSet::FunctionIndex,
110 "nvptx-f32ftz")
111 .getValueAsString() == "true");
112 else
113 return false;
114 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000115}
116
117/// Select - Select instructions not customized! Used for
118/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +0000119SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000120
Tim Northover31d093c2013-09-22 08:21:56 +0000121 if (N->isMachineOpcode()) {
122 N->setNodeId(-1);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000123 return NULL; // Already selected.
Tim Northover31d093c2013-09-22 08:21:56 +0000124 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000125
126 SDNode *ResNode = NULL;
127 switch (N->getOpcode()) {
128 case ISD::LOAD:
129 ResNode = SelectLoad(N);
130 break;
131 case ISD::STORE:
132 ResNode = SelectStore(N);
133 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000134 case NVPTXISD::LoadV2:
135 case NVPTXISD::LoadV4:
136 ResNode = SelectLoadVector(N);
137 break;
138 case NVPTXISD::LDGV2:
139 case NVPTXISD::LDGV4:
140 case NVPTXISD::LDUV2:
141 case NVPTXISD::LDUV4:
142 ResNode = SelectLDGLDUVector(N);
143 break;
144 case NVPTXISD::StoreV2:
145 case NVPTXISD::StoreV4:
146 ResNode = SelectStoreVector(N);
147 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000148 case NVPTXISD::LoadParam:
149 case NVPTXISD::LoadParamV2:
150 case NVPTXISD::LoadParamV4:
151 ResNode = SelectLoadParam(N);
152 break;
153 case NVPTXISD::StoreRetval:
154 case NVPTXISD::StoreRetvalV2:
155 case NVPTXISD::StoreRetvalV4:
156 ResNode = SelectStoreRetval(N);
157 break;
158 case NVPTXISD::StoreParam:
159 case NVPTXISD::StoreParamV2:
160 case NVPTXISD::StoreParamV4:
161 case NVPTXISD::StoreParamS32:
162 case NVPTXISD::StoreParamU32:
163 ResNode = SelectStoreParam(N);
164 break;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000165 case ISD::INTRINSIC_WO_CHAIN:
166 ResNode = SelectIntrinsicNoChain(N);
167 break;
168 case NVPTXISD::Tex1DFloatI32:
169 case NVPTXISD::Tex1DFloatFloat:
170 case NVPTXISD::Tex1DFloatFloatLevel:
171 case NVPTXISD::Tex1DFloatFloatGrad:
172 case NVPTXISD::Tex1DI32I32:
173 case NVPTXISD::Tex1DI32Float:
174 case NVPTXISD::Tex1DI32FloatLevel:
175 case NVPTXISD::Tex1DI32FloatGrad:
176 case NVPTXISD::Tex1DArrayFloatI32:
177 case NVPTXISD::Tex1DArrayFloatFloat:
178 case NVPTXISD::Tex1DArrayFloatFloatLevel:
179 case NVPTXISD::Tex1DArrayFloatFloatGrad:
180 case NVPTXISD::Tex1DArrayI32I32:
181 case NVPTXISD::Tex1DArrayI32Float:
182 case NVPTXISD::Tex1DArrayI32FloatLevel:
183 case NVPTXISD::Tex1DArrayI32FloatGrad:
184 case NVPTXISD::Tex2DFloatI32:
185 case NVPTXISD::Tex2DFloatFloat:
186 case NVPTXISD::Tex2DFloatFloatLevel:
187 case NVPTXISD::Tex2DFloatFloatGrad:
188 case NVPTXISD::Tex2DI32I32:
189 case NVPTXISD::Tex2DI32Float:
190 case NVPTXISD::Tex2DI32FloatLevel:
191 case NVPTXISD::Tex2DI32FloatGrad:
192 case NVPTXISD::Tex2DArrayFloatI32:
193 case NVPTXISD::Tex2DArrayFloatFloat:
194 case NVPTXISD::Tex2DArrayFloatFloatLevel:
195 case NVPTXISD::Tex2DArrayFloatFloatGrad:
196 case NVPTXISD::Tex2DArrayI32I32:
197 case NVPTXISD::Tex2DArrayI32Float:
198 case NVPTXISD::Tex2DArrayI32FloatLevel:
199 case NVPTXISD::Tex2DArrayI32FloatGrad:
200 case NVPTXISD::Tex3DFloatI32:
201 case NVPTXISD::Tex3DFloatFloat:
202 case NVPTXISD::Tex3DFloatFloatLevel:
203 case NVPTXISD::Tex3DFloatFloatGrad:
204 case NVPTXISD::Tex3DI32I32:
205 case NVPTXISD::Tex3DI32Float:
206 case NVPTXISD::Tex3DI32FloatLevel:
207 case NVPTXISD::Tex3DI32FloatGrad:
208 ResNode = SelectTextureIntrinsic(N);
209 break;
210 case NVPTXISD::Suld1DI8Trap:
211 case NVPTXISD::Suld1DI16Trap:
212 case NVPTXISD::Suld1DI32Trap:
213 case NVPTXISD::Suld1DV2I8Trap:
214 case NVPTXISD::Suld1DV2I16Trap:
215 case NVPTXISD::Suld1DV2I32Trap:
216 case NVPTXISD::Suld1DV4I8Trap:
217 case NVPTXISD::Suld1DV4I16Trap:
218 case NVPTXISD::Suld1DV4I32Trap:
219 case NVPTXISD::Suld1DArrayI8Trap:
220 case NVPTXISD::Suld1DArrayI16Trap:
221 case NVPTXISD::Suld1DArrayI32Trap:
222 case NVPTXISD::Suld1DArrayV2I8Trap:
223 case NVPTXISD::Suld1DArrayV2I16Trap:
224 case NVPTXISD::Suld1DArrayV2I32Trap:
225 case NVPTXISD::Suld1DArrayV4I8Trap:
226 case NVPTXISD::Suld1DArrayV4I16Trap:
227 case NVPTXISD::Suld1DArrayV4I32Trap:
228 case NVPTXISD::Suld2DI8Trap:
229 case NVPTXISD::Suld2DI16Trap:
230 case NVPTXISD::Suld2DI32Trap:
231 case NVPTXISD::Suld2DV2I8Trap:
232 case NVPTXISD::Suld2DV2I16Trap:
233 case NVPTXISD::Suld2DV2I32Trap:
234 case NVPTXISD::Suld2DV4I8Trap:
235 case NVPTXISD::Suld2DV4I16Trap:
236 case NVPTXISD::Suld2DV4I32Trap:
237 case NVPTXISD::Suld2DArrayI8Trap:
238 case NVPTXISD::Suld2DArrayI16Trap:
239 case NVPTXISD::Suld2DArrayI32Trap:
240 case NVPTXISD::Suld2DArrayV2I8Trap:
241 case NVPTXISD::Suld2DArrayV2I16Trap:
242 case NVPTXISD::Suld2DArrayV2I32Trap:
243 case NVPTXISD::Suld2DArrayV4I8Trap:
244 case NVPTXISD::Suld2DArrayV4I16Trap:
245 case NVPTXISD::Suld2DArrayV4I32Trap:
246 case NVPTXISD::Suld3DI8Trap:
247 case NVPTXISD::Suld3DI16Trap:
248 case NVPTXISD::Suld3DI32Trap:
249 case NVPTXISD::Suld3DV2I8Trap:
250 case NVPTXISD::Suld3DV2I16Trap:
251 case NVPTXISD::Suld3DV2I32Trap:
252 case NVPTXISD::Suld3DV4I8Trap:
253 case NVPTXISD::Suld3DV4I16Trap:
254 case NVPTXISD::Suld3DV4I32Trap:
255 ResNode = SelectSurfaceIntrinsic(N);
256 break;
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000257 case ISD::ADDRSPACECAST:
258 ResNode = SelectAddrSpaceCast(N);
259 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000260 default:
261 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000262 }
263 if (ResNode)
264 return ResNode;
265 return SelectCode(N);
266}
267
Justin Holewinski0497ab12013-03-30 14:29:21 +0000268static unsigned int getCodeAddrSpace(MemSDNode *N,
269 const NVPTXSubtarget &Subtarget) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000270 const Value *Src = N->getSrcValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000271
Justin Holewinskiae556d32012-05-04 20:18:50 +0000272 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000273 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000274
275 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
276 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000277 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
278 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
279 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
280 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
281 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
282 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
283 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000284 }
285 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000286 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000287}
288
Justin Holewinski30d56a72014-04-09 15:39:15 +0000289SDNode *NVPTXDAGToDAGISel::SelectIntrinsicNoChain(SDNode *N) {
290 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
291 switch (IID) {
292 default:
293 return NULL;
294 case Intrinsic::nvvm_texsurf_handle_internal:
295 return SelectTexSurfHandle(N);
296 }
297}
298
299SDNode *NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
300 // Op 0 is the intrinsic ID
301 SDValue Wrapper = N->getOperand(1);
302 SDValue GlobalVal = Wrapper.getOperand(0);
303 return CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N), MVT::i64,
304 GlobalVal);
305}
306
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000307SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
308 SDValue Src = N->getOperand(0);
309 AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
310 unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
311 unsigned DstAddrSpace = CastN->getDestAddressSpace();
312
313 assert(SrcAddrSpace != DstAddrSpace &&
314 "addrspacecast must be between different address spaces");
315
316 if (DstAddrSpace == ADDRESS_SPACE_GENERIC) {
317 // Specific to generic
318 unsigned Opc;
319 switch (SrcAddrSpace) {
320 default: report_fatal_error("Bad address space in addrspacecast");
321 case ADDRESS_SPACE_GLOBAL:
322 Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64
323 : NVPTX::cvta_global_yes;
324 break;
325 case ADDRESS_SPACE_SHARED:
326 Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64
327 : NVPTX::cvta_shared_yes;
328 break;
329 case ADDRESS_SPACE_CONST:
330 Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64
331 : NVPTX::cvta_const_yes;
332 break;
333 case ADDRESS_SPACE_LOCAL:
334 Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64
335 : NVPTX::cvta_local_yes;
336 break;
337 }
338 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
339 } else {
340 // Generic to specific
341 if (SrcAddrSpace != 0)
342 report_fatal_error("Cannot cast between two non-generic address spaces");
343 unsigned Opc;
344 switch (DstAddrSpace) {
345 default: report_fatal_error("Bad address space in addrspacecast");
346 case ADDRESS_SPACE_GLOBAL:
347 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64
348 : NVPTX::cvta_to_global_yes;
349 break;
350 case ADDRESS_SPACE_SHARED:
351 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64
352 : NVPTX::cvta_to_shared_yes;
353 break;
354 case ADDRESS_SPACE_CONST:
355 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64
356 : NVPTX::cvta_to_const_yes;
357 break;
358 case ADDRESS_SPACE_LOCAL:
359 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64
360 : NVPTX::cvta_to_local_yes;
361 break;
362 }
363 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
364 }
365}
366
Justin Holewinski0497ab12013-03-30 14:29:21 +0000367SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000368 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000369 LoadSDNode *LD = cast<LoadSDNode>(N);
370 EVT LoadedVT = LD->getMemoryVT();
Justin Holewinski0497ab12013-03-30 14:29:21 +0000371 SDNode *NVPTXLD = NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000372
373 // do not support pre/post inc/dec
374 if (LD->isIndexed())
375 return NULL;
376
377 if (!LoadedVT.isSimple())
378 return NULL;
379
380 // Address Space Setting
381 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
382
383 // Volatile Setting
384 // - .volatile is only availalble for .global and .shared
385 bool isVolatile = LD->isVolatile();
386 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
387 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
388 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
389 isVolatile = false;
390
391 // Vector Setting
392 MVT SimpleVT = LoadedVT.getSimpleVT();
393 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
394 if (SimpleVT.isVector()) {
395 unsigned num = SimpleVT.getVectorNumElements();
396 if (num == 2)
397 vecType = NVPTX::PTXLdStInstCode::V2;
398 else if (num == 4)
399 vecType = NVPTX::PTXLdStInstCode::V4;
400 else
401 return NULL;
402 }
403
404 // Type Setting: fromType + fromTypeWidth
405 //
406 // Sign : ISD::SEXTLOAD
407 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
408 // type is integer
409 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
410 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000411 // Read at least 8 bits (predicates are stored as 8-bit values)
412 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000413 unsigned int fromType;
414 if ((LD->getExtensionType() == ISD::SEXTLOAD))
415 fromType = NVPTX::PTXLdStInstCode::Signed;
416 else if (ScalarVT.isFloatingPoint())
417 fromType = NVPTX::PTXLdStInstCode::Float;
418 else
419 fromType = NVPTX::PTXLdStInstCode::Unsigned;
420
421 // Create the machine instruction DAG
422 SDValue Chain = N->getOperand(0);
423 SDValue N1 = N->getOperand(1);
424 SDValue Addr;
425 SDValue Offset, Base;
426 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000427 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000428
429 if (SelectDirectAddr(N1, Addr)) {
430 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000431 case MVT::i8:
432 Opcode = NVPTX::LD_i8_avar;
433 break;
434 case MVT::i16:
435 Opcode = NVPTX::LD_i16_avar;
436 break;
437 case MVT::i32:
438 Opcode = NVPTX::LD_i32_avar;
439 break;
440 case MVT::i64:
441 Opcode = NVPTX::LD_i64_avar;
442 break;
443 case MVT::f32:
444 Opcode = NVPTX::LD_f32_avar;
445 break;
446 case MVT::f64:
447 Opcode = NVPTX::LD_f64_avar;
448 break;
449 default:
450 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000451 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000452 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
453 getI32Imm(vecType), getI32Imm(fromType),
454 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000455 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000456 } else if (Subtarget.is64Bit()
457 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
458 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000459 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000460 case MVT::i8:
461 Opcode = NVPTX::LD_i8_asi;
462 break;
463 case MVT::i16:
464 Opcode = NVPTX::LD_i16_asi;
465 break;
466 case MVT::i32:
467 Opcode = NVPTX::LD_i32_asi;
468 break;
469 case MVT::i64:
470 Opcode = NVPTX::LD_i64_asi;
471 break;
472 case MVT::f32:
473 Opcode = NVPTX::LD_f32_asi;
474 break;
475 case MVT::f64:
476 Opcode = NVPTX::LD_f64_asi;
477 break;
478 default:
479 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000480 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000481 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
482 getI32Imm(vecType), getI32Imm(fromType),
483 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000484 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000485 } else if (Subtarget.is64Bit()
486 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
487 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000488 if (Subtarget.is64Bit()) {
489 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000490 case MVT::i8:
491 Opcode = NVPTX::LD_i8_ari_64;
492 break;
493 case MVT::i16:
494 Opcode = NVPTX::LD_i16_ari_64;
495 break;
496 case MVT::i32:
497 Opcode = NVPTX::LD_i32_ari_64;
498 break;
499 case MVT::i64:
500 Opcode = NVPTX::LD_i64_ari_64;
501 break;
502 case MVT::f32:
503 Opcode = NVPTX::LD_f32_ari_64;
504 break;
505 case MVT::f64:
506 Opcode = NVPTX::LD_f64_ari_64;
507 break;
508 default:
509 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000510 }
511 } else {
512 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000513 case MVT::i8:
514 Opcode = NVPTX::LD_i8_ari;
515 break;
516 case MVT::i16:
517 Opcode = NVPTX::LD_i16_ari;
518 break;
519 case MVT::i32:
520 Opcode = NVPTX::LD_i32_ari;
521 break;
522 case MVT::i64:
523 Opcode = NVPTX::LD_i64_ari;
524 break;
525 case MVT::f32:
526 Opcode = NVPTX::LD_f32_ari;
527 break;
528 case MVT::f64:
529 Opcode = NVPTX::LD_f64_ari;
530 break;
531 default:
532 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000533 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000534 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000535 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
536 getI32Imm(vecType), getI32Imm(fromType),
537 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000538 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000539 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000540 if (Subtarget.is64Bit()) {
541 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000542 case MVT::i8:
543 Opcode = NVPTX::LD_i8_areg_64;
544 break;
545 case MVT::i16:
546 Opcode = NVPTX::LD_i16_areg_64;
547 break;
548 case MVT::i32:
549 Opcode = NVPTX::LD_i32_areg_64;
550 break;
551 case MVT::i64:
552 Opcode = NVPTX::LD_i64_areg_64;
553 break;
554 case MVT::f32:
555 Opcode = NVPTX::LD_f32_areg_64;
556 break;
557 case MVT::f64:
558 Opcode = NVPTX::LD_f64_areg_64;
559 break;
560 default:
561 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000562 }
563 } else {
564 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000565 case MVT::i8:
566 Opcode = NVPTX::LD_i8_areg;
567 break;
568 case MVT::i16:
569 Opcode = NVPTX::LD_i16_areg;
570 break;
571 case MVT::i32:
572 Opcode = NVPTX::LD_i32_areg;
573 break;
574 case MVT::i64:
575 Opcode = NVPTX::LD_i64_areg;
576 break;
577 case MVT::f32:
578 Opcode = NVPTX::LD_f32_areg;
579 break;
580 case MVT::f64:
581 Opcode = NVPTX::LD_f64_areg;
582 break;
583 default:
584 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000585 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000586 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000587 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
588 getI32Imm(vecType), getI32Imm(fromType),
589 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000590 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000591 }
592
593 if (NVPTXLD != NULL) {
594 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
595 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
596 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
597 }
598
599 return NVPTXLD;
600}
601
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000602SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
603
604 SDValue Chain = N->getOperand(0);
605 SDValue Op1 = N->getOperand(1);
606 SDValue Addr, Offset, Base;
607 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000608 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000609 SDNode *LD;
610 MemSDNode *MemSD = cast<MemSDNode>(N);
611 EVT LoadedVT = MemSD->getMemoryVT();
612
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000613 if (!LoadedVT.isSimple())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000614 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000615
616 // Address Space Setting
617 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
618
619 // Volatile Setting
620 // - .volatile is only availalble for .global and .shared
621 bool IsVolatile = MemSD->isVolatile();
622 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
623 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
624 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
625 IsVolatile = false;
626
627 // Vector Setting
628 MVT SimpleVT = LoadedVT.getSimpleVT();
629
630 // Type Setting: fromType + fromTypeWidth
631 //
632 // Sign : ISD::SEXTLOAD
633 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
634 // type is integer
635 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
636 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000637 // Read at least 8 bits (predicates are stored as 8-bit values)
638 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000639 unsigned int FromType;
640 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000641 unsigned ExtensionType = cast<ConstantSDNode>(
642 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000643 if (ExtensionType == ISD::SEXTLOAD)
644 FromType = NVPTX::PTXLdStInstCode::Signed;
645 else if (ScalarVT.isFloatingPoint())
646 FromType = NVPTX::PTXLdStInstCode::Float;
647 else
648 FromType = NVPTX::PTXLdStInstCode::Unsigned;
649
650 unsigned VecType;
651
652 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000653 case NVPTXISD::LoadV2:
654 VecType = NVPTX::PTXLdStInstCode::V2;
655 break;
656 case NVPTXISD::LoadV4:
657 VecType = NVPTX::PTXLdStInstCode::V4;
658 break;
659 default:
660 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000661 }
662
663 EVT EltVT = N->getValueType(0);
664
665 if (SelectDirectAddr(Op1, Addr)) {
666 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000667 default:
668 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000669 case NVPTXISD::LoadV2:
670 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000671 default:
672 return NULL;
673 case MVT::i8:
674 Opcode = NVPTX::LDV_i8_v2_avar;
675 break;
676 case MVT::i16:
677 Opcode = NVPTX::LDV_i16_v2_avar;
678 break;
679 case MVT::i32:
680 Opcode = NVPTX::LDV_i32_v2_avar;
681 break;
682 case MVT::i64:
683 Opcode = NVPTX::LDV_i64_v2_avar;
684 break;
685 case MVT::f32:
686 Opcode = NVPTX::LDV_f32_v2_avar;
687 break;
688 case MVT::f64:
689 Opcode = NVPTX::LDV_f64_v2_avar;
690 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000691 }
692 break;
693 case NVPTXISD::LoadV4:
694 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000695 default:
696 return NULL;
697 case MVT::i8:
698 Opcode = NVPTX::LDV_i8_v4_avar;
699 break;
700 case MVT::i16:
701 Opcode = NVPTX::LDV_i16_v4_avar;
702 break;
703 case MVT::i32:
704 Opcode = NVPTX::LDV_i32_v4_avar;
705 break;
706 case MVT::f32:
707 Opcode = NVPTX::LDV_f32_v4_avar;
708 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000709 }
710 break;
711 }
712
Justin Holewinski0497ab12013-03-30 14:29:21 +0000713 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
714 getI32Imm(VecType), getI32Imm(FromType),
715 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000716 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000717 } else if (Subtarget.is64Bit()
718 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
719 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000720 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000721 default:
722 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000723 case NVPTXISD::LoadV2:
724 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000725 default:
726 return NULL;
727 case MVT::i8:
728 Opcode = NVPTX::LDV_i8_v2_asi;
729 break;
730 case MVT::i16:
731 Opcode = NVPTX::LDV_i16_v2_asi;
732 break;
733 case MVT::i32:
734 Opcode = NVPTX::LDV_i32_v2_asi;
735 break;
736 case MVT::i64:
737 Opcode = NVPTX::LDV_i64_v2_asi;
738 break;
739 case MVT::f32:
740 Opcode = NVPTX::LDV_f32_v2_asi;
741 break;
742 case MVT::f64:
743 Opcode = NVPTX::LDV_f64_v2_asi;
744 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000745 }
746 break;
747 case NVPTXISD::LoadV4:
748 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000749 default:
750 return NULL;
751 case MVT::i8:
752 Opcode = NVPTX::LDV_i8_v4_asi;
753 break;
754 case MVT::i16:
755 Opcode = NVPTX::LDV_i16_v4_asi;
756 break;
757 case MVT::i32:
758 Opcode = NVPTX::LDV_i32_v4_asi;
759 break;
760 case MVT::f32:
761 Opcode = NVPTX::LDV_f32_v4_asi;
762 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000763 }
764 break;
765 }
766
Justin Holewinski0497ab12013-03-30 14:29:21 +0000767 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
768 getI32Imm(VecType), getI32Imm(FromType),
769 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000770 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000771 } else if (Subtarget.is64Bit()
772 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
773 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000774 if (Subtarget.is64Bit()) {
775 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000776 default:
777 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000778 case NVPTXISD::LoadV2:
779 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000780 default:
781 return NULL;
782 case MVT::i8:
783 Opcode = NVPTX::LDV_i8_v2_ari_64;
784 break;
785 case MVT::i16:
786 Opcode = NVPTX::LDV_i16_v2_ari_64;
787 break;
788 case MVT::i32:
789 Opcode = NVPTX::LDV_i32_v2_ari_64;
790 break;
791 case MVT::i64:
792 Opcode = NVPTX::LDV_i64_v2_ari_64;
793 break;
794 case MVT::f32:
795 Opcode = NVPTX::LDV_f32_v2_ari_64;
796 break;
797 case MVT::f64:
798 Opcode = NVPTX::LDV_f64_v2_ari_64;
799 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000800 }
801 break;
802 case NVPTXISD::LoadV4:
803 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000804 default:
805 return NULL;
806 case MVT::i8:
807 Opcode = NVPTX::LDV_i8_v4_ari_64;
808 break;
809 case MVT::i16:
810 Opcode = NVPTX::LDV_i16_v4_ari_64;
811 break;
812 case MVT::i32:
813 Opcode = NVPTX::LDV_i32_v4_ari_64;
814 break;
815 case MVT::f32:
816 Opcode = NVPTX::LDV_f32_v4_ari_64;
817 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000818 }
819 break;
820 }
821 } else {
822 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000823 default:
824 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000825 case NVPTXISD::LoadV2:
826 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000827 default:
828 return NULL;
829 case MVT::i8:
830 Opcode = NVPTX::LDV_i8_v2_ari;
831 break;
832 case MVT::i16:
833 Opcode = NVPTX::LDV_i16_v2_ari;
834 break;
835 case MVT::i32:
836 Opcode = NVPTX::LDV_i32_v2_ari;
837 break;
838 case MVT::i64:
839 Opcode = NVPTX::LDV_i64_v2_ari;
840 break;
841 case MVT::f32:
842 Opcode = NVPTX::LDV_f32_v2_ari;
843 break;
844 case MVT::f64:
845 Opcode = NVPTX::LDV_f64_v2_ari;
846 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000847 }
848 break;
849 case NVPTXISD::LoadV4:
850 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000851 default:
852 return NULL;
853 case MVT::i8:
854 Opcode = NVPTX::LDV_i8_v4_ari;
855 break;
856 case MVT::i16:
857 Opcode = NVPTX::LDV_i16_v4_ari;
858 break;
859 case MVT::i32:
860 Opcode = NVPTX::LDV_i32_v4_ari;
861 break;
862 case MVT::f32:
863 Opcode = NVPTX::LDV_f32_v4_ari;
864 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000865 }
866 break;
867 }
868 }
869
Justin Holewinski0497ab12013-03-30 14:29:21 +0000870 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
871 getI32Imm(VecType), getI32Imm(FromType),
872 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000873
Michael Liaob53d8962013-04-19 22:22:57 +0000874 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000875 } else {
876 if (Subtarget.is64Bit()) {
877 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000878 default:
879 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000880 case NVPTXISD::LoadV2:
881 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000882 default:
883 return NULL;
884 case MVT::i8:
885 Opcode = NVPTX::LDV_i8_v2_areg_64;
886 break;
887 case MVT::i16:
888 Opcode = NVPTX::LDV_i16_v2_areg_64;
889 break;
890 case MVT::i32:
891 Opcode = NVPTX::LDV_i32_v2_areg_64;
892 break;
893 case MVT::i64:
894 Opcode = NVPTX::LDV_i64_v2_areg_64;
895 break;
896 case MVT::f32:
897 Opcode = NVPTX::LDV_f32_v2_areg_64;
898 break;
899 case MVT::f64:
900 Opcode = NVPTX::LDV_f64_v2_areg_64;
901 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000902 }
903 break;
904 case NVPTXISD::LoadV4:
905 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000906 default:
907 return NULL;
908 case MVT::i8:
909 Opcode = NVPTX::LDV_i8_v4_areg_64;
910 break;
911 case MVT::i16:
912 Opcode = NVPTX::LDV_i16_v4_areg_64;
913 break;
914 case MVT::i32:
915 Opcode = NVPTX::LDV_i32_v4_areg_64;
916 break;
917 case MVT::f32:
918 Opcode = NVPTX::LDV_f32_v4_areg_64;
919 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000920 }
921 break;
922 }
923 } else {
924 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000925 default:
926 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000927 case NVPTXISD::LoadV2:
928 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000929 default:
930 return NULL;
931 case MVT::i8:
932 Opcode = NVPTX::LDV_i8_v2_areg;
933 break;
934 case MVT::i16:
935 Opcode = NVPTX::LDV_i16_v2_areg;
936 break;
937 case MVT::i32:
938 Opcode = NVPTX::LDV_i32_v2_areg;
939 break;
940 case MVT::i64:
941 Opcode = NVPTX::LDV_i64_v2_areg;
942 break;
943 case MVT::f32:
944 Opcode = NVPTX::LDV_f32_v2_areg;
945 break;
946 case MVT::f64:
947 Opcode = NVPTX::LDV_f64_v2_areg;
948 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000949 }
950 break;
951 case NVPTXISD::LoadV4:
952 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000953 default:
954 return NULL;
955 case MVT::i8:
956 Opcode = NVPTX::LDV_i8_v4_areg;
957 break;
958 case MVT::i16:
959 Opcode = NVPTX::LDV_i16_v4_areg;
960 break;
961 case MVT::i32:
962 Opcode = NVPTX::LDV_i32_v4_areg;
963 break;
964 case MVT::f32:
965 Opcode = NVPTX::LDV_f32_v4_areg;
966 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000967 }
968 break;
969 }
970 }
971
Justin Holewinski0497ab12013-03-30 14:29:21 +0000972 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
973 getI32Imm(VecType), getI32Imm(FromType),
974 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000975 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000976 }
977
978 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
979 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
980 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
981
982 return LD;
983}
984
985SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
986
987 SDValue Chain = N->getOperand(0);
988 SDValue Op1 = N->getOperand(1);
989 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000990 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000991 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000992 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000993 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000994
Justin Holewinskie40e9292013-07-01 12:58:52 +0000995 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000996
Justin Holewinskie40e9292013-07-01 12:58:52 +0000997 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000998 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000999 default:
1000 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001001 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001002 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001003 default:
1004 return NULL;
1005 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001006 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001007 break;
1008 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001009 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001010 break;
1011 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001012 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001013 break;
1014 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001015 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001016 break;
1017 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001018 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001019 break;
1020 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001021 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001022 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001023 }
1024 break;
1025 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001026 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001027 default:
1028 return NULL;
1029 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001030 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001031 break;
1032 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001033 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001034 break;
1035 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001036 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001037 break;
1038 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001039 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001040 break;
1041 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001042 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001043 break;
1044 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001045 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
1046 break;
1047 }
1048 break;
1049 case NVPTXISD::LDGV4:
1050 switch (EltVT.getSimpleVT().SimpleTy) {
1051 default:
1052 return NULL;
1053 case MVT::i8:
1054 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
1055 break;
1056 case MVT::i16:
1057 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
1058 break;
1059 case MVT::i32:
1060 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
1061 break;
1062 case MVT::f32:
1063 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001064 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001065 }
1066 break;
1067 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001068 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001069 default:
1070 return NULL;
1071 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001072 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001073 break;
1074 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001075 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001076 break;
1077 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001078 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001079 break;
1080 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001081 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001082 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001083 }
1084 break;
1085 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001086
1087 SDValue Ops[] = { Addr, Chain };
1088 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1089 ArrayRef<SDValue>(Ops, 2));
1090 } else if (Subtarget.is64Bit()
1091 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
1092 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
1093 if (Subtarget.is64Bit()) {
1094 switch (N->getOpcode()) {
1095 default:
1096 return NULL;
1097 case NVPTXISD::LDGV2:
1098 switch (EltVT.getSimpleVT().SimpleTy) {
1099 default:
1100 return NULL;
1101 case MVT::i8:
1102 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
1103 break;
1104 case MVT::i16:
1105 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
1106 break;
1107 case MVT::i32:
1108 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
1109 break;
1110 case MVT::i64:
1111 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
1112 break;
1113 case MVT::f32:
1114 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
1115 break;
1116 case MVT::f64:
1117 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
1118 break;
1119 }
1120 break;
1121 case NVPTXISD::LDUV2:
1122 switch (EltVT.getSimpleVT().SimpleTy) {
1123 default:
1124 return NULL;
1125 case MVT::i8:
1126 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
1127 break;
1128 case MVT::i16:
1129 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
1130 break;
1131 case MVT::i32:
1132 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
1133 break;
1134 case MVT::i64:
1135 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
1136 break;
1137 case MVT::f32:
1138 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
1139 break;
1140 case MVT::f64:
1141 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
1142 break;
1143 }
1144 break;
1145 case NVPTXISD::LDGV4:
1146 switch (EltVT.getSimpleVT().SimpleTy) {
1147 default:
1148 return NULL;
1149 case MVT::i8:
1150 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
1151 break;
1152 case MVT::i16:
1153 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
1154 break;
1155 case MVT::i32:
1156 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
1157 break;
1158 case MVT::f32:
1159 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
1160 break;
1161 }
1162 break;
1163 case NVPTXISD::LDUV4:
1164 switch (EltVT.getSimpleVT().SimpleTy) {
1165 default:
1166 return NULL;
1167 case MVT::i8:
1168 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
1169 break;
1170 case MVT::i16:
1171 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
1172 break;
1173 case MVT::i32:
1174 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1175 break;
1176 case MVT::f32:
1177 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1178 break;
1179 }
1180 break;
1181 }
1182 } else {
1183 switch (N->getOpcode()) {
1184 default:
1185 return NULL;
1186 case NVPTXISD::LDGV2:
1187 switch (EltVT.getSimpleVT().SimpleTy) {
1188 default:
1189 return NULL;
1190 case MVT::i8:
1191 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1192 break;
1193 case MVT::i16:
1194 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1195 break;
1196 case MVT::i32:
1197 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1198 break;
1199 case MVT::i64:
1200 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1201 break;
1202 case MVT::f32:
1203 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1204 break;
1205 case MVT::f64:
1206 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1207 break;
1208 }
1209 break;
1210 case NVPTXISD::LDUV2:
1211 switch (EltVT.getSimpleVT().SimpleTy) {
1212 default:
1213 return NULL;
1214 case MVT::i8:
1215 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1216 break;
1217 case MVT::i16:
1218 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1219 break;
1220 case MVT::i32:
1221 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1222 break;
1223 case MVT::i64:
1224 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1225 break;
1226 case MVT::f32:
1227 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1228 break;
1229 case MVT::f64:
1230 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1231 break;
1232 }
1233 break;
1234 case NVPTXISD::LDGV4:
1235 switch (EltVT.getSimpleVT().SimpleTy) {
1236 default:
1237 return NULL;
1238 case MVT::i8:
1239 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1240 break;
1241 case MVT::i16:
1242 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1243 break;
1244 case MVT::i32:
1245 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1246 break;
1247 case MVT::f32:
1248 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1249 break;
1250 }
1251 break;
1252 case NVPTXISD::LDUV4:
1253 switch (EltVT.getSimpleVT().SimpleTy) {
1254 default:
1255 return NULL;
1256 case MVT::i8:
1257 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1258 break;
1259 case MVT::i16:
1260 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1261 break;
1262 case MVT::i32:
1263 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1264 break;
1265 case MVT::f32:
1266 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1267 break;
1268 }
1269 break;
1270 }
1271 }
1272
1273 SDValue Ops[] = { Base, Offset, Chain };
1274
1275 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1276 ArrayRef<SDValue>(Ops, 3));
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001277 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001278 if (Subtarget.is64Bit()) {
1279 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001280 default:
1281 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001282 case NVPTXISD::LDGV2:
1283 switch (EltVT.getSimpleVT().SimpleTy) {
1284 default:
1285 return NULL;
1286 case MVT::i8:
1287 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1288 break;
1289 case MVT::i16:
1290 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1291 break;
1292 case MVT::i32:
1293 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1294 break;
1295 case MVT::i64:
1296 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1297 break;
1298 case MVT::f32:
1299 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1300 break;
1301 case MVT::f64:
1302 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1303 break;
1304 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001305 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001306 case NVPTXISD::LDUV2:
1307 switch (EltVT.getSimpleVT().SimpleTy) {
1308 default:
1309 return NULL;
1310 case MVT::i8:
1311 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1312 break;
1313 case MVT::i16:
1314 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1315 break;
1316 case MVT::i32:
1317 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1318 break;
1319 case MVT::i64:
1320 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1321 break;
1322 case MVT::f32:
1323 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1324 break;
1325 case MVT::f64:
1326 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1327 break;
1328 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001329 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001330 case NVPTXISD::LDGV4:
1331 switch (EltVT.getSimpleVT().SimpleTy) {
1332 default:
1333 return NULL;
1334 case MVT::i8:
1335 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1336 break;
1337 case MVT::i16:
1338 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1339 break;
1340 case MVT::i32:
1341 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1342 break;
1343 case MVT::f32:
1344 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1345 break;
1346 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001347 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001348 case NVPTXISD::LDUV4:
1349 switch (EltVT.getSimpleVT().SimpleTy) {
1350 default:
1351 return NULL;
1352 case MVT::i8:
1353 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1354 break;
1355 case MVT::i16:
1356 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1357 break;
1358 case MVT::i32:
1359 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1360 break;
1361 case MVT::f32:
1362 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1363 break;
1364 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001365 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001366 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001367 } else {
1368 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001369 default:
1370 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001371 case NVPTXISD::LDGV2:
1372 switch (EltVT.getSimpleVT().SimpleTy) {
1373 default:
1374 return NULL;
1375 case MVT::i8:
1376 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1377 break;
1378 case MVT::i16:
1379 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1380 break;
1381 case MVT::i32:
1382 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1383 break;
1384 case MVT::i64:
1385 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1386 break;
1387 case MVT::f32:
1388 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1389 break;
1390 case MVT::f64:
1391 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1392 break;
1393 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001394 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001395 case NVPTXISD::LDUV2:
1396 switch (EltVT.getSimpleVT().SimpleTy) {
1397 default:
1398 return NULL;
1399 case MVT::i8:
1400 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1401 break;
1402 case MVT::i16:
1403 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1404 break;
1405 case MVT::i32:
1406 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1407 break;
1408 case MVT::i64:
1409 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1410 break;
1411 case MVT::f32:
1412 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1413 break;
1414 case MVT::f64:
1415 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1416 break;
1417 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001418 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001419 case NVPTXISD::LDGV4:
1420 switch (EltVT.getSimpleVT().SimpleTy) {
1421 default:
1422 return NULL;
1423 case MVT::i8:
1424 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1425 break;
1426 case MVT::i16:
1427 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1428 break;
1429 case MVT::i32:
1430 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1431 break;
1432 case MVT::f32:
1433 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1434 break;
1435 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001436 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001437 case NVPTXISD::LDUV4:
1438 switch (EltVT.getSimpleVT().SimpleTy) {
1439 default:
1440 return NULL;
1441 case MVT::i8:
1442 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1443 break;
1444 case MVT::i16:
1445 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1446 break;
1447 case MVT::i32:
1448 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1449 break;
1450 case MVT::f32:
1451 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1452 break;
1453 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001454 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001455 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001456 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001457
Justin Holewinskie40e9292013-07-01 12:58:52 +00001458 SDValue Ops[] = { Op1, Chain };
1459 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1460 ArrayRef<SDValue>(Ops, 2));
1461 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001462
1463 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1464 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1465 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1466
1467 return LD;
1468}
1469
Justin Holewinski0497ab12013-03-30 14:29:21 +00001470SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001471 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001472 StoreSDNode *ST = cast<StoreSDNode>(N);
1473 EVT StoreVT = ST->getMemoryVT();
1474 SDNode *NVPTXST = NULL;
1475
1476 // do not support pre/post inc/dec
1477 if (ST->isIndexed())
1478 return NULL;
1479
1480 if (!StoreVT.isSimple())
1481 return NULL;
1482
1483 // Address Space Setting
1484 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1485
1486 // Volatile Setting
1487 // - .volatile is only availalble for .global and .shared
1488 bool isVolatile = ST->isVolatile();
1489 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1490 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1491 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1492 isVolatile = false;
1493
1494 // Vector Setting
1495 MVT SimpleVT = StoreVT.getSimpleVT();
1496 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1497 if (SimpleVT.isVector()) {
1498 unsigned num = SimpleVT.getVectorNumElements();
1499 if (num == 2)
1500 vecType = NVPTX::PTXLdStInstCode::V2;
1501 else if (num == 4)
1502 vecType = NVPTX::PTXLdStInstCode::V4;
1503 else
1504 return NULL;
1505 }
1506
1507 // Type Setting: toType + toTypeWidth
1508 // - for integer type, always use 'u'
1509 //
1510 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001511 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001512 unsigned int toType;
1513 if (ScalarVT.isFloatingPoint())
1514 toType = NVPTX::PTXLdStInstCode::Float;
1515 else
1516 toType = NVPTX::PTXLdStInstCode::Unsigned;
1517
1518 // Create the machine instruction DAG
1519 SDValue Chain = N->getOperand(0);
1520 SDValue N1 = N->getOperand(1);
1521 SDValue N2 = N->getOperand(2);
1522 SDValue Addr;
1523 SDValue Offset, Base;
1524 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001525 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001526
1527 if (SelectDirectAddr(N2, Addr)) {
1528 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001529 case MVT::i8:
1530 Opcode = NVPTX::ST_i8_avar;
1531 break;
1532 case MVT::i16:
1533 Opcode = NVPTX::ST_i16_avar;
1534 break;
1535 case MVT::i32:
1536 Opcode = NVPTX::ST_i32_avar;
1537 break;
1538 case MVT::i64:
1539 Opcode = NVPTX::ST_i64_avar;
1540 break;
1541 case MVT::f32:
1542 Opcode = NVPTX::ST_f32_avar;
1543 break;
1544 case MVT::f64:
1545 Opcode = NVPTX::ST_f64_avar;
1546 break;
1547 default:
1548 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001549 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001550 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1551 getI32Imm(vecType), getI32Imm(toType),
1552 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001553 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001554 } else if (Subtarget.is64Bit()
1555 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1556 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001557 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001558 case MVT::i8:
1559 Opcode = NVPTX::ST_i8_asi;
1560 break;
1561 case MVT::i16:
1562 Opcode = NVPTX::ST_i16_asi;
1563 break;
1564 case MVT::i32:
1565 Opcode = NVPTX::ST_i32_asi;
1566 break;
1567 case MVT::i64:
1568 Opcode = NVPTX::ST_i64_asi;
1569 break;
1570 case MVT::f32:
1571 Opcode = NVPTX::ST_f32_asi;
1572 break;
1573 case MVT::f64:
1574 Opcode = NVPTX::ST_f64_asi;
1575 break;
1576 default:
1577 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001578 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001579 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1580 getI32Imm(vecType), getI32Imm(toType),
1581 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001582 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001583 } else if (Subtarget.is64Bit()
1584 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1585 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001586 if (Subtarget.is64Bit()) {
1587 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001588 case MVT::i8:
1589 Opcode = NVPTX::ST_i8_ari_64;
1590 break;
1591 case MVT::i16:
1592 Opcode = NVPTX::ST_i16_ari_64;
1593 break;
1594 case MVT::i32:
1595 Opcode = NVPTX::ST_i32_ari_64;
1596 break;
1597 case MVT::i64:
1598 Opcode = NVPTX::ST_i64_ari_64;
1599 break;
1600 case MVT::f32:
1601 Opcode = NVPTX::ST_f32_ari_64;
1602 break;
1603 case MVT::f64:
1604 Opcode = NVPTX::ST_f64_ari_64;
1605 break;
1606 default:
1607 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001608 }
1609 } else {
1610 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001611 case MVT::i8:
1612 Opcode = NVPTX::ST_i8_ari;
1613 break;
1614 case MVT::i16:
1615 Opcode = NVPTX::ST_i16_ari;
1616 break;
1617 case MVT::i32:
1618 Opcode = NVPTX::ST_i32_ari;
1619 break;
1620 case MVT::i64:
1621 Opcode = NVPTX::ST_i64_ari;
1622 break;
1623 case MVT::f32:
1624 Opcode = NVPTX::ST_f32_ari;
1625 break;
1626 case MVT::f64:
1627 Opcode = NVPTX::ST_f64_ari;
1628 break;
1629 default:
1630 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001631 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001632 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001633 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1634 getI32Imm(vecType), getI32Imm(toType),
1635 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001636 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001637 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001638 if (Subtarget.is64Bit()) {
1639 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001640 case MVT::i8:
1641 Opcode = NVPTX::ST_i8_areg_64;
1642 break;
1643 case MVT::i16:
1644 Opcode = NVPTX::ST_i16_areg_64;
1645 break;
1646 case MVT::i32:
1647 Opcode = NVPTX::ST_i32_areg_64;
1648 break;
1649 case MVT::i64:
1650 Opcode = NVPTX::ST_i64_areg_64;
1651 break;
1652 case MVT::f32:
1653 Opcode = NVPTX::ST_f32_areg_64;
1654 break;
1655 case MVT::f64:
1656 Opcode = NVPTX::ST_f64_areg_64;
1657 break;
1658 default:
1659 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001660 }
1661 } else {
1662 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001663 case MVT::i8:
1664 Opcode = NVPTX::ST_i8_areg;
1665 break;
1666 case MVT::i16:
1667 Opcode = NVPTX::ST_i16_areg;
1668 break;
1669 case MVT::i32:
1670 Opcode = NVPTX::ST_i32_areg;
1671 break;
1672 case MVT::i64:
1673 Opcode = NVPTX::ST_i64_areg;
1674 break;
1675 case MVT::f32:
1676 Opcode = NVPTX::ST_f32_areg;
1677 break;
1678 case MVT::f64:
1679 Opcode = NVPTX::ST_f64_areg;
1680 break;
1681 default:
1682 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001683 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001684 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001685 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1686 getI32Imm(vecType), getI32Imm(toType),
1687 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001688 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001689 }
1690
1691 if (NVPTXST != NULL) {
1692 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1693 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1694 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1695 }
1696
1697 return NVPTXST;
1698}
1699
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001700SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1701 SDValue Chain = N->getOperand(0);
1702 SDValue Op1 = N->getOperand(1);
1703 SDValue Addr, Offset, Base;
1704 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001705 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001706 SDNode *ST;
1707 EVT EltVT = Op1.getValueType();
1708 MemSDNode *MemSD = cast<MemSDNode>(N);
1709 EVT StoreVT = MemSD->getMemoryVT();
1710
1711 // Address Space Setting
1712 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1713
1714 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1715 report_fatal_error("Cannot store to pointer that points to constant "
1716 "memory space");
1717 }
1718
1719 // Volatile Setting
1720 // - .volatile is only availalble for .global and .shared
1721 bool IsVolatile = MemSD->isVolatile();
1722 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1723 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1724 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1725 IsVolatile = false;
1726
1727 // Type Setting: toType + toTypeWidth
1728 // - for integer type, always use 'u'
1729 assert(StoreVT.isSimple() && "Store value is not simple");
1730 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001731 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001732 unsigned ToType;
1733 if (ScalarVT.isFloatingPoint())
1734 ToType = NVPTX::PTXLdStInstCode::Float;
1735 else
1736 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1737
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001738 SmallVector<SDValue, 12> StOps;
1739 SDValue N2;
1740 unsigned VecType;
1741
1742 switch (N->getOpcode()) {
1743 case NVPTXISD::StoreV2:
1744 VecType = NVPTX::PTXLdStInstCode::V2;
1745 StOps.push_back(N->getOperand(1));
1746 StOps.push_back(N->getOperand(2));
1747 N2 = N->getOperand(3);
1748 break;
1749 case NVPTXISD::StoreV4:
1750 VecType = NVPTX::PTXLdStInstCode::V4;
1751 StOps.push_back(N->getOperand(1));
1752 StOps.push_back(N->getOperand(2));
1753 StOps.push_back(N->getOperand(3));
1754 StOps.push_back(N->getOperand(4));
1755 N2 = N->getOperand(5);
1756 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001757 default:
1758 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001759 }
1760
1761 StOps.push_back(getI32Imm(IsVolatile));
1762 StOps.push_back(getI32Imm(CodeAddrSpace));
1763 StOps.push_back(getI32Imm(VecType));
1764 StOps.push_back(getI32Imm(ToType));
1765 StOps.push_back(getI32Imm(ToTypeWidth));
1766
1767 if (SelectDirectAddr(N2, Addr)) {
1768 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001769 default:
1770 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001771 case NVPTXISD::StoreV2:
1772 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001773 default:
1774 return NULL;
1775 case MVT::i8:
1776 Opcode = NVPTX::STV_i8_v2_avar;
1777 break;
1778 case MVT::i16:
1779 Opcode = NVPTX::STV_i16_v2_avar;
1780 break;
1781 case MVT::i32:
1782 Opcode = NVPTX::STV_i32_v2_avar;
1783 break;
1784 case MVT::i64:
1785 Opcode = NVPTX::STV_i64_v2_avar;
1786 break;
1787 case MVT::f32:
1788 Opcode = NVPTX::STV_f32_v2_avar;
1789 break;
1790 case MVT::f64:
1791 Opcode = NVPTX::STV_f64_v2_avar;
1792 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001793 }
1794 break;
1795 case NVPTXISD::StoreV4:
1796 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001797 default:
1798 return NULL;
1799 case MVT::i8:
1800 Opcode = NVPTX::STV_i8_v4_avar;
1801 break;
1802 case MVT::i16:
1803 Opcode = NVPTX::STV_i16_v4_avar;
1804 break;
1805 case MVT::i32:
1806 Opcode = NVPTX::STV_i32_v4_avar;
1807 break;
1808 case MVT::f32:
1809 Opcode = NVPTX::STV_f32_v4_avar;
1810 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001811 }
1812 break;
1813 }
1814 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001815 } else if (Subtarget.is64Bit()
1816 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1817 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001818 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001819 default:
1820 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001821 case NVPTXISD::StoreV2:
1822 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001823 default:
1824 return NULL;
1825 case MVT::i8:
1826 Opcode = NVPTX::STV_i8_v2_asi;
1827 break;
1828 case MVT::i16:
1829 Opcode = NVPTX::STV_i16_v2_asi;
1830 break;
1831 case MVT::i32:
1832 Opcode = NVPTX::STV_i32_v2_asi;
1833 break;
1834 case MVT::i64:
1835 Opcode = NVPTX::STV_i64_v2_asi;
1836 break;
1837 case MVT::f32:
1838 Opcode = NVPTX::STV_f32_v2_asi;
1839 break;
1840 case MVT::f64:
1841 Opcode = NVPTX::STV_f64_v2_asi;
1842 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001843 }
1844 break;
1845 case NVPTXISD::StoreV4:
1846 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001847 default:
1848 return NULL;
1849 case MVT::i8:
1850 Opcode = NVPTX::STV_i8_v4_asi;
1851 break;
1852 case MVT::i16:
1853 Opcode = NVPTX::STV_i16_v4_asi;
1854 break;
1855 case MVT::i32:
1856 Opcode = NVPTX::STV_i32_v4_asi;
1857 break;
1858 case MVT::f32:
1859 Opcode = NVPTX::STV_f32_v4_asi;
1860 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001861 }
1862 break;
1863 }
1864 StOps.push_back(Base);
1865 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001866 } else if (Subtarget.is64Bit()
1867 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1868 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001869 if (Subtarget.is64Bit()) {
1870 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001871 default:
1872 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001873 case NVPTXISD::StoreV2:
1874 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001875 default:
1876 return NULL;
1877 case MVT::i8:
1878 Opcode = NVPTX::STV_i8_v2_ari_64;
1879 break;
1880 case MVT::i16:
1881 Opcode = NVPTX::STV_i16_v2_ari_64;
1882 break;
1883 case MVT::i32:
1884 Opcode = NVPTX::STV_i32_v2_ari_64;
1885 break;
1886 case MVT::i64:
1887 Opcode = NVPTX::STV_i64_v2_ari_64;
1888 break;
1889 case MVT::f32:
1890 Opcode = NVPTX::STV_f32_v2_ari_64;
1891 break;
1892 case MVT::f64:
1893 Opcode = NVPTX::STV_f64_v2_ari_64;
1894 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001895 }
1896 break;
1897 case NVPTXISD::StoreV4:
1898 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001899 default:
1900 return NULL;
1901 case MVT::i8:
1902 Opcode = NVPTX::STV_i8_v4_ari_64;
1903 break;
1904 case MVT::i16:
1905 Opcode = NVPTX::STV_i16_v4_ari_64;
1906 break;
1907 case MVT::i32:
1908 Opcode = NVPTX::STV_i32_v4_ari_64;
1909 break;
1910 case MVT::f32:
1911 Opcode = NVPTX::STV_f32_v4_ari_64;
1912 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001913 }
1914 break;
1915 }
1916 } else {
1917 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001918 default:
1919 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001920 case NVPTXISD::StoreV2:
1921 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001922 default:
1923 return NULL;
1924 case MVT::i8:
1925 Opcode = NVPTX::STV_i8_v2_ari;
1926 break;
1927 case MVT::i16:
1928 Opcode = NVPTX::STV_i16_v2_ari;
1929 break;
1930 case MVT::i32:
1931 Opcode = NVPTX::STV_i32_v2_ari;
1932 break;
1933 case MVT::i64:
1934 Opcode = NVPTX::STV_i64_v2_ari;
1935 break;
1936 case MVT::f32:
1937 Opcode = NVPTX::STV_f32_v2_ari;
1938 break;
1939 case MVT::f64:
1940 Opcode = NVPTX::STV_f64_v2_ari;
1941 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001942 }
1943 break;
1944 case NVPTXISD::StoreV4:
1945 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001946 default:
1947 return NULL;
1948 case MVT::i8:
1949 Opcode = NVPTX::STV_i8_v4_ari;
1950 break;
1951 case MVT::i16:
1952 Opcode = NVPTX::STV_i16_v4_ari;
1953 break;
1954 case MVT::i32:
1955 Opcode = NVPTX::STV_i32_v4_ari;
1956 break;
1957 case MVT::f32:
1958 Opcode = NVPTX::STV_f32_v4_ari;
1959 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001960 }
1961 break;
1962 }
1963 }
1964 StOps.push_back(Base);
1965 StOps.push_back(Offset);
1966 } else {
1967 if (Subtarget.is64Bit()) {
1968 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001969 default:
1970 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001971 case NVPTXISD::StoreV2:
1972 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001973 default:
1974 return NULL;
1975 case MVT::i8:
1976 Opcode = NVPTX::STV_i8_v2_areg_64;
1977 break;
1978 case MVT::i16:
1979 Opcode = NVPTX::STV_i16_v2_areg_64;
1980 break;
1981 case MVT::i32:
1982 Opcode = NVPTX::STV_i32_v2_areg_64;
1983 break;
1984 case MVT::i64:
1985 Opcode = NVPTX::STV_i64_v2_areg_64;
1986 break;
1987 case MVT::f32:
1988 Opcode = NVPTX::STV_f32_v2_areg_64;
1989 break;
1990 case MVT::f64:
1991 Opcode = NVPTX::STV_f64_v2_areg_64;
1992 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001993 }
1994 break;
1995 case NVPTXISD::StoreV4:
1996 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001997 default:
1998 return NULL;
1999 case MVT::i8:
2000 Opcode = NVPTX::STV_i8_v4_areg_64;
2001 break;
2002 case MVT::i16:
2003 Opcode = NVPTX::STV_i16_v4_areg_64;
2004 break;
2005 case MVT::i32:
2006 Opcode = NVPTX::STV_i32_v4_areg_64;
2007 break;
2008 case MVT::f32:
2009 Opcode = NVPTX::STV_f32_v4_areg_64;
2010 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002011 }
2012 break;
2013 }
2014 } else {
2015 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002016 default:
2017 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002018 case NVPTXISD::StoreV2:
2019 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002020 default:
2021 return NULL;
2022 case MVT::i8:
2023 Opcode = NVPTX::STV_i8_v2_areg;
2024 break;
2025 case MVT::i16:
2026 Opcode = NVPTX::STV_i16_v2_areg;
2027 break;
2028 case MVT::i32:
2029 Opcode = NVPTX::STV_i32_v2_areg;
2030 break;
2031 case MVT::i64:
2032 Opcode = NVPTX::STV_i64_v2_areg;
2033 break;
2034 case MVT::f32:
2035 Opcode = NVPTX::STV_f32_v2_areg;
2036 break;
2037 case MVT::f64:
2038 Opcode = NVPTX::STV_f64_v2_areg;
2039 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002040 }
2041 break;
2042 case NVPTXISD::StoreV4:
2043 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002044 default:
2045 return NULL;
2046 case MVT::i8:
2047 Opcode = NVPTX::STV_i8_v4_areg;
2048 break;
2049 case MVT::i16:
2050 Opcode = NVPTX::STV_i16_v4_areg;
2051 break;
2052 case MVT::i32:
2053 Opcode = NVPTX::STV_i32_v4_areg;
2054 break;
2055 case MVT::f32:
2056 Opcode = NVPTX::STV_f32_v4_areg;
2057 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002058 }
2059 break;
2060 }
2061 }
2062 StOps.push_back(N2);
2063 }
2064
2065 StOps.push_back(Chain);
2066
Michael Liaob53d8962013-04-19 22:22:57 +00002067 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002068
2069 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2070 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2071 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
2072
2073 return ST;
2074}
2075
Justin Holewinskif8f70912013-06-28 17:57:59 +00002076SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
2077 SDValue Chain = Node->getOperand(0);
2078 SDValue Offset = Node->getOperand(2);
2079 SDValue Flag = Node->getOperand(3);
2080 SDLoc DL(Node);
2081 MemSDNode *Mem = cast<MemSDNode>(Node);
2082
2083 unsigned VecSize;
2084 switch (Node->getOpcode()) {
2085 default:
2086 return NULL;
2087 case NVPTXISD::LoadParam:
2088 VecSize = 1;
2089 break;
2090 case NVPTXISD::LoadParamV2:
2091 VecSize = 2;
2092 break;
2093 case NVPTXISD::LoadParamV4:
2094 VecSize = 4;
2095 break;
2096 }
2097
2098 EVT EltVT = Node->getValueType(0);
2099 EVT MemVT = Mem->getMemoryVT();
2100
2101 unsigned Opc = 0;
2102
2103 switch (VecSize) {
2104 default:
2105 return NULL;
2106 case 1:
2107 switch (MemVT.getSimpleVT().SimpleTy) {
2108 default:
2109 return NULL;
2110 case MVT::i1:
2111 Opc = NVPTX::LoadParamMemI8;
2112 break;
2113 case MVT::i8:
2114 Opc = NVPTX::LoadParamMemI8;
2115 break;
2116 case MVT::i16:
2117 Opc = NVPTX::LoadParamMemI16;
2118 break;
2119 case MVT::i32:
2120 Opc = NVPTX::LoadParamMemI32;
2121 break;
2122 case MVT::i64:
2123 Opc = NVPTX::LoadParamMemI64;
2124 break;
2125 case MVT::f32:
2126 Opc = NVPTX::LoadParamMemF32;
2127 break;
2128 case MVT::f64:
2129 Opc = NVPTX::LoadParamMemF64;
2130 break;
2131 }
2132 break;
2133 case 2:
2134 switch (MemVT.getSimpleVT().SimpleTy) {
2135 default:
2136 return NULL;
2137 case MVT::i1:
2138 Opc = NVPTX::LoadParamMemV2I8;
2139 break;
2140 case MVT::i8:
2141 Opc = NVPTX::LoadParamMemV2I8;
2142 break;
2143 case MVT::i16:
2144 Opc = NVPTX::LoadParamMemV2I16;
2145 break;
2146 case MVT::i32:
2147 Opc = NVPTX::LoadParamMemV2I32;
2148 break;
2149 case MVT::i64:
2150 Opc = NVPTX::LoadParamMemV2I64;
2151 break;
2152 case MVT::f32:
2153 Opc = NVPTX::LoadParamMemV2F32;
2154 break;
2155 case MVT::f64:
2156 Opc = NVPTX::LoadParamMemV2F64;
2157 break;
2158 }
2159 break;
2160 case 4:
2161 switch (MemVT.getSimpleVT().SimpleTy) {
2162 default:
2163 return NULL;
2164 case MVT::i1:
2165 Opc = NVPTX::LoadParamMemV4I8;
2166 break;
2167 case MVT::i8:
2168 Opc = NVPTX::LoadParamMemV4I8;
2169 break;
2170 case MVT::i16:
2171 Opc = NVPTX::LoadParamMemV4I16;
2172 break;
2173 case MVT::i32:
2174 Opc = NVPTX::LoadParamMemV4I32;
2175 break;
2176 case MVT::f32:
2177 Opc = NVPTX::LoadParamMemV4F32;
2178 break;
2179 }
2180 break;
2181 }
2182
2183 SDVTList VTs;
2184 if (VecSize == 1) {
2185 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2186 } else if (VecSize == 2) {
2187 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2188 } else {
2189 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
Justin Holewinski44597172013-12-05 12:58:00 +00002190 VTs = CurDAG->getVTList(&EVTs[0], array_lengthof(EVTs));
Justin Holewinskif8f70912013-06-28 17:57:59 +00002191 }
2192
2193 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2194
2195 SmallVector<SDValue, 2> Ops;
2196 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2197 Ops.push_back(Chain);
2198 Ops.push_back(Flag);
2199
2200 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002201 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002202 return Ret;
2203}
2204
2205SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2206 SDLoc DL(N);
2207 SDValue Chain = N->getOperand(0);
2208 SDValue Offset = N->getOperand(1);
2209 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2210 MemSDNode *Mem = cast<MemSDNode>(N);
2211
2212 // How many elements do we have?
2213 unsigned NumElts = 1;
2214 switch (N->getOpcode()) {
2215 default:
2216 return NULL;
2217 case NVPTXISD::StoreRetval:
2218 NumElts = 1;
2219 break;
2220 case NVPTXISD::StoreRetvalV2:
2221 NumElts = 2;
2222 break;
2223 case NVPTXISD::StoreRetvalV4:
2224 NumElts = 4;
2225 break;
2226 }
2227
2228 // Build vector of operands
2229 SmallVector<SDValue, 6> Ops;
2230 for (unsigned i = 0; i < NumElts; ++i)
2231 Ops.push_back(N->getOperand(i + 2));
2232 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2233 Ops.push_back(Chain);
2234
2235 // Determine target opcode
2236 // If we have an i1, use an 8-bit store. The lowering code in
2237 // NVPTXISelLowering will have already emitted an upcast.
2238 unsigned Opcode = 0;
2239 switch (NumElts) {
2240 default:
2241 return NULL;
2242 case 1:
2243 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2244 default:
2245 return NULL;
2246 case MVT::i1:
2247 Opcode = NVPTX::StoreRetvalI8;
2248 break;
2249 case MVT::i8:
2250 Opcode = NVPTX::StoreRetvalI8;
2251 break;
2252 case MVT::i16:
2253 Opcode = NVPTX::StoreRetvalI16;
2254 break;
2255 case MVT::i32:
2256 Opcode = NVPTX::StoreRetvalI32;
2257 break;
2258 case MVT::i64:
2259 Opcode = NVPTX::StoreRetvalI64;
2260 break;
2261 case MVT::f32:
2262 Opcode = NVPTX::StoreRetvalF32;
2263 break;
2264 case MVT::f64:
2265 Opcode = NVPTX::StoreRetvalF64;
2266 break;
2267 }
2268 break;
2269 case 2:
2270 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2271 default:
2272 return NULL;
2273 case MVT::i1:
2274 Opcode = NVPTX::StoreRetvalV2I8;
2275 break;
2276 case MVT::i8:
2277 Opcode = NVPTX::StoreRetvalV2I8;
2278 break;
2279 case MVT::i16:
2280 Opcode = NVPTX::StoreRetvalV2I16;
2281 break;
2282 case MVT::i32:
2283 Opcode = NVPTX::StoreRetvalV2I32;
2284 break;
2285 case MVT::i64:
2286 Opcode = NVPTX::StoreRetvalV2I64;
2287 break;
2288 case MVT::f32:
2289 Opcode = NVPTX::StoreRetvalV2F32;
2290 break;
2291 case MVT::f64:
2292 Opcode = NVPTX::StoreRetvalV2F64;
2293 break;
2294 }
2295 break;
2296 case 4:
2297 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2298 default:
2299 return NULL;
2300 case MVT::i1:
2301 Opcode = NVPTX::StoreRetvalV4I8;
2302 break;
2303 case MVT::i8:
2304 Opcode = NVPTX::StoreRetvalV4I8;
2305 break;
2306 case MVT::i16:
2307 Opcode = NVPTX::StoreRetvalV4I16;
2308 break;
2309 case MVT::i32:
2310 Opcode = NVPTX::StoreRetvalV4I32;
2311 break;
2312 case MVT::f32:
2313 Opcode = NVPTX::StoreRetvalV4F32;
2314 break;
2315 }
2316 break;
2317 }
2318
2319 SDNode *Ret =
2320 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2321 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2322 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2323 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2324
2325 return Ret;
2326}
2327
2328SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2329 SDLoc DL(N);
2330 SDValue Chain = N->getOperand(0);
2331 SDValue Param = N->getOperand(1);
2332 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2333 SDValue Offset = N->getOperand(2);
2334 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2335 MemSDNode *Mem = cast<MemSDNode>(N);
2336 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2337
2338 // How many elements do we have?
2339 unsigned NumElts = 1;
2340 switch (N->getOpcode()) {
2341 default:
2342 return NULL;
2343 case NVPTXISD::StoreParamU32:
2344 case NVPTXISD::StoreParamS32:
2345 case NVPTXISD::StoreParam:
2346 NumElts = 1;
2347 break;
2348 case NVPTXISD::StoreParamV2:
2349 NumElts = 2;
2350 break;
2351 case NVPTXISD::StoreParamV4:
2352 NumElts = 4;
2353 break;
2354 }
2355
2356 // Build vector of operands
2357 SmallVector<SDValue, 8> Ops;
2358 for (unsigned i = 0; i < NumElts; ++i)
2359 Ops.push_back(N->getOperand(i + 3));
2360 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2361 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2362 Ops.push_back(Chain);
2363 Ops.push_back(Flag);
2364
2365 // Determine target opcode
2366 // If we have an i1, use an 8-bit store. The lowering code in
2367 // NVPTXISelLowering will have already emitted an upcast.
2368 unsigned Opcode = 0;
2369 switch (N->getOpcode()) {
2370 default:
2371 switch (NumElts) {
2372 default:
2373 return NULL;
2374 case 1:
2375 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2376 default:
2377 return NULL;
2378 case MVT::i1:
2379 Opcode = NVPTX::StoreParamI8;
2380 break;
2381 case MVT::i8:
2382 Opcode = NVPTX::StoreParamI8;
2383 break;
2384 case MVT::i16:
2385 Opcode = NVPTX::StoreParamI16;
2386 break;
2387 case MVT::i32:
2388 Opcode = NVPTX::StoreParamI32;
2389 break;
2390 case MVT::i64:
2391 Opcode = NVPTX::StoreParamI64;
2392 break;
2393 case MVT::f32:
2394 Opcode = NVPTX::StoreParamF32;
2395 break;
2396 case MVT::f64:
2397 Opcode = NVPTX::StoreParamF64;
2398 break;
2399 }
2400 break;
2401 case 2:
2402 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2403 default:
2404 return NULL;
2405 case MVT::i1:
2406 Opcode = NVPTX::StoreParamV2I8;
2407 break;
2408 case MVT::i8:
2409 Opcode = NVPTX::StoreParamV2I8;
2410 break;
2411 case MVT::i16:
2412 Opcode = NVPTX::StoreParamV2I16;
2413 break;
2414 case MVT::i32:
2415 Opcode = NVPTX::StoreParamV2I32;
2416 break;
2417 case MVT::i64:
2418 Opcode = NVPTX::StoreParamV2I64;
2419 break;
2420 case MVT::f32:
2421 Opcode = NVPTX::StoreParamV2F32;
2422 break;
2423 case MVT::f64:
2424 Opcode = NVPTX::StoreParamV2F64;
2425 break;
2426 }
2427 break;
2428 case 4:
2429 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2430 default:
2431 return NULL;
2432 case MVT::i1:
2433 Opcode = NVPTX::StoreParamV4I8;
2434 break;
2435 case MVT::i8:
2436 Opcode = NVPTX::StoreParamV4I8;
2437 break;
2438 case MVT::i16:
2439 Opcode = NVPTX::StoreParamV4I16;
2440 break;
2441 case MVT::i32:
2442 Opcode = NVPTX::StoreParamV4I32;
2443 break;
2444 case MVT::f32:
2445 Opcode = NVPTX::StoreParamV4F32;
2446 break;
2447 }
2448 break;
2449 }
2450 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002451 // Special case: if we have a sign-extend/zero-extend node, insert the
2452 // conversion instruction first, and use that as the value operand to
2453 // the selected StoreParam node.
2454 case NVPTXISD::StoreParamU32: {
2455 Opcode = NVPTX::StoreParamI32;
2456 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2457 MVT::i32);
2458 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2459 MVT::i32, Ops[0], CvtNone);
2460 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002461 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002462 }
2463 case NVPTXISD::StoreParamS32: {
2464 Opcode = NVPTX::StoreParamI32;
2465 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2466 MVT::i32);
2467 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2468 MVT::i32, Ops[0], CvtNone);
2469 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002470 break;
2471 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002472 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002473
Justin Holewinskidff28d22013-07-01 12:59:01 +00002474 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002475 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002476 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002477 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2478 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2479 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2480
2481 return Ret;
2482}
2483
Justin Holewinski30d56a72014-04-09 15:39:15 +00002484SDNode *NVPTXDAGToDAGISel::SelectTextureIntrinsic(SDNode *N) {
2485 SDValue Chain = N->getOperand(0);
2486 SDValue TexRef = N->getOperand(1);
2487 SDValue SampRef = N->getOperand(2);
2488 SDNode *Ret = NULL;
2489 unsigned Opc = 0;
2490 SmallVector<SDValue, 8> Ops;
2491
2492 switch (N->getOpcode()) {
2493 default: return NULL;
2494 case NVPTXISD::Tex1DFloatI32:
2495 Opc = NVPTX::TEX_1D_F32_I32;
2496 break;
2497 case NVPTXISD::Tex1DFloatFloat:
2498 Opc = NVPTX::TEX_1D_F32_F32;
2499 break;
2500 case NVPTXISD::Tex1DFloatFloatLevel:
2501 Opc = NVPTX::TEX_1D_F32_F32_LEVEL;
2502 break;
2503 case NVPTXISD::Tex1DFloatFloatGrad:
2504 Opc = NVPTX::TEX_1D_F32_F32_GRAD;
2505 break;
2506 case NVPTXISD::Tex1DI32I32:
2507 Opc = NVPTX::TEX_1D_I32_I32;
2508 break;
2509 case NVPTXISD::Tex1DI32Float:
2510 Opc = NVPTX::TEX_1D_I32_F32;
2511 break;
2512 case NVPTXISD::Tex1DI32FloatLevel:
2513 Opc = NVPTX::TEX_1D_I32_F32_LEVEL;
2514 break;
2515 case NVPTXISD::Tex1DI32FloatGrad:
2516 Opc = NVPTX::TEX_1D_I32_F32_GRAD;
2517 break;
2518 case NVPTXISD::Tex1DArrayFloatI32:
2519 Opc = NVPTX::TEX_1D_ARRAY_F32_I32;
2520 break;
2521 case NVPTXISD::Tex1DArrayFloatFloat:
2522 Opc = NVPTX::TEX_1D_ARRAY_F32_F32;
2523 break;
2524 case NVPTXISD::Tex1DArrayFloatFloatLevel:
2525 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_LEVEL;
2526 break;
2527 case NVPTXISD::Tex1DArrayFloatFloatGrad:
2528 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_GRAD;
2529 break;
2530 case NVPTXISD::Tex1DArrayI32I32:
2531 Opc = NVPTX::TEX_1D_ARRAY_I32_I32;
2532 break;
2533 case NVPTXISD::Tex1DArrayI32Float:
2534 Opc = NVPTX::TEX_1D_ARRAY_I32_F32;
2535 break;
2536 case NVPTXISD::Tex1DArrayI32FloatLevel:
2537 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_LEVEL;
2538 break;
2539 case NVPTXISD::Tex1DArrayI32FloatGrad:
2540 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_GRAD;
2541 break;
2542 case NVPTXISD::Tex2DFloatI32:
2543 Opc = NVPTX::TEX_2D_F32_I32;
2544 break;
2545 case NVPTXISD::Tex2DFloatFloat:
2546 Opc = NVPTX::TEX_2D_F32_F32;
2547 break;
2548 case NVPTXISD::Tex2DFloatFloatLevel:
2549 Opc = NVPTX::TEX_2D_F32_F32_LEVEL;
2550 break;
2551 case NVPTXISD::Tex2DFloatFloatGrad:
2552 Opc = NVPTX::TEX_2D_F32_F32_GRAD;
2553 break;
2554 case NVPTXISD::Tex2DI32I32:
2555 Opc = NVPTX::TEX_2D_I32_I32;
2556 break;
2557 case NVPTXISD::Tex2DI32Float:
2558 Opc = NVPTX::TEX_2D_I32_F32;
2559 break;
2560 case NVPTXISD::Tex2DI32FloatLevel:
2561 Opc = NVPTX::TEX_2D_I32_F32_LEVEL;
2562 break;
2563 case NVPTXISD::Tex2DI32FloatGrad:
2564 Opc = NVPTX::TEX_2D_I32_F32_GRAD;
2565 break;
2566 case NVPTXISD::Tex2DArrayFloatI32:
2567 Opc = NVPTX::TEX_2D_ARRAY_F32_I32;
2568 break;
2569 case NVPTXISD::Tex2DArrayFloatFloat:
2570 Opc = NVPTX::TEX_2D_ARRAY_F32_F32;
2571 break;
2572 case NVPTXISD::Tex2DArrayFloatFloatLevel:
2573 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_LEVEL;
2574 break;
2575 case NVPTXISD::Tex2DArrayFloatFloatGrad:
2576 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_GRAD;
2577 break;
2578 case NVPTXISD::Tex2DArrayI32I32:
2579 Opc = NVPTX::TEX_2D_ARRAY_I32_I32;
2580 break;
2581 case NVPTXISD::Tex2DArrayI32Float:
2582 Opc = NVPTX::TEX_2D_ARRAY_I32_F32;
2583 break;
2584 case NVPTXISD::Tex2DArrayI32FloatLevel:
2585 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_LEVEL;
2586 break;
2587 case NVPTXISD::Tex2DArrayI32FloatGrad:
2588 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_GRAD;
2589 break;
2590 case NVPTXISD::Tex3DFloatI32:
2591 Opc = NVPTX::TEX_3D_F32_I32;
2592 break;
2593 case NVPTXISD::Tex3DFloatFloat:
2594 Opc = NVPTX::TEX_3D_F32_F32;
2595 break;
2596 case NVPTXISD::Tex3DFloatFloatLevel:
2597 Opc = NVPTX::TEX_3D_F32_F32_LEVEL;
2598 break;
2599 case NVPTXISD::Tex3DFloatFloatGrad:
2600 Opc = NVPTX::TEX_3D_F32_F32_GRAD;
2601 break;
2602 case NVPTXISD::Tex3DI32I32:
2603 Opc = NVPTX::TEX_3D_I32_I32;
2604 break;
2605 case NVPTXISD::Tex3DI32Float:
2606 Opc = NVPTX::TEX_3D_I32_F32;
2607 break;
2608 case NVPTXISD::Tex3DI32FloatLevel:
2609 Opc = NVPTX::TEX_3D_I32_F32_LEVEL;
2610 break;
2611 case NVPTXISD::Tex3DI32FloatGrad:
2612 Opc = NVPTX::TEX_3D_I32_F32_GRAD;
2613 break;
2614 }
2615
2616 Ops.push_back(TexRef);
2617 Ops.push_back(SampRef);
2618
2619 // Copy over indices
2620 for (unsigned i = 3; i < N->getNumOperands(); ++i) {
2621 Ops.push_back(N->getOperand(i));
2622 }
2623
2624 Ops.push_back(Chain);
2625 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2626 return Ret;
2627}
2628
2629SDNode *NVPTXDAGToDAGISel::SelectSurfaceIntrinsic(SDNode *N) {
2630 SDValue Chain = N->getOperand(0);
2631 SDValue TexHandle = N->getOperand(1);
2632 SDNode *Ret = NULL;
2633 unsigned Opc = 0;
2634 SmallVector<SDValue, 8> Ops;
2635 switch (N->getOpcode()) {
2636 default: return NULL;
2637 case NVPTXISD::Suld1DI8Trap:
2638 Opc = NVPTX::SULD_1D_I8_TRAP;
2639 Ops.push_back(TexHandle);
2640 Ops.push_back(N->getOperand(2));
2641 Ops.push_back(Chain);
2642 break;
2643 case NVPTXISD::Suld1DI16Trap:
2644 Opc = NVPTX::SULD_1D_I16_TRAP;
2645 Ops.push_back(TexHandle);
2646 Ops.push_back(N->getOperand(2));
2647 Ops.push_back(Chain);
2648 break;
2649 case NVPTXISD::Suld1DI32Trap:
2650 Opc = NVPTX::SULD_1D_I32_TRAP;
2651 Ops.push_back(TexHandle);
2652 Ops.push_back(N->getOperand(2));
2653 Ops.push_back(Chain);
2654 break;
2655 case NVPTXISD::Suld1DV2I8Trap:
2656 Opc = NVPTX::SULD_1D_V2I8_TRAP;
2657 Ops.push_back(TexHandle);
2658 Ops.push_back(N->getOperand(2));
2659 Ops.push_back(Chain);
2660 break;
2661 case NVPTXISD::Suld1DV2I16Trap:
2662 Opc = NVPTX::SULD_1D_V2I16_TRAP;
2663 Ops.push_back(TexHandle);
2664 Ops.push_back(N->getOperand(2));
2665 Ops.push_back(Chain);
2666 break;
2667 case NVPTXISD::Suld1DV2I32Trap:
2668 Opc = NVPTX::SULD_1D_V2I32_TRAP;
2669 Ops.push_back(TexHandle);
2670 Ops.push_back(N->getOperand(2));
2671 Ops.push_back(Chain);
2672 break;
2673 case NVPTXISD::Suld1DV4I8Trap:
2674 Opc = NVPTX::SULD_1D_V4I8_TRAP;
2675 Ops.push_back(TexHandle);
2676 Ops.push_back(N->getOperand(2));
2677 Ops.push_back(Chain);
2678 break;
2679 case NVPTXISD::Suld1DV4I16Trap:
2680 Opc = NVPTX::SULD_1D_V4I16_TRAP;
2681 Ops.push_back(TexHandle);
2682 Ops.push_back(N->getOperand(2));
2683 Ops.push_back(Chain);
2684 break;
2685 case NVPTXISD::Suld1DV4I32Trap:
2686 Opc = NVPTX::SULD_1D_V4I32_TRAP;
2687 Ops.push_back(TexHandle);
2688 Ops.push_back(N->getOperand(2));
2689 Ops.push_back(Chain);
2690 break;
2691 case NVPTXISD::Suld1DArrayI8Trap:
2692 Opc = NVPTX::SULD_1D_ARRAY_I8_TRAP;
2693 Ops.push_back(TexHandle);
2694 Ops.push_back(N->getOperand(2));
2695 Ops.push_back(N->getOperand(3));
2696 Ops.push_back(Chain);
2697 break;
2698 case NVPTXISD::Suld1DArrayI16Trap:
2699 Opc = NVPTX::SULD_1D_ARRAY_I16_TRAP;
2700 Ops.push_back(TexHandle);
2701 Ops.push_back(N->getOperand(2));
2702 Ops.push_back(N->getOperand(3));
2703 Ops.push_back(Chain);
2704 break;
2705 case NVPTXISD::Suld1DArrayI32Trap:
2706 Opc = NVPTX::SULD_1D_ARRAY_I32_TRAP;
2707 Ops.push_back(TexHandle);
2708 Ops.push_back(N->getOperand(2));
2709 Ops.push_back(N->getOperand(3));
2710 Ops.push_back(Chain);
2711 break;
2712 case NVPTXISD::Suld1DArrayV2I8Trap:
2713 Opc = NVPTX::SULD_1D_ARRAY_V2I8_TRAP;
2714 Ops.push_back(TexHandle);
2715 Ops.push_back(N->getOperand(2));
2716 Ops.push_back(N->getOperand(3));
2717 Ops.push_back(Chain);
2718 break;
2719 case NVPTXISD::Suld1DArrayV2I16Trap:
2720 Opc = NVPTX::SULD_1D_ARRAY_V2I16_TRAP;
2721 Ops.push_back(TexHandle);
2722 Ops.push_back(N->getOperand(2));
2723 Ops.push_back(N->getOperand(3));
2724 Ops.push_back(Chain);
2725 break;
2726 case NVPTXISD::Suld1DArrayV2I32Trap:
2727 Opc = NVPTX::SULD_1D_ARRAY_V2I32_TRAP;
2728 Ops.push_back(TexHandle);
2729 Ops.push_back(N->getOperand(2));
2730 Ops.push_back(N->getOperand(3));
2731 Ops.push_back(Chain);
2732 break;
2733 case NVPTXISD::Suld1DArrayV4I8Trap:
2734 Opc = NVPTX::SULD_1D_ARRAY_V4I8_TRAP;
2735 Ops.push_back(TexHandle);
2736 Ops.push_back(N->getOperand(2));
2737 Ops.push_back(N->getOperand(3));
2738 Ops.push_back(Chain);
2739 break;
2740 case NVPTXISD::Suld1DArrayV4I16Trap:
2741 Opc = NVPTX::SULD_1D_ARRAY_V4I16_TRAP;
2742 Ops.push_back(TexHandle);
2743 Ops.push_back(N->getOperand(2));
2744 Ops.push_back(N->getOperand(3));
2745 Ops.push_back(Chain);
2746 break;
2747 case NVPTXISD::Suld1DArrayV4I32Trap:
2748 Opc = NVPTX::SULD_1D_ARRAY_V4I32_TRAP;
2749 Ops.push_back(TexHandle);
2750 Ops.push_back(N->getOperand(2));
2751 Ops.push_back(N->getOperand(3));
2752 Ops.push_back(Chain);
2753 break;
2754 case NVPTXISD::Suld2DI8Trap:
2755 Opc = NVPTX::SULD_2D_I8_TRAP;
2756 Ops.push_back(TexHandle);
2757 Ops.push_back(N->getOperand(2));
2758 Ops.push_back(N->getOperand(3));
2759 Ops.push_back(Chain);
2760 break;
2761 case NVPTXISD::Suld2DI16Trap:
2762 Opc = NVPTX::SULD_2D_I16_TRAP;
2763 Ops.push_back(TexHandle);
2764 Ops.push_back(N->getOperand(2));
2765 Ops.push_back(N->getOperand(3));
2766 Ops.push_back(Chain);
2767 break;
2768 case NVPTXISD::Suld2DI32Trap:
2769 Opc = NVPTX::SULD_2D_I32_TRAP;
2770 Ops.push_back(TexHandle);
2771 Ops.push_back(N->getOperand(2));
2772 Ops.push_back(N->getOperand(3));
2773 Ops.push_back(Chain);
2774 break;
2775 case NVPTXISD::Suld2DV2I8Trap:
2776 Opc = NVPTX::SULD_2D_V2I8_TRAP;
2777 Ops.push_back(TexHandle);
2778 Ops.push_back(N->getOperand(2));
2779 Ops.push_back(N->getOperand(3));
2780 Ops.push_back(Chain);
2781 break;
2782 case NVPTXISD::Suld2DV2I16Trap:
2783 Opc = NVPTX::SULD_2D_V2I16_TRAP;
2784 Ops.push_back(TexHandle);
2785 Ops.push_back(N->getOperand(2));
2786 Ops.push_back(N->getOperand(3));
2787 Ops.push_back(Chain);
2788 break;
2789 case NVPTXISD::Suld2DV2I32Trap:
2790 Opc = NVPTX::SULD_2D_V2I32_TRAP;
2791 Ops.push_back(TexHandle);
2792 Ops.push_back(N->getOperand(2));
2793 Ops.push_back(N->getOperand(3));
2794 Ops.push_back(Chain);
2795 break;
2796 case NVPTXISD::Suld2DV4I8Trap:
2797 Opc = NVPTX::SULD_2D_V4I8_TRAP;
2798 Ops.push_back(TexHandle);
2799 Ops.push_back(N->getOperand(2));
2800 Ops.push_back(N->getOperand(3));
2801 Ops.push_back(Chain);
2802 break;
2803 case NVPTXISD::Suld2DV4I16Trap:
2804 Opc = NVPTX::SULD_2D_V4I16_TRAP;
2805 Ops.push_back(TexHandle);
2806 Ops.push_back(N->getOperand(2));
2807 Ops.push_back(N->getOperand(3));
2808 Ops.push_back(Chain);
2809 break;
2810 case NVPTXISD::Suld2DV4I32Trap:
2811 Opc = NVPTX::SULD_2D_V4I32_TRAP;
2812 Ops.push_back(TexHandle);
2813 Ops.push_back(N->getOperand(2));
2814 Ops.push_back(N->getOperand(3));
2815 Ops.push_back(Chain);
2816 break;
2817 case NVPTXISD::Suld2DArrayI8Trap:
2818 Opc = NVPTX::SULD_2D_ARRAY_I8_TRAP;
2819 Ops.push_back(TexHandle);
2820 Ops.push_back(N->getOperand(2));
2821 Ops.push_back(N->getOperand(3));
2822 Ops.push_back(N->getOperand(4));
2823 Ops.push_back(Chain);
2824 break;
2825 case NVPTXISD::Suld2DArrayI16Trap:
2826 Opc = NVPTX::SULD_2D_ARRAY_I16_TRAP;
2827 Ops.push_back(TexHandle);
2828 Ops.push_back(N->getOperand(2));
2829 Ops.push_back(N->getOperand(3));
2830 Ops.push_back(N->getOperand(4));
2831 Ops.push_back(Chain);
2832 break;
2833 case NVPTXISD::Suld2DArrayI32Trap:
2834 Opc = NVPTX::SULD_2D_ARRAY_I32_TRAP;
2835 Ops.push_back(TexHandle);
2836 Ops.push_back(N->getOperand(2));
2837 Ops.push_back(N->getOperand(3));
2838 Ops.push_back(N->getOperand(4));
2839 Ops.push_back(Chain);
2840 break;
2841 case NVPTXISD::Suld2DArrayV2I8Trap:
2842 Opc = NVPTX::SULD_2D_ARRAY_V2I8_TRAP;
2843 Ops.push_back(TexHandle);
2844 Ops.push_back(N->getOperand(2));
2845 Ops.push_back(N->getOperand(3));
2846 Ops.push_back(N->getOperand(4));
2847 Ops.push_back(Chain);
2848 break;
2849 case NVPTXISD::Suld2DArrayV2I16Trap:
2850 Opc = NVPTX::SULD_2D_ARRAY_V2I16_TRAP;
2851 Ops.push_back(TexHandle);
2852 Ops.push_back(N->getOperand(2));
2853 Ops.push_back(N->getOperand(3));
2854 Ops.push_back(N->getOperand(4));
2855 Ops.push_back(Chain);
2856 break;
2857 case NVPTXISD::Suld2DArrayV2I32Trap:
2858 Opc = NVPTX::SULD_2D_ARRAY_V2I32_TRAP;
2859 Ops.push_back(TexHandle);
2860 Ops.push_back(N->getOperand(2));
2861 Ops.push_back(N->getOperand(3));
2862 Ops.push_back(N->getOperand(4));
2863 Ops.push_back(Chain);
2864 break;
2865 case NVPTXISD::Suld2DArrayV4I8Trap:
2866 Opc = NVPTX::SULD_2D_ARRAY_V4I8_TRAP;
2867 Ops.push_back(TexHandle);
2868 Ops.push_back(N->getOperand(2));
2869 Ops.push_back(N->getOperand(3));
2870 Ops.push_back(N->getOperand(4));
2871 Ops.push_back(Chain);
2872 break;
2873 case NVPTXISD::Suld2DArrayV4I16Trap:
2874 Opc = NVPTX::SULD_2D_ARRAY_V4I16_TRAP;
2875 Ops.push_back(TexHandle);
2876 Ops.push_back(N->getOperand(2));
2877 Ops.push_back(N->getOperand(3));
2878 Ops.push_back(N->getOperand(4));
2879 Ops.push_back(Chain);
2880 break;
2881 case NVPTXISD::Suld2DArrayV4I32Trap:
2882 Opc = NVPTX::SULD_2D_ARRAY_V4I32_TRAP;
2883 Ops.push_back(TexHandle);
2884 Ops.push_back(N->getOperand(2));
2885 Ops.push_back(N->getOperand(3));
2886 Ops.push_back(N->getOperand(4));
2887 Ops.push_back(Chain);
2888 break;
2889 case NVPTXISD::Suld3DI8Trap:
2890 Opc = NVPTX::SULD_3D_I8_TRAP;
2891 Ops.push_back(TexHandle);
2892 Ops.push_back(N->getOperand(2));
2893 Ops.push_back(N->getOperand(3));
2894 Ops.push_back(N->getOperand(4));
2895 Ops.push_back(Chain);
2896 break;
2897 case NVPTXISD::Suld3DI16Trap:
2898 Opc = NVPTX::SULD_3D_I16_TRAP;
2899 Ops.push_back(TexHandle);
2900 Ops.push_back(N->getOperand(2));
2901 Ops.push_back(N->getOperand(3));
2902 Ops.push_back(N->getOperand(4));
2903 Ops.push_back(Chain);
2904 break;
2905 case NVPTXISD::Suld3DI32Trap:
2906 Opc = NVPTX::SULD_3D_I32_TRAP;
2907 Ops.push_back(TexHandle);
2908 Ops.push_back(N->getOperand(2));
2909 Ops.push_back(N->getOperand(3));
2910 Ops.push_back(N->getOperand(4));
2911 Ops.push_back(Chain);
2912 break;
2913 case NVPTXISD::Suld3DV2I8Trap:
2914 Opc = NVPTX::SULD_3D_V2I8_TRAP;
2915 Ops.push_back(TexHandle);
2916 Ops.push_back(N->getOperand(2));
2917 Ops.push_back(N->getOperand(3));
2918 Ops.push_back(N->getOperand(4));
2919 Ops.push_back(Chain);
2920 break;
2921 case NVPTXISD::Suld3DV2I16Trap:
2922 Opc = NVPTX::SULD_3D_V2I16_TRAP;
2923 Ops.push_back(TexHandle);
2924 Ops.push_back(N->getOperand(2));
2925 Ops.push_back(N->getOperand(3));
2926 Ops.push_back(N->getOperand(4));
2927 Ops.push_back(Chain);
2928 break;
2929 case NVPTXISD::Suld3DV2I32Trap:
2930 Opc = NVPTX::SULD_3D_V2I32_TRAP;
2931 Ops.push_back(TexHandle);
2932 Ops.push_back(N->getOperand(2));
2933 Ops.push_back(N->getOperand(3));
2934 Ops.push_back(N->getOperand(4));
2935 Ops.push_back(Chain);
2936 break;
2937 case NVPTXISD::Suld3DV4I8Trap:
2938 Opc = NVPTX::SULD_3D_V4I8_TRAP;
2939 Ops.push_back(TexHandle);
2940 Ops.push_back(N->getOperand(2));
2941 Ops.push_back(N->getOperand(3));
2942 Ops.push_back(N->getOperand(4));
2943 Ops.push_back(Chain);
2944 break;
2945 case NVPTXISD::Suld3DV4I16Trap:
2946 Opc = NVPTX::SULD_3D_V4I16_TRAP;
2947 Ops.push_back(TexHandle);
2948 Ops.push_back(N->getOperand(2));
2949 Ops.push_back(N->getOperand(3));
2950 Ops.push_back(N->getOperand(4));
2951 Ops.push_back(Chain);
2952 break;
2953 case NVPTXISD::Suld3DV4I32Trap:
2954 Opc = NVPTX::SULD_3D_V4I32_TRAP;
2955 Ops.push_back(TexHandle);
2956 Ops.push_back(N->getOperand(2));
2957 Ops.push_back(N->getOperand(3));
2958 Ops.push_back(N->getOperand(4));
2959 Ops.push_back(Chain);
2960 break;
2961 }
2962 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2963 return Ret;
2964}
2965
Justin Holewinskiae556d32012-05-04 20:18:50 +00002966// SelectDirectAddr - Match a direct address for DAG.
2967// A direct address could be a globaladdress or externalsymbol.
2968bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2969 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002970 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2971 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002972 Address = N;
2973 return true;
2974 }
2975 if (N.getOpcode() == NVPTXISD::Wrapper) {
2976 Address = N.getOperand(0);
2977 return true;
2978 }
2979 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2980 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2981 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2982 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2983 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2984 }
2985 return false;
2986}
2987
2988// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002989bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2990 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002991 if (Addr.getOpcode() == ISD::ADD) {
2992 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002993 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002994 if (SelectDirectAddr(base, Base)) {
2995 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2996 return true;
2997 }
2998 }
2999 }
3000 return false;
3001}
3002
3003// symbol+offset
3004bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
3005 SDValue &Base, SDValue &Offset) {
3006 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
3007}
3008
3009// symbol+offset
3010bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
3011 SDValue &Base, SDValue &Offset) {
3012 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
3013}
3014
3015// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003016bool NVPTXDAGToDAGISel::SelectADDRri_imp(
3017 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003018 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
3019 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3020 Offset = CurDAG->getTargetConstant(0, mvt);
3021 return true;
3022 }
3023 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
3024 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00003025 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00003026
3027 if (Addr.getOpcode() == ISD::ADD) {
3028 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
3029 return false;
3030 }
3031 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
3032 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00003033 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00003034 // Constant offset from frame ref.
3035 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3036 else
3037 Base = Addr.getOperand(0);
3038 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3039 return true;
3040 }
3041 }
3042 return false;
3043}
3044
3045// register+offset
3046bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
3047 SDValue &Base, SDValue &Offset) {
3048 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
3049}
3050
3051// register+offset
3052bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
3053 SDValue &Base, SDValue &Offset) {
3054 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
3055}
3056
3057bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
3058 unsigned int spN) const {
3059 const Value *Src = NULL;
3060 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
3061 // the classof() for MemSDNode does not include MemIntrinsicSDNode
3062 // (See SelectionDAGNodes.h). So we need to check for both.
3063 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
3064 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00003065 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003066 Src = mN->getSrcValue();
3067 }
3068 if (!Src)
3069 return false;
3070 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
3071 return (PT->getAddressSpace() == spN);
3072 return false;
3073}
3074
3075/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3076/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003077bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
3078 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003079 SDValue Op0, Op1;
3080 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003081 default:
3082 return true;
3083 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00003084 if (SelectDirectAddr(Op, Op0)) {
3085 OutOps.push_back(Op0);
3086 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
3087 return false;
3088 }
3089 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
3090 OutOps.push_back(Op0);
3091 OutOps.push_back(Op1);
3092 return false;
3093 }
3094 break;
3095 }
3096 return true;
3097}