blob: 01fbdb3336720ca53478a015d80b74ea30ad1540 [file] [log] [blame]
Justin Holewinskiae556d32012-05-04 20:18:50 +00001//===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the NVPTX target.
11//
12//===----------------------------------------------------------------------===//
13
Justin Holewinskiae556d32012-05-04 20:18:50 +000014#include "NVPTXISelDAGToDAG.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000015#include "llvm/IR/GlobalValue.h"
16#include "llvm/IR/Instructions.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000017#include "llvm/Support/CommandLine.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000018#include "llvm/Support/Debug.h"
19#include "llvm/Support/ErrorHandling.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/Support/raw_ostream.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000021#include "llvm/Target/TargetIntrinsicInfo.h"
Justin Holewinskiae556d32012-05-04 20:18:50 +000022
23#undef DEBUG_TYPE
24#define DEBUG_TYPE "nvptx-isel"
25
26using namespace llvm;
27
Justin Holewinskiae556d32012-05-04 20:18:50 +000028static cl::opt<int>
Justin Holewinski0497ab12013-03-30 14:29:21 +000029FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore,
Justin Holewinskiae556d32012-05-04 20:18:50 +000030 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
Justin Holewinski0497ab12013-03-30 14:29:21 +000031 " 1: do it 2: do it aggressively"),
32 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000033
Justin Holewinski0497ab12013-03-30 14:29:21 +000034static cl::opt<int> UsePrecDivF32(
35 "nvptx-prec-divf32", cl::ZeroOrMore,
36 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
37 " IEEE Compliant F32 div.rnd if avaiable."),
38 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000039
Justin Holewinski48f4ad32013-05-21 16:51:30 +000040static cl::opt<bool>
41UsePrecSqrtF32("nvptx-prec-sqrtf32",
42 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
43 cl::init(true));
44
Justin Holewinskicd069e62013-07-22 12:18:04 +000045static cl::opt<bool>
46FtzEnabled("nvptx-f32ftz", cl::ZeroOrMore,
47 cl::desc("NVPTX Specific: Flush f32 subnormals to sign-preserving zero."),
48 cl::init(false));
49
50
Justin Holewinskiae556d32012-05-04 20:18:50 +000051/// createNVPTXISelDag - This pass converts a legalized DAG into a
52/// NVPTX-specific DAG, ready for instruction scheduling.
53FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
54 llvm::CodeGenOpt::Level OptLevel) {
55 return new NVPTXDAGToDAGISel(TM, OptLevel);
56}
57
Justin Holewinskiae556d32012-05-04 20:18:50 +000058NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
59 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000060 : SelectionDAGISel(tm, OptLevel),
61 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000062
Justin Holewinski0497ab12013-03-30 14:29:21 +000063 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
64 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
65 doFMAF32AGG =
66 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
67 doFMAF64AGG =
68 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000069
Justin Holewinskicd069e62013-07-22 12:18:04 +000070 allowFMA = (FMAContractLevel >= 1);
Benjamin Kramera25a61b2012-05-05 11:22:02 +000071
Justin Holewinskiae556d32012-05-04 20:18:50 +000072 doMulWide = (OptLevel > 0);
Justin Holewinskicd069e62013-07-22 12:18:04 +000073}
Justin Holewinskiae556d32012-05-04 20:18:50 +000074
Justin Holewinskicd069e62013-07-22 12:18:04 +000075int NVPTXDAGToDAGISel::getDivF32Level() const {
76 if (UsePrecDivF32.getNumOccurrences() > 0) {
77 // If nvptx-prec-div32=N is used on the command-line, always honor it
78 return UsePrecDivF32;
79 } else {
80 // Otherwise, use div.approx if fast math is enabled
81 if (TM.Options.UnsafeFPMath)
82 return 0;
83 else
84 return 2;
85 }
86}
Justin Holewinskiae556d32012-05-04 20:18:50 +000087
Justin Holewinskicd069e62013-07-22 12:18:04 +000088bool NVPTXDAGToDAGISel::usePrecSqrtF32() const {
89 if (UsePrecSqrtF32.getNumOccurrences() > 0) {
90 // If nvptx-prec-sqrtf32 is used on the command-line, always honor it
91 return UsePrecSqrtF32;
92 } else {
93 // Otherwise, use sqrt.approx if fast math is enabled
94 if (TM.Options.UnsafeFPMath)
95 return false;
96 else
97 return true;
98 }
99}
100
101bool NVPTXDAGToDAGISel::useF32FTZ() const {
102 if (FtzEnabled.getNumOccurrences() > 0) {
103 // If nvptx-f32ftz is used on the command-line, always honor it
104 return FtzEnabled;
105 } else {
106 const Function *F = MF->getFunction();
107 // Otherwise, check for an nvptx-f32ftz attribute on the function
108 if (F->hasFnAttribute("nvptx-f32ftz"))
109 return (F->getAttributes().getAttribute(AttributeSet::FunctionIndex,
110 "nvptx-f32ftz")
111 .getValueAsString() == "true");
112 else
113 return false;
114 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000115}
116
117/// Select - Select instructions not customized! Used for
118/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +0000119SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000120
121 if (N->isMachineOpcode())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000122 return NULL; // Already selected.
Justin Holewinskiae556d32012-05-04 20:18:50 +0000123
124 SDNode *ResNode = NULL;
125 switch (N->getOpcode()) {
126 case ISD::LOAD:
127 ResNode = SelectLoad(N);
128 break;
129 case ISD::STORE:
130 ResNode = SelectStore(N);
131 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000132 case NVPTXISD::LoadV2:
133 case NVPTXISD::LoadV4:
134 ResNode = SelectLoadVector(N);
135 break;
136 case NVPTXISD::LDGV2:
137 case NVPTXISD::LDGV4:
138 case NVPTXISD::LDUV2:
139 case NVPTXISD::LDUV4:
140 ResNode = SelectLDGLDUVector(N);
141 break;
142 case NVPTXISD::StoreV2:
143 case NVPTXISD::StoreV4:
144 ResNode = SelectStoreVector(N);
145 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000146 case NVPTXISD::LoadParam:
147 case NVPTXISD::LoadParamV2:
148 case NVPTXISD::LoadParamV4:
149 ResNode = SelectLoadParam(N);
150 break;
151 case NVPTXISD::StoreRetval:
152 case NVPTXISD::StoreRetvalV2:
153 case NVPTXISD::StoreRetvalV4:
154 ResNode = SelectStoreRetval(N);
155 break;
156 case NVPTXISD::StoreParam:
157 case NVPTXISD::StoreParamV2:
158 case NVPTXISD::StoreParamV4:
159 case NVPTXISD::StoreParamS32:
160 case NVPTXISD::StoreParamU32:
161 ResNode = SelectStoreParam(N);
162 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000163 default:
164 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000165 }
166 if (ResNode)
167 return ResNode;
168 return SelectCode(N);
169}
170
Justin Holewinski0497ab12013-03-30 14:29:21 +0000171static unsigned int getCodeAddrSpace(MemSDNode *N,
172 const NVPTXSubtarget &Subtarget) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000173 const Value *Src = N->getSrcValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000174
Justin Holewinskiae556d32012-05-04 20:18:50 +0000175 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000176 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000177
178 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
179 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000180 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
181 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
182 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
183 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
184 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
185 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
186 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000187 }
188 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000189 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000190}
191
Justin Holewinski0497ab12013-03-30 14:29:21 +0000192SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000193 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000194 LoadSDNode *LD = cast<LoadSDNode>(N);
195 EVT LoadedVT = LD->getMemoryVT();
Justin Holewinski0497ab12013-03-30 14:29:21 +0000196 SDNode *NVPTXLD = NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000197
198 // do not support pre/post inc/dec
199 if (LD->isIndexed())
200 return NULL;
201
202 if (!LoadedVT.isSimple())
203 return NULL;
204
205 // Address Space Setting
206 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
207
208 // Volatile Setting
209 // - .volatile is only availalble for .global and .shared
210 bool isVolatile = LD->isVolatile();
211 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
212 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
213 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
214 isVolatile = false;
215
216 // Vector Setting
217 MVT SimpleVT = LoadedVT.getSimpleVT();
218 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
219 if (SimpleVT.isVector()) {
220 unsigned num = SimpleVT.getVectorNumElements();
221 if (num == 2)
222 vecType = NVPTX::PTXLdStInstCode::V2;
223 else if (num == 4)
224 vecType = NVPTX::PTXLdStInstCode::V4;
225 else
226 return NULL;
227 }
228
229 // Type Setting: fromType + fromTypeWidth
230 //
231 // Sign : ISD::SEXTLOAD
232 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
233 // type is integer
234 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
235 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000236 // Read at least 8 bits (predicates are stored as 8-bit values)
237 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000238 unsigned int fromType;
239 if ((LD->getExtensionType() == ISD::SEXTLOAD))
240 fromType = NVPTX::PTXLdStInstCode::Signed;
241 else if (ScalarVT.isFloatingPoint())
242 fromType = NVPTX::PTXLdStInstCode::Float;
243 else
244 fromType = NVPTX::PTXLdStInstCode::Unsigned;
245
246 // Create the machine instruction DAG
247 SDValue Chain = N->getOperand(0);
248 SDValue N1 = N->getOperand(1);
249 SDValue Addr;
250 SDValue Offset, Base;
251 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000252 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000253
254 if (SelectDirectAddr(N1, Addr)) {
255 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000256 case MVT::i8:
257 Opcode = NVPTX::LD_i8_avar;
258 break;
259 case MVT::i16:
260 Opcode = NVPTX::LD_i16_avar;
261 break;
262 case MVT::i32:
263 Opcode = NVPTX::LD_i32_avar;
264 break;
265 case MVT::i64:
266 Opcode = NVPTX::LD_i64_avar;
267 break;
268 case MVT::f32:
269 Opcode = NVPTX::LD_f32_avar;
270 break;
271 case MVT::f64:
272 Opcode = NVPTX::LD_f64_avar;
273 break;
274 default:
275 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000276 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000277 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
278 getI32Imm(vecType), getI32Imm(fromType),
279 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000280 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000281 } else if (Subtarget.is64Bit()
282 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
283 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000284 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000285 case MVT::i8:
286 Opcode = NVPTX::LD_i8_asi;
287 break;
288 case MVT::i16:
289 Opcode = NVPTX::LD_i16_asi;
290 break;
291 case MVT::i32:
292 Opcode = NVPTX::LD_i32_asi;
293 break;
294 case MVT::i64:
295 Opcode = NVPTX::LD_i64_asi;
296 break;
297 case MVT::f32:
298 Opcode = NVPTX::LD_f32_asi;
299 break;
300 case MVT::f64:
301 Opcode = NVPTX::LD_f64_asi;
302 break;
303 default:
304 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000305 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000306 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
307 getI32Imm(vecType), getI32Imm(fromType),
308 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000309 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000310 } else if (Subtarget.is64Bit()
311 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
312 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000313 if (Subtarget.is64Bit()) {
314 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000315 case MVT::i8:
316 Opcode = NVPTX::LD_i8_ari_64;
317 break;
318 case MVT::i16:
319 Opcode = NVPTX::LD_i16_ari_64;
320 break;
321 case MVT::i32:
322 Opcode = NVPTX::LD_i32_ari_64;
323 break;
324 case MVT::i64:
325 Opcode = NVPTX::LD_i64_ari_64;
326 break;
327 case MVT::f32:
328 Opcode = NVPTX::LD_f32_ari_64;
329 break;
330 case MVT::f64:
331 Opcode = NVPTX::LD_f64_ari_64;
332 break;
333 default:
334 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000335 }
336 } else {
337 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000338 case MVT::i8:
339 Opcode = NVPTX::LD_i8_ari;
340 break;
341 case MVT::i16:
342 Opcode = NVPTX::LD_i16_ari;
343 break;
344 case MVT::i32:
345 Opcode = NVPTX::LD_i32_ari;
346 break;
347 case MVT::i64:
348 Opcode = NVPTX::LD_i64_ari;
349 break;
350 case MVT::f32:
351 Opcode = NVPTX::LD_f32_ari;
352 break;
353 case MVT::f64:
354 Opcode = NVPTX::LD_f64_ari;
355 break;
356 default:
357 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000358 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000359 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000360 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
361 getI32Imm(vecType), getI32Imm(fromType),
362 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000363 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000364 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000365 if (Subtarget.is64Bit()) {
366 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000367 case MVT::i8:
368 Opcode = NVPTX::LD_i8_areg_64;
369 break;
370 case MVT::i16:
371 Opcode = NVPTX::LD_i16_areg_64;
372 break;
373 case MVT::i32:
374 Opcode = NVPTX::LD_i32_areg_64;
375 break;
376 case MVT::i64:
377 Opcode = NVPTX::LD_i64_areg_64;
378 break;
379 case MVT::f32:
380 Opcode = NVPTX::LD_f32_areg_64;
381 break;
382 case MVT::f64:
383 Opcode = NVPTX::LD_f64_areg_64;
384 break;
385 default:
386 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000387 }
388 } else {
389 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000390 case MVT::i8:
391 Opcode = NVPTX::LD_i8_areg;
392 break;
393 case MVT::i16:
394 Opcode = NVPTX::LD_i16_areg;
395 break;
396 case MVT::i32:
397 Opcode = NVPTX::LD_i32_areg;
398 break;
399 case MVT::i64:
400 Opcode = NVPTX::LD_i64_areg;
401 break;
402 case MVT::f32:
403 Opcode = NVPTX::LD_f32_areg;
404 break;
405 case MVT::f64:
406 Opcode = NVPTX::LD_f64_areg;
407 break;
408 default:
409 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000410 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000411 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000412 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
413 getI32Imm(vecType), getI32Imm(fromType),
414 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000415 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000416 }
417
418 if (NVPTXLD != NULL) {
419 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
420 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
421 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
422 }
423
424 return NVPTXLD;
425}
426
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000427SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
428
429 SDValue Chain = N->getOperand(0);
430 SDValue Op1 = N->getOperand(1);
431 SDValue Addr, Offset, Base;
432 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000433 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000434 SDNode *LD;
435 MemSDNode *MemSD = cast<MemSDNode>(N);
436 EVT LoadedVT = MemSD->getMemoryVT();
437
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000438 if (!LoadedVT.isSimple())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000439 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000440
441 // Address Space Setting
442 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
443
444 // Volatile Setting
445 // - .volatile is only availalble for .global and .shared
446 bool IsVolatile = MemSD->isVolatile();
447 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
448 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
449 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
450 IsVolatile = false;
451
452 // Vector Setting
453 MVT SimpleVT = LoadedVT.getSimpleVT();
454
455 // Type Setting: fromType + fromTypeWidth
456 //
457 // Sign : ISD::SEXTLOAD
458 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
459 // type is integer
460 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
461 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000462 // Read at least 8 bits (predicates are stored as 8-bit values)
463 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000464 unsigned int FromType;
465 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000466 unsigned ExtensionType = cast<ConstantSDNode>(
467 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000468 if (ExtensionType == ISD::SEXTLOAD)
469 FromType = NVPTX::PTXLdStInstCode::Signed;
470 else if (ScalarVT.isFloatingPoint())
471 FromType = NVPTX::PTXLdStInstCode::Float;
472 else
473 FromType = NVPTX::PTXLdStInstCode::Unsigned;
474
475 unsigned VecType;
476
477 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000478 case NVPTXISD::LoadV2:
479 VecType = NVPTX::PTXLdStInstCode::V2;
480 break;
481 case NVPTXISD::LoadV4:
482 VecType = NVPTX::PTXLdStInstCode::V4;
483 break;
484 default:
485 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000486 }
487
488 EVT EltVT = N->getValueType(0);
489
490 if (SelectDirectAddr(Op1, Addr)) {
491 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000492 default:
493 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000494 case NVPTXISD::LoadV2:
495 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000496 default:
497 return NULL;
498 case MVT::i8:
499 Opcode = NVPTX::LDV_i8_v2_avar;
500 break;
501 case MVT::i16:
502 Opcode = NVPTX::LDV_i16_v2_avar;
503 break;
504 case MVT::i32:
505 Opcode = NVPTX::LDV_i32_v2_avar;
506 break;
507 case MVT::i64:
508 Opcode = NVPTX::LDV_i64_v2_avar;
509 break;
510 case MVT::f32:
511 Opcode = NVPTX::LDV_f32_v2_avar;
512 break;
513 case MVT::f64:
514 Opcode = NVPTX::LDV_f64_v2_avar;
515 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000516 }
517 break;
518 case NVPTXISD::LoadV4:
519 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000520 default:
521 return NULL;
522 case MVT::i8:
523 Opcode = NVPTX::LDV_i8_v4_avar;
524 break;
525 case MVT::i16:
526 Opcode = NVPTX::LDV_i16_v4_avar;
527 break;
528 case MVT::i32:
529 Opcode = NVPTX::LDV_i32_v4_avar;
530 break;
531 case MVT::f32:
532 Opcode = NVPTX::LDV_f32_v4_avar;
533 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000534 }
535 break;
536 }
537
Justin Holewinski0497ab12013-03-30 14:29:21 +0000538 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
539 getI32Imm(VecType), getI32Imm(FromType),
540 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000541 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000542 } else if (Subtarget.is64Bit()
543 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
544 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000545 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000546 default:
547 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000548 case NVPTXISD::LoadV2:
549 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000550 default:
551 return NULL;
552 case MVT::i8:
553 Opcode = NVPTX::LDV_i8_v2_asi;
554 break;
555 case MVT::i16:
556 Opcode = NVPTX::LDV_i16_v2_asi;
557 break;
558 case MVT::i32:
559 Opcode = NVPTX::LDV_i32_v2_asi;
560 break;
561 case MVT::i64:
562 Opcode = NVPTX::LDV_i64_v2_asi;
563 break;
564 case MVT::f32:
565 Opcode = NVPTX::LDV_f32_v2_asi;
566 break;
567 case MVT::f64:
568 Opcode = NVPTX::LDV_f64_v2_asi;
569 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000570 }
571 break;
572 case NVPTXISD::LoadV4:
573 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000574 default:
575 return NULL;
576 case MVT::i8:
577 Opcode = NVPTX::LDV_i8_v4_asi;
578 break;
579 case MVT::i16:
580 Opcode = NVPTX::LDV_i16_v4_asi;
581 break;
582 case MVT::i32:
583 Opcode = NVPTX::LDV_i32_v4_asi;
584 break;
585 case MVT::f32:
586 Opcode = NVPTX::LDV_f32_v4_asi;
587 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000588 }
589 break;
590 }
591
Justin Holewinski0497ab12013-03-30 14:29:21 +0000592 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
593 getI32Imm(VecType), getI32Imm(FromType),
594 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000595 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000596 } else if (Subtarget.is64Bit()
597 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
598 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000599 if (Subtarget.is64Bit()) {
600 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000601 default:
602 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000603 case NVPTXISD::LoadV2:
604 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000605 default:
606 return NULL;
607 case MVT::i8:
608 Opcode = NVPTX::LDV_i8_v2_ari_64;
609 break;
610 case MVT::i16:
611 Opcode = NVPTX::LDV_i16_v2_ari_64;
612 break;
613 case MVT::i32:
614 Opcode = NVPTX::LDV_i32_v2_ari_64;
615 break;
616 case MVT::i64:
617 Opcode = NVPTX::LDV_i64_v2_ari_64;
618 break;
619 case MVT::f32:
620 Opcode = NVPTX::LDV_f32_v2_ari_64;
621 break;
622 case MVT::f64:
623 Opcode = NVPTX::LDV_f64_v2_ari_64;
624 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000625 }
626 break;
627 case NVPTXISD::LoadV4:
628 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000629 default:
630 return NULL;
631 case MVT::i8:
632 Opcode = NVPTX::LDV_i8_v4_ari_64;
633 break;
634 case MVT::i16:
635 Opcode = NVPTX::LDV_i16_v4_ari_64;
636 break;
637 case MVT::i32:
638 Opcode = NVPTX::LDV_i32_v4_ari_64;
639 break;
640 case MVT::f32:
641 Opcode = NVPTX::LDV_f32_v4_ari_64;
642 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000643 }
644 break;
645 }
646 } else {
647 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000648 default:
649 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000650 case NVPTXISD::LoadV2:
651 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000652 default:
653 return NULL;
654 case MVT::i8:
655 Opcode = NVPTX::LDV_i8_v2_ari;
656 break;
657 case MVT::i16:
658 Opcode = NVPTX::LDV_i16_v2_ari;
659 break;
660 case MVT::i32:
661 Opcode = NVPTX::LDV_i32_v2_ari;
662 break;
663 case MVT::i64:
664 Opcode = NVPTX::LDV_i64_v2_ari;
665 break;
666 case MVT::f32:
667 Opcode = NVPTX::LDV_f32_v2_ari;
668 break;
669 case MVT::f64:
670 Opcode = NVPTX::LDV_f64_v2_ari;
671 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000672 }
673 break;
674 case NVPTXISD::LoadV4:
675 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000676 default:
677 return NULL;
678 case MVT::i8:
679 Opcode = NVPTX::LDV_i8_v4_ari;
680 break;
681 case MVT::i16:
682 Opcode = NVPTX::LDV_i16_v4_ari;
683 break;
684 case MVT::i32:
685 Opcode = NVPTX::LDV_i32_v4_ari;
686 break;
687 case MVT::f32:
688 Opcode = NVPTX::LDV_f32_v4_ari;
689 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000690 }
691 break;
692 }
693 }
694
Justin Holewinski0497ab12013-03-30 14:29:21 +0000695 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
696 getI32Imm(VecType), getI32Imm(FromType),
697 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000698
Michael Liaob53d8962013-04-19 22:22:57 +0000699 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000700 } else {
701 if (Subtarget.is64Bit()) {
702 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000703 default:
704 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000705 case NVPTXISD::LoadV2:
706 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000707 default:
708 return NULL;
709 case MVT::i8:
710 Opcode = NVPTX::LDV_i8_v2_areg_64;
711 break;
712 case MVT::i16:
713 Opcode = NVPTX::LDV_i16_v2_areg_64;
714 break;
715 case MVT::i32:
716 Opcode = NVPTX::LDV_i32_v2_areg_64;
717 break;
718 case MVT::i64:
719 Opcode = NVPTX::LDV_i64_v2_areg_64;
720 break;
721 case MVT::f32:
722 Opcode = NVPTX::LDV_f32_v2_areg_64;
723 break;
724 case MVT::f64:
725 Opcode = NVPTX::LDV_f64_v2_areg_64;
726 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000727 }
728 break;
729 case NVPTXISD::LoadV4:
730 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000731 default:
732 return NULL;
733 case MVT::i8:
734 Opcode = NVPTX::LDV_i8_v4_areg_64;
735 break;
736 case MVT::i16:
737 Opcode = NVPTX::LDV_i16_v4_areg_64;
738 break;
739 case MVT::i32:
740 Opcode = NVPTX::LDV_i32_v4_areg_64;
741 break;
742 case MVT::f32:
743 Opcode = NVPTX::LDV_f32_v4_areg_64;
744 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000745 }
746 break;
747 }
748 } else {
749 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000750 default:
751 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000752 case NVPTXISD::LoadV2:
753 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000754 default:
755 return NULL;
756 case MVT::i8:
757 Opcode = NVPTX::LDV_i8_v2_areg;
758 break;
759 case MVT::i16:
760 Opcode = NVPTX::LDV_i16_v2_areg;
761 break;
762 case MVT::i32:
763 Opcode = NVPTX::LDV_i32_v2_areg;
764 break;
765 case MVT::i64:
766 Opcode = NVPTX::LDV_i64_v2_areg;
767 break;
768 case MVT::f32:
769 Opcode = NVPTX::LDV_f32_v2_areg;
770 break;
771 case MVT::f64:
772 Opcode = NVPTX::LDV_f64_v2_areg;
773 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000774 }
775 break;
776 case NVPTXISD::LoadV4:
777 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000778 default:
779 return NULL;
780 case MVT::i8:
781 Opcode = NVPTX::LDV_i8_v4_areg;
782 break;
783 case MVT::i16:
784 Opcode = NVPTX::LDV_i16_v4_areg;
785 break;
786 case MVT::i32:
787 Opcode = NVPTX::LDV_i32_v4_areg;
788 break;
789 case MVT::f32:
790 Opcode = NVPTX::LDV_f32_v4_areg;
791 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000792 }
793 break;
794 }
795 }
796
Justin Holewinski0497ab12013-03-30 14:29:21 +0000797 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
798 getI32Imm(VecType), getI32Imm(FromType),
799 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000800 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000801 }
802
803 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
804 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
805 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
806
807 return LD;
808}
809
810SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
811
812 SDValue Chain = N->getOperand(0);
813 SDValue Op1 = N->getOperand(1);
814 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000815 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000816 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000817 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000818 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000819
Justin Holewinskie40e9292013-07-01 12:58:52 +0000820 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000821
Justin Holewinskie40e9292013-07-01 12:58:52 +0000822 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000823 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000824 default:
825 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000826 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000827 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000828 default:
829 return NULL;
830 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000831 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000832 break;
833 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000834 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000835 break;
836 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000837 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000838 break;
839 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000840 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000841 break;
842 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000843 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000844 break;
845 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000846 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000847 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000848 }
849 break;
850 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000851 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000852 default:
853 return NULL;
854 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000855 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000856 break;
857 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000858 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000859 break;
860 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000861 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000862 break;
863 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000864 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000865 break;
866 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000867 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000868 break;
869 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000870 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
871 break;
872 }
873 break;
874 case NVPTXISD::LDGV4:
875 switch (EltVT.getSimpleVT().SimpleTy) {
876 default:
877 return NULL;
878 case MVT::i8:
879 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
880 break;
881 case MVT::i16:
882 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
883 break;
884 case MVT::i32:
885 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
886 break;
887 case MVT::f32:
888 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000889 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000890 }
891 break;
892 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000893 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000894 default:
895 return NULL;
896 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000897 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000898 break;
899 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000900 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000901 break;
902 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000903 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000904 break;
905 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +0000906 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000907 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000908 }
909 break;
910 }
Justin Holewinskie40e9292013-07-01 12:58:52 +0000911
912 SDValue Ops[] = { Addr, Chain };
913 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
914 ArrayRef<SDValue>(Ops, 2));
915 } else if (Subtarget.is64Bit()
916 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
917 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
918 if (Subtarget.is64Bit()) {
919 switch (N->getOpcode()) {
920 default:
921 return NULL;
922 case NVPTXISD::LDGV2:
923 switch (EltVT.getSimpleVT().SimpleTy) {
924 default:
925 return NULL;
926 case MVT::i8:
927 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
928 break;
929 case MVT::i16:
930 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
931 break;
932 case MVT::i32:
933 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
934 break;
935 case MVT::i64:
936 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
937 break;
938 case MVT::f32:
939 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
940 break;
941 case MVT::f64:
942 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
943 break;
944 }
945 break;
946 case NVPTXISD::LDUV2:
947 switch (EltVT.getSimpleVT().SimpleTy) {
948 default:
949 return NULL;
950 case MVT::i8:
951 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
952 break;
953 case MVT::i16:
954 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
955 break;
956 case MVT::i32:
957 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
958 break;
959 case MVT::i64:
960 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
961 break;
962 case MVT::f32:
963 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
964 break;
965 case MVT::f64:
966 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
967 break;
968 }
969 break;
970 case NVPTXISD::LDGV4:
971 switch (EltVT.getSimpleVT().SimpleTy) {
972 default:
973 return NULL;
974 case MVT::i8:
975 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
976 break;
977 case MVT::i16:
978 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
979 break;
980 case MVT::i32:
981 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
982 break;
983 case MVT::f32:
984 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
985 break;
986 }
987 break;
988 case NVPTXISD::LDUV4:
989 switch (EltVT.getSimpleVT().SimpleTy) {
990 default:
991 return NULL;
992 case MVT::i8:
993 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
994 break;
995 case MVT::i16:
996 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
997 break;
998 case MVT::i32:
999 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1000 break;
1001 case MVT::f32:
1002 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1003 break;
1004 }
1005 break;
1006 }
1007 } else {
1008 switch (N->getOpcode()) {
1009 default:
1010 return NULL;
1011 case NVPTXISD::LDGV2:
1012 switch (EltVT.getSimpleVT().SimpleTy) {
1013 default:
1014 return NULL;
1015 case MVT::i8:
1016 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1017 break;
1018 case MVT::i16:
1019 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1020 break;
1021 case MVT::i32:
1022 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1023 break;
1024 case MVT::i64:
1025 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1026 break;
1027 case MVT::f32:
1028 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1029 break;
1030 case MVT::f64:
1031 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1032 break;
1033 }
1034 break;
1035 case NVPTXISD::LDUV2:
1036 switch (EltVT.getSimpleVT().SimpleTy) {
1037 default:
1038 return NULL;
1039 case MVT::i8:
1040 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1041 break;
1042 case MVT::i16:
1043 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1044 break;
1045 case MVT::i32:
1046 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1047 break;
1048 case MVT::i64:
1049 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1050 break;
1051 case MVT::f32:
1052 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1053 break;
1054 case MVT::f64:
1055 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1056 break;
1057 }
1058 break;
1059 case NVPTXISD::LDGV4:
1060 switch (EltVT.getSimpleVT().SimpleTy) {
1061 default:
1062 return NULL;
1063 case MVT::i8:
1064 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1065 break;
1066 case MVT::i16:
1067 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1068 break;
1069 case MVT::i32:
1070 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1071 break;
1072 case MVT::f32:
1073 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1074 break;
1075 }
1076 break;
1077 case NVPTXISD::LDUV4:
1078 switch (EltVT.getSimpleVT().SimpleTy) {
1079 default:
1080 return NULL;
1081 case MVT::i8:
1082 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1083 break;
1084 case MVT::i16:
1085 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1086 break;
1087 case MVT::i32:
1088 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1089 break;
1090 case MVT::f32:
1091 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1092 break;
1093 }
1094 break;
1095 }
1096 }
1097
1098 SDValue Ops[] = { Base, Offset, Chain };
1099
1100 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1101 ArrayRef<SDValue>(Ops, 3));
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001102 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001103 if (Subtarget.is64Bit()) {
1104 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001105 default:
1106 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001107 case NVPTXISD::LDGV2:
1108 switch (EltVT.getSimpleVT().SimpleTy) {
1109 default:
1110 return NULL;
1111 case MVT::i8:
1112 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1113 break;
1114 case MVT::i16:
1115 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1116 break;
1117 case MVT::i32:
1118 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1119 break;
1120 case MVT::i64:
1121 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1122 break;
1123 case MVT::f32:
1124 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1125 break;
1126 case MVT::f64:
1127 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1128 break;
1129 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001130 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001131 case NVPTXISD::LDUV2:
1132 switch (EltVT.getSimpleVT().SimpleTy) {
1133 default:
1134 return NULL;
1135 case MVT::i8:
1136 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1137 break;
1138 case MVT::i16:
1139 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1140 break;
1141 case MVT::i32:
1142 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1143 break;
1144 case MVT::i64:
1145 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1146 break;
1147 case MVT::f32:
1148 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1149 break;
1150 case MVT::f64:
1151 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1152 break;
1153 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001154 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001155 case NVPTXISD::LDGV4:
1156 switch (EltVT.getSimpleVT().SimpleTy) {
1157 default:
1158 return NULL;
1159 case MVT::i8:
1160 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1161 break;
1162 case MVT::i16:
1163 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1164 break;
1165 case MVT::i32:
1166 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1167 break;
1168 case MVT::f32:
1169 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1170 break;
1171 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001172 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001173 case NVPTXISD::LDUV4:
1174 switch (EltVT.getSimpleVT().SimpleTy) {
1175 default:
1176 return NULL;
1177 case MVT::i8:
1178 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1179 break;
1180 case MVT::i16:
1181 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1182 break;
1183 case MVT::i32:
1184 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1185 break;
1186 case MVT::f32:
1187 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1188 break;
1189 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001190 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001191 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001192 } else {
1193 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001194 default:
1195 return NULL;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001196 case NVPTXISD::LDGV2:
1197 switch (EltVT.getSimpleVT().SimpleTy) {
1198 default:
1199 return NULL;
1200 case MVT::i8:
1201 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1202 break;
1203 case MVT::i16:
1204 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1205 break;
1206 case MVT::i32:
1207 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1208 break;
1209 case MVT::i64:
1210 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1211 break;
1212 case MVT::f32:
1213 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1214 break;
1215 case MVT::f64:
1216 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1217 break;
1218 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001219 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001220 case NVPTXISD::LDUV2:
1221 switch (EltVT.getSimpleVT().SimpleTy) {
1222 default:
1223 return NULL;
1224 case MVT::i8:
1225 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1226 break;
1227 case MVT::i16:
1228 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1229 break;
1230 case MVT::i32:
1231 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1232 break;
1233 case MVT::i64:
1234 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1235 break;
1236 case MVT::f32:
1237 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1238 break;
1239 case MVT::f64:
1240 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1241 break;
1242 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001243 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001244 case NVPTXISD::LDGV4:
1245 switch (EltVT.getSimpleVT().SimpleTy) {
1246 default:
1247 return NULL;
1248 case MVT::i8:
1249 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1250 break;
1251 case MVT::i16:
1252 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1253 break;
1254 case MVT::i32:
1255 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1256 break;
1257 case MVT::f32:
1258 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1259 break;
1260 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001261 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001262 case NVPTXISD::LDUV4:
1263 switch (EltVT.getSimpleVT().SimpleTy) {
1264 default:
1265 return NULL;
1266 case MVT::i8:
1267 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1268 break;
1269 case MVT::i16:
1270 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1271 break;
1272 case MVT::i32:
1273 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1274 break;
1275 case MVT::f32:
1276 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1277 break;
1278 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001279 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001280 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001281 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001282
Justin Holewinskie40e9292013-07-01 12:58:52 +00001283 SDValue Ops[] = { Op1, Chain };
1284 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(),
1285 ArrayRef<SDValue>(Ops, 2));
1286 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001287
1288 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1289 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1290 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1291
1292 return LD;
1293}
1294
Justin Holewinski0497ab12013-03-30 14:29:21 +00001295SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001296 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001297 StoreSDNode *ST = cast<StoreSDNode>(N);
1298 EVT StoreVT = ST->getMemoryVT();
1299 SDNode *NVPTXST = NULL;
1300
1301 // do not support pre/post inc/dec
1302 if (ST->isIndexed())
1303 return NULL;
1304
1305 if (!StoreVT.isSimple())
1306 return NULL;
1307
1308 // Address Space Setting
1309 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1310
1311 // Volatile Setting
1312 // - .volatile is only availalble for .global and .shared
1313 bool isVolatile = ST->isVolatile();
1314 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1315 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1316 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1317 isVolatile = false;
1318
1319 // Vector Setting
1320 MVT SimpleVT = StoreVT.getSimpleVT();
1321 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1322 if (SimpleVT.isVector()) {
1323 unsigned num = SimpleVT.getVectorNumElements();
1324 if (num == 2)
1325 vecType = NVPTX::PTXLdStInstCode::V2;
1326 else if (num == 4)
1327 vecType = NVPTX::PTXLdStInstCode::V4;
1328 else
1329 return NULL;
1330 }
1331
1332 // Type Setting: toType + toTypeWidth
1333 // - for integer type, always use 'u'
1334 //
1335 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001336 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001337 unsigned int toType;
1338 if (ScalarVT.isFloatingPoint())
1339 toType = NVPTX::PTXLdStInstCode::Float;
1340 else
1341 toType = NVPTX::PTXLdStInstCode::Unsigned;
1342
1343 // Create the machine instruction DAG
1344 SDValue Chain = N->getOperand(0);
1345 SDValue N1 = N->getOperand(1);
1346 SDValue N2 = N->getOperand(2);
1347 SDValue Addr;
1348 SDValue Offset, Base;
1349 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001350 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001351
1352 if (SelectDirectAddr(N2, Addr)) {
1353 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001354 case MVT::i8:
1355 Opcode = NVPTX::ST_i8_avar;
1356 break;
1357 case MVT::i16:
1358 Opcode = NVPTX::ST_i16_avar;
1359 break;
1360 case MVT::i32:
1361 Opcode = NVPTX::ST_i32_avar;
1362 break;
1363 case MVT::i64:
1364 Opcode = NVPTX::ST_i64_avar;
1365 break;
1366 case MVT::f32:
1367 Opcode = NVPTX::ST_f32_avar;
1368 break;
1369 case MVT::f64:
1370 Opcode = NVPTX::ST_f64_avar;
1371 break;
1372 default:
1373 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001374 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001375 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1376 getI32Imm(vecType), getI32Imm(toType),
1377 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001378 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001379 } else if (Subtarget.is64Bit()
1380 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1381 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001382 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001383 case MVT::i8:
1384 Opcode = NVPTX::ST_i8_asi;
1385 break;
1386 case MVT::i16:
1387 Opcode = NVPTX::ST_i16_asi;
1388 break;
1389 case MVT::i32:
1390 Opcode = NVPTX::ST_i32_asi;
1391 break;
1392 case MVT::i64:
1393 Opcode = NVPTX::ST_i64_asi;
1394 break;
1395 case MVT::f32:
1396 Opcode = NVPTX::ST_f32_asi;
1397 break;
1398 case MVT::f64:
1399 Opcode = NVPTX::ST_f64_asi;
1400 break;
1401 default:
1402 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001403 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001404 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1405 getI32Imm(vecType), getI32Imm(toType),
1406 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001407 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001408 } else if (Subtarget.is64Bit()
1409 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1410 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001411 if (Subtarget.is64Bit()) {
1412 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001413 case MVT::i8:
1414 Opcode = NVPTX::ST_i8_ari_64;
1415 break;
1416 case MVT::i16:
1417 Opcode = NVPTX::ST_i16_ari_64;
1418 break;
1419 case MVT::i32:
1420 Opcode = NVPTX::ST_i32_ari_64;
1421 break;
1422 case MVT::i64:
1423 Opcode = NVPTX::ST_i64_ari_64;
1424 break;
1425 case MVT::f32:
1426 Opcode = NVPTX::ST_f32_ari_64;
1427 break;
1428 case MVT::f64:
1429 Opcode = NVPTX::ST_f64_ari_64;
1430 break;
1431 default:
1432 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001433 }
1434 } else {
1435 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001436 case MVT::i8:
1437 Opcode = NVPTX::ST_i8_ari;
1438 break;
1439 case MVT::i16:
1440 Opcode = NVPTX::ST_i16_ari;
1441 break;
1442 case MVT::i32:
1443 Opcode = NVPTX::ST_i32_ari;
1444 break;
1445 case MVT::i64:
1446 Opcode = NVPTX::ST_i64_ari;
1447 break;
1448 case MVT::f32:
1449 Opcode = NVPTX::ST_f32_ari;
1450 break;
1451 case MVT::f64:
1452 Opcode = NVPTX::ST_f64_ari;
1453 break;
1454 default:
1455 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001456 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001457 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001458 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1459 getI32Imm(vecType), getI32Imm(toType),
1460 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001461 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001462 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001463 if (Subtarget.is64Bit()) {
1464 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001465 case MVT::i8:
1466 Opcode = NVPTX::ST_i8_areg_64;
1467 break;
1468 case MVT::i16:
1469 Opcode = NVPTX::ST_i16_areg_64;
1470 break;
1471 case MVT::i32:
1472 Opcode = NVPTX::ST_i32_areg_64;
1473 break;
1474 case MVT::i64:
1475 Opcode = NVPTX::ST_i64_areg_64;
1476 break;
1477 case MVT::f32:
1478 Opcode = NVPTX::ST_f32_areg_64;
1479 break;
1480 case MVT::f64:
1481 Opcode = NVPTX::ST_f64_areg_64;
1482 break;
1483 default:
1484 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001485 }
1486 } else {
1487 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001488 case MVT::i8:
1489 Opcode = NVPTX::ST_i8_areg;
1490 break;
1491 case MVT::i16:
1492 Opcode = NVPTX::ST_i16_areg;
1493 break;
1494 case MVT::i32:
1495 Opcode = NVPTX::ST_i32_areg;
1496 break;
1497 case MVT::i64:
1498 Opcode = NVPTX::ST_i64_areg;
1499 break;
1500 case MVT::f32:
1501 Opcode = NVPTX::ST_f32_areg;
1502 break;
1503 case MVT::f64:
1504 Opcode = NVPTX::ST_f64_areg;
1505 break;
1506 default:
1507 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001508 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001509 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001510 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1511 getI32Imm(vecType), getI32Imm(toType),
1512 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001513 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001514 }
1515
1516 if (NVPTXST != NULL) {
1517 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1518 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1519 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1520 }
1521
1522 return NVPTXST;
1523}
1524
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001525SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1526 SDValue Chain = N->getOperand(0);
1527 SDValue Op1 = N->getOperand(1);
1528 SDValue Addr, Offset, Base;
1529 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001530 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001531 SDNode *ST;
1532 EVT EltVT = Op1.getValueType();
1533 MemSDNode *MemSD = cast<MemSDNode>(N);
1534 EVT StoreVT = MemSD->getMemoryVT();
1535
1536 // Address Space Setting
1537 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1538
1539 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1540 report_fatal_error("Cannot store to pointer that points to constant "
1541 "memory space");
1542 }
1543
1544 // Volatile Setting
1545 // - .volatile is only availalble for .global and .shared
1546 bool IsVolatile = MemSD->isVolatile();
1547 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1548 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1549 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1550 IsVolatile = false;
1551
1552 // Type Setting: toType + toTypeWidth
1553 // - for integer type, always use 'u'
1554 assert(StoreVT.isSimple() && "Store value is not simple");
1555 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001556 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001557 unsigned ToType;
1558 if (ScalarVT.isFloatingPoint())
1559 ToType = NVPTX::PTXLdStInstCode::Float;
1560 else
1561 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1562
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001563 SmallVector<SDValue, 12> StOps;
1564 SDValue N2;
1565 unsigned VecType;
1566
1567 switch (N->getOpcode()) {
1568 case NVPTXISD::StoreV2:
1569 VecType = NVPTX::PTXLdStInstCode::V2;
1570 StOps.push_back(N->getOperand(1));
1571 StOps.push_back(N->getOperand(2));
1572 N2 = N->getOperand(3);
1573 break;
1574 case NVPTXISD::StoreV4:
1575 VecType = NVPTX::PTXLdStInstCode::V4;
1576 StOps.push_back(N->getOperand(1));
1577 StOps.push_back(N->getOperand(2));
1578 StOps.push_back(N->getOperand(3));
1579 StOps.push_back(N->getOperand(4));
1580 N2 = N->getOperand(5);
1581 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001582 default:
1583 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001584 }
1585
1586 StOps.push_back(getI32Imm(IsVolatile));
1587 StOps.push_back(getI32Imm(CodeAddrSpace));
1588 StOps.push_back(getI32Imm(VecType));
1589 StOps.push_back(getI32Imm(ToType));
1590 StOps.push_back(getI32Imm(ToTypeWidth));
1591
1592 if (SelectDirectAddr(N2, Addr)) {
1593 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001594 default:
1595 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001596 case NVPTXISD::StoreV2:
1597 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001598 default:
1599 return NULL;
1600 case MVT::i8:
1601 Opcode = NVPTX::STV_i8_v2_avar;
1602 break;
1603 case MVT::i16:
1604 Opcode = NVPTX::STV_i16_v2_avar;
1605 break;
1606 case MVT::i32:
1607 Opcode = NVPTX::STV_i32_v2_avar;
1608 break;
1609 case MVT::i64:
1610 Opcode = NVPTX::STV_i64_v2_avar;
1611 break;
1612 case MVT::f32:
1613 Opcode = NVPTX::STV_f32_v2_avar;
1614 break;
1615 case MVT::f64:
1616 Opcode = NVPTX::STV_f64_v2_avar;
1617 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001618 }
1619 break;
1620 case NVPTXISD::StoreV4:
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_v4_avar;
1626 break;
1627 case MVT::i16:
1628 Opcode = NVPTX::STV_i16_v4_avar;
1629 break;
1630 case MVT::i32:
1631 Opcode = NVPTX::STV_i32_v4_avar;
1632 break;
1633 case MVT::f32:
1634 Opcode = NVPTX::STV_f32_v4_avar;
1635 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001636 }
1637 break;
1638 }
1639 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001640 } else if (Subtarget.is64Bit()
1641 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1642 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001643 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001644 default:
1645 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001646 case NVPTXISD::StoreV2:
1647 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001648 default:
1649 return NULL;
1650 case MVT::i8:
1651 Opcode = NVPTX::STV_i8_v2_asi;
1652 break;
1653 case MVT::i16:
1654 Opcode = NVPTX::STV_i16_v2_asi;
1655 break;
1656 case MVT::i32:
1657 Opcode = NVPTX::STV_i32_v2_asi;
1658 break;
1659 case MVT::i64:
1660 Opcode = NVPTX::STV_i64_v2_asi;
1661 break;
1662 case MVT::f32:
1663 Opcode = NVPTX::STV_f32_v2_asi;
1664 break;
1665 case MVT::f64:
1666 Opcode = NVPTX::STV_f64_v2_asi;
1667 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001668 }
1669 break;
1670 case NVPTXISD::StoreV4:
1671 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001672 default:
1673 return NULL;
1674 case MVT::i8:
1675 Opcode = NVPTX::STV_i8_v4_asi;
1676 break;
1677 case MVT::i16:
1678 Opcode = NVPTX::STV_i16_v4_asi;
1679 break;
1680 case MVT::i32:
1681 Opcode = NVPTX::STV_i32_v4_asi;
1682 break;
1683 case MVT::f32:
1684 Opcode = NVPTX::STV_f32_v4_asi;
1685 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001686 }
1687 break;
1688 }
1689 StOps.push_back(Base);
1690 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001691 } else if (Subtarget.is64Bit()
1692 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1693 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001694 if (Subtarget.is64Bit()) {
1695 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001696 default:
1697 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001698 case NVPTXISD::StoreV2:
1699 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001700 default:
1701 return NULL;
1702 case MVT::i8:
1703 Opcode = NVPTX::STV_i8_v2_ari_64;
1704 break;
1705 case MVT::i16:
1706 Opcode = NVPTX::STV_i16_v2_ari_64;
1707 break;
1708 case MVT::i32:
1709 Opcode = NVPTX::STV_i32_v2_ari_64;
1710 break;
1711 case MVT::i64:
1712 Opcode = NVPTX::STV_i64_v2_ari_64;
1713 break;
1714 case MVT::f32:
1715 Opcode = NVPTX::STV_f32_v2_ari_64;
1716 break;
1717 case MVT::f64:
1718 Opcode = NVPTX::STV_f64_v2_ari_64;
1719 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001720 }
1721 break;
1722 case NVPTXISD::StoreV4:
1723 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001724 default:
1725 return NULL;
1726 case MVT::i8:
1727 Opcode = NVPTX::STV_i8_v4_ari_64;
1728 break;
1729 case MVT::i16:
1730 Opcode = NVPTX::STV_i16_v4_ari_64;
1731 break;
1732 case MVT::i32:
1733 Opcode = NVPTX::STV_i32_v4_ari_64;
1734 break;
1735 case MVT::f32:
1736 Opcode = NVPTX::STV_f32_v4_ari_64;
1737 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001738 }
1739 break;
1740 }
1741 } else {
1742 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001743 default:
1744 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001745 case NVPTXISD::StoreV2:
1746 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001747 default:
1748 return NULL;
1749 case MVT::i8:
1750 Opcode = NVPTX::STV_i8_v2_ari;
1751 break;
1752 case MVT::i16:
1753 Opcode = NVPTX::STV_i16_v2_ari;
1754 break;
1755 case MVT::i32:
1756 Opcode = NVPTX::STV_i32_v2_ari;
1757 break;
1758 case MVT::i64:
1759 Opcode = NVPTX::STV_i64_v2_ari;
1760 break;
1761 case MVT::f32:
1762 Opcode = NVPTX::STV_f32_v2_ari;
1763 break;
1764 case MVT::f64:
1765 Opcode = NVPTX::STV_f64_v2_ari;
1766 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001767 }
1768 break;
1769 case NVPTXISD::StoreV4:
1770 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001771 default:
1772 return NULL;
1773 case MVT::i8:
1774 Opcode = NVPTX::STV_i8_v4_ari;
1775 break;
1776 case MVT::i16:
1777 Opcode = NVPTX::STV_i16_v4_ari;
1778 break;
1779 case MVT::i32:
1780 Opcode = NVPTX::STV_i32_v4_ari;
1781 break;
1782 case MVT::f32:
1783 Opcode = NVPTX::STV_f32_v4_ari;
1784 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001785 }
1786 break;
1787 }
1788 }
1789 StOps.push_back(Base);
1790 StOps.push_back(Offset);
1791 } else {
1792 if (Subtarget.is64Bit()) {
1793 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001794 default:
1795 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001796 case NVPTXISD::StoreV2:
1797 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001798 default:
1799 return NULL;
1800 case MVT::i8:
1801 Opcode = NVPTX::STV_i8_v2_areg_64;
1802 break;
1803 case MVT::i16:
1804 Opcode = NVPTX::STV_i16_v2_areg_64;
1805 break;
1806 case MVT::i32:
1807 Opcode = NVPTX::STV_i32_v2_areg_64;
1808 break;
1809 case MVT::i64:
1810 Opcode = NVPTX::STV_i64_v2_areg_64;
1811 break;
1812 case MVT::f32:
1813 Opcode = NVPTX::STV_f32_v2_areg_64;
1814 break;
1815 case MVT::f64:
1816 Opcode = NVPTX::STV_f64_v2_areg_64;
1817 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001818 }
1819 break;
1820 case NVPTXISD::StoreV4:
1821 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001822 default:
1823 return NULL;
1824 case MVT::i8:
1825 Opcode = NVPTX::STV_i8_v4_areg_64;
1826 break;
1827 case MVT::i16:
1828 Opcode = NVPTX::STV_i16_v4_areg_64;
1829 break;
1830 case MVT::i32:
1831 Opcode = NVPTX::STV_i32_v4_areg_64;
1832 break;
1833 case MVT::f32:
1834 Opcode = NVPTX::STV_f32_v4_areg_64;
1835 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001836 }
1837 break;
1838 }
1839 } else {
1840 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001841 default:
1842 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001843 case NVPTXISD::StoreV2:
1844 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001845 default:
1846 return NULL;
1847 case MVT::i8:
1848 Opcode = NVPTX::STV_i8_v2_areg;
1849 break;
1850 case MVT::i16:
1851 Opcode = NVPTX::STV_i16_v2_areg;
1852 break;
1853 case MVT::i32:
1854 Opcode = NVPTX::STV_i32_v2_areg;
1855 break;
1856 case MVT::i64:
1857 Opcode = NVPTX::STV_i64_v2_areg;
1858 break;
1859 case MVT::f32:
1860 Opcode = NVPTX::STV_f32_v2_areg;
1861 break;
1862 case MVT::f64:
1863 Opcode = NVPTX::STV_f64_v2_areg;
1864 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001865 }
1866 break;
1867 case NVPTXISD::StoreV4:
1868 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001869 default:
1870 return NULL;
1871 case MVT::i8:
1872 Opcode = NVPTX::STV_i8_v4_areg;
1873 break;
1874 case MVT::i16:
1875 Opcode = NVPTX::STV_i16_v4_areg;
1876 break;
1877 case MVT::i32:
1878 Opcode = NVPTX::STV_i32_v4_areg;
1879 break;
1880 case MVT::f32:
1881 Opcode = NVPTX::STV_f32_v4_areg;
1882 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001883 }
1884 break;
1885 }
1886 }
1887 StOps.push_back(N2);
1888 }
1889
1890 StOps.push_back(Chain);
1891
Michael Liaob53d8962013-04-19 22:22:57 +00001892 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001893
1894 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1895 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1896 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1897
1898 return ST;
1899}
1900
Justin Holewinskif8f70912013-06-28 17:57:59 +00001901SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
1902 SDValue Chain = Node->getOperand(0);
1903 SDValue Offset = Node->getOperand(2);
1904 SDValue Flag = Node->getOperand(3);
1905 SDLoc DL(Node);
1906 MemSDNode *Mem = cast<MemSDNode>(Node);
1907
1908 unsigned VecSize;
1909 switch (Node->getOpcode()) {
1910 default:
1911 return NULL;
1912 case NVPTXISD::LoadParam:
1913 VecSize = 1;
1914 break;
1915 case NVPTXISD::LoadParamV2:
1916 VecSize = 2;
1917 break;
1918 case NVPTXISD::LoadParamV4:
1919 VecSize = 4;
1920 break;
1921 }
1922
1923 EVT EltVT = Node->getValueType(0);
1924 EVT MemVT = Mem->getMemoryVT();
1925
1926 unsigned Opc = 0;
1927
1928 switch (VecSize) {
1929 default:
1930 return NULL;
1931 case 1:
1932 switch (MemVT.getSimpleVT().SimpleTy) {
1933 default:
1934 return NULL;
1935 case MVT::i1:
1936 Opc = NVPTX::LoadParamMemI8;
1937 break;
1938 case MVT::i8:
1939 Opc = NVPTX::LoadParamMemI8;
1940 break;
1941 case MVT::i16:
1942 Opc = NVPTX::LoadParamMemI16;
1943 break;
1944 case MVT::i32:
1945 Opc = NVPTX::LoadParamMemI32;
1946 break;
1947 case MVT::i64:
1948 Opc = NVPTX::LoadParamMemI64;
1949 break;
1950 case MVT::f32:
1951 Opc = NVPTX::LoadParamMemF32;
1952 break;
1953 case MVT::f64:
1954 Opc = NVPTX::LoadParamMemF64;
1955 break;
1956 }
1957 break;
1958 case 2:
1959 switch (MemVT.getSimpleVT().SimpleTy) {
1960 default:
1961 return NULL;
1962 case MVT::i1:
1963 Opc = NVPTX::LoadParamMemV2I8;
1964 break;
1965 case MVT::i8:
1966 Opc = NVPTX::LoadParamMemV2I8;
1967 break;
1968 case MVT::i16:
1969 Opc = NVPTX::LoadParamMemV2I16;
1970 break;
1971 case MVT::i32:
1972 Opc = NVPTX::LoadParamMemV2I32;
1973 break;
1974 case MVT::i64:
1975 Opc = NVPTX::LoadParamMemV2I64;
1976 break;
1977 case MVT::f32:
1978 Opc = NVPTX::LoadParamMemV2F32;
1979 break;
1980 case MVT::f64:
1981 Opc = NVPTX::LoadParamMemV2F64;
1982 break;
1983 }
1984 break;
1985 case 4:
1986 switch (MemVT.getSimpleVT().SimpleTy) {
1987 default:
1988 return NULL;
1989 case MVT::i1:
1990 Opc = NVPTX::LoadParamMemV4I8;
1991 break;
1992 case MVT::i8:
1993 Opc = NVPTX::LoadParamMemV4I8;
1994 break;
1995 case MVT::i16:
1996 Opc = NVPTX::LoadParamMemV4I16;
1997 break;
1998 case MVT::i32:
1999 Opc = NVPTX::LoadParamMemV4I32;
2000 break;
2001 case MVT::f32:
2002 Opc = NVPTX::LoadParamMemV4F32;
2003 break;
2004 }
2005 break;
2006 }
2007
2008 SDVTList VTs;
2009 if (VecSize == 1) {
2010 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2011 } else if (VecSize == 2) {
2012 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2013 } else {
2014 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
2015 VTs = CurDAG->getVTList(&EVTs[0], 5);
2016 }
2017
2018 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2019
2020 SmallVector<SDValue, 2> Ops;
2021 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2022 Ops.push_back(Chain);
2023 Ops.push_back(Flag);
2024
2025 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002026 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002027 return Ret;
2028}
2029
2030SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2031 SDLoc DL(N);
2032 SDValue Chain = N->getOperand(0);
2033 SDValue Offset = N->getOperand(1);
2034 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2035 MemSDNode *Mem = cast<MemSDNode>(N);
2036
2037 // How many elements do we have?
2038 unsigned NumElts = 1;
2039 switch (N->getOpcode()) {
2040 default:
2041 return NULL;
2042 case NVPTXISD::StoreRetval:
2043 NumElts = 1;
2044 break;
2045 case NVPTXISD::StoreRetvalV2:
2046 NumElts = 2;
2047 break;
2048 case NVPTXISD::StoreRetvalV4:
2049 NumElts = 4;
2050 break;
2051 }
2052
2053 // Build vector of operands
2054 SmallVector<SDValue, 6> Ops;
2055 for (unsigned i = 0; i < NumElts; ++i)
2056 Ops.push_back(N->getOperand(i + 2));
2057 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2058 Ops.push_back(Chain);
2059
2060 // Determine target opcode
2061 // If we have an i1, use an 8-bit store. The lowering code in
2062 // NVPTXISelLowering will have already emitted an upcast.
2063 unsigned Opcode = 0;
2064 switch (NumElts) {
2065 default:
2066 return NULL;
2067 case 1:
2068 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2069 default:
2070 return NULL;
2071 case MVT::i1:
2072 Opcode = NVPTX::StoreRetvalI8;
2073 break;
2074 case MVT::i8:
2075 Opcode = NVPTX::StoreRetvalI8;
2076 break;
2077 case MVT::i16:
2078 Opcode = NVPTX::StoreRetvalI16;
2079 break;
2080 case MVT::i32:
2081 Opcode = NVPTX::StoreRetvalI32;
2082 break;
2083 case MVT::i64:
2084 Opcode = NVPTX::StoreRetvalI64;
2085 break;
2086 case MVT::f32:
2087 Opcode = NVPTX::StoreRetvalF32;
2088 break;
2089 case MVT::f64:
2090 Opcode = NVPTX::StoreRetvalF64;
2091 break;
2092 }
2093 break;
2094 case 2:
2095 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2096 default:
2097 return NULL;
2098 case MVT::i1:
2099 Opcode = NVPTX::StoreRetvalV2I8;
2100 break;
2101 case MVT::i8:
2102 Opcode = NVPTX::StoreRetvalV2I8;
2103 break;
2104 case MVT::i16:
2105 Opcode = NVPTX::StoreRetvalV2I16;
2106 break;
2107 case MVT::i32:
2108 Opcode = NVPTX::StoreRetvalV2I32;
2109 break;
2110 case MVT::i64:
2111 Opcode = NVPTX::StoreRetvalV2I64;
2112 break;
2113 case MVT::f32:
2114 Opcode = NVPTX::StoreRetvalV2F32;
2115 break;
2116 case MVT::f64:
2117 Opcode = NVPTX::StoreRetvalV2F64;
2118 break;
2119 }
2120 break;
2121 case 4:
2122 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2123 default:
2124 return NULL;
2125 case MVT::i1:
2126 Opcode = NVPTX::StoreRetvalV4I8;
2127 break;
2128 case MVT::i8:
2129 Opcode = NVPTX::StoreRetvalV4I8;
2130 break;
2131 case MVT::i16:
2132 Opcode = NVPTX::StoreRetvalV4I16;
2133 break;
2134 case MVT::i32:
2135 Opcode = NVPTX::StoreRetvalV4I32;
2136 break;
2137 case MVT::f32:
2138 Opcode = NVPTX::StoreRetvalV4F32;
2139 break;
2140 }
2141 break;
2142 }
2143
2144 SDNode *Ret =
2145 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2146 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2147 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2148 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2149
2150 return Ret;
2151}
2152
2153SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2154 SDLoc DL(N);
2155 SDValue Chain = N->getOperand(0);
2156 SDValue Param = N->getOperand(1);
2157 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2158 SDValue Offset = N->getOperand(2);
2159 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2160 MemSDNode *Mem = cast<MemSDNode>(N);
2161 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2162
2163 // How many elements do we have?
2164 unsigned NumElts = 1;
2165 switch (N->getOpcode()) {
2166 default:
2167 return NULL;
2168 case NVPTXISD::StoreParamU32:
2169 case NVPTXISD::StoreParamS32:
2170 case NVPTXISD::StoreParam:
2171 NumElts = 1;
2172 break;
2173 case NVPTXISD::StoreParamV2:
2174 NumElts = 2;
2175 break;
2176 case NVPTXISD::StoreParamV4:
2177 NumElts = 4;
2178 break;
2179 }
2180
2181 // Build vector of operands
2182 SmallVector<SDValue, 8> Ops;
2183 for (unsigned i = 0; i < NumElts; ++i)
2184 Ops.push_back(N->getOperand(i + 3));
2185 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2186 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2187 Ops.push_back(Chain);
2188 Ops.push_back(Flag);
2189
2190 // Determine target opcode
2191 // If we have an i1, use an 8-bit store. The lowering code in
2192 // NVPTXISelLowering will have already emitted an upcast.
2193 unsigned Opcode = 0;
2194 switch (N->getOpcode()) {
2195 default:
2196 switch (NumElts) {
2197 default:
2198 return NULL;
2199 case 1:
2200 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2201 default:
2202 return NULL;
2203 case MVT::i1:
2204 Opcode = NVPTX::StoreParamI8;
2205 break;
2206 case MVT::i8:
2207 Opcode = NVPTX::StoreParamI8;
2208 break;
2209 case MVT::i16:
2210 Opcode = NVPTX::StoreParamI16;
2211 break;
2212 case MVT::i32:
2213 Opcode = NVPTX::StoreParamI32;
2214 break;
2215 case MVT::i64:
2216 Opcode = NVPTX::StoreParamI64;
2217 break;
2218 case MVT::f32:
2219 Opcode = NVPTX::StoreParamF32;
2220 break;
2221 case MVT::f64:
2222 Opcode = NVPTX::StoreParamF64;
2223 break;
2224 }
2225 break;
2226 case 2:
2227 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2228 default:
2229 return NULL;
2230 case MVT::i1:
2231 Opcode = NVPTX::StoreParamV2I8;
2232 break;
2233 case MVT::i8:
2234 Opcode = NVPTX::StoreParamV2I8;
2235 break;
2236 case MVT::i16:
2237 Opcode = NVPTX::StoreParamV2I16;
2238 break;
2239 case MVT::i32:
2240 Opcode = NVPTX::StoreParamV2I32;
2241 break;
2242 case MVT::i64:
2243 Opcode = NVPTX::StoreParamV2I64;
2244 break;
2245 case MVT::f32:
2246 Opcode = NVPTX::StoreParamV2F32;
2247 break;
2248 case MVT::f64:
2249 Opcode = NVPTX::StoreParamV2F64;
2250 break;
2251 }
2252 break;
2253 case 4:
2254 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2255 default:
2256 return NULL;
2257 case MVT::i1:
2258 Opcode = NVPTX::StoreParamV4I8;
2259 break;
2260 case MVT::i8:
2261 Opcode = NVPTX::StoreParamV4I8;
2262 break;
2263 case MVT::i16:
2264 Opcode = NVPTX::StoreParamV4I16;
2265 break;
2266 case MVT::i32:
2267 Opcode = NVPTX::StoreParamV4I32;
2268 break;
2269 case MVT::f32:
2270 Opcode = NVPTX::StoreParamV4F32;
2271 break;
2272 }
2273 break;
2274 }
2275 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002276 // Special case: if we have a sign-extend/zero-extend node, insert the
2277 // conversion instruction first, and use that as the value operand to
2278 // the selected StoreParam node.
2279 case NVPTXISD::StoreParamU32: {
2280 Opcode = NVPTX::StoreParamI32;
2281 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2282 MVT::i32);
2283 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2284 MVT::i32, Ops[0], CvtNone);
2285 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002286 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002287 }
2288 case NVPTXISD::StoreParamS32: {
2289 Opcode = NVPTX::StoreParamI32;
2290 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2291 MVT::i32);
2292 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2293 MVT::i32, Ops[0], CvtNone);
2294 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002295 break;
2296 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002297 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002298
Justin Holewinskidff28d22013-07-01 12:59:01 +00002299 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002300 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002301 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002302 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2303 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2304 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2305
2306 return Ret;
2307}
2308
Justin Holewinskiae556d32012-05-04 20:18:50 +00002309// SelectDirectAddr - Match a direct address for DAG.
2310// A direct address could be a globaladdress or externalsymbol.
2311bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
2312 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002313 if (N.getOpcode() == ISD::TargetGlobalAddress ||
2314 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002315 Address = N;
2316 return true;
2317 }
2318 if (N.getOpcode() == NVPTXISD::Wrapper) {
2319 Address = N.getOperand(0);
2320 return true;
2321 }
2322 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
2323 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
2324 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
2325 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
2326 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
2327 }
2328 return false;
2329}
2330
2331// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002332bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
2333 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002334 if (Addr.getOpcode() == ISD::ADD) {
2335 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002336 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00002337 if (SelectDirectAddr(base, Base)) {
2338 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2339 return true;
2340 }
2341 }
2342 }
2343 return false;
2344}
2345
2346// symbol+offset
2347bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
2348 SDValue &Base, SDValue &Offset) {
2349 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
2350}
2351
2352// symbol+offset
2353bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
2354 SDValue &Base, SDValue &Offset) {
2355 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
2356}
2357
2358// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00002359bool NVPTXDAGToDAGISel::SelectADDRri_imp(
2360 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002361 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2362 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2363 Offset = CurDAG->getTargetConstant(0, mvt);
2364 return true;
2365 }
2366 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2367 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00002368 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00002369
2370 if (Addr.getOpcode() == ISD::ADD) {
2371 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
2372 return false;
2373 }
2374 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
2375 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00002376 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002377 // Constant offset from frame ref.
2378 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
2379 else
2380 Base = Addr.getOperand(0);
2381 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
2382 return true;
2383 }
2384 }
2385 return false;
2386}
2387
2388// register+offset
2389bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
2390 SDValue &Base, SDValue &Offset) {
2391 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
2392}
2393
2394// register+offset
2395bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
2396 SDValue &Base, SDValue &Offset) {
2397 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
2398}
2399
2400bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
2401 unsigned int spN) const {
2402 const Value *Src = NULL;
2403 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
2404 // the classof() for MemSDNode does not include MemIntrinsicSDNode
2405 // (See SelectionDAGNodes.h). So we need to check for both.
2406 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
2407 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00002408 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002409 Src = mN->getSrcValue();
2410 }
2411 if (!Src)
2412 return false;
2413 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
2414 return (PT->getAddressSpace() == spN);
2415 return false;
2416}
2417
2418/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
2419/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002420bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
2421 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00002422 SDValue Op0, Op1;
2423 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002424 default:
2425 return true;
2426 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00002427 if (SelectDirectAddr(Op, Op0)) {
2428 OutOps.push_back(Op0);
2429 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
2430 return false;
2431 }
2432 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
2433 OutOps.push_back(Op0);
2434 OutOps.push_back(Op1);
2435 return false;
2436 }
2437 break;
2438 }
2439 return true;
2440}
2441
2442// Return true if N is a undef or a constant.
2443// If N was undef, return a (i8imm 0) in Retval
2444// If N was imm, convert it to i8imm and return in Retval
2445// Note: The convert to i8imm is required, otherwise the
2446// pattern matcher inserts a bunch of IMOVi8rr to convert
2447// the imm to i8imm, and this causes instruction selection
2448// to fail.
Justin Holewinski0497ab12013-03-30 14:29:21 +00002449bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
2450 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
Justin Holewinskiae556d32012-05-04 20:18:50 +00002451 return false;
2452
2453 if (N.getOpcode() == ISD::UNDEF)
2454 Retval = CurDAG->getTargetConstant(0, MVT::i8);
2455 else {
2456 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
2457 unsigned retval = cn->getZExtValue();
2458 Retval = CurDAG->getTargetConstant(retval, MVT::i8);
2459 }
2460 return true;
2461}