blob: 03a3aa4f4da9d6975f0e19f7bebf020558da571f [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 Holewinski0497ab12013-03-30 14:29:21 +000028static cl::opt<bool> UseFMADInstruction(
29 "nvptx-mad-enable", cl::ZeroOrMore,
30 cl::desc("NVPTX Specific: Enable generating FMAD instructions"),
31 cl::init(false));
Justin Holewinskiae556d32012-05-04 20:18:50 +000032
33static cl::opt<int>
Justin Holewinski0497ab12013-03-30 14:29:21 +000034FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore,
Justin Holewinskiae556d32012-05-04 20:18:50 +000035 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
Justin Holewinski0497ab12013-03-30 14:29:21 +000036 " 1: do it 2: do it aggressively"),
37 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000038
Justin Holewinski0497ab12013-03-30 14:29:21 +000039static cl::opt<int> UsePrecDivF32(
40 "nvptx-prec-divf32", cl::ZeroOrMore,
41 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
42 " IEEE Compliant F32 div.rnd if avaiable."),
43 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000044
Justin Holewinski48f4ad32013-05-21 16:51:30 +000045static cl::opt<bool>
46UsePrecSqrtF32("nvptx-prec-sqrtf32",
47 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
48 cl::init(true));
49
Justin Holewinskiae556d32012-05-04 20:18:50 +000050/// createNVPTXISelDag - This pass converts a legalized DAG into a
51/// NVPTX-specific DAG, ready for instruction scheduling.
52FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
53 llvm::CodeGenOpt::Level OptLevel) {
54 return new NVPTXDAGToDAGISel(TM, OptLevel);
55}
56
Justin Holewinskiae556d32012-05-04 20:18:50 +000057NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
58 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000059 : SelectionDAGISel(tm, OptLevel),
60 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000061 // Always do fma.f32 fpcontract if the target supports the instruction.
62 // Always do fma.f64 fpcontract if the target supports the instruction.
63 // Do mad.f32 is nvptx-mad-enable is specified and the target does not
64 // support fma.f32.
65
66 doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32();
Justin Holewinski0497ab12013-03-30 14:29:21 +000067 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
68 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
69 doFMAF32AGG =
70 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
71 doFMAF64AGG =
72 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000073
74 allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction;
75
Benjamin Kramera25a61b2012-05-05 11:22:02 +000076 UseF32FTZ = false;
77
Justin Holewinskiae556d32012-05-04 20:18:50 +000078 doMulWide = (OptLevel > 0);
79
80 // Decide how to translate f32 div
81 do_DIVF32_PREC = UsePrecDivF32;
Justin Holewinski48f4ad32013-05-21 16:51:30 +000082 // Decide how to translate f32 sqrt
83 do_SQRTF32_PREC = UsePrecSqrtF32;
Justin Holewinskiae556d32012-05-04 20:18:50 +000084 // sm less than sm_20 does not support div.rnd. Use div.full.
85 if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
86 do_DIVF32_PREC = 1;
87
88}
89
90/// Select - Select instructions not customized! Used for
91/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +000092SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000093
94 if (N->isMachineOpcode())
Justin Holewinski0497ab12013-03-30 14:29:21 +000095 return NULL; // Already selected.
Justin Holewinskiae556d32012-05-04 20:18:50 +000096
97 SDNode *ResNode = NULL;
98 switch (N->getOpcode()) {
99 case ISD::LOAD:
100 ResNode = SelectLoad(N);
101 break;
102 case ISD::STORE:
103 ResNode = SelectStore(N);
104 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000105 case NVPTXISD::LoadV2:
106 case NVPTXISD::LoadV4:
107 ResNode = SelectLoadVector(N);
108 break;
109 case NVPTXISD::LDGV2:
110 case NVPTXISD::LDGV4:
111 case NVPTXISD::LDUV2:
112 case NVPTXISD::LDUV4:
113 ResNode = SelectLDGLDUVector(N);
114 break;
115 case NVPTXISD::StoreV2:
116 case NVPTXISD::StoreV4:
117 ResNode = SelectStoreVector(N);
118 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000119 case NVPTXISD::LoadParam:
120 case NVPTXISD::LoadParamV2:
121 case NVPTXISD::LoadParamV4:
122 ResNode = SelectLoadParam(N);
123 break;
124 case NVPTXISD::StoreRetval:
125 case NVPTXISD::StoreRetvalV2:
126 case NVPTXISD::StoreRetvalV4:
127 ResNode = SelectStoreRetval(N);
128 break;
129 case NVPTXISD::StoreParam:
130 case NVPTXISD::StoreParamV2:
131 case NVPTXISD::StoreParamV4:
132 case NVPTXISD::StoreParamS32:
133 case NVPTXISD::StoreParamU32:
134 ResNode = SelectStoreParam(N);
135 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000136 default:
137 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000138 }
139 if (ResNode)
140 return ResNode;
141 return SelectCode(N);
142}
143
Justin Holewinski0497ab12013-03-30 14:29:21 +0000144static unsigned int getCodeAddrSpace(MemSDNode *N,
145 const NVPTXSubtarget &Subtarget) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000146 const Value *Src = N->getSrcValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000147
Justin Holewinskiae556d32012-05-04 20:18:50 +0000148 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000149 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000150
151 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
152 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000153 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
154 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
155 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
156 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
157 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
158 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
159 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000160 }
161 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000162 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000163}
164
Justin Holewinski0497ab12013-03-30 14:29:21 +0000165SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000166 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000167 LoadSDNode *LD = cast<LoadSDNode>(N);
168 EVT LoadedVT = LD->getMemoryVT();
Justin Holewinski0497ab12013-03-30 14:29:21 +0000169 SDNode *NVPTXLD = NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000170
171 // do not support pre/post inc/dec
172 if (LD->isIndexed())
173 return NULL;
174
175 if (!LoadedVT.isSimple())
176 return NULL;
177
178 // Address Space Setting
179 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
180
181 // Volatile Setting
182 // - .volatile is only availalble for .global and .shared
183 bool isVolatile = LD->isVolatile();
184 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
185 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
186 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
187 isVolatile = false;
188
189 // Vector Setting
190 MVT SimpleVT = LoadedVT.getSimpleVT();
191 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
192 if (SimpleVT.isVector()) {
193 unsigned num = SimpleVT.getVectorNumElements();
194 if (num == 2)
195 vecType = NVPTX::PTXLdStInstCode::V2;
196 else if (num == 4)
197 vecType = NVPTX::PTXLdStInstCode::V4;
198 else
199 return NULL;
200 }
201
202 // Type Setting: fromType + fromTypeWidth
203 //
204 // Sign : ISD::SEXTLOAD
205 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
206 // type is integer
207 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
208 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000209 // Read at least 8 bits (predicates are stored as 8-bit values)
210 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000211 unsigned int fromType;
212 if ((LD->getExtensionType() == ISD::SEXTLOAD))
213 fromType = NVPTX::PTXLdStInstCode::Signed;
214 else if (ScalarVT.isFloatingPoint())
215 fromType = NVPTX::PTXLdStInstCode::Float;
216 else
217 fromType = NVPTX::PTXLdStInstCode::Unsigned;
218
219 // Create the machine instruction DAG
220 SDValue Chain = N->getOperand(0);
221 SDValue N1 = N->getOperand(1);
222 SDValue Addr;
223 SDValue Offset, Base;
224 unsigned Opcode;
225 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
226
227 if (SelectDirectAddr(N1, Addr)) {
228 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000229 case MVT::i8:
230 Opcode = NVPTX::LD_i8_avar;
231 break;
232 case MVT::i16:
233 Opcode = NVPTX::LD_i16_avar;
234 break;
235 case MVT::i32:
236 Opcode = NVPTX::LD_i32_avar;
237 break;
238 case MVT::i64:
239 Opcode = NVPTX::LD_i64_avar;
240 break;
241 case MVT::f32:
242 Opcode = NVPTX::LD_f32_avar;
243 break;
244 case MVT::f64:
245 Opcode = NVPTX::LD_f64_avar;
246 break;
247 default:
248 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000249 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000250 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
251 getI32Imm(vecType), getI32Imm(fromType),
252 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000253 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000254 } else if (Subtarget.is64Bit()
255 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
256 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000257 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000258 case MVT::i8:
259 Opcode = NVPTX::LD_i8_asi;
260 break;
261 case MVT::i16:
262 Opcode = NVPTX::LD_i16_asi;
263 break;
264 case MVT::i32:
265 Opcode = NVPTX::LD_i32_asi;
266 break;
267 case MVT::i64:
268 Opcode = NVPTX::LD_i64_asi;
269 break;
270 case MVT::f32:
271 Opcode = NVPTX::LD_f32_asi;
272 break;
273 case MVT::f64:
274 Opcode = NVPTX::LD_f64_asi;
275 break;
276 default:
277 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000278 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000279 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
280 getI32Imm(vecType), getI32Imm(fromType),
281 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000282 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000283 } else if (Subtarget.is64Bit()
284 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
285 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000286 if (Subtarget.is64Bit()) {
287 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000288 case MVT::i8:
289 Opcode = NVPTX::LD_i8_ari_64;
290 break;
291 case MVT::i16:
292 Opcode = NVPTX::LD_i16_ari_64;
293 break;
294 case MVT::i32:
295 Opcode = NVPTX::LD_i32_ari_64;
296 break;
297 case MVT::i64:
298 Opcode = NVPTX::LD_i64_ari_64;
299 break;
300 case MVT::f32:
301 Opcode = NVPTX::LD_f32_ari_64;
302 break;
303 case MVT::f64:
304 Opcode = NVPTX::LD_f64_ari_64;
305 break;
306 default:
307 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000308 }
309 } else {
310 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000311 case MVT::i8:
312 Opcode = NVPTX::LD_i8_ari;
313 break;
314 case MVT::i16:
315 Opcode = NVPTX::LD_i16_ari;
316 break;
317 case MVT::i32:
318 Opcode = NVPTX::LD_i32_ari;
319 break;
320 case MVT::i64:
321 Opcode = NVPTX::LD_i64_ari;
322 break;
323 case MVT::f32:
324 Opcode = NVPTX::LD_f32_ari;
325 break;
326 case MVT::f64:
327 Opcode = NVPTX::LD_f64_ari;
328 break;
329 default:
330 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000331 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000332 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000333 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
334 getI32Imm(vecType), getI32Imm(fromType),
335 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000336 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000337 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000338 if (Subtarget.is64Bit()) {
339 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000340 case MVT::i8:
341 Opcode = NVPTX::LD_i8_areg_64;
342 break;
343 case MVT::i16:
344 Opcode = NVPTX::LD_i16_areg_64;
345 break;
346 case MVT::i32:
347 Opcode = NVPTX::LD_i32_areg_64;
348 break;
349 case MVT::i64:
350 Opcode = NVPTX::LD_i64_areg_64;
351 break;
352 case MVT::f32:
353 Opcode = NVPTX::LD_f32_areg_64;
354 break;
355 case MVT::f64:
356 Opcode = NVPTX::LD_f64_areg_64;
357 break;
358 default:
359 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000360 }
361 } else {
362 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000363 case MVT::i8:
364 Opcode = NVPTX::LD_i8_areg;
365 break;
366 case MVT::i16:
367 Opcode = NVPTX::LD_i16_areg;
368 break;
369 case MVT::i32:
370 Opcode = NVPTX::LD_i32_areg;
371 break;
372 case MVT::i64:
373 Opcode = NVPTX::LD_i64_areg;
374 break;
375 case MVT::f32:
376 Opcode = NVPTX::LD_f32_areg;
377 break;
378 case MVT::f64:
379 Opcode = NVPTX::LD_f64_areg;
380 break;
381 default:
382 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000383 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000384 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000385 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
386 getI32Imm(vecType), getI32Imm(fromType),
387 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000388 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000389 }
390
391 if (NVPTXLD != NULL) {
392 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
393 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
394 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
395 }
396
397 return NVPTXLD;
398}
399
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000400SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
401
402 SDValue Chain = N->getOperand(0);
403 SDValue Op1 = N->getOperand(1);
404 SDValue Addr, Offset, Base;
405 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000406 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000407 SDNode *LD;
408 MemSDNode *MemSD = cast<MemSDNode>(N);
409 EVT LoadedVT = MemSD->getMemoryVT();
410
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000411 if (!LoadedVT.isSimple())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000412 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000413
414 // Address Space Setting
415 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
416
417 // Volatile Setting
418 // - .volatile is only availalble for .global and .shared
419 bool IsVolatile = MemSD->isVolatile();
420 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
421 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
422 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
423 IsVolatile = false;
424
425 // Vector Setting
426 MVT SimpleVT = LoadedVT.getSimpleVT();
427
428 // Type Setting: fromType + fromTypeWidth
429 //
430 // Sign : ISD::SEXTLOAD
431 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
432 // type is integer
433 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
434 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000435 // Read at least 8 bits (predicates are stored as 8-bit values)
436 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000437 unsigned int FromType;
438 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000439 unsigned ExtensionType = cast<ConstantSDNode>(
440 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000441 if (ExtensionType == ISD::SEXTLOAD)
442 FromType = NVPTX::PTXLdStInstCode::Signed;
443 else if (ScalarVT.isFloatingPoint())
444 FromType = NVPTX::PTXLdStInstCode::Float;
445 else
446 FromType = NVPTX::PTXLdStInstCode::Unsigned;
447
448 unsigned VecType;
449
450 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000451 case NVPTXISD::LoadV2:
452 VecType = NVPTX::PTXLdStInstCode::V2;
453 break;
454 case NVPTXISD::LoadV4:
455 VecType = NVPTX::PTXLdStInstCode::V4;
456 break;
457 default:
458 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000459 }
460
461 EVT EltVT = N->getValueType(0);
462
463 if (SelectDirectAddr(Op1, Addr)) {
464 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000465 default:
466 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000467 case NVPTXISD::LoadV2:
468 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000469 default:
470 return NULL;
471 case MVT::i8:
472 Opcode = NVPTX::LDV_i8_v2_avar;
473 break;
474 case MVT::i16:
475 Opcode = NVPTX::LDV_i16_v2_avar;
476 break;
477 case MVT::i32:
478 Opcode = NVPTX::LDV_i32_v2_avar;
479 break;
480 case MVT::i64:
481 Opcode = NVPTX::LDV_i64_v2_avar;
482 break;
483 case MVT::f32:
484 Opcode = NVPTX::LDV_f32_v2_avar;
485 break;
486 case MVT::f64:
487 Opcode = NVPTX::LDV_f64_v2_avar;
488 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000489 }
490 break;
491 case NVPTXISD::LoadV4:
492 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000493 default:
494 return NULL;
495 case MVT::i8:
496 Opcode = NVPTX::LDV_i8_v4_avar;
497 break;
498 case MVT::i16:
499 Opcode = NVPTX::LDV_i16_v4_avar;
500 break;
501 case MVT::i32:
502 Opcode = NVPTX::LDV_i32_v4_avar;
503 break;
504 case MVT::f32:
505 Opcode = NVPTX::LDV_f32_v4_avar;
506 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000507 }
508 break;
509 }
510
Justin Holewinski0497ab12013-03-30 14:29:21 +0000511 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
512 getI32Imm(VecType), getI32Imm(FromType),
513 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000514 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000515 } else if (Subtarget.is64Bit()
516 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
517 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000518 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000519 default:
520 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000521 case NVPTXISD::LoadV2:
522 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000523 default:
524 return NULL;
525 case MVT::i8:
526 Opcode = NVPTX::LDV_i8_v2_asi;
527 break;
528 case MVT::i16:
529 Opcode = NVPTX::LDV_i16_v2_asi;
530 break;
531 case MVT::i32:
532 Opcode = NVPTX::LDV_i32_v2_asi;
533 break;
534 case MVT::i64:
535 Opcode = NVPTX::LDV_i64_v2_asi;
536 break;
537 case MVT::f32:
538 Opcode = NVPTX::LDV_f32_v2_asi;
539 break;
540 case MVT::f64:
541 Opcode = NVPTX::LDV_f64_v2_asi;
542 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000543 }
544 break;
545 case NVPTXISD::LoadV4:
546 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000547 default:
548 return NULL;
549 case MVT::i8:
550 Opcode = NVPTX::LDV_i8_v4_asi;
551 break;
552 case MVT::i16:
553 Opcode = NVPTX::LDV_i16_v4_asi;
554 break;
555 case MVT::i32:
556 Opcode = NVPTX::LDV_i32_v4_asi;
557 break;
558 case MVT::f32:
559 Opcode = NVPTX::LDV_f32_v4_asi;
560 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000561 }
562 break;
563 }
564
Justin Holewinski0497ab12013-03-30 14:29:21 +0000565 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
566 getI32Imm(VecType), getI32Imm(FromType),
567 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000568 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000569 } else if (Subtarget.is64Bit()
570 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
571 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000572 if (Subtarget.is64Bit()) {
573 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000574 default:
575 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000576 case NVPTXISD::LoadV2:
577 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000578 default:
579 return NULL;
580 case MVT::i8:
581 Opcode = NVPTX::LDV_i8_v2_ari_64;
582 break;
583 case MVT::i16:
584 Opcode = NVPTX::LDV_i16_v2_ari_64;
585 break;
586 case MVT::i32:
587 Opcode = NVPTX::LDV_i32_v2_ari_64;
588 break;
589 case MVT::i64:
590 Opcode = NVPTX::LDV_i64_v2_ari_64;
591 break;
592 case MVT::f32:
593 Opcode = NVPTX::LDV_f32_v2_ari_64;
594 break;
595 case MVT::f64:
596 Opcode = NVPTX::LDV_f64_v2_ari_64;
597 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000598 }
599 break;
600 case NVPTXISD::LoadV4:
601 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000602 default:
603 return NULL;
604 case MVT::i8:
605 Opcode = NVPTX::LDV_i8_v4_ari_64;
606 break;
607 case MVT::i16:
608 Opcode = NVPTX::LDV_i16_v4_ari_64;
609 break;
610 case MVT::i32:
611 Opcode = NVPTX::LDV_i32_v4_ari_64;
612 break;
613 case MVT::f32:
614 Opcode = NVPTX::LDV_f32_v4_ari_64;
615 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000616 }
617 break;
618 }
619 } else {
620 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000621 default:
622 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000623 case NVPTXISD::LoadV2:
624 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000625 default:
626 return NULL;
627 case MVT::i8:
628 Opcode = NVPTX::LDV_i8_v2_ari;
629 break;
630 case MVT::i16:
631 Opcode = NVPTX::LDV_i16_v2_ari;
632 break;
633 case MVT::i32:
634 Opcode = NVPTX::LDV_i32_v2_ari;
635 break;
636 case MVT::i64:
637 Opcode = NVPTX::LDV_i64_v2_ari;
638 break;
639 case MVT::f32:
640 Opcode = NVPTX::LDV_f32_v2_ari;
641 break;
642 case MVT::f64:
643 Opcode = NVPTX::LDV_f64_v2_ari;
644 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000645 }
646 break;
647 case NVPTXISD::LoadV4:
648 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000649 default:
650 return NULL;
651 case MVT::i8:
652 Opcode = NVPTX::LDV_i8_v4_ari;
653 break;
654 case MVT::i16:
655 Opcode = NVPTX::LDV_i16_v4_ari;
656 break;
657 case MVT::i32:
658 Opcode = NVPTX::LDV_i32_v4_ari;
659 break;
660 case MVT::f32:
661 Opcode = NVPTX::LDV_f32_v4_ari;
662 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000663 }
664 break;
665 }
666 }
667
Justin Holewinski0497ab12013-03-30 14:29:21 +0000668 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
669 getI32Imm(VecType), getI32Imm(FromType),
670 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000671
Michael Liaob53d8962013-04-19 22:22:57 +0000672 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000673 } else {
674 if (Subtarget.is64Bit()) {
675 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000676 default:
677 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000678 case NVPTXISD::LoadV2:
679 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000680 default:
681 return NULL;
682 case MVT::i8:
683 Opcode = NVPTX::LDV_i8_v2_areg_64;
684 break;
685 case MVT::i16:
686 Opcode = NVPTX::LDV_i16_v2_areg_64;
687 break;
688 case MVT::i32:
689 Opcode = NVPTX::LDV_i32_v2_areg_64;
690 break;
691 case MVT::i64:
692 Opcode = NVPTX::LDV_i64_v2_areg_64;
693 break;
694 case MVT::f32:
695 Opcode = NVPTX::LDV_f32_v2_areg_64;
696 break;
697 case MVT::f64:
698 Opcode = NVPTX::LDV_f64_v2_areg_64;
699 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000700 }
701 break;
702 case NVPTXISD::LoadV4:
703 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000704 default:
705 return NULL;
706 case MVT::i8:
707 Opcode = NVPTX::LDV_i8_v4_areg_64;
708 break;
709 case MVT::i16:
710 Opcode = NVPTX::LDV_i16_v4_areg_64;
711 break;
712 case MVT::i32:
713 Opcode = NVPTX::LDV_i32_v4_areg_64;
714 break;
715 case MVT::f32:
716 Opcode = NVPTX::LDV_f32_v4_areg_64;
717 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000718 }
719 break;
720 }
721 } else {
722 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000723 default:
724 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000725 case NVPTXISD::LoadV2:
726 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000727 default:
728 return NULL;
729 case MVT::i8:
730 Opcode = NVPTX::LDV_i8_v2_areg;
731 break;
732 case MVT::i16:
733 Opcode = NVPTX::LDV_i16_v2_areg;
734 break;
735 case MVT::i32:
736 Opcode = NVPTX::LDV_i32_v2_areg;
737 break;
738 case MVT::i64:
739 Opcode = NVPTX::LDV_i64_v2_areg;
740 break;
741 case MVT::f32:
742 Opcode = NVPTX::LDV_f32_v2_areg;
743 break;
744 case MVT::f64:
745 Opcode = NVPTX::LDV_f64_v2_areg;
746 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000747 }
748 break;
749 case NVPTXISD::LoadV4:
750 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000751 default:
752 return NULL;
753 case MVT::i8:
754 Opcode = NVPTX::LDV_i8_v4_areg;
755 break;
756 case MVT::i16:
757 Opcode = NVPTX::LDV_i16_v4_areg;
758 break;
759 case MVT::i32:
760 Opcode = NVPTX::LDV_i32_v4_areg;
761 break;
762 case MVT::f32:
763 Opcode = NVPTX::LDV_f32_v4_areg;
764 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000765 }
766 break;
767 }
768 }
769
Justin Holewinski0497ab12013-03-30 14:29:21 +0000770 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
771 getI32Imm(VecType), getI32Imm(FromType),
772 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000773 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000774 }
775
776 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
777 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
778 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
779
780 return LD;
781}
782
783SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
784
785 SDValue Chain = N->getOperand(0);
786 SDValue Op1 = N->getOperand(1);
787 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000788 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000789 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000790 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000791 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000792
Justin Holewinskie40e9292013-07-01 12:58:52 +0000793 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000794
Justin Holewinskie40e9292013-07-01 12:58:52 +0000795 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000796 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000797 default:
798 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000799 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000800 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000801 default:
802 return NULL;
803 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000804 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000805 break;
806 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000807 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000808 break;
809 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000810 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000811 break;
812 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000813 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000814 break;
815 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000816 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000817 break;
818 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000819 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000820 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000821 }
822 break;
823 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000824 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000825 default:
826 return NULL;
827 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000828 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000829 break;
830 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000831 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000832 break;
833 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000834 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000835 break;
836 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000837 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000838 break;
839 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000840 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000841 break;
842 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000843 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
844 break;
845 }
846 break;
847 case NVPTXISD::LDGV4:
848 switch (EltVT.getSimpleVT().SimpleTy) {
849 default:
850 return NULL;
851 case MVT::i8:
852 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
853 break;
854 case MVT::i16:
855 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
856 break;
857 case MVT::i32:
858 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
859 break;
860 case MVT::f32:
861 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000862 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000863 }
864 break;
865 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000866 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000867 default:
868 return NULL;
869 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000870 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000871 break;
872 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000873 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000874 break;
875 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000876 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000877 break;
878 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000879 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000880 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000881 }
882 break;
883 }
Justin Holewinskie40e9292013-07-01 12:58:52 +0000884
885 SDValue Ops[] = { Addr, Chain };
886 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
887 ArrayRef<SDValue>(Ops, 2));
888 } else if (Subtarget.is64Bit()
889 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
890 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
891 if (Subtarget.is64Bit()) {
892 switch (N->getOpcode()) {
893 default:
894 return NULL;
895 case NVPTXISD::LDGV2:
896 switch (EltVT.getSimpleVT().SimpleTy) {
897 default:
898 return NULL;
899 case MVT::i8:
900 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
901 break;
902 case MVT::i16:
903 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
904 break;
905 case MVT::i32:
906 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
907 break;
908 case MVT::i64:
909 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
910 break;
911 case MVT::f32:
912 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
913 break;
914 case MVT::f64:
915 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
916 break;
917 }
918 break;
919 case NVPTXISD::LDUV2:
920 switch (EltVT.getSimpleVT().SimpleTy) {
921 default:
922 return NULL;
923 case MVT::i8:
924 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
925 break;
926 case MVT::i16:
927 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
928 break;
929 case MVT::i32:
930 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
931 break;
932 case MVT::i64:
933 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
934 break;
935 case MVT::f32:
936 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
937 break;
938 case MVT::f64:
939 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
940 break;
941 }
942 break;
943 case NVPTXISD::LDGV4:
944 switch (EltVT.getSimpleVT().SimpleTy) {
945 default:
946 return NULL;
947 case MVT::i8:
948 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
949 break;
950 case MVT::i16:
951 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
952 break;
953 case MVT::i32:
954 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
955 break;
956 case MVT::f32:
957 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
958 break;
959 }
960 break;
961 case NVPTXISD::LDUV4:
962 switch (EltVT.getSimpleVT().SimpleTy) {
963 default:
964 return NULL;
965 case MVT::i8:
966 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
967 break;
968 case MVT::i16:
969 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
970 break;
971 case MVT::i32:
972 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
973 break;
974 case MVT::f32:
975 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
976 break;
977 }
978 break;
979 }
980 } else {
981 switch (N->getOpcode()) {
982 default:
983 return NULL;
984 case NVPTXISD::LDGV2:
985 switch (EltVT.getSimpleVT().SimpleTy) {
986 default:
987 return NULL;
988 case MVT::i8:
989 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
990 break;
991 case MVT::i16:
992 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
993 break;
994 case MVT::i32:
995 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
996 break;
997 case MVT::i64:
998 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
999 break;
1000 case MVT::f32:
1001 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1002 break;
1003 case MVT::f64:
1004 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1005 break;
1006 }
1007 break;
1008 case NVPTXISD::LDUV2:
1009 switch (EltVT.getSimpleVT().SimpleTy) {
1010 default:
1011 return NULL;
1012 case MVT::i8:
1013 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1014 break;
1015 case MVT::i16:
1016 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1017 break;
1018 case MVT::i32:
1019 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1020 break;
1021 case MVT::i64:
1022 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1023 break;
1024 case MVT::f32:
1025 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1026 break;
1027 case MVT::f64:
1028 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1029 break;
1030 }
1031 break;
1032 case NVPTXISD::LDGV4:
1033 switch (EltVT.getSimpleVT().SimpleTy) {
1034 default:
1035 return NULL;
1036 case MVT::i8:
1037 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1038 break;
1039 case MVT::i16:
1040 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1041 break;
1042 case MVT::i32:
1043 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1044 break;
1045 case MVT::f32:
1046 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1047 break;
1048 }
1049 break;
1050 case NVPTXISD::LDUV4:
1051 switch (EltVT.getSimpleVT().SimpleTy) {
1052 default:
1053 return NULL;
1054 case MVT::i8:
1055 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1056 break;
1057 case MVT::i16:
1058 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1059 break;
1060 case MVT::i32:
1061 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1062 break;
1063 case MVT::f32:
1064 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1065 break;
1066 }
1067 break;
1068 }
1069 }
1070
1071 SDValue Ops[] = { Base, Offset, Chain };
1072
1073 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1074 ArrayRef<SDValue>(Ops, 3));
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001075 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001076 if (Subtarget.is64Bit()) {
1077 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001078 default:
1079 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001080 case NVPTXISD::LDGV2:
1081 switch (EltVT.getSimpleVT().SimpleTy) {
1082 default:
1083 return NULL;
1084 case MVT::i8:
1085 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1086 break;
1087 case MVT::i16:
1088 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1089 break;
1090 case MVT::i32:
1091 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1092 break;
1093 case MVT::i64:
1094 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1095 break;
1096 case MVT::f32:
1097 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1098 break;
1099 case MVT::f64:
1100 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1101 break;
1102 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001103 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001104 case NVPTXISD::LDUV2:
1105 switch (EltVT.getSimpleVT().SimpleTy) {
1106 default:
1107 return NULL;
1108 case MVT::i8:
1109 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1110 break;
1111 case MVT::i16:
1112 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1113 break;
1114 case MVT::i32:
1115 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1116 break;
1117 case MVT::i64:
1118 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1119 break;
1120 case MVT::f32:
1121 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1122 break;
1123 case MVT::f64:
1124 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1125 break;
1126 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001127 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001128 case NVPTXISD::LDGV4:
1129 switch (EltVT.getSimpleVT().SimpleTy) {
1130 default:
1131 return NULL;
1132 case MVT::i8:
1133 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1134 break;
1135 case MVT::i16:
1136 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1137 break;
1138 case MVT::i32:
1139 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1140 break;
1141 case MVT::f32:
1142 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1143 break;
1144 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001145 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001146 case NVPTXISD::LDUV4:
1147 switch (EltVT.getSimpleVT().SimpleTy) {
1148 default:
1149 return NULL;
1150 case MVT::i8:
1151 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1152 break;
1153 case MVT::i16:
1154 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1155 break;
1156 case MVT::i32:
1157 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1158 break;
1159 case MVT::f32:
1160 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1161 break;
1162 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001163 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001164 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001165 } else {
1166 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001167 default:
1168 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001169 case NVPTXISD::LDGV2:
1170 switch (EltVT.getSimpleVT().SimpleTy) {
1171 default:
1172 return NULL;
1173 case MVT::i8:
1174 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1175 break;
1176 case MVT::i16:
1177 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1178 break;
1179 case MVT::i32:
1180 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1181 break;
1182 case MVT::i64:
1183 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1184 break;
1185 case MVT::f32:
1186 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1187 break;
1188 case MVT::f64:
1189 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1190 break;
1191 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001192 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001193 case NVPTXISD::LDUV2:
1194 switch (EltVT.getSimpleVT().SimpleTy) {
1195 default:
1196 return NULL;
1197 case MVT::i8:
1198 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1199 break;
1200 case MVT::i16:
1201 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1202 break;
1203 case MVT::i32:
1204 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1205 break;
1206 case MVT::i64:
1207 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1208 break;
1209 case MVT::f32:
1210 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1211 break;
1212 case MVT::f64:
1213 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1214 break;
1215 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001216 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001217 case NVPTXISD::LDGV4:
1218 switch (EltVT.getSimpleVT().SimpleTy) {
1219 default:
1220 return NULL;
1221 case MVT::i8:
1222 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1223 break;
1224 case MVT::i16:
1225 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1226 break;
1227 case MVT::i32:
1228 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1229 break;
1230 case MVT::f32:
1231 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1232 break;
1233 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001234 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001235 case NVPTXISD::LDUV4:
1236 switch (EltVT.getSimpleVT().SimpleTy) {
1237 default:
1238 return NULL;
1239 case MVT::i8:
1240 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1241 break;
1242 case MVT::i16:
1243 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1244 break;
1245 case MVT::i32:
1246 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1247 break;
1248 case MVT::f32:
1249 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1250 break;
1251 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001252 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001253 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001254 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001255
Justin Holewinskie40e9292013-07-01 12:58:52 +00001256 SDValue Ops[] = { Op1, Chain };
1257 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1258 ArrayRef<SDValue>(Ops, 2));
1259 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001260
1261 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1262 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1263 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1264
1265 return LD;
1266}
1267
Justin Holewinski0497ab12013-03-30 14:29:21 +00001268SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001269 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001270 StoreSDNode *ST = cast<StoreSDNode>(N);
1271 EVT StoreVT = ST->getMemoryVT();
1272 SDNode *NVPTXST = NULL;
1273
1274 // do not support pre/post inc/dec
1275 if (ST->isIndexed())
1276 return NULL;
1277
1278 if (!StoreVT.isSimple())
1279 return NULL;
1280
1281 // Address Space Setting
1282 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1283
1284 // Volatile Setting
1285 // - .volatile is only availalble for .global and .shared
1286 bool isVolatile = ST->isVolatile();
1287 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1288 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1289 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1290 isVolatile = false;
1291
1292 // Vector Setting
1293 MVT SimpleVT = StoreVT.getSimpleVT();
1294 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1295 if (SimpleVT.isVector()) {
1296 unsigned num = SimpleVT.getVectorNumElements();
1297 if (num == 2)
1298 vecType = NVPTX::PTXLdStInstCode::V2;
1299 else if (num == 4)
1300 vecType = NVPTX::PTXLdStInstCode::V4;
1301 else
1302 return NULL;
1303 }
1304
1305 // Type Setting: toType + toTypeWidth
1306 // - for integer type, always use 'u'
1307 //
1308 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001309 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001310 unsigned int toType;
1311 if (ScalarVT.isFloatingPoint())
1312 toType = NVPTX::PTXLdStInstCode::Float;
1313 else
1314 toType = NVPTX::PTXLdStInstCode::Unsigned;
1315
1316 // Create the machine instruction DAG
1317 SDValue Chain = N->getOperand(0);
1318 SDValue N1 = N->getOperand(1);
1319 SDValue N2 = N->getOperand(2);
1320 SDValue Addr;
1321 SDValue Offset, Base;
1322 unsigned Opcode;
1323 MVT::SimpleValueType SourceVT =
1324 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1325
1326 if (SelectDirectAddr(N2, Addr)) {
1327 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001328 case MVT::i8:
1329 Opcode = NVPTX::ST_i8_avar;
1330 break;
1331 case MVT::i16:
1332 Opcode = NVPTX::ST_i16_avar;
1333 break;
1334 case MVT::i32:
1335 Opcode = NVPTX::ST_i32_avar;
1336 break;
1337 case MVT::i64:
1338 Opcode = NVPTX::ST_i64_avar;
1339 break;
1340 case MVT::f32:
1341 Opcode = NVPTX::ST_f32_avar;
1342 break;
1343 case MVT::f64:
1344 Opcode = NVPTX::ST_f64_avar;
1345 break;
1346 default:
1347 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001348 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001349 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1350 getI32Imm(vecType), getI32Imm(toType),
1351 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001352 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001353 } else if (Subtarget.is64Bit()
1354 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1355 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001356 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001357 case MVT::i8:
1358 Opcode = NVPTX::ST_i8_asi;
1359 break;
1360 case MVT::i16:
1361 Opcode = NVPTX::ST_i16_asi;
1362 break;
1363 case MVT::i32:
1364 Opcode = NVPTX::ST_i32_asi;
1365 break;
1366 case MVT::i64:
1367 Opcode = NVPTX::ST_i64_asi;
1368 break;
1369 case MVT::f32:
1370 Opcode = NVPTX::ST_f32_asi;
1371 break;
1372 case MVT::f64:
1373 Opcode = NVPTX::ST_f64_asi;
1374 break;
1375 default:
1376 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001377 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001378 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1379 getI32Imm(vecType), getI32Imm(toType),
1380 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001381 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001382 } else if (Subtarget.is64Bit()
1383 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1384 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001385 if (Subtarget.is64Bit()) {
1386 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001387 case MVT::i8:
1388 Opcode = NVPTX::ST_i8_ari_64;
1389 break;
1390 case MVT::i16:
1391 Opcode = NVPTX::ST_i16_ari_64;
1392 break;
1393 case MVT::i32:
1394 Opcode = NVPTX::ST_i32_ari_64;
1395 break;
1396 case MVT::i64:
1397 Opcode = NVPTX::ST_i64_ari_64;
1398 break;
1399 case MVT::f32:
1400 Opcode = NVPTX::ST_f32_ari_64;
1401 break;
1402 case MVT::f64:
1403 Opcode = NVPTX::ST_f64_ari_64;
1404 break;
1405 default:
1406 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001407 }
1408 } else {
1409 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001410 case MVT::i8:
1411 Opcode = NVPTX::ST_i8_ari;
1412 break;
1413 case MVT::i16:
1414 Opcode = NVPTX::ST_i16_ari;
1415 break;
1416 case MVT::i32:
1417 Opcode = NVPTX::ST_i32_ari;
1418 break;
1419 case MVT::i64:
1420 Opcode = NVPTX::ST_i64_ari;
1421 break;
1422 case MVT::f32:
1423 Opcode = NVPTX::ST_f32_ari;
1424 break;
1425 case MVT::f64:
1426 Opcode = NVPTX::ST_f64_ari;
1427 break;
1428 default:
1429 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001430 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001431 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001432 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1433 getI32Imm(vecType), getI32Imm(toType),
1434 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001435 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001436 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001437 if (Subtarget.is64Bit()) {
1438 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001439 case MVT::i8:
1440 Opcode = NVPTX::ST_i8_areg_64;
1441 break;
1442 case MVT::i16:
1443 Opcode = NVPTX::ST_i16_areg_64;
1444 break;
1445 case MVT::i32:
1446 Opcode = NVPTX::ST_i32_areg_64;
1447 break;
1448 case MVT::i64:
1449 Opcode = NVPTX::ST_i64_areg_64;
1450 break;
1451 case MVT::f32:
1452 Opcode = NVPTX::ST_f32_areg_64;
1453 break;
1454 case MVT::f64:
1455 Opcode = NVPTX::ST_f64_areg_64;
1456 break;
1457 default:
1458 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001459 }
1460 } else {
1461 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001462 case MVT::i8:
1463 Opcode = NVPTX::ST_i8_areg;
1464 break;
1465 case MVT::i16:
1466 Opcode = NVPTX::ST_i16_areg;
1467 break;
1468 case MVT::i32:
1469 Opcode = NVPTX::ST_i32_areg;
1470 break;
1471 case MVT::i64:
1472 Opcode = NVPTX::ST_i64_areg;
1473 break;
1474 case MVT::f32:
1475 Opcode = NVPTX::ST_f32_areg;
1476 break;
1477 case MVT::f64:
1478 Opcode = NVPTX::ST_f64_areg;
1479 break;
1480 default:
1481 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001482 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001483 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001484 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1485 getI32Imm(vecType), getI32Imm(toType),
1486 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001487 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001488 }
1489
1490 if (NVPTXST != NULL) {
1491 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1492 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1493 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1494 }
1495
1496 return NVPTXST;
1497}
1498
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001499SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1500 SDValue Chain = N->getOperand(0);
1501 SDValue Op1 = N->getOperand(1);
1502 SDValue Addr, Offset, Base;
1503 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001504 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001505 SDNode *ST;
1506 EVT EltVT = Op1.getValueType();
1507 MemSDNode *MemSD = cast<MemSDNode>(N);
1508 EVT StoreVT = MemSD->getMemoryVT();
1509
1510 // Address Space Setting
1511 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1512
1513 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1514 report_fatal_error("Cannot store to pointer that points to constant "
1515 "memory space");
1516 }
1517
1518 // Volatile Setting
1519 // - .volatile is only availalble for .global and .shared
1520 bool IsVolatile = MemSD->isVolatile();
1521 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1522 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1523 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1524 IsVolatile = false;
1525
1526 // Type Setting: toType + toTypeWidth
1527 // - for integer type, always use 'u'
1528 assert(StoreVT.isSimple() && "Store value is not simple");
1529 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001530 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001531 unsigned ToType;
1532 if (ScalarVT.isFloatingPoint())
1533 ToType = NVPTX::PTXLdStInstCode::Float;
1534 else
1535 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1536
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001537 SmallVector<SDValue, 12> StOps;
1538 SDValue N2;
1539 unsigned VecType;
1540
1541 switch (N->getOpcode()) {
1542 case NVPTXISD::StoreV2:
1543 VecType = NVPTX::PTXLdStInstCode::V2;
1544 StOps.push_back(N->getOperand(1));
1545 StOps.push_back(N->getOperand(2));
1546 N2 = N->getOperand(3);
1547 break;
1548 case NVPTXISD::StoreV4:
1549 VecType = NVPTX::PTXLdStInstCode::V4;
1550 StOps.push_back(N->getOperand(1));
1551 StOps.push_back(N->getOperand(2));
1552 StOps.push_back(N->getOperand(3));
1553 StOps.push_back(N->getOperand(4));
1554 N2 = N->getOperand(5);
1555 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001556 default:
1557 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001558 }
1559
1560 StOps.push_back(getI32Imm(IsVolatile));
1561 StOps.push_back(getI32Imm(CodeAddrSpace));
1562 StOps.push_back(getI32Imm(VecType));
1563 StOps.push_back(getI32Imm(ToType));
1564 StOps.push_back(getI32Imm(ToTypeWidth));
1565
1566 if (SelectDirectAddr(N2, Addr)) {
1567 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001568 default:
1569 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001570 case NVPTXISD::StoreV2:
1571 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001572 default:
1573 return NULL;
1574 case MVT::i8:
1575 Opcode = NVPTX::STV_i8_v2_avar;
1576 break;
1577 case MVT::i16:
1578 Opcode = NVPTX::STV_i16_v2_avar;
1579 break;
1580 case MVT::i32:
1581 Opcode = NVPTX::STV_i32_v2_avar;
1582 break;
1583 case MVT::i64:
1584 Opcode = NVPTX::STV_i64_v2_avar;
1585 break;
1586 case MVT::f32:
1587 Opcode = NVPTX::STV_f32_v2_avar;
1588 break;
1589 case MVT::f64:
1590 Opcode = NVPTX::STV_f64_v2_avar;
1591 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001592 }
1593 break;
1594 case NVPTXISD::StoreV4:
1595 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001596 default:
1597 return NULL;
1598 case MVT::i8:
1599 Opcode = NVPTX::STV_i8_v4_avar;
1600 break;
1601 case MVT::i16:
1602 Opcode = NVPTX::STV_i16_v4_avar;
1603 break;
1604 case MVT::i32:
1605 Opcode = NVPTX::STV_i32_v4_avar;
1606 break;
1607 case MVT::f32:
1608 Opcode = NVPTX::STV_f32_v4_avar;
1609 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001610 }
1611 break;
1612 }
1613 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001614 } else if (Subtarget.is64Bit()
1615 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1616 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001617 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001618 default:
1619 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001620 case NVPTXISD::StoreV2:
1621 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001622 default:
1623 return NULL;
1624 case MVT::i8:
1625 Opcode = NVPTX::STV_i8_v2_asi;
1626 break;
1627 case MVT::i16:
1628 Opcode = NVPTX::STV_i16_v2_asi;
1629 break;
1630 case MVT::i32:
1631 Opcode = NVPTX::STV_i32_v2_asi;
1632 break;
1633 case MVT::i64:
1634 Opcode = NVPTX::STV_i64_v2_asi;
1635 break;
1636 case MVT::f32:
1637 Opcode = NVPTX::STV_f32_v2_asi;
1638 break;
1639 case MVT::f64:
1640 Opcode = NVPTX::STV_f64_v2_asi;
1641 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001642 }
1643 break;
1644 case NVPTXISD::StoreV4:
1645 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001646 default:
1647 return NULL;
1648 case MVT::i8:
1649 Opcode = NVPTX::STV_i8_v4_asi;
1650 break;
1651 case MVT::i16:
1652 Opcode = NVPTX::STV_i16_v4_asi;
1653 break;
1654 case MVT::i32:
1655 Opcode = NVPTX::STV_i32_v4_asi;
1656 break;
1657 case MVT::f32:
1658 Opcode = NVPTX::STV_f32_v4_asi;
1659 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001660 }
1661 break;
1662 }
1663 StOps.push_back(Base);
1664 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001665 } else if (Subtarget.is64Bit()
1666 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1667 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001668 if (Subtarget.is64Bit()) {
1669 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001670 default:
1671 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001672 case NVPTXISD::StoreV2:
1673 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001674 default:
1675 return NULL;
1676 case MVT::i8:
1677 Opcode = NVPTX::STV_i8_v2_ari_64;
1678 break;
1679 case MVT::i16:
1680 Opcode = NVPTX::STV_i16_v2_ari_64;
1681 break;
1682 case MVT::i32:
1683 Opcode = NVPTX::STV_i32_v2_ari_64;
1684 break;
1685 case MVT::i64:
1686 Opcode = NVPTX::STV_i64_v2_ari_64;
1687 break;
1688 case MVT::f32:
1689 Opcode = NVPTX::STV_f32_v2_ari_64;
1690 break;
1691 case MVT::f64:
1692 Opcode = NVPTX::STV_f64_v2_ari_64;
1693 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001694 }
1695 break;
1696 case NVPTXISD::StoreV4:
1697 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001698 default:
1699 return NULL;
1700 case MVT::i8:
1701 Opcode = NVPTX::STV_i8_v4_ari_64;
1702 break;
1703 case MVT::i16:
1704 Opcode = NVPTX::STV_i16_v4_ari_64;
1705 break;
1706 case MVT::i32:
1707 Opcode = NVPTX::STV_i32_v4_ari_64;
1708 break;
1709 case MVT::f32:
1710 Opcode = NVPTX::STV_f32_v4_ari_64;
1711 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001712 }
1713 break;
1714 }
1715 } else {
1716 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001717 default:
1718 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001719 case NVPTXISD::StoreV2:
1720 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001721 default:
1722 return NULL;
1723 case MVT::i8:
1724 Opcode = NVPTX::STV_i8_v2_ari;
1725 break;
1726 case MVT::i16:
1727 Opcode = NVPTX::STV_i16_v2_ari;
1728 break;
1729 case MVT::i32:
1730 Opcode = NVPTX::STV_i32_v2_ari;
1731 break;
1732 case MVT::i64:
1733 Opcode = NVPTX::STV_i64_v2_ari;
1734 break;
1735 case MVT::f32:
1736 Opcode = NVPTX::STV_f32_v2_ari;
1737 break;
1738 case MVT::f64:
1739 Opcode = NVPTX::STV_f64_v2_ari;
1740 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001741 }
1742 break;
1743 case NVPTXISD::StoreV4:
1744 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001745 default:
1746 return NULL;
1747 case MVT::i8:
1748 Opcode = NVPTX::STV_i8_v4_ari;
1749 break;
1750 case MVT::i16:
1751 Opcode = NVPTX::STV_i16_v4_ari;
1752 break;
1753 case MVT::i32:
1754 Opcode = NVPTX::STV_i32_v4_ari;
1755 break;
1756 case MVT::f32:
1757 Opcode = NVPTX::STV_f32_v4_ari;
1758 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001759 }
1760 break;
1761 }
1762 }
1763 StOps.push_back(Base);
1764 StOps.push_back(Offset);
1765 } else {
1766 if (Subtarget.is64Bit()) {
1767 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001768 default:
1769 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001770 case NVPTXISD::StoreV2:
1771 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001772 default:
1773 return NULL;
1774 case MVT::i8:
1775 Opcode = NVPTX::STV_i8_v2_areg_64;
1776 break;
1777 case MVT::i16:
1778 Opcode = NVPTX::STV_i16_v2_areg_64;
1779 break;
1780 case MVT::i32:
1781 Opcode = NVPTX::STV_i32_v2_areg_64;
1782 break;
1783 case MVT::i64:
1784 Opcode = NVPTX::STV_i64_v2_areg_64;
1785 break;
1786 case MVT::f32:
1787 Opcode = NVPTX::STV_f32_v2_areg_64;
1788 break;
1789 case MVT::f64:
1790 Opcode = NVPTX::STV_f64_v2_areg_64;
1791 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001792 }
1793 break;
1794 case NVPTXISD::StoreV4:
1795 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001796 default:
1797 return NULL;
1798 case MVT::i8:
1799 Opcode = NVPTX::STV_i8_v4_areg_64;
1800 break;
1801 case MVT::i16:
1802 Opcode = NVPTX::STV_i16_v4_areg_64;
1803 break;
1804 case MVT::i32:
1805 Opcode = NVPTX::STV_i32_v4_areg_64;
1806 break;
1807 case MVT::f32:
1808 Opcode = NVPTX::STV_f32_v4_areg_64;
1809 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001810 }
1811 break;
1812 }
1813 } else {
1814 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001815 default:
1816 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001817 case NVPTXISD::StoreV2:
1818 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001819 default:
1820 return NULL;
1821 case MVT::i8:
1822 Opcode = NVPTX::STV_i8_v2_areg;
1823 break;
1824 case MVT::i16:
1825 Opcode = NVPTX::STV_i16_v2_areg;
1826 break;
1827 case MVT::i32:
1828 Opcode = NVPTX::STV_i32_v2_areg;
1829 break;
1830 case MVT::i64:
1831 Opcode = NVPTX::STV_i64_v2_areg;
1832 break;
1833 case MVT::f32:
1834 Opcode = NVPTX::STV_f32_v2_areg;
1835 break;
1836 case MVT::f64:
1837 Opcode = NVPTX::STV_f64_v2_areg;
1838 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001839 }
1840 break;
1841 case NVPTXISD::StoreV4:
1842 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001843 default:
1844 return NULL;
1845 case MVT::i8:
1846 Opcode = NVPTX::STV_i8_v4_areg;
1847 break;
1848 case MVT::i16:
1849 Opcode = NVPTX::STV_i16_v4_areg;
1850 break;
1851 case MVT::i32:
1852 Opcode = NVPTX::STV_i32_v4_areg;
1853 break;
1854 case MVT::f32:
1855 Opcode = NVPTX::STV_f32_v4_areg;
1856 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001857 }
1858 break;
1859 }
1860 }
1861 StOps.push_back(N2);
1862 }
1863
1864 StOps.push_back(Chain);
1865
Michael Liaob53d8962013-04-19 22:22:57 +00001866 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001867
1868 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1869 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1870 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1871
1872 return ST;
1873}
1874
Justin Holewinskif8f70912013-06-28 17:57:59 +00001875SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
1876 SDValue Chain = Node->getOperand(0);
1877 SDValue Offset = Node->getOperand(2);
1878 SDValue Flag = Node->getOperand(3);
1879 SDLoc DL(Node);
1880 MemSDNode *Mem = cast<MemSDNode>(Node);
1881
1882 unsigned VecSize;
1883 switch (Node->getOpcode()) {
1884 default:
1885 return NULL;
1886 case NVPTXISD::LoadParam:
1887 VecSize = 1;
1888 break;
1889 case NVPTXISD::LoadParamV2:
1890 VecSize = 2;
1891 break;
1892 case NVPTXISD::LoadParamV4:
1893 VecSize = 4;
1894 break;
1895 }
1896
1897 EVT EltVT = Node->getValueType(0);
1898 EVT MemVT = Mem->getMemoryVT();
1899
1900 unsigned Opc = 0;
1901
1902 switch (VecSize) {
1903 default:
1904 return NULL;
1905 case 1:
1906 switch (MemVT.getSimpleVT().SimpleTy) {
1907 default:
1908 return NULL;
1909 case MVT::i1:
1910 Opc = NVPTX::LoadParamMemI8;
1911 break;
1912 case MVT::i8:
1913 Opc = NVPTX::LoadParamMemI8;
1914 break;
1915 case MVT::i16:
1916 Opc = NVPTX::LoadParamMemI16;
1917 break;
1918 case MVT::i32:
1919 Opc = NVPTX::LoadParamMemI32;
1920 break;
1921 case MVT::i64:
1922 Opc = NVPTX::LoadParamMemI64;
1923 break;
1924 case MVT::f32:
1925 Opc = NVPTX::LoadParamMemF32;
1926 break;
1927 case MVT::f64:
1928 Opc = NVPTX::LoadParamMemF64;
1929 break;
1930 }
1931 break;
1932 case 2:
1933 switch (MemVT.getSimpleVT().SimpleTy) {
1934 default:
1935 return NULL;
1936 case MVT::i1:
1937 Opc = NVPTX::LoadParamMemV2I8;
1938 break;
1939 case MVT::i8:
1940 Opc = NVPTX::LoadParamMemV2I8;
1941 break;
1942 case MVT::i16:
1943 Opc = NVPTX::LoadParamMemV2I16;
1944 break;
1945 case MVT::i32:
1946 Opc = NVPTX::LoadParamMemV2I32;
1947 break;
1948 case MVT::i64:
1949 Opc = NVPTX::LoadParamMemV2I64;
1950 break;
1951 case MVT::f32:
1952 Opc = NVPTX::LoadParamMemV2F32;
1953 break;
1954 case MVT::f64:
1955 Opc = NVPTX::LoadParamMemV2F64;
1956 break;
1957 }
1958 break;
1959 case 4:
1960 switch (MemVT.getSimpleVT().SimpleTy) {
1961 default:
1962 return NULL;
1963 case MVT::i1:
1964 Opc = NVPTX::LoadParamMemV4I8;
1965 break;
1966 case MVT::i8:
1967 Opc = NVPTX::LoadParamMemV4I8;
1968 break;
1969 case MVT::i16:
1970 Opc = NVPTX::LoadParamMemV4I16;
1971 break;
1972 case MVT::i32:
1973 Opc = NVPTX::LoadParamMemV4I32;
1974 break;
1975 case MVT::f32:
1976 Opc = NVPTX::LoadParamMemV4F32;
1977 break;
1978 }
1979 break;
1980 }
1981
1982 SDVTList VTs;
1983 if (VecSize == 1) {
1984 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
1985 } else if (VecSize == 2) {
1986 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
1987 } else {
1988 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
1989 VTs = CurDAG->getVTList(&EVTs[0], 5);
1990 }
1991
1992 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
1993
1994 SmallVector<SDValue, 2> Ops;
1995 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
1996 Ops.push_back(Chain);
1997 Ops.push_back(Flag);
1998
1999 SDNode *Ret =
2000 CurDAG->getMachineNode(Opc, DL, Node->getVTList(), Ops);
2001 return Ret;
2002}
2003
2004SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2005 SDLoc DL(N);
2006 SDValue Chain = N->getOperand(0);
2007 SDValue Offset = N->getOperand(1);
2008 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2009 MemSDNode *Mem = cast<MemSDNode>(N);
2010
2011 // How many elements do we have?
2012 unsigned NumElts = 1;
2013 switch (N->getOpcode()) {
2014 default:
2015 return NULL;
2016 case NVPTXISD::StoreRetval:
2017 NumElts = 1;
2018 break;
2019 case NVPTXISD::StoreRetvalV2:
2020 NumElts = 2;
2021 break;
2022 case NVPTXISD::StoreRetvalV4:
2023 NumElts = 4;
2024 break;
2025 }
2026
2027 // Build vector of operands
2028 SmallVector<SDValue, 6> Ops;
2029 for (unsigned i = 0; i < NumElts; ++i)
2030 Ops.push_back(N->getOperand(i + 2));
2031 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2032 Ops.push_back(Chain);
2033
2034 // Determine target opcode
2035 // If we have an i1, use an 8-bit store. The lowering code in
2036 // NVPTXISelLowering will have already emitted an upcast.
2037 unsigned Opcode = 0;
2038 switch (NumElts) {
2039 default:
2040 return NULL;
2041 case 1:
2042 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2043 default:
2044 return NULL;
2045 case MVT::i1:
2046 Opcode = NVPTX::StoreRetvalI8;
2047 break;
2048 case MVT::i8:
2049 Opcode = NVPTX::StoreRetvalI8;
2050 break;
2051 case MVT::i16:
2052 Opcode = NVPTX::StoreRetvalI16;
2053 break;
2054 case MVT::i32:
2055 Opcode = NVPTX::StoreRetvalI32;
2056 break;
2057 case MVT::i64:
2058 Opcode = NVPTX::StoreRetvalI64;
2059 break;
2060 case MVT::f32:
2061 Opcode = NVPTX::StoreRetvalF32;
2062 break;
2063 case MVT::f64:
2064 Opcode = NVPTX::StoreRetvalF64;
2065 break;
2066 }
2067 break;
2068 case 2:
2069 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2070 default:
2071 return NULL;
2072 case MVT::i1:
2073 Opcode = NVPTX::StoreRetvalV2I8;
2074 break;
2075 case MVT::i8:
2076 Opcode = NVPTX::StoreRetvalV2I8;
2077 break;
2078 case MVT::i16:
2079 Opcode = NVPTX::StoreRetvalV2I16;
2080 break;
2081 case MVT::i32:
2082 Opcode = NVPTX::StoreRetvalV2I32;
2083 break;
2084 case MVT::i64:
2085 Opcode = NVPTX::StoreRetvalV2I64;
2086 break;
2087 case MVT::f32:
2088 Opcode = NVPTX::StoreRetvalV2F32;
2089 break;
2090 case MVT::f64:
2091 Opcode = NVPTX::StoreRetvalV2F64;
2092 break;
2093 }
2094 break;
2095 case 4:
2096 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2097 default:
2098 return NULL;
2099 case MVT::i1:
2100 Opcode = NVPTX::StoreRetvalV4I8;
2101 break;
2102 case MVT::i8:
2103 Opcode = NVPTX::StoreRetvalV4I8;
2104 break;
2105 case MVT::i16:
2106 Opcode = NVPTX::StoreRetvalV4I16;
2107 break;
2108 case MVT::i32:
2109 Opcode = NVPTX::StoreRetvalV4I32;
2110 break;
2111 case MVT::f32:
2112 Opcode = NVPTX::StoreRetvalV4F32;
2113 break;
2114 }
2115 break;
2116 }
2117
2118 SDNode *Ret =
2119 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2120 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2121 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2122 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2123
2124 return Ret;
2125}
2126
2127SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2128 SDLoc DL(N);
2129 SDValue Chain = N->getOperand(0);
2130 SDValue Param = N->getOperand(1);
2131 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2132 SDValue Offset = N->getOperand(2);
2133 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2134 MemSDNode *Mem = cast<MemSDNode>(N);
2135 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2136
2137 // How many elements do we have?
2138 unsigned NumElts = 1;
2139 switch (N->getOpcode()) {
2140 default:
2141 return NULL;
2142 case NVPTXISD::StoreParamU32:
2143 case NVPTXISD::StoreParamS32:
2144 case NVPTXISD::StoreParam:
2145 NumElts = 1;
2146 break;
2147 case NVPTXISD::StoreParamV2:
2148 NumElts = 2;
2149 break;
2150 case NVPTXISD::StoreParamV4:
2151 NumElts = 4;
2152 break;
2153 }
2154
2155 // Build vector of operands
2156 SmallVector<SDValue, 8> Ops;
2157 for (unsigned i = 0; i < NumElts; ++i)
2158 Ops.push_back(N->getOperand(i + 3));
2159 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2160 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2161 Ops.push_back(Chain);
2162 Ops.push_back(Flag);
2163
2164 // Determine target opcode
2165 // If we have an i1, use an 8-bit store. The lowering code in
2166 // NVPTXISelLowering will have already emitted an upcast.
2167 unsigned Opcode = 0;
2168 switch (N->getOpcode()) {
2169 default:
2170 switch (NumElts) {
2171 default:
2172 return NULL;
2173 case 1:
2174 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2175 default:
2176 return NULL;
2177 case MVT::i1:
2178 Opcode = NVPTX::StoreParamI8;
2179 break;
2180 case MVT::i8:
2181 Opcode = NVPTX::StoreParamI8;
2182 break;
2183 case MVT::i16:
2184 Opcode = NVPTX::StoreParamI16;
2185 break;
2186 case MVT::i32:
2187 Opcode = NVPTX::StoreParamI32;
2188 break;
2189 case MVT::i64:
2190 Opcode = NVPTX::StoreParamI64;
2191 break;
2192 case MVT::f32:
2193 Opcode = NVPTX::StoreParamF32;
2194 break;
2195 case MVT::f64:
2196 Opcode = NVPTX::StoreParamF64;
2197 break;
2198 }
2199 break;
2200 case 2:
2201 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2202 default:
2203 return NULL;
2204 case MVT::i1:
2205 Opcode = NVPTX::StoreParamV2I8;
2206 break;
2207 case MVT::i8:
2208 Opcode = NVPTX::StoreParamV2I8;
2209 break;
2210 case MVT::i16:
2211 Opcode = NVPTX::StoreParamV2I16;
2212 break;
2213 case MVT::i32:
2214 Opcode = NVPTX::StoreParamV2I32;
2215 break;
2216 case MVT::i64:
2217 Opcode = NVPTX::StoreParamV2I64;
2218 break;
2219 case MVT::f32:
2220 Opcode = NVPTX::StoreParamV2F32;
2221 break;
2222 case MVT::f64:
2223 Opcode = NVPTX::StoreParamV2F64;
2224 break;
2225 }
2226 break;
2227 case 4:
2228 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2229 default:
2230 return NULL;
2231 case MVT::i1:
2232 Opcode = NVPTX::StoreParamV4I8;
2233 break;
2234 case MVT::i8:
2235 Opcode = NVPTX::StoreParamV4I8;
2236 break;
2237 case MVT::i16:
2238 Opcode = NVPTX::StoreParamV4I16;
2239 break;
2240 case MVT::i32:
2241 Opcode = NVPTX::StoreParamV4I32;
2242 break;
2243 case MVT::f32:
2244 Opcode = NVPTX::StoreParamV4F32;
2245 break;
2246 }
2247 break;
2248 }
2249 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002250 // Special case: if we have a sign-extend/zero-extend node, insert the
2251 // conversion instruction first, and use that as the value operand to
2252 // the selected StoreParam node.
2253 case NVPTXISD::StoreParamU32: {
2254 Opcode = NVPTX::StoreParamI32;
2255 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2256 MVT::i32);
2257 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2258 MVT::i32, Ops[0], CvtNone);
2259 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002260 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002261 }
2262 case NVPTXISD::StoreParamS32: {
2263 Opcode = NVPTX::StoreParamI32;
2264 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2265 MVT::i32);
2266 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2267 MVT::i32, Ops[0], CvtNone);
2268 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002269 break;
2270 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002271 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002272
2273 SDNode *Ret =
2274 CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
2275 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2276 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2277 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2278
2279 return Ret;
2280}
2281
Justin Holewinskiae556d32012-05-04 20:18:50 +00002282// SelectDirectAddr - Match a direct address for DAG.
2283// A direct address could be a globaladdress or externalsymbol.
2284bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2285 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002286 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2287 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002288 Address = N;
2289 return true;
2290 }
2291 if (N.getOpcode() == NVPTXISD::Wrapper) {
2292 Address = N.getOperand(0);
2293 return true;
2294 }
2295 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2296 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2297 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2298 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2299 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2300 }
2301 return false;
2302}
2303
2304// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002305bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2306 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002307 if (Addr.getOpcode() == ISD::ADD) {
2308 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002309 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002310 if (SelectDirectAddr(base, Base)) {
2311 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2312 return true;
2313 }
2314 }
2315 }
2316 return false;
2317}
2318
2319// symbol+offset
2320bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
2321 SDValue &Base, SDValue &Offset) {
2322 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
2323}
2324
2325// symbol+offset
2326bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
2327 SDValue &Base, SDValue &Offset) {
2328 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
2329}
2330
2331// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002332bool NVPTXDAGToDAGISel::SelectADDRri_imp(
2333 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002334 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2335 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2336 Offset = CurDAG->getTargetConstant(0, mvt);
2337 return true;
2338 }
2339 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2340 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00002341 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00002342
2343 if (Addr.getOpcode() == ISD::ADD) {
2344 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
2345 return false;
2346 }
2347 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
2348 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00002349 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002350 // Constant offset from frame ref.
2351 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2352 else
2353 Base = Addr.getOperand(0);
2354 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2355 return true;
2356 }
2357 }
2358 return false;
2359}
2360
2361// register+offset
2362bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
2363 SDValue &Base, SDValue &Offset) {
2364 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
2365}
2366
2367// register+offset
2368bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
2369 SDValue &Base, SDValue &Offset) {
2370 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
2371}
2372
2373bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
2374 unsigned int spN) const {
2375 const Value *Src = NULL;
2376 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
2377 // the classof() for MemSDNode does not include MemIntrinsicSDNode
2378 // (See SelectionDAGNodes.h). So we need to check for both.
2379 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
2380 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00002381 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002382 Src = mN->getSrcValue();
2383 }
2384 if (!Src)
2385 return false;
2386 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
2387 return (PT->getAddressSpace() == spN);
2388 return false;
2389}
2390
2391/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2392/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002393bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
2394 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002395 SDValue Op0, Op1;
2396 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002397 default:
2398 return true;
2399 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00002400 if (SelectDirectAddr(Op, Op0)) {
2401 OutOps.push_back(Op0);
2402 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
2403 return false;
2404 }
2405 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
2406 OutOps.push_back(Op0);
2407 OutOps.push_back(Op1);
2408 return false;
2409 }
2410 break;
2411 }
2412 return true;
2413}
2414
2415// Return true if N is a undef or a constant.
2416// If N was undef, return a (i8imm 0) in Retval
2417// If N was imm, convert it to i8imm and return in Retval
2418// Note: The convert to i8imm is required, otherwise the
2419// pattern matcher inserts a bunch of IMOVi8rr to convert
2420// the imm to i8imm, and this causes instruction selection
2421// to fail.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002422bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
2423 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002424 return false;
2425
2426 if (N.getOpcode() == ISD::UNDEF)
2427 Retval = CurDAG->getTargetConstant(0, MVT::i8);
2428 else {
2429 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
2430 unsigned retval = cn->getZExtValue();
2431 Retval = CurDAG->getTargetConstant(retval, MVT::i8);
2432 }
2433 return true;
2434}