blob: 4457ec349cba9e80f1ad802aa455f04a85f655bb [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;
790
Justin Holewinskif8f70912013-06-28 17:57:59 +0000791 MemSDNode *Mem = cast<MemSDNode>(N);
792
793 EVT RetVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000794
795 // Select opcode
796 if (Subtarget.is64Bit()) {
797 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000798 default:
799 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000800 case NVPTXISD::LDGV2:
801 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000802 default:
803 return NULL;
804 case MVT::i8:
805 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
806 break;
807 case MVT::i16:
808 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
809 break;
810 case MVT::i32:
811 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
812 break;
813 case MVT::i64:
814 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
815 break;
816 case MVT::f32:
817 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
818 break;
819 case MVT::f64:
820 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
821 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000822 }
823 break;
824 case NVPTXISD::LDGV4:
825 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000826 default:
827 return NULL;
828 case MVT::i8:
829 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
830 break;
831 case MVT::i16:
832 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
833 break;
834 case MVT::i32:
835 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
836 break;
837 case MVT::f32:
838 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
839 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000840 }
841 break;
842 case NVPTXISD::LDUV2:
843 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000844 default:
845 return NULL;
846 case MVT::i8:
847 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
848 break;
849 case MVT::i16:
850 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
851 break;
852 case MVT::i32:
853 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
854 break;
855 case MVT::i64:
856 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
857 break;
858 case MVT::f32:
859 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
860 break;
861 case MVT::f64:
862 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
863 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000864 }
865 break;
866 case NVPTXISD::LDUV4:
867 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000868 default:
869 return NULL;
870 case MVT::i8:
871 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
872 break;
873 case MVT::i16:
874 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
875 break;
876 case MVT::i32:
877 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
878 break;
879 case MVT::f32:
880 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
881 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000882 }
883 break;
884 }
885 } else {
886 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000887 default:
888 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000889 case NVPTXISD::LDGV2:
890 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000891 default:
892 return NULL;
893 case MVT::i8:
894 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
895 break;
896 case MVT::i16:
897 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
898 break;
899 case MVT::i32:
900 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
901 break;
902 case MVT::i64:
903 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
904 break;
905 case MVT::f32:
906 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
907 break;
908 case MVT::f64:
909 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
910 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000911 }
912 break;
913 case NVPTXISD::LDGV4:
914 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000915 default:
916 return NULL;
917 case MVT::i8:
918 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
919 break;
920 case MVT::i16:
921 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
922 break;
923 case MVT::i32:
924 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
925 break;
926 case MVT::f32:
927 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
928 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000929 }
930 break;
931 case NVPTXISD::LDUV2:
932 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000933 default:
934 return NULL;
935 case MVT::i8:
936 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
937 break;
938 case MVT::i16:
939 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
940 break;
941 case MVT::i32:
942 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
943 break;
944 case MVT::i64:
945 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
946 break;
947 case MVT::f32:
948 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
949 break;
950 case MVT::f64:
951 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
952 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000953 }
954 break;
955 case NVPTXISD::LDUV4:
956 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000957 default:
958 return NULL;
959 case MVT::i8:
960 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
961 break;
962 case MVT::i16:
963 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
964 break;
965 case MVT::i32:
966 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
967 break;
968 case MVT::f32:
969 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
970 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000971 }
972 break;
973 }
974 }
975
976 SDValue Ops[] = { Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000977 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000978
979 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
980 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
981 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
982
983 return LD;
984}
985
Justin Holewinski0497ab12013-03-30 14:29:21 +0000986SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000987 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000988 StoreSDNode *ST = cast<StoreSDNode>(N);
989 EVT StoreVT = ST->getMemoryVT();
990 SDNode *NVPTXST = NULL;
991
992 // do not support pre/post inc/dec
993 if (ST->isIndexed())
994 return NULL;
995
996 if (!StoreVT.isSimple())
997 return NULL;
998
999 // Address Space Setting
1000 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1001
1002 // Volatile Setting
1003 // - .volatile is only availalble for .global and .shared
1004 bool isVolatile = ST->isVolatile();
1005 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1006 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1007 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1008 isVolatile = false;
1009
1010 // Vector Setting
1011 MVT SimpleVT = StoreVT.getSimpleVT();
1012 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1013 if (SimpleVT.isVector()) {
1014 unsigned num = SimpleVT.getVectorNumElements();
1015 if (num == 2)
1016 vecType = NVPTX::PTXLdStInstCode::V2;
1017 else if (num == 4)
1018 vecType = NVPTX::PTXLdStInstCode::V4;
1019 else
1020 return NULL;
1021 }
1022
1023 // Type Setting: toType + toTypeWidth
1024 // - for integer type, always use 'u'
1025 //
1026 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001027 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001028 unsigned int toType;
1029 if (ScalarVT.isFloatingPoint())
1030 toType = NVPTX::PTXLdStInstCode::Float;
1031 else
1032 toType = NVPTX::PTXLdStInstCode::Unsigned;
1033
1034 // Create the machine instruction DAG
1035 SDValue Chain = N->getOperand(0);
1036 SDValue N1 = N->getOperand(1);
1037 SDValue N2 = N->getOperand(2);
1038 SDValue Addr;
1039 SDValue Offset, Base;
1040 unsigned Opcode;
1041 MVT::SimpleValueType SourceVT =
1042 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1043
1044 if (SelectDirectAddr(N2, Addr)) {
1045 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001046 case MVT::i8:
1047 Opcode = NVPTX::ST_i8_avar;
1048 break;
1049 case MVT::i16:
1050 Opcode = NVPTX::ST_i16_avar;
1051 break;
1052 case MVT::i32:
1053 Opcode = NVPTX::ST_i32_avar;
1054 break;
1055 case MVT::i64:
1056 Opcode = NVPTX::ST_i64_avar;
1057 break;
1058 case MVT::f32:
1059 Opcode = NVPTX::ST_f32_avar;
1060 break;
1061 case MVT::f64:
1062 Opcode = NVPTX::ST_f64_avar;
1063 break;
1064 default:
1065 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001066 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001067 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1068 getI32Imm(vecType), getI32Imm(toType),
1069 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001070 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001071 } else if (Subtarget.is64Bit()
1072 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1073 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001074 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001075 case MVT::i8:
1076 Opcode = NVPTX::ST_i8_asi;
1077 break;
1078 case MVT::i16:
1079 Opcode = NVPTX::ST_i16_asi;
1080 break;
1081 case MVT::i32:
1082 Opcode = NVPTX::ST_i32_asi;
1083 break;
1084 case MVT::i64:
1085 Opcode = NVPTX::ST_i64_asi;
1086 break;
1087 case MVT::f32:
1088 Opcode = NVPTX::ST_f32_asi;
1089 break;
1090 case MVT::f64:
1091 Opcode = NVPTX::ST_f64_asi;
1092 break;
1093 default:
1094 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001095 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001096 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1097 getI32Imm(vecType), getI32Imm(toType),
1098 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001099 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001100 } else if (Subtarget.is64Bit()
1101 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1102 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001103 if (Subtarget.is64Bit()) {
1104 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001105 case MVT::i8:
1106 Opcode = NVPTX::ST_i8_ari_64;
1107 break;
1108 case MVT::i16:
1109 Opcode = NVPTX::ST_i16_ari_64;
1110 break;
1111 case MVT::i32:
1112 Opcode = NVPTX::ST_i32_ari_64;
1113 break;
1114 case MVT::i64:
1115 Opcode = NVPTX::ST_i64_ari_64;
1116 break;
1117 case MVT::f32:
1118 Opcode = NVPTX::ST_f32_ari_64;
1119 break;
1120 case MVT::f64:
1121 Opcode = NVPTX::ST_f64_ari_64;
1122 break;
1123 default:
1124 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001125 }
1126 } else {
1127 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001128 case MVT::i8:
1129 Opcode = NVPTX::ST_i8_ari;
1130 break;
1131 case MVT::i16:
1132 Opcode = NVPTX::ST_i16_ari;
1133 break;
1134 case MVT::i32:
1135 Opcode = NVPTX::ST_i32_ari;
1136 break;
1137 case MVT::i64:
1138 Opcode = NVPTX::ST_i64_ari;
1139 break;
1140 case MVT::f32:
1141 Opcode = NVPTX::ST_f32_ari;
1142 break;
1143 case MVT::f64:
1144 Opcode = NVPTX::ST_f64_ari;
1145 break;
1146 default:
1147 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001148 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001149 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001150 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1151 getI32Imm(vecType), getI32Imm(toType),
1152 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001153 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001154 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001155 if (Subtarget.is64Bit()) {
1156 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001157 case MVT::i8:
1158 Opcode = NVPTX::ST_i8_areg_64;
1159 break;
1160 case MVT::i16:
1161 Opcode = NVPTX::ST_i16_areg_64;
1162 break;
1163 case MVT::i32:
1164 Opcode = NVPTX::ST_i32_areg_64;
1165 break;
1166 case MVT::i64:
1167 Opcode = NVPTX::ST_i64_areg_64;
1168 break;
1169 case MVT::f32:
1170 Opcode = NVPTX::ST_f32_areg_64;
1171 break;
1172 case MVT::f64:
1173 Opcode = NVPTX::ST_f64_areg_64;
1174 break;
1175 default:
1176 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001177 }
1178 } else {
1179 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001180 case MVT::i8:
1181 Opcode = NVPTX::ST_i8_areg;
1182 break;
1183 case MVT::i16:
1184 Opcode = NVPTX::ST_i16_areg;
1185 break;
1186 case MVT::i32:
1187 Opcode = NVPTX::ST_i32_areg;
1188 break;
1189 case MVT::i64:
1190 Opcode = NVPTX::ST_i64_areg;
1191 break;
1192 case MVT::f32:
1193 Opcode = NVPTX::ST_f32_areg;
1194 break;
1195 case MVT::f64:
1196 Opcode = NVPTX::ST_f64_areg;
1197 break;
1198 default:
1199 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001200 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001201 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001202 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1203 getI32Imm(vecType), getI32Imm(toType),
1204 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001205 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001206 }
1207
1208 if (NVPTXST != NULL) {
1209 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1210 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1211 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1212 }
1213
1214 return NVPTXST;
1215}
1216
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001217SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1218 SDValue Chain = N->getOperand(0);
1219 SDValue Op1 = N->getOperand(1);
1220 SDValue Addr, Offset, Base;
1221 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001222 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001223 SDNode *ST;
1224 EVT EltVT = Op1.getValueType();
1225 MemSDNode *MemSD = cast<MemSDNode>(N);
1226 EVT StoreVT = MemSD->getMemoryVT();
1227
1228 // Address Space Setting
1229 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1230
1231 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1232 report_fatal_error("Cannot store to pointer that points to constant "
1233 "memory space");
1234 }
1235
1236 // Volatile Setting
1237 // - .volatile is only availalble for .global and .shared
1238 bool IsVolatile = MemSD->isVolatile();
1239 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1240 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1241 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1242 IsVolatile = false;
1243
1244 // Type Setting: toType + toTypeWidth
1245 // - for integer type, always use 'u'
1246 assert(StoreVT.isSimple() && "Store value is not simple");
1247 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001248 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001249 unsigned ToType;
1250 if (ScalarVT.isFloatingPoint())
1251 ToType = NVPTX::PTXLdStInstCode::Float;
1252 else
1253 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1254
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001255 SmallVector<SDValue, 12> StOps;
1256 SDValue N2;
1257 unsigned VecType;
1258
1259 switch (N->getOpcode()) {
1260 case NVPTXISD::StoreV2:
1261 VecType = NVPTX::PTXLdStInstCode::V2;
1262 StOps.push_back(N->getOperand(1));
1263 StOps.push_back(N->getOperand(2));
1264 N2 = N->getOperand(3);
1265 break;
1266 case NVPTXISD::StoreV4:
1267 VecType = NVPTX::PTXLdStInstCode::V4;
1268 StOps.push_back(N->getOperand(1));
1269 StOps.push_back(N->getOperand(2));
1270 StOps.push_back(N->getOperand(3));
1271 StOps.push_back(N->getOperand(4));
1272 N2 = N->getOperand(5);
1273 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001274 default:
1275 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001276 }
1277
1278 StOps.push_back(getI32Imm(IsVolatile));
1279 StOps.push_back(getI32Imm(CodeAddrSpace));
1280 StOps.push_back(getI32Imm(VecType));
1281 StOps.push_back(getI32Imm(ToType));
1282 StOps.push_back(getI32Imm(ToTypeWidth));
1283
1284 if (SelectDirectAddr(N2, Addr)) {
1285 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001286 default:
1287 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001288 case NVPTXISD::StoreV2:
1289 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001290 default:
1291 return NULL;
1292 case MVT::i8:
1293 Opcode = NVPTX::STV_i8_v2_avar;
1294 break;
1295 case MVT::i16:
1296 Opcode = NVPTX::STV_i16_v2_avar;
1297 break;
1298 case MVT::i32:
1299 Opcode = NVPTX::STV_i32_v2_avar;
1300 break;
1301 case MVT::i64:
1302 Opcode = NVPTX::STV_i64_v2_avar;
1303 break;
1304 case MVT::f32:
1305 Opcode = NVPTX::STV_f32_v2_avar;
1306 break;
1307 case MVT::f64:
1308 Opcode = NVPTX::STV_f64_v2_avar;
1309 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001310 }
1311 break;
1312 case NVPTXISD::StoreV4:
1313 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001314 default:
1315 return NULL;
1316 case MVT::i8:
1317 Opcode = NVPTX::STV_i8_v4_avar;
1318 break;
1319 case MVT::i16:
1320 Opcode = NVPTX::STV_i16_v4_avar;
1321 break;
1322 case MVT::i32:
1323 Opcode = NVPTX::STV_i32_v4_avar;
1324 break;
1325 case MVT::f32:
1326 Opcode = NVPTX::STV_f32_v4_avar;
1327 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001328 }
1329 break;
1330 }
1331 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001332 } else if (Subtarget.is64Bit()
1333 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1334 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001335 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001336 default:
1337 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001338 case NVPTXISD::StoreV2:
1339 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001340 default:
1341 return NULL;
1342 case MVT::i8:
1343 Opcode = NVPTX::STV_i8_v2_asi;
1344 break;
1345 case MVT::i16:
1346 Opcode = NVPTX::STV_i16_v2_asi;
1347 break;
1348 case MVT::i32:
1349 Opcode = NVPTX::STV_i32_v2_asi;
1350 break;
1351 case MVT::i64:
1352 Opcode = NVPTX::STV_i64_v2_asi;
1353 break;
1354 case MVT::f32:
1355 Opcode = NVPTX::STV_f32_v2_asi;
1356 break;
1357 case MVT::f64:
1358 Opcode = NVPTX::STV_f64_v2_asi;
1359 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001360 }
1361 break;
1362 case NVPTXISD::StoreV4:
1363 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001364 default:
1365 return NULL;
1366 case MVT::i8:
1367 Opcode = NVPTX::STV_i8_v4_asi;
1368 break;
1369 case MVT::i16:
1370 Opcode = NVPTX::STV_i16_v4_asi;
1371 break;
1372 case MVT::i32:
1373 Opcode = NVPTX::STV_i32_v4_asi;
1374 break;
1375 case MVT::f32:
1376 Opcode = NVPTX::STV_f32_v4_asi;
1377 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001378 }
1379 break;
1380 }
1381 StOps.push_back(Base);
1382 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001383 } else if (Subtarget.is64Bit()
1384 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1385 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001386 if (Subtarget.is64Bit()) {
1387 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001388 default:
1389 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001390 case NVPTXISD::StoreV2:
1391 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001392 default:
1393 return NULL;
1394 case MVT::i8:
1395 Opcode = NVPTX::STV_i8_v2_ari_64;
1396 break;
1397 case MVT::i16:
1398 Opcode = NVPTX::STV_i16_v2_ari_64;
1399 break;
1400 case MVT::i32:
1401 Opcode = NVPTX::STV_i32_v2_ari_64;
1402 break;
1403 case MVT::i64:
1404 Opcode = NVPTX::STV_i64_v2_ari_64;
1405 break;
1406 case MVT::f32:
1407 Opcode = NVPTX::STV_f32_v2_ari_64;
1408 break;
1409 case MVT::f64:
1410 Opcode = NVPTX::STV_f64_v2_ari_64;
1411 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001412 }
1413 break;
1414 case NVPTXISD::StoreV4:
1415 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001416 default:
1417 return NULL;
1418 case MVT::i8:
1419 Opcode = NVPTX::STV_i8_v4_ari_64;
1420 break;
1421 case MVT::i16:
1422 Opcode = NVPTX::STV_i16_v4_ari_64;
1423 break;
1424 case MVT::i32:
1425 Opcode = NVPTX::STV_i32_v4_ari_64;
1426 break;
1427 case MVT::f32:
1428 Opcode = NVPTX::STV_f32_v4_ari_64;
1429 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001430 }
1431 break;
1432 }
1433 } else {
1434 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001435 default:
1436 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001437 case NVPTXISD::StoreV2:
1438 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001439 default:
1440 return NULL;
1441 case MVT::i8:
1442 Opcode = NVPTX::STV_i8_v2_ari;
1443 break;
1444 case MVT::i16:
1445 Opcode = NVPTX::STV_i16_v2_ari;
1446 break;
1447 case MVT::i32:
1448 Opcode = NVPTX::STV_i32_v2_ari;
1449 break;
1450 case MVT::i64:
1451 Opcode = NVPTX::STV_i64_v2_ari;
1452 break;
1453 case MVT::f32:
1454 Opcode = NVPTX::STV_f32_v2_ari;
1455 break;
1456 case MVT::f64:
1457 Opcode = NVPTX::STV_f64_v2_ari;
1458 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001459 }
1460 break;
1461 case NVPTXISD::StoreV4:
1462 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001463 default:
1464 return NULL;
1465 case MVT::i8:
1466 Opcode = NVPTX::STV_i8_v4_ari;
1467 break;
1468 case MVT::i16:
1469 Opcode = NVPTX::STV_i16_v4_ari;
1470 break;
1471 case MVT::i32:
1472 Opcode = NVPTX::STV_i32_v4_ari;
1473 break;
1474 case MVT::f32:
1475 Opcode = NVPTX::STV_f32_v4_ari;
1476 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001477 }
1478 break;
1479 }
1480 }
1481 StOps.push_back(Base);
1482 StOps.push_back(Offset);
1483 } else {
1484 if (Subtarget.is64Bit()) {
1485 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001486 default:
1487 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001488 case NVPTXISD::StoreV2:
1489 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001490 default:
1491 return NULL;
1492 case MVT::i8:
1493 Opcode = NVPTX::STV_i8_v2_areg_64;
1494 break;
1495 case MVT::i16:
1496 Opcode = NVPTX::STV_i16_v2_areg_64;
1497 break;
1498 case MVT::i32:
1499 Opcode = NVPTX::STV_i32_v2_areg_64;
1500 break;
1501 case MVT::i64:
1502 Opcode = NVPTX::STV_i64_v2_areg_64;
1503 break;
1504 case MVT::f32:
1505 Opcode = NVPTX::STV_f32_v2_areg_64;
1506 break;
1507 case MVT::f64:
1508 Opcode = NVPTX::STV_f64_v2_areg_64;
1509 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001510 }
1511 break;
1512 case NVPTXISD::StoreV4:
1513 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001514 default:
1515 return NULL;
1516 case MVT::i8:
1517 Opcode = NVPTX::STV_i8_v4_areg_64;
1518 break;
1519 case MVT::i16:
1520 Opcode = NVPTX::STV_i16_v4_areg_64;
1521 break;
1522 case MVT::i32:
1523 Opcode = NVPTX::STV_i32_v4_areg_64;
1524 break;
1525 case MVT::f32:
1526 Opcode = NVPTX::STV_f32_v4_areg_64;
1527 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001528 }
1529 break;
1530 }
1531 } else {
1532 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001533 default:
1534 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001535 case NVPTXISD::StoreV2:
1536 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001537 default:
1538 return NULL;
1539 case MVT::i8:
1540 Opcode = NVPTX::STV_i8_v2_areg;
1541 break;
1542 case MVT::i16:
1543 Opcode = NVPTX::STV_i16_v2_areg;
1544 break;
1545 case MVT::i32:
1546 Opcode = NVPTX::STV_i32_v2_areg;
1547 break;
1548 case MVT::i64:
1549 Opcode = NVPTX::STV_i64_v2_areg;
1550 break;
1551 case MVT::f32:
1552 Opcode = NVPTX::STV_f32_v2_areg;
1553 break;
1554 case MVT::f64:
1555 Opcode = NVPTX::STV_f64_v2_areg;
1556 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001557 }
1558 break;
1559 case NVPTXISD::StoreV4:
1560 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001561 default:
1562 return NULL;
1563 case MVT::i8:
1564 Opcode = NVPTX::STV_i8_v4_areg;
1565 break;
1566 case MVT::i16:
1567 Opcode = NVPTX::STV_i16_v4_areg;
1568 break;
1569 case MVT::i32:
1570 Opcode = NVPTX::STV_i32_v4_areg;
1571 break;
1572 case MVT::f32:
1573 Opcode = NVPTX::STV_f32_v4_areg;
1574 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001575 }
1576 break;
1577 }
1578 }
1579 StOps.push_back(N2);
1580 }
1581
1582 StOps.push_back(Chain);
1583
Michael Liaob53d8962013-04-19 22:22:57 +00001584 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001585
1586 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1587 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1588 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1589
1590 return ST;
1591}
1592
Justin Holewinskif8f70912013-06-28 17:57:59 +00001593SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
1594 SDValue Chain = Node->getOperand(0);
1595 SDValue Offset = Node->getOperand(2);
1596 SDValue Flag = Node->getOperand(3);
1597 SDLoc DL(Node);
1598 MemSDNode *Mem = cast<MemSDNode>(Node);
1599
1600 unsigned VecSize;
1601 switch (Node->getOpcode()) {
1602 default:
1603 return NULL;
1604 case NVPTXISD::LoadParam:
1605 VecSize = 1;
1606 break;
1607 case NVPTXISD::LoadParamV2:
1608 VecSize = 2;
1609 break;
1610 case NVPTXISD::LoadParamV4:
1611 VecSize = 4;
1612 break;
1613 }
1614
1615 EVT EltVT = Node->getValueType(0);
1616 EVT MemVT = Mem->getMemoryVT();
1617
1618 unsigned Opc = 0;
1619
1620 switch (VecSize) {
1621 default:
1622 return NULL;
1623 case 1:
1624 switch (MemVT.getSimpleVT().SimpleTy) {
1625 default:
1626 return NULL;
1627 case MVT::i1:
1628 Opc = NVPTX::LoadParamMemI8;
1629 break;
1630 case MVT::i8:
1631 Opc = NVPTX::LoadParamMemI8;
1632 break;
1633 case MVT::i16:
1634 Opc = NVPTX::LoadParamMemI16;
1635 break;
1636 case MVT::i32:
1637 Opc = NVPTX::LoadParamMemI32;
1638 break;
1639 case MVT::i64:
1640 Opc = NVPTX::LoadParamMemI64;
1641 break;
1642 case MVT::f32:
1643 Opc = NVPTX::LoadParamMemF32;
1644 break;
1645 case MVT::f64:
1646 Opc = NVPTX::LoadParamMemF64;
1647 break;
1648 }
1649 break;
1650 case 2:
1651 switch (MemVT.getSimpleVT().SimpleTy) {
1652 default:
1653 return NULL;
1654 case MVT::i1:
1655 Opc = NVPTX::LoadParamMemV2I8;
1656 break;
1657 case MVT::i8:
1658 Opc = NVPTX::LoadParamMemV2I8;
1659 break;
1660 case MVT::i16:
1661 Opc = NVPTX::LoadParamMemV2I16;
1662 break;
1663 case MVT::i32:
1664 Opc = NVPTX::LoadParamMemV2I32;
1665 break;
1666 case MVT::i64:
1667 Opc = NVPTX::LoadParamMemV2I64;
1668 break;
1669 case MVT::f32:
1670 Opc = NVPTX::LoadParamMemV2F32;
1671 break;
1672 case MVT::f64:
1673 Opc = NVPTX::LoadParamMemV2F64;
1674 break;
1675 }
1676 break;
1677 case 4:
1678 switch (MemVT.getSimpleVT().SimpleTy) {
1679 default:
1680 return NULL;
1681 case MVT::i1:
1682 Opc = NVPTX::LoadParamMemV4I8;
1683 break;
1684 case MVT::i8:
1685 Opc = NVPTX::LoadParamMemV4I8;
1686 break;
1687 case MVT::i16:
1688 Opc = NVPTX::LoadParamMemV4I16;
1689 break;
1690 case MVT::i32:
1691 Opc = NVPTX::LoadParamMemV4I32;
1692 break;
1693 case MVT::f32:
1694 Opc = NVPTX::LoadParamMemV4F32;
1695 break;
1696 }
1697 break;
1698 }
1699
1700 SDVTList VTs;
1701 if (VecSize == 1) {
1702 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
1703 } else if (VecSize == 2) {
1704 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
1705 } else {
1706 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
1707 VTs = CurDAG->getVTList(&EVTs[0], 5);
1708 }
1709
1710 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
1711
1712 SmallVector<SDValue, 2> Ops;
1713 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
1714 Ops.push_back(Chain);
1715 Ops.push_back(Flag);
1716
1717 SDNode *Ret =
1718 CurDAG->getMachineNode(Opc, DL, Node->getVTList(), Ops);
1719 return Ret;
1720}
1721
1722SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
1723 SDLoc DL(N);
1724 SDValue Chain = N->getOperand(0);
1725 SDValue Offset = N->getOperand(1);
1726 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
1727 MemSDNode *Mem = cast<MemSDNode>(N);
1728
1729 // How many elements do we have?
1730 unsigned NumElts = 1;
1731 switch (N->getOpcode()) {
1732 default:
1733 return NULL;
1734 case NVPTXISD::StoreRetval:
1735 NumElts = 1;
1736 break;
1737 case NVPTXISD::StoreRetvalV2:
1738 NumElts = 2;
1739 break;
1740 case NVPTXISD::StoreRetvalV4:
1741 NumElts = 4;
1742 break;
1743 }
1744
1745 // Build vector of operands
1746 SmallVector<SDValue, 6> Ops;
1747 for (unsigned i = 0; i < NumElts; ++i)
1748 Ops.push_back(N->getOperand(i + 2));
1749 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
1750 Ops.push_back(Chain);
1751
1752 // Determine target opcode
1753 // If we have an i1, use an 8-bit store. The lowering code in
1754 // NVPTXISelLowering will have already emitted an upcast.
1755 unsigned Opcode = 0;
1756 switch (NumElts) {
1757 default:
1758 return NULL;
1759 case 1:
1760 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1761 default:
1762 return NULL;
1763 case MVT::i1:
1764 Opcode = NVPTX::StoreRetvalI8;
1765 break;
1766 case MVT::i8:
1767 Opcode = NVPTX::StoreRetvalI8;
1768 break;
1769 case MVT::i16:
1770 Opcode = NVPTX::StoreRetvalI16;
1771 break;
1772 case MVT::i32:
1773 Opcode = NVPTX::StoreRetvalI32;
1774 break;
1775 case MVT::i64:
1776 Opcode = NVPTX::StoreRetvalI64;
1777 break;
1778 case MVT::f32:
1779 Opcode = NVPTX::StoreRetvalF32;
1780 break;
1781 case MVT::f64:
1782 Opcode = NVPTX::StoreRetvalF64;
1783 break;
1784 }
1785 break;
1786 case 2:
1787 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1788 default:
1789 return NULL;
1790 case MVT::i1:
1791 Opcode = NVPTX::StoreRetvalV2I8;
1792 break;
1793 case MVT::i8:
1794 Opcode = NVPTX::StoreRetvalV2I8;
1795 break;
1796 case MVT::i16:
1797 Opcode = NVPTX::StoreRetvalV2I16;
1798 break;
1799 case MVT::i32:
1800 Opcode = NVPTX::StoreRetvalV2I32;
1801 break;
1802 case MVT::i64:
1803 Opcode = NVPTX::StoreRetvalV2I64;
1804 break;
1805 case MVT::f32:
1806 Opcode = NVPTX::StoreRetvalV2F32;
1807 break;
1808 case MVT::f64:
1809 Opcode = NVPTX::StoreRetvalV2F64;
1810 break;
1811 }
1812 break;
1813 case 4:
1814 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1815 default:
1816 return NULL;
1817 case MVT::i1:
1818 Opcode = NVPTX::StoreRetvalV4I8;
1819 break;
1820 case MVT::i8:
1821 Opcode = NVPTX::StoreRetvalV4I8;
1822 break;
1823 case MVT::i16:
1824 Opcode = NVPTX::StoreRetvalV4I16;
1825 break;
1826 case MVT::i32:
1827 Opcode = NVPTX::StoreRetvalV4I32;
1828 break;
1829 case MVT::f32:
1830 Opcode = NVPTX::StoreRetvalV4F32;
1831 break;
1832 }
1833 break;
1834 }
1835
1836 SDNode *Ret =
1837 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
1838 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1839 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1840 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
1841
1842 return Ret;
1843}
1844
1845SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
1846 SDLoc DL(N);
1847 SDValue Chain = N->getOperand(0);
1848 SDValue Param = N->getOperand(1);
1849 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
1850 SDValue Offset = N->getOperand(2);
1851 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
1852 MemSDNode *Mem = cast<MemSDNode>(N);
1853 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
1854
1855 // How many elements do we have?
1856 unsigned NumElts = 1;
1857 switch (N->getOpcode()) {
1858 default:
1859 return NULL;
1860 case NVPTXISD::StoreParamU32:
1861 case NVPTXISD::StoreParamS32:
1862 case NVPTXISD::StoreParam:
1863 NumElts = 1;
1864 break;
1865 case NVPTXISD::StoreParamV2:
1866 NumElts = 2;
1867 break;
1868 case NVPTXISD::StoreParamV4:
1869 NumElts = 4;
1870 break;
1871 }
1872
1873 // Build vector of operands
1874 SmallVector<SDValue, 8> Ops;
1875 for (unsigned i = 0; i < NumElts; ++i)
1876 Ops.push_back(N->getOperand(i + 3));
1877 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
1878 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
1879 Ops.push_back(Chain);
1880 Ops.push_back(Flag);
1881
1882 // Determine target opcode
1883 // If we have an i1, use an 8-bit store. The lowering code in
1884 // NVPTXISelLowering will have already emitted an upcast.
1885 unsigned Opcode = 0;
1886 switch (N->getOpcode()) {
1887 default:
1888 switch (NumElts) {
1889 default:
1890 return NULL;
1891 case 1:
1892 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1893 default:
1894 return NULL;
1895 case MVT::i1:
1896 Opcode = NVPTX::StoreParamI8;
1897 break;
1898 case MVT::i8:
1899 Opcode = NVPTX::StoreParamI8;
1900 break;
1901 case MVT::i16:
1902 Opcode = NVPTX::StoreParamI16;
1903 break;
1904 case MVT::i32:
1905 Opcode = NVPTX::StoreParamI32;
1906 break;
1907 case MVT::i64:
1908 Opcode = NVPTX::StoreParamI64;
1909 break;
1910 case MVT::f32:
1911 Opcode = NVPTX::StoreParamF32;
1912 break;
1913 case MVT::f64:
1914 Opcode = NVPTX::StoreParamF64;
1915 break;
1916 }
1917 break;
1918 case 2:
1919 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1920 default:
1921 return NULL;
1922 case MVT::i1:
1923 Opcode = NVPTX::StoreParamV2I8;
1924 break;
1925 case MVT::i8:
1926 Opcode = NVPTX::StoreParamV2I8;
1927 break;
1928 case MVT::i16:
1929 Opcode = NVPTX::StoreParamV2I16;
1930 break;
1931 case MVT::i32:
1932 Opcode = NVPTX::StoreParamV2I32;
1933 break;
1934 case MVT::i64:
1935 Opcode = NVPTX::StoreParamV2I64;
1936 break;
1937 case MVT::f32:
1938 Opcode = NVPTX::StoreParamV2F32;
1939 break;
1940 case MVT::f64:
1941 Opcode = NVPTX::StoreParamV2F64;
1942 break;
1943 }
1944 break;
1945 case 4:
1946 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
1947 default:
1948 return NULL;
1949 case MVT::i1:
1950 Opcode = NVPTX::StoreParamV4I8;
1951 break;
1952 case MVT::i8:
1953 Opcode = NVPTX::StoreParamV4I8;
1954 break;
1955 case MVT::i16:
1956 Opcode = NVPTX::StoreParamV4I16;
1957 break;
1958 case MVT::i32:
1959 Opcode = NVPTX::StoreParamV4I32;
1960 break;
1961 case MVT::f32:
1962 Opcode = NVPTX::StoreParamV4F32;
1963 break;
1964 }
1965 break;
1966 }
1967 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00001968 // Special case: if we have a sign-extend/zero-extend node, insert the
1969 // conversion instruction first, and use that as the value operand to
1970 // the selected StoreParam node.
1971 case NVPTXISD::StoreParamU32: {
1972 Opcode = NVPTX::StoreParamI32;
1973 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
1974 MVT::i32);
1975 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
1976 MVT::i32, Ops[0], CvtNone);
1977 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00001978 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00001979 }
1980 case NVPTXISD::StoreParamS32: {
1981 Opcode = NVPTX::StoreParamI32;
1982 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
1983 MVT::i32);
1984 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
1985 MVT::i32, Ops[0], CvtNone);
1986 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00001987 break;
1988 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00001989 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00001990
1991 SDNode *Ret =
1992 CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
1993 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1994 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1995 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
1996
1997 return Ret;
1998}
1999
Justin Holewinskiae556d32012-05-04 20:18:50 +00002000// SelectDirectAddr - Match a direct address for DAG.
2001// A direct address could be a globaladdress or externalsymbol.
2002bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2003 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002004 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2005 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002006 Address = N;
2007 return true;
2008 }
2009 if (N.getOpcode() == NVPTXISD::Wrapper) {
2010 Address = N.getOperand(0);
2011 return true;
2012 }
2013 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2014 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2015 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2016 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2017 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2018 }
2019 return false;
2020}
2021
2022// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002023bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2024 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002025 if (Addr.getOpcode() == ISD::ADD) {
2026 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002027 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002028 if (SelectDirectAddr(base, Base)) {
2029 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2030 return true;
2031 }
2032 }
2033 }
2034 return false;
2035}
2036
2037// symbol+offset
2038bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
2039 SDValue &Base, SDValue &Offset) {
2040 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
2041}
2042
2043// symbol+offset
2044bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
2045 SDValue &Base, SDValue &Offset) {
2046 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
2047}
2048
2049// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002050bool NVPTXDAGToDAGISel::SelectADDRri_imp(
2051 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002052 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2053 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2054 Offset = CurDAG->getTargetConstant(0, mvt);
2055 return true;
2056 }
2057 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2058 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00002059 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00002060
2061 if (Addr.getOpcode() == ISD::ADD) {
2062 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
2063 return false;
2064 }
2065 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
2066 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00002067 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002068 // Constant offset from frame ref.
2069 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2070 else
2071 Base = Addr.getOperand(0);
2072 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2073 return true;
2074 }
2075 }
2076 return false;
2077}
2078
2079// register+offset
2080bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
2081 SDValue &Base, SDValue &Offset) {
2082 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
2083}
2084
2085// register+offset
2086bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
2087 SDValue &Base, SDValue &Offset) {
2088 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
2089}
2090
2091bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
2092 unsigned int spN) const {
2093 const Value *Src = NULL;
2094 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
2095 // the classof() for MemSDNode does not include MemIntrinsicSDNode
2096 // (See SelectionDAGNodes.h). So we need to check for both.
2097 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
2098 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00002099 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002100 Src = mN->getSrcValue();
2101 }
2102 if (!Src)
2103 return false;
2104 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
2105 return (PT->getAddressSpace() == spN);
2106 return false;
2107}
2108
2109/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2110/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002111bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
2112 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002113 SDValue Op0, Op1;
2114 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002115 default:
2116 return true;
2117 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00002118 if (SelectDirectAddr(Op, Op0)) {
2119 OutOps.push_back(Op0);
2120 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
2121 return false;
2122 }
2123 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
2124 OutOps.push_back(Op0);
2125 OutOps.push_back(Op1);
2126 return false;
2127 }
2128 break;
2129 }
2130 return true;
2131}
2132
2133// Return true if N is a undef or a constant.
2134// If N was undef, return a (i8imm 0) in Retval
2135// If N was imm, convert it to i8imm and return in Retval
2136// Note: The convert to i8imm is required, otherwise the
2137// pattern matcher inserts a bunch of IMOVi8rr to convert
2138// the imm to i8imm, and this causes instruction selection
2139// to fail.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002140bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
2141 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002142 return false;
2143
2144 if (N.getOpcode() == ISD::UNDEF)
2145 Retval = CurDAG->getTargetConstant(0, MVT::i8);
2146 else {
2147 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
2148 unsigned retval = cn->getZExtValue();
2149 Retval = CurDAG->getTargetConstant(retval, MVT::i8);
2150 }
2151 return true;
2152}