blob: bd08d2d8ad9cad7e6a1d3c08e5d180186e3aa725 [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 Holewinskiba2fa6d2014-03-24 11:17:53 +0000165 case ISD::ADDRSPACECAST:
166 ResNode = SelectAddrSpaceCast(N);
167 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000168 default:
169 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000170 }
171 if (ResNode)
172 return ResNode;
173 return SelectCode(N);
174}
175
Justin Holewinski0497ab12013-03-30 14:29:21 +0000176static unsigned int getCodeAddrSpace(MemSDNode *N,
177 const NVPTXSubtarget &Subtarget) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000178 const Value *Src = N->getSrcValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000179
Justin Holewinskiae556d32012-05-04 20:18:50 +0000180 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000181 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000182
183 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
184 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000185 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
186 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
187 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
188 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
189 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
190 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
191 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000192 }
193 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000194 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000195}
196
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000197SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
198 SDValue Src = N->getOperand(0);
199 AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
200 unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
201 unsigned DstAddrSpace = CastN->getDestAddressSpace();
202
203 assert(SrcAddrSpace != DstAddrSpace &&
204 "addrspacecast must be between different address spaces");
205
206 if (DstAddrSpace == ADDRESS_SPACE_GENERIC) {
207 // Specific to generic
208 unsigned Opc;
209 switch (SrcAddrSpace) {
210 default: report_fatal_error("Bad address space in addrspacecast");
211 case ADDRESS_SPACE_GLOBAL:
212 Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64
213 : NVPTX::cvta_global_yes;
214 break;
215 case ADDRESS_SPACE_SHARED:
216 Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64
217 : NVPTX::cvta_shared_yes;
218 break;
219 case ADDRESS_SPACE_CONST:
220 Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64
221 : NVPTX::cvta_const_yes;
222 break;
223 case ADDRESS_SPACE_LOCAL:
224 Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64
225 : NVPTX::cvta_local_yes;
226 break;
227 }
228 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
229 } else {
230 // Generic to specific
231 if (SrcAddrSpace != 0)
232 report_fatal_error("Cannot cast between two non-generic address spaces");
233 unsigned Opc;
234 switch (DstAddrSpace) {
235 default: report_fatal_error("Bad address space in addrspacecast");
236 case ADDRESS_SPACE_GLOBAL:
237 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64
238 : NVPTX::cvta_to_global_yes;
239 break;
240 case ADDRESS_SPACE_SHARED:
241 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64
242 : NVPTX::cvta_to_shared_yes;
243 break;
244 case ADDRESS_SPACE_CONST:
245 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64
246 : NVPTX::cvta_to_const_yes;
247 break;
248 case ADDRESS_SPACE_LOCAL:
249 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64
250 : NVPTX::cvta_to_local_yes;
251 break;
252 }
253 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
254 }
255}
256
Justin Holewinski0497ab12013-03-30 14:29:21 +0000257SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000258 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000259 LoadSDNode *LD = cast<LoadSDNode>(N);
260 EVT LoadedVT = LD->getMemoryVT();
Justin Holewinski0497ab12013-03-30 14:29:21 +0000261 SDNode *NVPTXLD = NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000262
263 // do not support pre/post inc/dec
264 if (LD->isIndexed())
265 return NULL;
266
267 if (!LoadedVT.isSimple())
268 return NULL;
269
270 // Address Space Setting
271 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
272
273 // Volatile Setting
274 // - .volatile is only availalble for .global and .shared
275 bool isVolatile = LD->isVolatile();
276 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
277 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
278 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
279 isVolatile = false;
280
281 // Vector Setting
282 MVT SimpleVT = LoadedVT.getSimpleVT();
283 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
284 if (SimpleVT.isVector()) {
285 unsigned num = SimpleVT.getVectorNumElements();
286 if (num == 2)
287 vecType = NVPTX::PTXLdStInstCode::V2;
288 else if (num == 4)
289 vecType = NVPTX::PTXLdStInstCode::V4;
290 else
291 return NULL;
292 }
293
294 // Type Setting: fromType + fromTypeWidth
295 //
296 // Sign : ISD::SEXTLOAD
297 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
298 // type is integer
299 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
300 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000301 // Read at least 8 bits (predicates are stored as 8-bit values)
302 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000303 unsigned int fromType;
304 if ((LD->getExtensionType() == ISD::SEXTLOAD))
305 fromType = NVPTX::PTXLdStInstCode::Signed;
306 else if (ScalarVT.isFloatingPoint())
307 fromType = NVPTX::PTXLdStInstCode::Float;
308 else
309 fromType = NVPTX::PTXLdStInstCode::Unsigned;
310
311 // Create the machine instruction DAG
312 SDValue Chain = N->getOperand(0);
313 SDValue N1 = N->getOperand(1);
314 SDValue Addr;
315 SDValue Offset, Base;
316 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000317 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000318
319 if (SelectDirectAddr(N1, Addr)) {
320 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000321 case MVT::i8:
322 Opcode = NVPTX::LD_i8_avar;
323 break;
324 case MVT::i16:
325 Opcode = NVPTX::LD_i16_avar;
326 break;
327 case MVT::i32:
328 Opcode = NVPTX::LD_i32_avar;
329 break;
330 case MVT::i64:
331 Opcode = NVPTX::LD_i64_avar;
332 break;
333 case MVT::f32:
334 Opcode = NVPTX::LD_f32_avar;
335 break;
336 case MVT::f64:
337 Opcode = NVPTX::LD_f64_avar;
338 break;
339 default:
340 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000341 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000342 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
343 getI32Imm(vecType), getI32Imm(fromType),
344 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000345 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000346 } else if (Subtarget.is64Bit()
347 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
348 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000349 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000350 case MVT::i8:
351 Opcode = NVPTX::LD_i8_asi;
352 break;
353 case MVT::i16:
354 Opcode = NVPTX::LD_i16_asi;
355 break;
356 case MVT::i32:
357 Opcode = NVPTX::LD_i32_asi;
358 break;
359 case MVT::i64:
360 Opcode = NVPTX::LD_i64_asi;
361 break;
362 case MVT::f32:
363 Opcode = NVPTX::LD_f32_asi;
364 break;
365 case MVT::f64:
366 Opcode = NVPTX::LD_f64_asi;
367 break;
368 default:
369 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000370 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000371 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
372 getI32Imm(vecType), getI32Imm(fromType),
373 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000374 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000375 } else if (Subtarget.is64Bit()
376 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
377 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000378 if (Subtarget.is64Bit()) {
379 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000380 case MVT::i8:
381 Opcode = NVPTX::LD_i8_ari_64;
382 break;
383 case MVT::i16:
384 Opcode = NVPTX::LD_i16_ari_64;
385 break;
386 case MVT::i32:
387 Opcode = NVPTX::LD_i32_ari_64;
388 break;
389 case MVT::i64:
390 Opcode = NVPTX::LD_i64_ari_64;
391 break;
392 case MVT::f32:
393 Opcode = NVPTX::LD_f32_ari_64;
394 break;
395 case MVT::f64:
396 Opcode = NVPTX::LD_f64_ari_64;
397 break;
398 default:
399 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000400 }
401 } else {
402 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000403 case MVT::i8:
404 Opcode = NVPTX::LD_i8_ari;
405 break;
406 case MVT::i16:
407 Opcode = NVPTX::LD_i16_ari;
408 break;
409 case MVT::i32:
410 Opcode = NVPTX::LD_i32_ari;
411 break;
412 case MVT::i64:
413 Opcode = NVPTX::LD_i64_ari;
414 break;
415 case MVT::f32:
416 Opcode = NVPTX::LD_f32_ari;
417 break;
418 case MVT::f64:
419 Opcode = NVPTX::LD_f64_ari;
420 break;
421 default:
422 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000423 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000424 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000425 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
426 getI32Imm(vecType), getI32Imm(fromType),
427 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000428 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000429 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000430 if (Subtarget.is64Bit()) {
431 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000432 case MVT::i8:
433 Opcode = NVPTX::LD_i8_areg_64;
434 break;
435 case MVT::i16:
436 Opcode = NVPTX::LD_i16_areg_64;
437 break;
438 case MVT::i32:
439 Opcode = NVPTX::LD_i32_areg_64;
440 break;
441 case MVT::i64:
442 Opcode = NVPTX::LD_i64_areg_64;
443 break;
444 case MVT::f32:
445 Opcode = NVPTX::LD_f32_areg_64;
446 break;
447 case MVT::f64:
448 Opcode = NVPTX::LD_f64_areg_64;
449 break;
450 default:
451 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000452 }
453 } else {
454 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000455 case MVT::i8:
456 Opcode = NVPTX::LD_i8_areg;
457 break;
458 case MVT::i16:
459 Opcode = NVPTX::LD_i16_areg;
460 break;
461 case MVT::i32:
462 Opcode = NVPTX::LD_i32_areg;
463 break;
464 case MVT::i64:
465 Opcode = NVPTX::LD_i64_areg;
466 break;
467 case MVT::f32:
468 Opcode = NVPTX::LD_f32_areg;
469 break;
470 case MVT::f64:
471 Opcode = NVPTX::LD_f64_areg;
472 break;
473 default:
474 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000475 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000476 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000477 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
478 getI32Imm(vecType), getI32Imm(fromType),
479 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000480 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000481 }
482
483 if (NVPTXLD != NULL) {
484 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
485 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
486 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
487 }
488
489 return NVPTXLD;
490}
491
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000492SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
493
494 SDValue Chain = N->getOperand(0);
495 SDValue Op1 = N->getOperand(1);
496 SDValue Addr, Offset, Base;
497 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000498 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000499 SDNode *LD;
500 MemSDNode *MemSD = cast<MemSDNode>(N);
501 EVT LoadedVT = MemSD->getMemoryVT();
502
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000503 if (!LoadedVT.isSimple())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000504 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000505
506 // Address Space Setting
507 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
508
509 // Volatile Setting
510 // - .volatile is only availalble for .global and .shared
511 bool IsVolatile = MemSD->isVolatile();
512 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
513 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
514 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
515 IsVolatile = false;
516
517 // Vector Setting
518 MVT SimpleVT = LoadedVT.getSimpleVT();
519
520 // Type Setting: fromType + fromTypeWidth
521 //
522 // Sign : ISD::SEXTLOAD
523 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
524 // type is integer
525 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
526 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000527 // Read at least 8 bits (predicates are stored as 8-bit values)
528 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000529 unsigned int FromType;
530 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000531 unsigned ExtensionType = cast<ConstantSDNode>(
532 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000533 if (ExtensionType == ISD::SEXTLOAD)
534 FromType = NVPTX::PTXLdStInstCode::Signed;
535 else if (ScalarVT.isFloatingPoint())
536 FromType = NVPTX::PTXLdStInstCode::Float;
537 else
538 FromType = NVPTX::PTXLdStInstCode::Unsigned;
539
540 unsigned VecType;
541
542 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000543 case NVPTXISD::LoadV2:
544 VecType = NVPTX::PTXLdStInstCode::V2;
545 break;
546 case NVPTXISD::LoadV4:
547 VecType = NVPTX::PTXLdStInstCode::V4;
548 break;
549 default:
550 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000551 }
552
553 EVT EltVT = N->getValueType(0);
554
555 if (SelectDirectAddr(Op1, Addr)) {
556 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000557 default:
558 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000559 case NVPTXISD::LoadV2:
560 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000561 default:
562 return NULL;
563 case MVT::i8:
564 Opcode = NVPTX::LDV_i8_v2_avar;
565 break;
566 case MVT::i16:
567 Opcode = NVPTX::LDV_i16_v2_avar;
568 break;
569 case MVT::i32:
570 Opcode = NVPTX::LDV_i32_v2_avar;
571 break;
572 case MVT::i64:
573 Opcode = NVPTX::LDV_i64_v2_avar;
574 break;
575 case MVT::f32:
576 Opcode = NVPTX::LDV_f32_v2_avar;
577 break;
578 case MVT::f64:
579 Opcode = NVPTX::LDV_f64_v2_avar;
580 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000581 }
582 break;
583 case NVPTXISD::LoadV4:
584 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000585 default:
586 return NULL;
587 case MVT::i8:
588 Opcode = NVPTX::LDV_i8_v4_avar;
589 break;
590 case MVT::i16:
591 Opcode = NVPTX::LDV_i16_v4_avar;
592 break;
593 case MVT::i32:
594 Opcode = NVPTX::LDV_i32_v4_avar;
595 break;
596 case MVT::f32:
597 Opcode = NVPTX::LDV_f32_v4_avar;
598 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000599 }
600 break;
601 }
602
Justin Holewinski0497ab12013-03-30 14:29:21 +0000603 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
604 getI32Imm(VecType), getI32Imm(FromType),
605 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000606 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000607 } else if (Subtarget.is64Bit()
608 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
609 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000610 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000611 default:
612 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000613 case NVPTXISD::LoadV2:
614 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000615 default:
616 return NULL;
617 case MVT::i8:
618 Opcode = NVPTX::LDV_i8_v2_asi;
619 break;
620 case MVT::i16:
621 Opcode = NVPTX::LDV_i16_v2_asi;
622 break;
623 case MVT::i32:
624 Opcode = NVPTX::LDV_i32_v2_asi;
625 break;
626 case MVT::i64:
627 Opcode = NVPTX::LDV_i64_v2_asi;
628 break;
629 case MVT::f32:
630 Opcode = NVPTX::LDV_f32_v2_asi;
631 break;
632 case MVT::f64:
633 Opcode = NVPTX::LDV_f64_v2_asi;
634 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000635 }
636 break;
637 case NVPTXISD::LoadV4:
638 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000639 default:
640 return NULL;
641 case MVT::i8:
642 Opcode = NVPTX::LDV_i8_v4_asi;
643 break;
644 case MVT::i16:
645 Opcode = NVPTX::LDV_i16_v4_asi;
646 break;
647 case MVT::i32:
648 Opcode = NVPTX::LDV_i32_v4_asi;
649 break;
650 case MVT::f32:
651 Opcode = NVPTX::LDV_f32_v4_asi;
652 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000653 }
654 break;
655 }
656
Justin Holewinski0497ab12013-03-30 14:29:21 +0000657 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
658 getI32Imm(VecType), getI32Imm(FromType),
659 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000660 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000661 } else if (Subtarget.is64Bit()
662 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
663 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000664 if (Subtarget.is64Bit()) {
665 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000666 default:
667 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000668 case NVPTXISD::LoadV2:
669 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000670 default:
671 return NULL;
672 case MVT::i8:
673 Opcode = NVPTX::LDV_i8_v2_ari_64;
674 break;
675 case MVT::i16:
676 Opcode = NVPTX::LDV_i16_v2_ari_64;
677 break;
678 case MVT::i32:
679 Opcode = NVPTX::LDV_i32_v2_ari_64;
680 break;
681 case MVT::i64:
682 Opcode = NVPTX::LDV_i64_v2_ari_64;
683 break;
684 case MVT::f32:
685 Opcode = NVPTX::LDV_f32_v2_ari_64;
686 break;
687 case MVT::f64:
688 Opcode = NVPTX::LDV_f64_v2_ari_64;
689 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000690 }
691 break;
692 case NVPTXISD::LoadV4:
693 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000694 default:
695 return NULL;
696 case MVT::i8:
697 Opcode = NVPTX::LDV_i8_v4_ari_64;
698 break;
699 case MVT::i16:
700 Opcode = NVPTX::LDV_i16_v4_ari_64;
701 break;
702 case MVT::i32:
703 Opcode = NVPTX::LDV_i32_v4_ari_64;
704 break;
705 case MVT::f32:
706 Opcode = NVPTX::LDV_f32_v4_ari_64;
707 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000708 }
709 break;
710 }
711 } else {
712 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000713 default:
714 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000715 case NVPTXISD::LoadV2:
716 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000717 default:
718 return NULL;
719 case MVT::i8:
720 Opcode = NVPTX::LDV_i8_v2_ari;
721 break;
722 case MVT::i16:
723 Opcode = NVPTX::LDV_i16_v2_ari;
724 break;
725 case MVT::i32:
726 Opcode = NVPTX::LDV_i32_v2_ari;
727 break;
728 case MVT::i64:
729 Opcode = NVPTX::LDV_i64_v2_ari;
730 break;
731 case MVT::f32:
732 Opcode = NVPTX::LDV_f32_v2_ari;
733 break;
734 case MVT::f64:
735 Opcode = NVPTX::LDV_f64_v2_ari;
736 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000737 }
738 break;
739 case NVPTXISD::LoadV4:
740 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000741 default:
742 return NULL;
743 case MVT::i8:
744 Opcode = NVPTX::LDV_i8_v4_ari;
745 break;
746 case MVT::i16:
747 Opcode = NVPTX::LDV_i16_v4_ari;
748 break;
749 case MVT::i32:
750 Opcode = NVPTX::LDV_i32_v4_ari;
751 break;
752 case MVT::f32:
753 Opcode = NVPTX::LDV_f32_v4_ari;
754 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000755 }
756 break;
757 }
758 }
759
Justin Holewinski0497ab12013-03-30 14:29:21 +0000760 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
761 getI32Imm(VecType), getI32Imm(FromType),
762 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000763
Michael Liaob53d8962013-04-19 22:22:57 +0000764 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000765 } else {
766 if (Subtarget.is64Bit()) {
767 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000768 default:
769 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000770 case NVPTXISD::LoadV2:
771 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000772 default:
773 return NULL;
774 case MVT::i8:
775 Opcode = NVPTX::LDV_i8_v2_areg_64;
776 break;
777 case MVT::i16:
778 Opcode = NVPTX::LDV_i16_v2_areg_64;
779 break;
780 case MVT::i32:
781 Opcode = NVPTX::LDV_i32_v2_areg_64;
782 break;
783 case MVT::i64:
784 Opcode = NVPTX::LDV_i64_v2_areg_64;
785 break;
786 case MVT::f32:
787 Opcode = NVPTX::LDV_f32_v2_areg_64;
788 break;
789 case MVT::f64:
790 Opcode = NVPTX::LDV_f64_v2_areg_64;
791 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000792 }
793 break;
794 case NVPTXISD::LoadV4:
795 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000796 default:
797 return NULL;
798 case MVT::i8:
799 Opcode = NVPTX::LDV_i8_v4_areg_64;
800 break;
801 case MVT::i16:
802 Opcode = NVPTX::LDV_i16_v4_areg_64;
803 break;
804 case MVT::i32:
805 Opcode = NVPTX::LDV_i32_v4_areg_64;
806 break;
807 case MVT::f32:
808 Opcode = NVPTX::LDV_f32_v4_areg_64;
809 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000810 }
811 break;
812 }
813 } else {
814 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000815 default:
816 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000817 case NVPTXISD::LoadV2:
818 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000819 default:
820 return NULL;
821 case MVT::i8:
822 Opcode = NVPTX::LDV_i8_v2_areg;
823 break;
824 case MVT::i16:
825 Opcode = NVPTX::LDV_i16_v2_areg;
826 break;
827 case MVT::i32:
828 Opcode = NVPTX::LDV_i32_v2_areg;
829 break;
830 case MVT::i64:
831 Opcode = NVPTX::LDV_i64_v2_areg;
832 break;
833 case MVT::f32:
834 Opcode = NVPTX::LDV_f32_v2_areg;
835 break;
836 case MVT::f64:
837 Opcode = NVPTX::LDV_f64_v2_areg;
838 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000839 }
840 break;
841 case NVPTXISD::LoadV4:
842 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000843 default:
844 return NULL;
845 case MVT::i8:
846 Opcode = NVPTX::LDV_i8_v4_areg;
847 break;
848 case MVT::i16:
849 Opcode = NVPTX::LDV_i16_v4_areg;
850 break;
851 case MVT::i32:
852 Opcode = NVPTX::LDV_i32_v4_areg;
853 break;
854 case MVT::f32:
855 Opcode = NVPTX::LDV_f32_v4_areg;
856 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000857 }
858 break;
859 }
860 }
861
Justin Holewinski0497ab12013-03-30 14:29:21 +0000862 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
863 getI32Imm(VecType), getI32Imm(FromType),
864 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000865 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000866 }
867
868 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
869 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
870 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
871
872 return LD;
873}
874
875SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
876
877 SDValue Chain = N->getOperand(0);
878 SDValue Op1 = N->getOperand(1);
879 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000880 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000881 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000882 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000883 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000884
Justin Holewinskie40e9292013-07-01 12:58:52 +0000885 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000886
Justin Holewinskie40e9292013-07-01 12:58:52 +0000887 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000888 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000889 default:
890 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000891 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000892 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000893 default:
894 return NULL;
895 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000896 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000897 break;
898 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000899 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000900 break;
901 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000902 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000903 break;
904 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000905 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000906 break;
907 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000908 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000909 break;
910 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000911 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000912 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000913 }
914 break;
915 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000916 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000917 default:
918 return NULL;
919 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000920 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000921 break;
922 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000923 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000924 break;
925 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000926 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000927 break;
928 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000929 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000930 break;
931 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000932 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000933 break;
934 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000935 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
936 break;
937 }
938 break;
939 case NVPTXISD::LDGV4:
940 switch (EltVT.getSimpleVT().SimpleTy) {
941 default:
942 return NULL;
943 case MVT::i8:
944 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
945 break;
946 case MVT::i16:
947 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
948 break;
949 case MVT::i32:
950 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
951 break;
952 case MVT::f32:
953 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000954 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000955 }
956 break;
957 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000958 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000959 default:
960 return NULL;
961 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000962 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000963 break;
964 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000965 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000966 break;
967 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000968 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000969 break;
970 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000971 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000972 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000973 }
974 break;
975 }
Justin Holewinskie40e9292013-07-01 12:58:52 +0000976
977 SDValue Ops[] = { Addr, Chain };
978 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
979 ArrayRef<SDValue>(Ops, 2));
980 } else if (Subtarget.is64Bit()
981 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
982 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
983 if (Subtarget.is64Bit()) {
984 switch (N->getOpcode()) {
985 default:
986 return NULL;
987 case NVPTXISD::LDGV2:
988 switch (EltVT.getSimpleVT().SimpleTy) {
989 default:
990 return NULL;
991 case MVT::i8:
992 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
993 break;
994 case MVT::i16:
995 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
996 break;
997 case MVT::i32:
998 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
999 break;
1000 case MVT::i64:
1001 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
1002 break;
1003 case MVT::f32:
1004 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
1005 break;
1006 case MVT::f64:
1007 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
1008 break;
1009 }
1010 break;
1011 case NVPTXISD::LDUV2:
1012 switch (EltVT.getSimpleVT().SimpleTy) {
1013 default:
1014 return NULL;
1015 case MVT::i8:
1016 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
1017 break;
1018 case MVT::i16:
1019 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
1020 break;
1021 case MVT::i32:
1022 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
1023 break;
1024 case MVT::i64:
1025 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
1026 break;
1027 case MVT::f32:
1028 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
1029 break;
1030 case MVT::f64:
1031 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
1032 break;
1033 }
1034 break;
1035 case NVPTXISD::LDGV4:
1036 switch (EltVT.getSimpleVT().SimpleTy) {
1037 default:
1038 return NULL;
1039 case MVT::i8:
1040 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
1041 break;
1042 case MVT::i16:
1043 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
1044 break;
1045 case MVT::i32:
1046 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
1047 break;
1048 case MVT::f32:
1049 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
1050 break;
1051 }
1052 break;
1053 case NVPTXISD::LDUV4:
1054 switch (EltVT.getSimpleVT().SimpleTy) {
1055 default:
1056 return NULL;
1057 case MVT::i8:
1058 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
1059 break;
1060 case MVT::i16:
1061 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
1062 break;
1063 case MVT::i32:
1064 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1065 break;
1066 case MVT::f32:
1067 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1068 break;
1069 }
1070 break;
1071 }
1072 } else {
1073 switch (N->getOpcode()) {
1074 default:
1075 return NULL;
1076 case NVPTXISD::LDGV2:
1077 switch (EltVT.getSimpleVT().SimpleTy) {
1078 default:
1079 return NULL;
1080 case MVT::i8:
1081 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1082 break;
1083 case MVT::i16:
1084 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1085 break;
1086 case MVT::i32:
1087 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1088 break;
1089 case MVT::i64:
1090 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1091 break;
1092 case MVT::f32:
1093 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1094 break;
1095 case MVT::f64:
1096 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1097 break;
1098 }
1099 break;
1100 case NVPTXISD::LDUV2:
1101 switch (EltVT.getSimpleVT().SimpleTy) {
1102 default:
1103 return NULL;
1104 case MVT::i8:
1105 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1106 break;
1107 case MVT::i16:
1108 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1109 break;
1110 case MVT::i32:
1111 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1112 break;
1113 case MVT::i64:
1114 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1115 break;
1116 case MVT::f32:
1117 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1118 break;
1119 case MVT::f64:
1120 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1121 break;
1122 }
1123 break;
1124 case NVPTXISD::LDGV4:
1125 switch (EltVT.getSimpleVT().SimpleTy) {
1126 default:
1127 return NULL;
1128 case MVT::i8:
1129 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1130 break;
1131 case MVT::i16:
1132 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1133 break;
1134 case MVT::i32:
1135 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1136 break;
1137 case MVT::f32:
1138 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1139 break;
1140 }
1141 break;
1142 case NVPTXISD::LDUV4:
1143 switch (EltVT.getSimpleVT().SimpleTy) {
1144 default:
1145 return NULL;
1146 case MVT::i8:
1147 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1148 break;
1149 case MVT::i16:
1150 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1151 break;
1152 case MVT::i32:
1153 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1154 break;
1155 case MVT::f32:
1156 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1157 break;
1158 }
1159 break;
1160 }
1161 }
1162
1163 SDValue Ops[] = { Base, Offset, Chain };
1164
1165 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1166 ArrayRef<SDValue>(Ops, 3));
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001167 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001168 if (Subtarget.is64Bit()) {
1169 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001170 default:
1171 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001172 case NVPTXISD::LDGV2:
1173 switch (EltVT.getSimpleVT().SimpleTy) {
1174 default:
1175 return NULL;
1176 case MVT::i8:
1177 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1178 break;
1179 case MVT::i16:
1180 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1181 break;
1182 case MVT::i32:
1183 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1184 break;
1185 case MVT::i64:
1186 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1187 break;
1188 case MVT::f32:
1189 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1190 break;
1191 case MVT::f64:
1192 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1193 break;
1194 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001195 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001196 case NVPTXISD::LDUV2:
1197 switch (EltVT.getSimpleVT().SimpleTy) {
1198 default:
1199 return NULL;
1200 case MVT::i8:
1201 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1202 break;
1203 case MVT::i16:
1204 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1205 break;
1206 case MVT::i32:
1207 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1208 break;
1209 case MVT::i64:
1210 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1211 break;
1212 case MVT::f32:
1213 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1214 break;
1215 case MVT::f64:
1216 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1217 break;
1218 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001219 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001220 case NVPTXISD::LDGV4:
1221 switch (EltVT.getSimpleVT().SimpleTy) {
1222 default:
1223 return NULL;
1224 case MVT::i8:
1225 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1226 break;
1227 case MVT::i16:
1228 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1229 break;
1230 case MVT::i32:
1231 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1232 break;
1233 case MVT::f32:
1234 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1235 break;
1236 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001237 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001238 case NVPTXISD::LDUV4:
1239 switch (EltVT.getSimpleVT().SimpleTy) {
1240 default:
1241 return NULL;
1242 case MVT::i8:
1243 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1244 break;
1245 case MVT::i16:
1246 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1247 break;
1248 case MVT::i32:
1249 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1250 break;
1251 case MVT::f32:
1252 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1253 break;
1254 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001255 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001256 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001257 } else {
1258 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001259 default:
1260 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001261 case NVPTXISD::LDGV2:
1262 switch (EltVT.getSimpleVT().SimpleTy) {
1263 default:
1264 return NULL;
1265 case MVT::i8:
1266 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1267 break;
1268 case MVT::i16:
1269 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1270 break;
1271 case MVT::i32:
1272 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1273 break;
1274 case MVT::i64:
1275 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1276 break;
1277 case MVT::f32:
1278 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1279 break;
1280 case MVT::f64:
1281 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1282 break;
1283 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001284 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001285 case NVPTXISD::LDUV2:
1286 switch (EltVT.getSimpleVT().SimpleTy) {
1287 default:
1288 return NULL;
1289 case MVT::i8:
1290 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1291 break;
1292 case MVT::i16:
1293 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1294 break;
1295 case MVT::i32:
1296 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1297 break;
1298 case MVT::i64:
1299 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1300 break;
1301 case MVT::f32:
1302 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1303 break;
1304 case MVT::f64:
1305 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1306 break;
1307 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001308 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001309 case NVPTXISD::LDGV4:
1310 switch (EltVT.getSimpleVT().SimpleTy) {
1311 default:
1312 return NULL;
1313 case MVT::i8:
1314 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1315 break;
1316 case MVT::i16:
1317 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1318 break;
1319 case MVT::i32:
1320 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1321 break;
1322 case MVT::f32:
1323 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1324 break;
1325 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001326 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001327 case NVPTXISD::LDUV4:
1328 switch (EltVT.getSimpleVT().SimpleTy) {
1329 default:
1330 return NULL;
1331 case MVT::i8:
1332 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1333 break;
1334 case MVT::i16:
1335 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1336 break;
1337 case MVT::i32:
1338 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1339 break;
1340 case MVT::f32:
1341 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1342 break;
1343 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001344 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001345 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001346 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001347
Justin Holewinskie40e9292013-07-01 12:58:52 +00001348 SDValue Ops[] = { Op1, Chain };
1349 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1350 ArrayRef<SDValue>(Ops, 2));
1351 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001352
1353 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1354 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1355 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1356
1357 return LD;
1358}
1359
Justin Holewinski0497ab12013-03-30 14:29:21 +00001360SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001361 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001362 StoreSDNode *ST = cast<StoreSDNode>(N);
1363 EVT StoreVT = ST->getMemoryVT();
1364 SDNode *NVPTXST = NULL;
1365
1366 // do not support pre/post inc/dec
1367 if (ST->isIndexed())
1368 return NULL;
1369
1370 if (!StoreVT.isSimple())
1371 return NULL;
1372
1373 // Address Space Setting
1374 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1375
1376 // Volatile Setting
1377 // - .volatile is only availalble for .global and .shared
1378 bool isVolatile = ST->isVolatile();
1379 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1380 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1381 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1382 isVolatile = false;
1383
1384 // Vector Setting
1385 MVT SimpleVT = StoreVT.getSimpleVT();
1386 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1387 if (SimpleVT.isVector()) {
1388 unsigned num = SimpleVT.getVectorNumElements();
1389 if (num == 2)
1390 vecType = NVPTX::PTXLdStInstCode::V2;
1391 else if (num == 4)
1392 vecType = NVPTX::PTXLdStInstCode::V4;
1393 else
1394 return NULL;
1395 }
1396
1397 // Type Setting: toType + toTypeWidth
1398 // - for integer type, always use 'u'
1399 //
1400 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001401 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001402 unsigned int toType;
1403 if (ScalarVT.isFloatingPoint())
1404 toType = NVPTX::PTXLdStInstCode::Float;
1405 else
1406 toType = NVPTX::PTXLdStInstCode::Unsigned;
1407
1408 // Create the machine instruction DAG
1409 SDValue Chain = N->getOperand(0);
1410 SDValue N1 = N->getOperand(1);
1411 SDValue N2 = N->getOperand(2);
1412 SDValue Addr;
1413 SDValue Offset, Base;
1414 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001415 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001416
1417 if (SelectDirectAddr(N2, Addr)) {
1418 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001419 case MVT::i8:
1420 Opcode = NVPTX::ST_i8_avar;
1421 break;
1422 case MVT::i16:
1423 Opcode = NVPTX::ST_i16_avar;
1424 break;
1425 case MVT::i32:
1426 Opcode = NVPTX::ST_i32_avar;
1427 break;
1428 case MVT::i64:
1429 Opcode = NVPTX::ST_i64_avar;
1430 break;
1431 case MVT::f32:
1432 Opcode = NVPTX::ST_f32_avar;
1433 break;
1434 case MVT::f64:
1435 Opcode = NVPTX::ST_f64_avar;
1436 break;
1437 default:
1438 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001439 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001440 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1441 getI32Imm(vecType), getI32Imm(toType),
1442 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001443 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001444 } else if (Subtarget.is64Bit()
1445 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1446 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001447 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001448 case MVT::i8:
1449 Opcode = NVPTX::ST_i8_asi;
1450 break;
1451 case MVT::i16:
1452 Opcode = NVPTX::ST_i16_asi;
1453 break;
1454 case MVT::i32:
1455 Opcode = NVPTX::ST_i32_asi;
1456 break;
1457 case MVT::i64:
1458 Opcode = NVPTX::ST_i64_asi;
1459 break;
1460 case MVT::f32:
1461 Opcode = NVPTX::ST_f32_asi;
1462 break;
1463 case MVT::f64:
1464 Opcode = NVPTX::ST_f64_asi;
1465 break;
1466 default:
1467 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001468 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001469 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1470 getI32Imm(vecType), getI32Imm(toType),
1471 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001472 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001473 } else if (Subtarget.is64Bit()
1474 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1475 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001476 if (Subtarget.is64Bit()) {
1477 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001478 case MVT::i8:
1479 Opcode = NVPTX::ST_i8_ari_64;
1480 break;
1481 case MVT::i16:
1482 Opcode = NVPTX::ST_i16_ari_64;
1483 break;
1484 case MVT::i32:
1485 Opcode = NVPTX::ST_i32_ari_64;
1486 break;
1487 case MVT::i64:
1488 Opcode = NVPTX::ST_i64_ari_64;
1489 break;
1490 case MVT::f32:
1491 Opcode = NVPTX::ST_f32_ari_64;
1492 break;
1493 case MVT::f64:
1494 Opcode = NVPTX::ST_f64_ari_64;
1495 break;
1496 default:
1497 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001498 }
1499 } else {
1500 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001501 case MVT::i8:
1502 Opcode = NVPTX::ST_i8_ari;
1503 break;
1504 case MVT::i16:
1505 Opcode = NVPTX::ST_i16_ari;
1506 break;
1507 case MVT::i32:
1508 Opcode = NVPTX::ST_i32_ari;
1509 break;
1510 case MVT::i64:
1511 Opcode = NVPTX::ST_i64_ari;
1512 break;
1513 case MVT::f32:
1514 Opcode = NVPTX::ST_f32_ari;
1515 break;
1516 case MVT::f64:
1517 Opcode = NVPTX::ST_f64_ari;
1518 break;
1519 default:
1520 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001521 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001522 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001523 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1524 getI32Imm(vecType), getI32Imm(toType),
1525 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001526 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001527 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001528 if (Subtarget.is64Bit()) {
1529 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001530 case MVT::i8:
1531 Opcode = NVPTX::ST_i8_areg_64;
1532 break;
1533 case MVT::i16:
1534 Opcode = NVPTX::ST_i16_areg_64;
1535 break;
1536 case MVT::i32:
1537 Opcode = NVPTX::ST_i32_areg_64;
1538 break;
1539 case MVT::i64:
1540 Opcode = NVPTX::ST_i64_areg_64;
1541 break;
1542 case MVT::f32:
1543 Opcode = NVPTX::ST_f32_areg_64;
1544 break;
1545 case MVT::f64:
1546 Opcode = NVPTX::ST_f64_areg_64;
1547 break;
1548 default:
1549 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001550 }
1551 } else {
1552 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001553 case MVT::i8:
1554 Opcode = NVPTX::ST_i8_areg;
1555 break;
1556 case MVT::i16:
1557 Opcode = NVPTX::ST_i16_areg;
1558 break;
1559 case MVT::i32:
1560 Opcode = NVPTX::ST_i32_areg;
1561 break;
1562 case MVT::i64:
1563 Opcode = NVPTX::ST_i64_areg;
1564 break;
1565 case MVT::f32:
1566 Opcode = NVPTX::ST_f32_areg;
1567 break;
1568 case MVT::f64:
1569 Opcode = NVPTX::ST_f64_areg;
1570 break;
1571 default:
1572 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001573 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001574 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001575 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1576 getI32Imm(vecType), getI32Imm(toType),
1577 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001578 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001579 }
1580
1581 if (NVPTXST != NULL) {
1582 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1583 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1584 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1585 }
1586
1587 return NVPTXST;
1588}
1589
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001590SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1591 SDValue Chain = N->getOperand(0);
1592 SDValue Op1 = N->getOperand(1);
1593 SDValue Addr, Offset, Base;
1594 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001595 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001596 SDNode *ST;
1597 EVT EltVT = Op1.getValueType();
1598 MemSDNode *MemSD = cast<MemSDNode>(N);
1599 EVT StoreVT = MemSD->getMemoryVT();
1600
1601 // Address Space Setting
1602 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1603
1604 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1605 report_fatal_error("Cannot store to pointer that points to constant "
1606 "memory space");
1607 }
1608
1609 // Volatile Setting
1610 // - .volatile is only availalble for .global and .shared
1611 bool IsVolatile = MemSD->isVolatile();
1612 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1613 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1614 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1615 IsVolatile = false;
1616
1617 // Type Setting: toType + toTypeWidth
1618 // - for integer type, always use 'u'
1619 assert(StoreVT.isSimple() && "Store value is not simple");
1620 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001621 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001622 unsigned ToType;
1623 if (ScalarVT.isFloatingPoint())
1624 ToType = NVPTX::PTXLdStInstCode::Float;
1625 else
1626 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1627
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001628 SmallVector<SDValue, 12> StOps;
1629 SDValue N2;
1630 unsigned VecType;
1631
1632 switch (N->getOpcode()) {
1633 case NVPTXISD::StoreV2:
1634 VecType = NVPTX::PTXLdStInstCode::V2;
1635 StOps.push_back(N->getOperand(1));
1636 StOps.push_back(N->getOperand(2));
1637 N2 = N->getOperand(3);
1638 break;
1639 case NVPTXISD::StoreV4:
1640 VecType = NVPTX::PTXLdStInstCode::V4;
1641 StOps.push_back(N->getOperand(1));
1642 StOps.push_back(N->getOperand(2));
1643 StOps.push_back(N->getOperand(3));
1644 StOps.push_back(N->getOperand(4));
1645 N2 = N->getOperand(5);
1646 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001647 default:
1648 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001649 }
1650
1651 StOps.push_back(getI32Imm(IsVolatile));
1652 StOps.push_back(getI32Imm(CodeAddrSpace));
1653 StOps.push_back(getI32Imm(VecType));
1654 StOps.push_back(getI32Imm(ToType));
1655 StOps.push_back(getI32Imm(ToTypeWidth));
1656
1657 if (SelectDirectAddr(N2, Addr)) {
1658 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001659 default:
1660 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001661 case NVPTXISD::StoreV2:
1662 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001663 default:
1664 return NULL;
1665 case MVT::i8:
1666 Opcode = NVPTX::STV_i8_v2_avar;
1667 break;
1668 case MVT::i16:
1669 Opcode = NVPTX::STV_i16_v2_avar;
1670 break;
1671 case MVT::i32:
1672 Opcode = NVPTX::STV_i32_v2_avar;
1673 break;
1674 case MVT::i64:
1675 Opcode = NVPTX::STV_i64_v2_avar;
1676 break;
1677 case MVT::f32:
1678 Opcode = NVPTX::STV_f32_v2_avar;
1679 break;
1680 case MVT::f64:
1681 Opcode = NVPTX::STV_f64_v2_avar;
1682 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001683 }
1684 break;
1685 case NVPTXISD::StoreV4:
1686 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001687 default:
1688 return NULL;
1689 case MVT::i8:
1690 Opcode = NVPTX::STV_i8_v4_avar;
1691 break;
1692 case MVT::i16:
1693 Opcode = NVPTX::STV_i16_v4_avar;
1694 break;
1695 case MVT::i32:
1696 Opcode = NVPTX::STV_i32_v4_avar;
1697 break;
1698 case MVT::f32:
1699 Opcode = NVPTX::STV_f32_v4_avar;
1700 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001701 }
1702 break;
1703 }
1704 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001705 } else if (Subtarget.is64Bit()
1706 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1707 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001708 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001709 default:
1710 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001711 case NVPTXISD::StoreV2:
1712 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001713 default:
1714 return NULL;
1715 case MVT::i8:
1716 Opcode = NVPTX::STV_i8_v2_asi;
1717 break;
1718 case MVT::i16:
1719 Opcode = NVPTX::STV_i16_v2_asi;
1720 break;
1721 case MVT::i32:
1722 Opcode = NVPTX::STV_i32_v2_asi;
1723 break;
1724 case MVT::i64:
1725 Opcode = NVPTX::STV_i64_v2_asi;
1726 break;
1727 case MVT::f32:
1728 Opcode = NVPTX::STV_f32_v2_asi;
1729 break;
1730 case MVT::f64:
1731 Opcode = NVPTX::STV_f64_v2_asi;
1732 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001733 }
1734 break;
1735 case NVPTXISD::StoreV4:
1736 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001737 default:
1738 return NULL;
1739 case MVT::i8:
1740 Opcode = NVPTX::STV_i8_v4_asi;
1741 break;
1742 case MVT::i16:
1743 Opcode = NVPTX::STV_i16_v4_asi;
1744 break;
1745 case MVT::i32:
1746 Opcode = NVPTX::STV_i32_v4_asi;
1747 break;
1748 case MVT::f32:
1749 Opcode = NVPTX::STV_f32_v4_asi;
1750 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001751 }
1752 break;
1753 }
1754 StOps.push_back(Base);
1755 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001756 } else if (Subtarget.is64Bit()
1757 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1758 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001759 if (Subtarget.is64Bit()) {
1760 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001761 default:
1762 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001763 case NVPTXISD::StoreV2:
1764 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001765 default:
1766 return NULL;
1767 case MVT::i8:
1768 Opcode = NVPTX::STV_i8_v2_ari_64;
1769 break;
1770 case MVT::i16:
1771 Opcode = NVPTX::STV_i16_v2_ari_64;
1772 break;
1773 case MVT::i32:
1774 Opcode = NVPTX::STV_i32_v2_ari_64;
1775 break;
1776 case MVT::i64:
1777 Opcode = NVPTX::STV_i64_v2_ari_64;
1778 break;
1779 case MVT::f32:
1780 Opcode = NVPTX::STV_f32_v2_ari_64;
1781 break;
1782 case MVT::f64:
1783 Opcode = NVPTX::STV_f64_v2_ari_64;
1784 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001785 }
1786 break;
1787 case NVPTXISD::StoreV4:
1788 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001789 default:
1790 return NULL;
1791 case MVT::i8:
1792 Opcode = NVPTX::STV_i8_v4_ari_64;
1793 break;
1794 case MVT::i16:
1795 Opcode = NVPTX::STV_i16_v4_ari_64;
1796 break;
1797 case MVT::i32:
1798 Opcode = NVPTX::STV_i32_v4_ari_64;
1799 break;
1800 case MVT::f32:
1801 Opcode = NVPTX::STV_f32_v4_ari_64;
1802 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001803 }
1804 break;
1805 }
1806 } else {
1807 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001808 default:
1809 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001810 case NVPTXISD::StoreV2:
1811 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001812 default:
1813 return NULL;
1814 case MVT::i8:
1815 Opcode = NVPTX::STV_i8_v2_ari;
1816 break;
1817 case MVT::i16:
1818 Opcode = NVPTX::STV_i16_v2_ari;
1819 break;
1820 case MVT::i32:
1821 Opcode = NVPTX::STV_i32_v2_ari;
1822 break;
1823 case MVT::i64:
1824 Opcode = NVPTX::STV_i64_v2_ari;
1825 break;
1826 case MVT::f32:
1827 Opcode = NVPTX::STV_f32_v2_ari;
1828 break;
1829 case MVT::f64:
1830 Opcode = NVPTX::STV_f64_v2_ari;
1831 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001832 }
1833 break;
1834 case NVPTXISD::StoreV4:
1835 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001836 default:
1837 return NULL;
1838 case MVT::i8:
1839 Opcode = NVPTX::STV_i8_v4_ari;
1840 break;
1841 case MVT::i16:
1842 Opcode = NVPTX::STV_i16_v4_ari;
1843 break;
1844 case MVT::i32:
1845 Opcode = NVPTX::STV_i32_v4_ari;
1846 break;
1847 case MVT::f32:
1848 Opcode = NVPTX::STV_f32_v4_ari;
1849 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001850 }
1851 break;
1852 }
1853 }
1854 StOps.push_back(Base);
1855 StOps.push_back(Offset);
1856 } else {
1857 if (Subtarget.is64Bit()) {
1858 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001859 default:
1860 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001861 case NVPTXISD::StoreV2:
1862 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001863 default:
1864 return NULL;
1865 case MVT::i8:
1866 Opcode = NVPTX::STV_i8_v2_areg_64;
1867 break;
1868 case MVT::i16:
1869 Opcode = NVPTX::STV_i16_v2_areg_64;
1870 break;
1871 case MVT::i32:
1872 Opcode = NVPTX::STV_i32_v2_areg_64;
1873 break;
1874 case MVT::i64:
1875 Opcode = NVPTX::STV_i64_v2_areg_64;
1876 break;
1877 case MVT::f32:
1878 Opcode = NVPTX::STV_f32_v2_areg_64;
1879 break;
1880 case MVT::f64:
1881 Opcode = NVPTX::STV_f64_v2_areg_64;
1882 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001883 }
1884 break;
1885 case NVPTXISD::StoreV4:
1886 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001887 default:
1888 return NULL;
1889 case MVT::i8:
1890 Opcode = NVPTX::STV_i8_v4_areg_64;
1891 break;
1892 case MVT::i16:
1893 Opcode = NVPTX::STV_i16_v4_areg_64;
1894 break;
1895 case MVT::i32:
1896 Opcode = NVPTX::STV_i32_v4_areg_64;
1897 break;
1898 case MVT::f32:
1899 Opcode = NVPTX::STV_f32_v4_areg_64;
1900 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001901 }
1902 break;
1903 }
1904 } else {
1905 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001906 default:
1907 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001908 case NVPTXISD::StoreV2:
1909 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001910 default:
1911 return NULL;
1912 case MVT::i8:
1913 Opcode = NVPTX::STV_i8_v2_areg;
1914 break;
1915 case MVT::i16:
1916 Opcode = NVPTX::STV_i16_v2_areg;
1917 break;
1918 case MVT::i32:
1919 Opcode = NVPTX::STV_i32_v2_areg;
1920 break;
1921 case MVT::i64:
1922 Opcode = NVPTX::STV_i64_v2_areg;
1923 break;
1924 case MVT::f32:
1925 Opcode = NVPTX::STV_f32_v2_areg;
1926 break;
1927 case MVT::f64:
1928 Opcode = NVPTX::STV_f64_v2_areg;
1929 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001930 }
1931 break;
1932 case NVPTXISD::StoreV4:
1933 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001934 default:
1935 return NULL;
1936 case MVT::i8:
1937 Opcode = NVPTX::STV_i8_v4_areg;
1938 break;
1939 case MVT::i16:
1940 Opcode = NVPTX::STV_i16_v4_areg;
1941 break;
1942 case MVT::i32:
1943 Opcode = NVPTX::STV_i32_v4_areg;
1944 break;
1945 case MVT::f32:
1946 Opcode = NVPTX::STV_f32_v4_areg;
1947 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001948 }
1949 break;
1950 }
1951 }
1952 StOps.push_back(N2);
1953 }
1954
1955 StOps.push_back(Chain);
1956
Michael Liaob53d8962013-04-19 22:22:57 +00001957 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001958
1959 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1960 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1961 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1962
1963 return ST;
1964}
1965
Justin Holewinskif8f70912013-06-28 17:57:59 +00001966SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
1967 SDValue Chain = Node->getOperand(0);
1968 SDValue Offset = Node->getOperand(2);
1969 SDValue Flag = Node->getOperand(3);
1970 SDLoc DL(Node);
1971 MemSDNode *Mem = cast<MemSDNode>(Node);
1972
1973 unsigned VecSize;
1974 switch (Node->getOpcode()) {
1975 default:
1976 return NULL;
1977 case NVPTXISD::LoadParam:
1978 VecSize = 1;
1979 break;
1980 case NVPTXISD::LoadParamV2:
1981 VecSize = 2;
1982 break;
1983 case NVPTXISD::LoadParamV4:
1984 VecSize = 4;
1985 break;
1986 }
1987
1988 EVT EltVT = Node->getValueType(0);
1989 EVT MemVT = Mem->getMemoryVT();
1990
1991 unsigned Opc = 0;
1992
1993 switch (VecSize) {
1994 default:
1995 return NULL;
1996 case 1:
1997 switch (MemVT.getSimpleVT().SimpleTy) {
1998 default:
1999 return NULL;
2000 case MVT::i1:
2001 Opc = NVPTX::LoadParamMemI8;
2002 break;
2003 case MVT::i8:
2004 Opc = NVPTX::LoadParamMemI8;
2005 break;
2006 case MVT::i16:
2007 Opc = NVPTX::LoadParamMemI16;
2008 break;
2009 case MVT::i32:
2010 Opc = NVPTX::LoadParamMemI32;
2011 break;
2012 case MVT::i64:
2013 Opc = NVPTX::LoadParamMemI64;
2014 break;
2015 case MVT::f32:
2016 Opc = NVPTX::LoadParamMemF32;
2017 break;
2018 case MVT::f64:
2019 Opc = NVPTX::LoadParamMemF64;
2020 break;
2021 }
2022 break;
2023 case 2:
2024 switch (MemVT.getSimpleVT().SimpleTy) {
2025 default:
2026 return NULL;
2027 case MVT::i1:
2028 Opc = NVPTX::LoadParamMemV2I8;
2029 break;
2030 case MVT::i8:
2031 Opc = NVPTX::LoadParamMemV2I8;
2032 break;
2033 case MVT::i16:
2034 Opc = NVPTX::LoadParamMemV2I16;
2035 break;
2036 case MVT::i32:
2037 Opc = NVPTX::LoadParamMemV2I32;
2038 break;
2039 case MVT::i64:
2040 Opc = NVPTX::LoadParamMemV2I64;
2041 break;
2042 case MVT::f32:
2043 Opc = NVPTX::LoadParamMemV2F32;
2044 break;
2045 case MVT::f64:
2046 Opc = NVPTX::LoadParamMemV2F64;
2047 break;
2048 }
2049 break;
2050 case 4:
2051 switch (MemVT.getSimpleVT().SimpleTy) {
2052 default:
2053 return NULL;
2054 case MVT::i1:
2055 Opc = NVPTX::LoadParamMemV4I8;
2056 break;
2057 case MVT::i8:
2058 Opc = NVPTX::LoadParamMemV4I8;
2059 break;
2060 case MVT::i16:
2061 Opc = NVPTX::LoadParamMemV4I16;
2062 break;
2063 case MVT::i32:
2064 Opc = NVPTX::LoadParamMemV4I32;
2065 break;
2066 case MVT::f32:
2067 Opc = NVPTX::LoadParamMemV4F32;
2068 break;
2069 }
2070 break;
2071 }
2072
2073 SDVTList VTs;
2074 if (VecSize == 1) {
2075 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2076 } else if (VecSize == 2) {
2077 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2078 } else {
2079 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
Justin Holewinski44597172013-12-05 12:58:00 +00002080 VTs = CurDAG->getVTList(&EVTs[0], array_lengthof(EVTs));
Justin Holewinskif8f70912013-06-28 17:57:59 +00002081 }
2082
2083 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2084
2085 SmallVector<SDValue, 2> Ops;
2086 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2087 Ops.push_back(Chain);
2088 Ops.push_back(Flag);
2089
2090 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002091 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002092 return Ret;
2093}
2094
2095SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2096 SDLoc DL(N);
2097 SDValue Chain = N->getOperand(0);
2098 SDValue Offset = N->getOperand(1);
2099 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2100 MemSDNode *Mem = cast<MemSDNode>(N);
2101
2102 // How many elements do we have?
2103 unsigned NumElts = 1;
2104 switch (N->getOpcode()) {
2105 default:
2106 return NULL;
2107 case NVPTXISD::StoreRetval:
2108 NumElts = 1;
2109 break;
2110 case NVPTXISD::StoreRetvalV2:
2111 NumElts = 2;
2112 break;
2113 case NVPTXISD::StoreRetvalV4:
2114 NumElts = 4;
2115 break;
2116 }
2117
2118 // Build vector of operands
2119 SmallVector<SDValue, 6> Ops;
2120 for (unsigned i = 0; i < NumElts; ++i)
2121 Ops.push_back(N->getOperand(i + 2));
2122 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2123 Ops.push_back(Chain);
2124
2125 // Determine target opcode
2126 // If we have an i1, use an 8-bit store. The lowering code in
2127 // NVPTXISelLowering will have already emitted an upcast.
2128 unsigned Opcode = 0;
2129 switch (NumElts) {
2130 default:
2131 return NULL;
2132 case 1:
2133 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2134 default:
2135 return NULL;
2136 case MVT::i1:
2137 Opcode = NVPTX::StoreRetvalI8;
2138 break;
2139 case MVT::i8:
2140 Opcode = NVPTX::StoreRetvalI8;
2141 break;
2142 case MVT::i16:
2143 Opcode = NVPTX::StoreRetvalI16;
2144 break;
2145 case MVT::i32:
2146 Opcode = NVPTX::StoreRetvalI32;
2147 break;
2148 case MVT::i64:
2149 Opcode = NVPTX::StoreRetvalI64;
2150 break;
2151 case MVT::f32:
2152 Opcode = NVPTX::StoreRetvalF32;
2153 break;
2154 case MVT::f64:
2155 Opcode = NVPTX::StoreRetvalF64;
2156 break;
2157 }
2158 break;
2159 case 2:
2160 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2161 default:
2162 return NULL;
2163 case MVT::i1:
2164 Opcode = NVPTX::StoreRetvalV2I8;
2165 break;
2166 case MVT::i8:
2167 Opcode = NVPTX::StoreRetvalV2I8;
2168 break;
2169 case MVT::i16:
2170 Opcode = NVPTX::StoreRetvalV2I16;
2171 break;
2172 case MVT::i32:
2173 Opcode = NVPTX::StoreRetvalV2I32;
2174 break;
2175 case MVT::i64:
2176 Opcode = NVPTX::StoreRetvalV2I64;
2177 break;
2178 case MVT::f32:
2179 Opcode = NVPTX::StoreRetvalV2F32;
2180 break;
2181 case MVT::f64:
2182 Opcode = NVPTX::StoreRetvalV2F64;
2183 break;
2184 }
2185 break;
2186 case 4:
2187 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2188 default:
2189 return NULL;
2190 case MVT::i1:
2191 Opcode = NVPTX::StoreRetvalV4I8;
2192 break;
2193 case MVT::i8:
2194 Opcode = NVPTX::StoreRetvalV4I8;
2195 break;
2196 case MVT::i16:
2197 Opcode = NVPTX::StoreRetvalV4I16;
2198 break;
2199 case MVT::i32:
2200 Opcode = NVPTX::StoreRetvalV4I32;
2201 break;
2202 case MVT::f32:
2203 Opcode = NVPTX::StoreRetvalV4F32;
2204 break;
2205 }
2206 break;
2207 }
2208
2209 SDNode *Ret =
2210 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2211 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2212 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2213 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2214
2215 return Ret;
2216}
2217
2218SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2219 SDLoc DL(N);
2220 SDValue Chain = N->getOperand(0);
2221 SDValue Param = N->getOperand(1);
2222 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2223 SDValue Offset = N->getOperand(2);
2224 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2225 MemSDNode *Mem = cast<MemSDNode>(N);
2226 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2227
2228 // How many elements do we have?
2229 unsigned NumElts = 1;
2230 switch (N->getOpcode()) {
2231 default:
2232 return NULL;
2233 case NVPTXISD::StoreParamU32:
2234 case NVPTXISD::StoreParamS32:
2235 case NVPTXISD::StoreParam:
2236 NumElts = 1;
2237 break;
2238 case NVPTXISD::StoreParamV2:
2239 NumElts = 2;
2240 break;
2241 case NVPTXISD::StoreParamV4:
2242 NumElts = 4;
2243 break;
2244 }
2245
2246 // Build vector of operands
2247 SmallVector<SDValue, 8> Ops;
2248 for (unsigned i = 0; i < NumElts; ++i)
2249 Ops.push_back(N->getOperand(i + 3));
2250 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2251 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2252 Ops.push_back(Chain);
2253 Ops.push_back(Flag);
2254
2255 // Determine target opcode
2256 // If we have an i1, use an 8-bit store. The lowering code in
2257 // NVPTXISelLowering will have already emitted an upcast.
2258 unsigned Opcode = 0;
2259 switch (N->getOpcode()) {
2260 default:
2261 switch (NumElts) {
2262 default:
2263 return NULL;
2264 case 1:
2265 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2266 default:
2267 return NULL;
2268 case MVT::i1:
2269 Opcode = NVPTX::StoreParamI8;
2270 break;
2271 case MVT::i8:
2272 Opcode = NVPTX::StoreParamI8;
2273 break;
2274 case MVT::i16:
2275 Opcode = NVPTX::StoreParamI16;
2276 break;
2277 case MVT::i32:
2278 Opcode = NVPTX::StoreParamI32;
2279 break;
2280 case MVT::i64:
2281 Opcode = NVPTX::StoreParamI64;
2282 break;
2283 case MVT::f32:
2284 Opcode = NVPTX::StoreParamF32;
2285 break;
2286 case MVT::f64:
2287 Opcode = NVPTX::StoreParamF64;
2288 break;
2289 }
2290 break;
2291 case 2:
2292 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2293 default:
2294 return NULL;
2295 case MVT::i1:
2296 Opcode = NVPTX::StoreParamV2I8;
2297 break;
2298 case MVT::i8:
2299 Opcode = NVPTX::StoreParamV2I8;
2300 break;
2301 case MVT::i16:
2302 Opcode = NVPTX::StoreParamV2I16;
2303 break;
2304 case MVT::i32:
2305 Opcode = NVPTX::StoreParamV2I32;
2306 break;
2307 case MVT::i64:
2308 Opcode = NVPTX::StoreParamV2I64;
2309 break;
2310 case MVT::f32:
2311 Opcode = NVPTX::StoreParamV2F32;
2312 break;
2313 case MVT::f64:
2314 Opcode = NVPTX::StoreParamV2F64;
2315 break;
2316 }
2317 break;
2318 case 4:
2319 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2320 default:
2321 return NULL;
2322 case MVT::i1:
2323 Opcode = NVPTX::StoreParamV4I8;
2324 break;
2325 case MVT::i8:
2326 Opcode = NVPTX::StoreParamV4I8;
2327 break;
2328 case MVT::i16:
2329 Opcode = NVPTX::StoreParamV4I16;
2330 break;
2331 case MVT::i32:
2332 Opcode = NVPTX::StoreParamV4I32;
2333 break;
2334 case MVT::f32:
2335 Opcode = NVPTX::StoreParamV4F32;
2336 break;
2337 }
2338 break;
2339 }
2340 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002341 // Special case: if we have a sign-extend/zero-extend node, insert the
2342 // conversion instruction first, and use that as the value operand to
2343 // the selected StoreParam node.
2344 case NVPTXISD::StoreParamU32: {
2345 Opcode = NVPTX::StoreParamI32;
2346 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2347 MVT::i32);
2348 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2349 MVT::i32, Ops[0], CvtNone);
2350 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002351 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002352 }
2353 case NVPTXISD::StoreParamS32: {
2354 Opcode = NVPTX::StoreParamI32;
2355 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2356 MVT::i32);
2357 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2358 MVT::i32, Ops[0], CvtNone);
2359 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002360 break;
2361 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002362 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002363
Justin Holewinskidff28d22013-07-01 12:59:01 +00002364 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002365 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002366 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002367 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2368 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2369 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2370
2371 return Ret;
2372}
2373
Justin Holewinskiae556d32012-05-04 20:18:50 +00002374// SelectDirectAddr - Match a direct address for DAG.
2375// A direct address could be a globaladdress or externalsymbol.
2376bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2377 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002378 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2379 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002380 Address = N;
2381 return true;
2382 }
2383 if (N.getOpcode() == NVPTXISD::Wrapper) {
2384 Address = N.getOperand(0);
2385 return true;
2386 }
2387 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2388 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2389 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2390 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2391 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2392 }
2393 return false;
2394}
2395
2396// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002397bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2398 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002399 if (Addr.getOpcode() == ISD::ADD) {
2400 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002401 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002402 if (SelectDirectAddr(base, Base)) {
2403 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2404 return true;
2405 }
2406 }
2407 }
2408 return false;
2409}
2410
2411// symbol+offset
2412bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
2413 SDValue &Base, SDValue &Offset) {
2414 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
2415}
2416
2417// symbol+offset
2418bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
2419 SDValue &Base, SDValue &Offset) {
2420 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
2421}
2422
2423// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002424bool NVPTXDAGToDAGISel::SelectADDRri_imp(
2425 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002426 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2427 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2428 Offset = CurDAG->getTargetConstant(0, mvt);
2429 return true;
2430 }
2431 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2432 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00002433 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00002434
2435 if (Addr.getOpcode() == ISD::ADD) {
2436 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
2437 return false;
2438 }
2439 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
2440 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00002441 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002442 // Constant offset from frame ref.
2443 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2444 else
2445 Base = Addr.getOperand(0);
2446 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2447 return true;
2448 }
2449 }
2450 return false;
2451}
2452
2453// register+offset
2454bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
2455 SDValue &Base, SDValue &Offset) {
2456 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
2457}
2458
2459// register+offset
2460bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
2461 SDValue &Base, SDValue &Offset) {
2462 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
2463}
2464
2465bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
2466 unsigned int spN) const {
2467 const Value *Src = NULL;
2468 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
2469 // the classof() for MemSDNode does not include MemIntrinsicSDNode
2470 // (See SelectionDAGNodes.h). So we need to check for both.
2471 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
2472 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00002473 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002474 Src = mN->getSrcValue();
2475 }
2476 if (!Src)
2477 return false;
2478 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
2479 return (PT->getAddressSpace() == spN);
2480 return false;
2481}
2482
2483/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2484/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002485bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
2486 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002487 SDValue Op0, Op1;
2488 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002489 default:
2490 return true;
2491 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00002492 if (SelectDirectAddr(Op, Op0)) {
2493 OutOps.push_back(Op0);
2494 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
2495 return false;
2496 }
2497 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
2498 OutOps.push_back(Op0);
2499 OutOps.push_back(Op1);
2500 return false;
2501 }
2502 break;
2503 }
2504 return true;
2505}