blob: ac6dbb9eb65da3b94cc553c10442e748629409df [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 Holewinski0497ab12013-03-30 14:29:21 +0000119 default:
120 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000121 }
122 if (ResNode)
123 return ResNode;
124 return SelectCode(N);
125}
126
Justin Holewinski0497ab12013-03-30 14:29:21 +0000127static unsigned int getCodeAddrSpace(MemSDNode *N,
128 const NVPTXSubtarget &Subtarget) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000129 const Value *Src = N->getSrcValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000130
Justin Holewinskiae556d32012-05-04 20:18:50 +0000131 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000132 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000133
134 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
135 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000136 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
137 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
138 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
139 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
140 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
141 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
142 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000143 }
144 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000145 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000146}
147
Justin Holewinski0497ab12013-03-30 14:29:21 +0000148SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000149 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000150 LoadSDNode *LD = cast<LoadSDNode>(N);
151 EVT LoadedVT = LD->getMemoryVT();
Justin Holewinski0497ab12013-03-30 14:29:21 +0000152 SDNode *NVPTXLD = NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000153
154 // do not support pre/post inc/dec
155 if (LD->isIndexed())
156 return NULL;
157
158 if (!LoadedVT.isSimple())
159 return NULL;
160
161 // Address Space Setting
162 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
163
164 // Volatile Setting
165 // - .volatile is only availalble for .global and .shared
166 bool isVolatile = LD->isVolatile();
167 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
168 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
169 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
170 isVolatile = false;
171
172 // Vector Setting
173 MVT SimpleVT = LoadedVT.getSimpleVT();
174 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
175 if (SimpleVT.isVector()) {
176 unsigned num = SimpleVT.getVectorNumElements();
177 if (num == 2)
178 vecType = NVPTX::PTXLdStInstCode::V2;
179 else if (num == 4)
180 vecType = NVPTX::PTXLdStInstCode::V4;
181 else
182 return NULL;
183 }
184
185 // Type Setting: fromType + fromTypeWidth
186 //
187 // Sign : ISD::SEXTLOAD
188 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
189 // type is integer
190 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
191 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000192 // Read at least 8 bits (predicates are stored as 8-bit values)
193 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000194 unsigned int fromType;
195 if ((LD->getExtensionType() == ISD::SEXTLOAD))
196 fromType = NVPTX::PTXLdStInstCode::Signed;
197 else if (ScalarVT.isFloatingPoint())
198 fromType = NVPTX::PTXLdStInstCode::Float;
199 else
200 fromType = NVPTX::PTXLdStInstCode::Unsigned;
201
202 // Create the machine instruction DAG
203 SDValue Chain = N->getOperand(0);
204 SDValue N1 = N->getOperand(1);
205 SDValue Addr;
206 SDValue Offset, Base;
207 unsigned Opcode;
208 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
209
210 if (SelectDirectAddr(N1, Addr)) {
211 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000212 case MVT::i8:
213 Opcode = NVPTX::LD_i8_avar;
214 break;
215 case MVT::i16:
216 Opcode = NVPTX::LD_i16_avar;
217 break;
218 case MVT::i32:
219 Opcode = NVPTX::LD_i32_avar;
220 break;
221 case MVT::i64:
222 Opcode = NVPTX::LD_i64_avar;
223 break;
224 case MVT::f32:
225 Opcode = NVPTX::LD_f32_avar;
226 break;
227 case MVT::f64:
228 Opcode = NVPTX::LD_f64_avar;
229 break;
230 default:
231 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000232 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000233 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
234 getI32Imm(vecType), getI32Imm(fromType),
235 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000236 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000237 } else if (Subtarget.is64Bit()
238 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
239 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000240 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000241 case MVT::i8:
242 Opcode = NVPTX::LD_i8_asi;
243 break;
244 case MVT::i16:
245 Opcode = NVPTX::LD_i16_asi;
246 break;
247 case MVT::i32:
248 Opcode = NVPTX::LD_i32_asi;
249 break;
250 case MVT::i64:
251 Opcode = NVPTX::LD_i64_asi;
252 break;
253 case MVT::f32:
254 Opcode = NVPTX::LD_f32_asi;
255 break;
256 case MVT::f64:
257 Opcode = NVPTX::LD_f64_asi;
258 break;
259 default:
260 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000261 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000262 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
263 getI32Imm(vecType), getI32Imm(fromType),
264 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000265 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000266 } else if (Subtarget.is64Bit()
267 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
268 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000269 if (Subtarget.is64Bit()) {
270 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000271 case MVT::i8:
272 Opcode = NVPTX::LD_i8_ari_64;
273 break;
274 case MVT::i16:
275 Opcode = NVPTX::LD_i16_ari_64;
276 break;
277 case MVT::i32:
278 Opcode = NVPTX::LD_i32_ari_64;
279 break;
280 case MVT::i64:
281 Opcode = NVPTX::LD_i64_ari_64;
282 break;
283 case MVT::f32:
284 Opcode = NVPTX::LD_f32_ari_64;
285 break;
286 case MVT::f64:
287 Opcode = NVPTX::LD_f64_ari_64;
288 break;
289 default:
290 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000291 }
292 } else {
293 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000294 case MVT::i8:
295 Opcode = NVPTX::LD_i8_ari;
296 break;
297 case MVT::i16:
298 Opcode = NVPTX::LD_i16_ari;
299 break;
300 case MVT::i32:
301 Opcode = NVPTX::LD_i32_ari;
302 break;
303 case MVT::i64:
304 Opcode = NVPTX::LD_i64_ari;
305 break;
306 case MVT::f32:
307 Opcode = NVPTX::LD_f32_ari;
308 break;
309 case MVT::f64:
310 Opcode = NVPTX::LD_f64_ari;
311 break;
312 default:
313 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000314 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000315 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000316 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
317 getI32Imm(vecType), getI32Imm(fromType),
318 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000319 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000320 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000321 if (Subtarget.is64Bit()) {
322 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000323 case MVT::i8:
324 Opcode = NVPTX::LD_i8_areg_64;
325 break;
326 case MVT::i16:
327 Opcode = NVPTX::LD_i16_areg_64;
328 break;
329 case MVT::i32:
330 Opcode = NVPTX::LD_i32_areg_64;
331 break;
332 case MVT::i64:
333 Opcode = NVPTX::LD_i64_areg_64;
334 break;
335 case MVT::f32:
336 Opcode = NVPTX::LD_f32_areg_64;
337 break;
338 case MVT::f64:
339 Opcode = NVPTX::LD_f64_areg_64;
340 break;
341 default:
342 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000343 }
344 } else {
345 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000346 case MVT::i8:
347 Opcode = NVPTX::LD_i8_areg;
348 break;
349 case MVT::i16:
350 Opcode = NVPTX::LD_i16_areg;
351 break;
352 case MVT::i32:
353 Opcode = NVPTX::LD_i32_areg;
354 break;
355 case MVT::i64:
356 Opcode = NVPTX::LD_i64_areg;
357 break;
358 case MVT::f32:
359 Opcode = NVPTX::LD_f32_areg;
360 break;
361 case MVT::f64:
362 Opcode = NVPTX::LD_f64_areg;
363 break;
364 default:
365 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000366 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000367 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000368 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
369 getI32Imm(vecType), getI32Imm(fromType),
370 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000371 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000372 }
373
374 if (NVPTXLD != NULL) {
375 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
376 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
377 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
378 }
379
380 return NVPTXLD;
381}
382
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000383SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
384
385 SDValue Chain = N->getOperand(0);
386 SDValue Op1 = N->getOperand(1);
387 SDValue Addr, Offset, Base;
388 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000389 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000390 SDNode *LD;
391 MemSDNode *MemSD = cast<MemSDNode>(N);
392 EVT LoadedVT = MemSD->getMemoryVT();
393
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000394 if (!LoadedVT.isSimple())
Justin Holewinski0497ab12013-03-30 14:29:21 +0000395 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000396
397 // Address Space Setting
398 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
399
400 // Volatile Setting
401 // - .volatile is only availalble for .global and .shared
402 bool IsVolatile = MemSD->isVolatile();
403 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
404 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
405 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
406 IsVolatile = false;
407
408 // Vector Setting
409 MVT SimpleVT = LoadedVT.getSimpleVT();
410
411 // Type Setting: fromType + fromTypeWidth
412 //
413 // Sign : ISD::SEXTLOAD
414 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
415 // type is integer
416 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
417 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000418 // Read at least 8 bits (predicates are stored as 8-bit values)
419 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000420 unsigned int FromType;
421 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000422 unsigned ExtensionType = cast<ConstantSDNode>(
423 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000424 if (ExtensionType == ISD::SEXTLOAD)
425 FromType = NVPTX::PTXLdStInstCode::Signed;
426 else if (ScalarVT.isFloatingPoint())
427 FromType = NVPTX::PTXLdStInstCode::Float;
428 else
429 FromType = NVPTX::PTXLdStInstCode::Unsigned;
430
431 unsigned VecType;
432
433 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000434 case NVPTXISD::LoadV2:
435 VecType = NVPTX::PTXLdStInstCode::V2;
436 break;
437 case NVPTXISD::LoadV4:
438 VecType = NVPTX::PTXLdStInstCode::V4;
439 break;
440 default:
441 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000442 }
443
444 EVT EltVT = N->getValueType(0);
445
446 if (SelectDirectAddr(Op1, Addr)) {
447 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000448 default:
449 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000450 case NVPTXISD::LoadV2:
451 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000452 default:
453 return NULL;
454 case MVT::i8:
455 Opcode = NVPTX::LDV_i8_v2_avar;
456 break;
457 case MVT::i16:
458 Opcode = NVPTX::LDV_i16_v2_avar;
459 break;
460 case MVT::i32:
461 Opcode = NVPTX::LDV_i32_v2_avar;
462 break;
463 case MVT::i64:
464 Opcode = NVPTX::LDV_i64_v2_avar;
465 break;
466 case MVT::f32:
467 Opcode = NVPTX::LDV_f32_v2_avar;
468 break;
469 case MVT::f64:
470 Opcode = NVPTX::LDV_f64_v2_avar;
471 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000472 }
473 break;
474 case NVPTXISD::LoadV4:
475 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000476 default:
477 return NULL;
478 case MVT::i8:
479 Opcode = NVPTX::LDV_i8_v4_avar;
480 break;
481 case MVT::i16:
482 Opcode = NVPTX::LDV_i16_v4_avar;
483 break;
484 case MVT::i32:
485 Opcode = NVPTX::LDV_i32_v4_avar;
486 break;
487 case MVT::f32:
488 Opcode = NVPTX::LDV_f32_v4_avar;
489 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000490 }
491 break;
492 }
493
Justin Holewinski0497ab12013-03-30 14:29:21 +0000494 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
495 getI32Imm(VecType), getI32Imm(FromType),
496 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000497 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000498 } else if (Subtarget.is64Bit()
499 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
500 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000501 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000502 default:
503 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000504 case NVPTXISD::LoadV2:
505 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000506 default:
507 return NULL;
508 case MVT::i8:
509 Opcode = NVPTX::LDV_i8_v2_asi;
510 break;
511 case MVT::i16:
512 Opcode = NVPTX::LDV_i16_v2_asi;
513 break;
514 case MVT::i32:
515 Opcode = NVPTX::LDV_i32_v2_asi;
516 break;
517 case MVT::i64:
518 Opcode = NVPTX::LDV_i64_v2_asi;
519 break;
520 case MVT::f32:
521 Opcode = NVPTX::LDV_f32_v2_asi;
522 break;
523 case MVT::f64:
524 Opcode = NVPTX::LDV_f64_v2_asi;
525 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000526 }
527 break;
528 case NVPTXISD::LoadV4:
529 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000530 default:
531 return NULL;
532 case MVT::i8:
533 Opcode = NVPTX::LDV_i8_v4_asi;
534 break;
535 case MVT::i16:
536 Opcode = NVPTX::LDV_i16_v4_asi;
537 break;
538 case MVT::i32:
539 Opcode = NVPTX::LDV_i32_v4_asi;
540 break;
541 case MVT::f32:
542 Opcode = NVPTX::LDV_f32_v4_asi;
543 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000544 }
545 break;
546 }
547
Justin Holewinski0497ab12013-03-30 14:29:21 +0000548 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
549 getI32Imm(VecType), getI32Imm(FromType),
550 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000551 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000552 } else if (Subtarget.is64Bit()
553 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
554 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000555 if (Subtarget.is64Bit()) {
556 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000557 default:
558 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000559 case NVPTXISD::LoadV2:
560 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000561 default:
562 return NULL;
563 case MVT::i8:
564 Opcode = NVPTX::LDV_i8_v2_ari_64;
565 break;
566 case MVT::i16:
567 Opcode = NVPTX::LDV_i16_v2_ari_64;
568 break;
569 case MVT::i32:
570 Opcode = NVPTX::LDV_i32_v2_ari_64;
571 break;
572 case MVT::i64:
573 Opcode = NVPTX::LDV_i64_v2_ari_64;
574 break;
575 case MVT::f32:
576 Opcode = NVPTX::LDV_f32_v2_ari_64;
577 break;
578 case MVT::f64:
579 Opcode = NVPTX::LDV_f64_v2_ari_64;
580 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000581 }
582 break;
583 case NVPTXISD::LoadV4:
584 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000585 default:
586 return NULL;
587 case MVT::i8:
588 Opcode = NVPTX::LDV_i8_v4_ari_64;
589 break;
590 case MVT::i16:
591 Opcode = NVPTX::LDV_i16_v4_ari_64;
592 break;
593 case MVT::i32:
594 Opcode = NVPTX::LDV_i32_v4_ari_64;
595 break;
596 case MVT::f32:
597 Opcode = NVPTX::LDV_f32_v4_ari_64;
598 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000599 }
600 break;
601 }
602 } else {
603 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000604 default:
605 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000606 case NVPTXISD::LoadV2:
607 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000608 default:
609 return NULL;
610 case MVT::i8:
611 Opcode = NVPTX::LDV_i8_v2_ari;
612 break;
613 case MVT::i16:
614 Opcode = NVPTX::LDV_i16_v2_ari;
615 break;
616 case MVT::i32:
617 Opcode = NVPTX::LDV_i32_v2_ari;
618 break;
619 case MVT::i64:
620 Opcode = NVPTX::LDV_i64_v2_ari;
621 break;
622 case MVT::f32:
623 Opcode = NVPTX::LDV_f32_v2_ari;
624 break;
625 case MVT::f64:
626 Opcode = NVPTX::LDV_f64_v2_ari;
627 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000628 }
629 break;
630 case NVPTXISD::LoadV4:
631 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000632 default:
633 return NULL;
634 case MVT::i8:
635 Opcode = NVPTX::LDV_i8_v4_ari;
636 break;
637 case MVT::i16:
638 Opcode = NVPTX::LDV_i16_v4_ari;
639 break;
640 case MVT::i32:
641 Opcode = NVPTX::LDV_i32_v4_ari;
642 break;
643 case MVT::f32:
644 Opcode = NVPTX::LDV_f32_v4_ari;
645 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000646 }
647 break;
648 }
649 }
650
Justin Holewinski0497ab12013-03-30 14:29:21 +0000651 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
652 getI32Imm(VecType), getI32Imm(FromType),
653 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000654
Michael Liaob53d8962013-04-19 22:22:57 +0000655 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000656 } else {
657 if (Subtarget.is64Bit()) {
658 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000659 default:
660 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000661 case NVPTXISD::LoadV2:
662 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000663 default:
664 return NULL;
665 case MVT::i8:
666 Opcode = NVPTX::LDV_i8_v2_areg_64;
667 break;
668 case MVT::i16:
669 Opcode = NVPTX::LDV_i16_v2_areg_64;
670 break;
671 case MVT::i32:
672 Opcode = NVPTX::LDV_i32_v2_areg_64;
673 break;
674 case MVT::i64:
675 Opcode = NVPTX::LDV_i64_v2_areg_64;
676 break;
677 case MVT::f32:
678 Opcode = NVPTX::LDV_f32_v2_areg_64;
679 break;
680 case MVT::f64:
681 Opcode = NVPTX::LDV_f64_v2_areg_64;
682 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000683 }
684 break;
685 case NVPTXISD::LoadV4:
686 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000687 default:
688 return NULL;
689 case MVT::i8:
690 Opcode = NVPTX::LDV_i8_v4_areg_64;
691 break;
692 case MVT::i16:
693 Opcode = NVPTX::LDV_i16_v4_areg_64;
694 break;
695 case MVT::i32:
696 Opcode = NVPTX::LDV_i32_v4_areg_64;
697 break;
698 case MVT::f32:
699 Opcode = NVPTX::LDV_f32_v4_areg_64;
700 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000701 }
702 break;
703 }
704 } else {
705 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000706 default:
707 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000708 case NVPTXISD::LoadV2:
709 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000710 default:
711 return NULL;
712 case MVT::i8:
713 Opcode = NVPTX::LDV_i8_v2_areg;
714 break;
715 case MVT::i16:
716 Opcode = NVPTX::LDV_i16_v2_areg;
717 break;
718 case MVT::i32:
719 Opcode = NVPTX::LDV_i32_v2_areg;
720 break;
721 case MVT::i64:
722 Opcode = NVPTX::LDV_i64_v2_areg;
723 break;
724 case MVT::f32:
725 Opcode = NVPTX::LDV_f32_v2_areg;
726 break;
727 case MVT::f64:
728 Opcode = NVPTX::LDV_f64_v2_areg;
729 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000730 }
731 break;
732 case NVPTXISD::LoadV4:
733 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000734 default:
735 return NULL;
736 case MVT::i8:
737 Opcode = NVPTX::LDV_i8_v4_areg;
738 break;
739 case MVT::i16:
740 Opcode = NVPTX::LDV_i16_v4_areg;
741 break;
742 case MVT::i32:
743 Opcode = NVPTX::LDV_i32_v4_areg;
744 break;
745 case MVT::f32:
746 Opcode = NVPTX::LDV_f32_v4_areg;
747 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000748 }
749 break;
750 }
751 }
752
Justin Holewinski0497ab12013-03-30 14:29:21 +0000753 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
754 getI32Imm(VecType), getI32Imm(FromType),
755 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000756 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000757 }
758
759 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
760 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
761 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
762
763 return LD;
764}
765
766SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
767
768 SDValue Chain = N->getOperand(0);
769 SDValue Op1 = N->getOperand(1);
770 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000771 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000772 SDNode *LD;
773
774 EVT RetVT = N->getValueType(0);
775
776 // Select opcode
777 if (Subtarget.is64Bit()) {
778 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000779 default:
780 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000781 case NVPTXISD::LDGV2:
782 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000783 default:
784 return NULL;
785 case MVT::i8:
786 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
787 break;
788 case MVT::i16:
789 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
790 break;
791 case MVT::i32:
792 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
793 break;
794 case MVT::i64:
795 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
796 break;
797 case MVT::f32:
798 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
799 break;
800 case MVT::f64:
801 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
802 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000803 }
804 break;
805 case NVPTXISD::LDGV4:
806 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000807 default:
808 return NULL;
809 case MVT::i8:
810 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
811 break;
812 case MVT::i16:
813 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
814 break;
815 case MVT::i32:
816 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
817 break;
818 case MVT::f32:
819 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
820 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000821 }
822 break;
823 case NVPTXISD::LDUV2:
824 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000825 default:
826 return NULL;
827 case MVT::i8:
828 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
829 break;
830 case MVT::i16:
831 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
832 break;
833 case MVT::i32:
834 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
835 break;
836 case MVT::i64:
837 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
838 break;
839 case MVT::f32:
840 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
841 break;
842 case MVT::f64:
843 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
844 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000845 }
846 break;
847 case NVPTXISD::LDUV4:
848 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000849 default:
850 return NULL;
851 case MVT::i8:
852 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
853 break;
854 case MVT::i16:
855 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
856 break;
857 case MVT::i32:
858 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
859 break;
860 case MVT::f32:
861 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
862 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000863 }
864 break;
865 }
866 } else {
867 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000868 default:
869 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000870 case NVPTXISD::LDGV2:
871 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000872 default:
873 return NULL;
874 case MVT::i8:
875 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
876 break;
877 case MVT::i16:
878 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
879 break;
880 case MVT::i32:
881 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
882 break;
883 case MVT::i64:
884 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
885 break;
886 case MVT::f32:
887 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
888 break;
889 case MVT::f64:
890 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
891 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000892 }
893 break;
894 case NVPTXISD::LDGV4:
895 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000896 default:
897 return NULL;
898 case MVT::i8:
899 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
900 break;
901 case MVT::i16:
902 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
903 break;
904 case MVT::i32:
905 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
906 break;
907 case MVT::f32:
908 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
909 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000910 }
911 break;
912 case NVPTXISD::LDUV2:
913 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000914 default:
915 return NULL;
916 case MVT::i8:
917 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
918 break;
919 case MVT::i16:
920 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
921 break;
922 case MVT::i32:
923 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
924 break;
925 case MVT::i64:
926 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
927 break;
928 case MVT::f32:
929 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
930 break;
931 case MVT::f64:
932 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
933 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000934 }
935 break;
936 case NVPTXISD::LDUV4:
937 switch (RetVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000938 default:
939 return NULL;
940 case MVT::i8:
941 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
942 break;
943 case MVT::i16:
944 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
945 break;
946 case MVT::i32:
947 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
948 break;
949 case MVT::f32:
950 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
951 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000952 }
953 break;
954 }
955 }
956
957 SDValue Ops[] = { Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000958 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000959
960 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
961 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
962 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
963
964 return LD;
965}
966
Justin Holewinski0497ab12013-03-30 14:29:21 +0000967SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000968 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000969 StoreSDNode *ST = cast<StoreSDNode>(N);
970 EVT StoreVT = ST->getMemoryVT();
971 SDNode *NVPTXST = NULL;
972
973 // do not support pre/post inc/dec
974 if (ST->isIndexed())
975 return NULL;
976
977 if (!StoreVT.isSimple())
978 return NULL;
979
980 // Address Space Setting
981 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
982
983 // Volatile Setting
984 // - .volatile is only availalble for .global and .shared
985 bool isVolatile = ST->isVolatile();
986 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
987 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
988 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
989 isVolatile = false;
990
991 // Vector Setting
992 MVT SimpleVT = StoreVT.getSimpleVT();
993 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
994 if (SimpleVT.isVector()) {
995 unsigned num = SimpleVT.getVectorNumElements();
996 if (num == 2)
997 vecType = NVPTX::PTXLdStInstCode::V2;
998 else if (num == 4)
999 vecType = NVPTX::PTXLdStInstCode::V4;
1000 else
1001 return NULL;
1002 }
1003
1004 // Type Setting: toType + toTypeWidth
1005 // - for integer type, always use 'u'
1006 //
1007 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001008 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001009 unsigned int toType;
1010 if (ScalarVT.isFloatingPoint())
1011 toType = NVPTX::PTXLdStInstCode::Float;
1012 else
1013 toType = NVPTX::PTXLdStInstCode::Unsigned;
1014
1015 // Create the machine instruction DAG
1016 SDValue Chain = N->getOperand(0);
1017 SDValue N1 = N->getOperand(1);
1018 SDValue N2 = N->getOperand(2);
1019 SDValue Addr;
1020 SDValue Offset, Base;
1021 unsigned Opcode;
1022 MVT::SimpleValueType SourceVT =
1023 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1024
1025 if (SelectDirectAddr(N2, Addr)) {
1026 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001027 case MVT::i8:
1028 Opcode = NVPTX::ST_i8_avar;
1029 break;
1030 case MVT::i16:
1031 Opcode = NVPTX::ST_i16_avar;
1032 break;
1033 case MVT::i32:
1034 Opcode = NVPTX::ST_i32_avar;
1035 break;
1036 case MVT::i64:
1037 Opcode = NVPTX::ST_i64_avar;
1038 break;
1039 case MVT::f32:
1040 Opcode = NVPTX::ST_f32_avar;
1041 break;
1042 case MVT::f64:
1043 Opcode = NVPTX::ST_f64_avar;
1044 break;
1045 default:
1046 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001047 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001048 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1049 getI32Imm(vecType), getI32Imm(toType),
1050 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001051 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001052 } else if (Subtarget.is64Bit()
1053 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1054 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001055 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001056 case MVT::i8:
1057 Opcode = NVPTX::ST_i8_asi;
1058 break;
1059 case MVT::i16:
1060 Opcode = NVPTX::ST_i16_asi;
1061 break;
1062 case MVT::i32:
1063 Opcode = NVPTX::ST_i32_asi;
1064 break;
1065 case MVT::i64:
1066 Opcode = NVPTX::ST_i64_asi;
1067 break;
1068 case MVT::f32:
1069 Opcode = NVPTX::ST_f32_asi;
1070 break;
1071 case MVT::f64:
1072 Opcode = NVPTX::ST_f64_asi;
1073 break;
1074 default:
1075 return NULL;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001076 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001077 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1078 getI32Imm(vecType), getI32Imm(toType),
1079 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001080 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001081 } else if (Subtarget.is64Bit()
1082 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1083 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001084 if (Subtarget.is64Bit()) {
1085 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001086 case MVT::i8:
1087 Opcode = NVPTX::ST_i8_ari_64;
1088 break;
1089 case MVT::i16:
1090 Opcode = NVPTX::ST_i16_ari_64;
1091 break;
1092 case MVT::i32:
1093 Opcode = NVPTX::ST_i32_ari_64;
1094 break;
1095 case MVT::i64:
1096 Opcode = NVPTX::ST_i64_ari_64;
1097 break;
1098 case MVT::f32:
1099 Opcode = NVPTX::ST_f32_ari_64;
1100 break;
1101 case MVT::f64:
1102 Opcode = NVPTX::ST_f64_ari_64;
1103 break;
1104 default:
1105 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001106 }
1107 } else {
1108 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001109 case MVT::i8:
1110 Opcode = NVPTX::ST_i8_ari;
1111 break;
1112 case MVT::i16:
1113 Opcode = NVPTX::ST_i16_ari;
1114 break;
1115 case MVT::i32:
1116 Opcode = NVPTX::ST_i32_ari;
1117 break;
1118 case MVT::i64:
1119 Opcode = NVPTX::ST_i64_ari;
1120 break;
1121 case MVT::f32:
1122 Opcode = NVPTX::ST_f32_ari;
1123 break;
1124 case MVT::f64:
1125 Opcode = NVPTX::ST_f64_ari;
1126 break;
1127 default:
1128 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001129 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001130 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001131 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1132 getI32Imm(vecType), getI32Imm(toType),
1133 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001134 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001135 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001136 if (Subtarget.is64Bit()) {
1137 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001138 case MVT::i8:
1139 Opcode = NVPTX::ST_i8_areg_64;
1140 break;
1141 case MVT::i16:
1142 Opcode = NVPTX::ST_i16_areg_64;
1143 break;
1144 case MVT::i32:
1145 Opcode = NVPTX::ST_i32_areg_64;
1146 break;
1147 case MVT::i64:
1148 Opcode = NVPTX::ST_i64_areg_64;
1149 break;
1150 case MVT::f32:
1151 Opcode = NVPTX::ST_f32_areg_64;
1152 break;
1153 case MVT::f64:
1154 Opcode = NVPTX::ST_f64_areg_64;
1155 break;
1156 default:
1157 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001158 }
1159 } else {
1160 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001161 case MVT::i8:
1162 Opcode = NVPTX::ST_i8_areg;
1163 break;
1164 case MVT::i16:
1165 Opcode = NVPTX::ST_i16_areg;
1166 break;
1167 case MVT::i32:
1168 Opcode = NVPTX::ST_i32_areg;
1169 break;
1170 case MVT::i64:
1171 Opcode = NVPTX::ST_i64_areg;
1172 break;
1173 case MVT::f32:
1174 Opcode = NVPTX::ST_f32_areg;
1175 break;
1176 case MVT::f64:
1177 Opcode = NVPTX::ST_f64_areg;
1178 break;
1179 default:
1180 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001181 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001182 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001183 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1184 getI32Imm(vecType), getI32Imm(toType),
1185 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001186 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001187 }
1188
1189 if (NVPTXST != NULL) {
1190 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1191 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1192 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1193 }
1194
1195 return NVPTXST;
1196}
1197
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001198SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1199 SDValue Chain = N->getOperand(0);
1200 SDValue Op1 = N->getOperand(1);
1201 SDValue Addr, Offset, Base;
1202 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001203 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001204 SDNode *ST;
1205 EVT EltVT = Op1.getValueType();
1206 MemSDNode *MemSD = cast<MemSDNode>(N);
1207 EVT StoreVT = MemSD->getMemoryVT();
1208
1209 // Address Space Setting
1210 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1211
1212 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1213 report_fatal_error("Cannot store to pointer that points to constant "
1214 "memory space");
1215 }
1216
1217 // Volatile Setting
1218 // - .volatile is only availalble for .global and .shared
1219 bool IsVolatile = MemSD->isVolatile();
1220 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1221 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1222 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1223 IsVolatile = false;
1224
1225 // Type Setting: toType + toTypeWidth
1226 // - for integer type, always use 'u'
1227 assert(StoreVT.isSimple() && "Store value is not simple");
1228 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001229 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001230 unsigned ToType;
1231 if (ScalarVT.isFloatingPoint())
1232 ToType = NVPTX::PTXLdStInstCode::Float;
1233 else
1234 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1235
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001236 SmallVector<SDValue, 12> StOps;
1237 SDValue N2;
1238 unsigned VecType;
1239
1240 switch (N->getOpcode()) {
1241 case NVPTXISD::StoreV2:
1242 VecType = NVPTX::PTXLdStInstCode::V2;
1243 StOps.push_back(N->getOperand(1));
1244 StOps.push_back(N->getOperand(2));
1245 N2 = N->getOperand(3);
1246 break;
1247 case NVPTXISD::StoreV4:
1248 VecType = NVPTX::PTXLdStInstCode::V4;
1249 StOps.push_back(N->getOperand(1));
1250 StOps.push_back(N->getOperand(2));
1251 StOps.push_back(N->getOperand(3));
1252 StOps.push_back(N->getOperand(4));
1253 N2 = N->getOperand(5);
1254 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001255 default:
1256 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001257 }
1258
1259 StOps.push_back(getI32Imm(IsVolatile));
1260 StOps.push_back(getI32Imm(CodeAddrSpace));
1261 StOps.push_back(getI32Imm(VecType));
1262 StOps.push_back(getI32Imm(ToType));
1263 StOps.push_back(getI32Imm(ToTypeWidth));
1264
1265 if (SelectDirectAddr(N2, Addr)) {
1266 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001267 default:
1268 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001269 case NVPTXISD::StoreV2:
1270 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001271 default:
1272 return NULL;
1273 case MVT::i8:
1274 Opcode = NVPTX::STV_i8_v2_avar;
1275 break;
1276 case MVT::i16:
1277 Opcode = NVPTX::STV_i16_v2_avar;
1278 break;
1279 case MVT::i32:
1280 Opcode = NVPTX::STV_i32_v2_avar;
1281 break;
1282 case MVT::i64:
1283 Opcode = NVPTX::STV_i64_v2_avar;
1284 break;
1285 case MVT::f32:
1286 Opcode = NVPTX::STV_f32_v2_avar;
1287 break;
1288 case MVT::f64:
1289 Opcode = NVPTX::STV_f64_v2_avar;
1290 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001291 }
1292 break;
1293 case NVPTXISD::StoreV4:
1294 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001295 default:
1296 return NULL;
1297 case MVT::i8:
1298 Opcode = NVPTX::STV_i8_v4_avar;
1299 break;
1300 case MVT::i16:
1301 Opcode = NVPTX::STV_i16_v4_avar;
1302 break;
1303 case MVT::i32:
1304 Opcode = NVPTX::STV_i32_v4_avar;
1305 break;
1306 case MVT::f32:
1307 Opcode = NVPTX::STV_f32_v4_avar;
1308 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001309 }
1310 break;
1311 }
1312 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001313 } else if (Subtarget.is64Bit()
1314 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1315 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001316 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001317 default:
1318 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001319 case NVPTXISD::StoreV2:
1320 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001321 default:
1322 return NULL;
1323 case MVT::i8:
1324 Opcode = NVPTX::STV_i8_v2_asi;
1325 break;
1326 case MVT::i16:
1327 Opcode = NVPTX::STV_i16_v2_asi;
1328 break;
1329 case MVT::i32:
1330 Opcode = NVPTX::STV_i32_v2_asi;
1331 break;
1332 case MVT::i64:
1333 Opcode = NVPTX::STV_i64_v2_asi;
1334 break;
1335 case MVT::f32:
1336 Opcode = NVPTX::STV_f32_v2_asi;
1337 break;
1338 case MVT::f64:
1339 Opcode = NVPTX::STV_f64_v2_asi;
1340 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001341 }
1342 break;
1343 case NVPTXISD::StoreV4:
1344 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001345 default:
1346 return NULL;
1347 case MVT::i8:
1348 Opcode = NVPTX::STV_i8_v4_asi;
1349 break;
1350 case MVT::i16:
1351 Opcode = NVPTX::STV_i16_v4_asi;
1352 break;
1353 case MVT::i32:
1354 Opcode = NVPTX::STV_i32_v4_asi;
1355 break;
1356 case MVT::f32:
1357 Opcode = NVPTX::STV_f32_v4_asi;
1358 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001359 }
1360 break;
1361 }
1362 StOps.push_back(Base);
1363 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001364 } else if (Subtarget.is64Bit()
1365 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1366 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001367 if (Subtarget.is64Bit()) {
1368 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001369 default:
1370 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001371 case NVPTXISD::StoreV2:
1372 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001373 default:
1374 return NULL;
1375 case MVT::i8:
1376 Opcode = NVPTX::STV_i8_v2_ari_64;
1377 break;
1378 case MVT::i16:
1379 Opcode = NVPTX::STV_i16_v2_ari_64;
1380 break;
1381 case MVT::i32:
1382 Opcode = NVPTX::STV_i32_v2_ari_64;
1383 break;
1384 case MVT::i64:
1385 Opcode = NVPTX::STV_i64_v2_ari_64;
1386 break;
1387 case MVT::f32:
1388 Opcode = NVPTX::STV_f32_v2_ari_64;
1389 break;
1390 case MVT::f64:
1391 Opcode = NVPTX::STV_f64_v2_ari_64;
1392 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001393 }
1394 break;
1395 case NVPTXISD::StoreV4:
1396 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001397 default:
1398 return NULL;
1399 case MVT::i8:
1400 Opcode = NVPTX::STV_i8_v4_ari_64;
1401 break;
1402 case MVT::i16:
1403 Opcode = NVPTX::STV_i16_v4_ari_64;
1404 break;
1405 case MVT::i32:
1406 Opcode = NVPTX::STV_i32_v4_ari_64;
1407 break;
1408 case MVT::f32:
1409 Opcode = NVPTX::STV_f32_v4_ari_64;
1410 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001411 }
1412 break;
1413 }
1414 } else {
1415 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001416 default:
1417 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001418 case NVPTXISD::StoreV2:
1419 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001420 default:
1421 return NULL;
1422 case MVT::i8:
1423 Opcode = NVPTX::STV_i8_v2_ari;
1424 break;
1425 case MVT::i16:
1426 Opcode = NVPTX::STV_i16_v2_ari;
1427 break;
1428 case MVT::i32:
1429 Opcode = NVPTX::STV_i32_v2_ari;
1430 break;
1431 case MVT::i64:
1432 Opcode = NVPTX::STV_i64_v2_ari;
1433 break;
1434 case MVT::f32:
1435 Opcode = NVPTX::STV_f32_v2_ari;
1436 break;
1437 case MVT::f64:
1438 Opcode = NVPTX::STV_f64_v2_ari;
1439 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001440 }
1441 break;
1442 case NVPTXISD::StoreV4:
1443 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001444 default:
1445 return NULL;
1446 case MVT::i8:
1447 Opcode = NVPTX::STV_i8_v4_ari;
1448 break;
1449 case MVT::i16:
1450 Opcode = NVPTX::STV_i16_v4_ari;
1451 break;
1452 case MVT::i32:
1453 Opcode = NVPTX::STV_i32_v4_ari;
1454 break;
1455 case MVT::f32:
1456 Opcode = NVPTX::STV_f32_v4_ari;
1457 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001458 }
1459 break;
1460 }
1461 }
1462 StOps.push_back(Base);
1463 StOps.push_back(Offset);
1464 } else {
1465 if (Subtarget.is64Bit()) {
1466 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001467 default:
1468 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001469 case NVPTXISD::StoreV2:
1470 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001471 default:
1472 return NULL;
1473 case MVT::i8:
1474 Opcode = NVPTX::STV_i8_v2_areg_64;
1475 break;
1476 case MVT::i16:
1477 Opcode = NVPTX::STV_i16_v2_areg_64;
1478 break;
1479 case MVT::i32:
1480 Opcode = NVPTX::STV_i32_v2_areg_64;
1481 break;
1482 case MVT::i64:
1483 Opcode = NVPTX::STV_i64_v2_areg_64;
1484 break;
1485 case MVT::f32:
1486 Opcode = NVPTX::STV_f32_v2_areg_64;
1487 break;
1488 case MVT::f64:
1489 Opcode = NVPTX::STV_f64_v2_areg_64;
1490 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001491 }
1492 break;
1493 case NVPTXISD::StoreV4:
1494 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001495 default:
1496 return NULL;
1497 case MVT::i8:
1498 Opcode = NVPTX::STV_i8_v4_areg_64;
1499 break;
1500 case MVT::i16:
1501 Opcode = NVPTX::STV_i16_v4_areg_64;
1502 break;
1503 case MVT::i32:
1504 Opcode = NVPTX::STV_i32_v4_areg_64;
1505 break;
1506 case MVT::f32:
1507 Opcode = NVPTX::STV_f32_v4_areg_64;
1508 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001509 }
1510 break;
1511 }
1512 } else {
1513 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001514 default:
1515 return NULL;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001516 case NVPTXISD::StoreV2:
1517 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001518 default:
1519 return NULL;
1520 case MVT::i8:
1521 Opcode = NVPTX::STV_i8_v2_areg;
1522 break;
1523 case MVT::i16:
1524 Opcode = NVPTX::STV_i16_v2_areg;
1525 break;
1526 case MVT::i32:
1527 Opcode = NVPTX::STV_i32_v2_areg;
1528 break;
1529 case MVT::i64:
1530 Opcode = NVPTX::STV_i64_v2_areg;
1531 break;
1532 case MVT::f32:
1533 Opcode = NVPTX::STV_f32_v2_areg;
1534 break;
1535 case MVT::f64:
1536 Opcode = NVPTX::STV_f64_v2_areg;
1537 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001538 }
1539 break;
1540 case NVPTXISD::StoreV4:
1541 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001542 default:
1543 return NULL;
1544 case MVT::i8:
1545 Opcode = NVPTX::STV_i8_v4_areg;
1546 break;
1547 case MVT::i16:
1548 Opcode = NVPTX::STV_i16_v4_areg;
1549 break;
1550 case MVT::i32:
1551 Opcode = NVPTX::STV_i32_v4_areg;
1552 break;
1553 case MVT::f32:
1554 Opcode = NVPTX::STV_f32_v4_areg;
1555 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001556 }
1557 break;
1558 }
1559 }
1560 StOps.push_back(N2);
1561 }
1562
1563 StOps.push_back(Chain);
1564
Michael Liaob53d8962013-04-19 22:22:57 +00001565 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001566
1567 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1568 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1569 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1570
1571 return ST;
1572}
1573
Justin Holewinskiae556d32012-05-04 20:18:50 +00001574// SelectDirectAddr - Match a direct address for DAG.
1575// A direct address could be a globaladdress or externalsymbol.
1576bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
1577 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00001578 if (N.getOpcode() == ISD::TargetGlobalAddress ||
1579 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001580 Address = N;
1581 return true;
1582 }
1583 if (N.getOpcode() == NVPTXISD::Wrapper) {
1584 Address = N.getOperand(0);
1585 return true;
1586 }
1587 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
1588 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
1589 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
1590 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
1591 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
1592 }
1593 return false;
1594}
1595
1596// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00001597bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
1598 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001599 if (Addr.getOpcode() == ISD::ADD) {
1600 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001601 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001602 if (SelectDirectAddr(base, Base)) {
1603 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1604 return true;
1605 }
1606 }
1607 }
1608 return false;
1609}
1610
1611// symbol+offset
1612bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
1613 SDValue &Base, SDValue &Offset) {
1614 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
1615}
1616
1617// symbol+offset
1618bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
1619 SDValue &Base, SDValue &Offset) {
1620 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
1621}
1622
1623// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00001624bool NVPTXDAGToDAGISel::SelectADDRri_imp(
1625 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001626 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1627 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1628 Offset = CurDAG->getTargetConstant(0, mvt);
1629 return true;
1630 }
1631 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1632 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00001633 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00001634
1635 if (Addr.getOpcode() == ISD::ADD) {
1636 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
1637 return false;
1638 }
1639 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1640 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00001641 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00001642 // Constant offset from frame ref.
1643 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1644 else
1645 Base = Addr.getOperand(0);
1646 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1647 return true;
1648 }
1649 }
1650 return false;
1651}
1652
1653// register+offset
1654bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
1655 SDValue &Base, SDValue &Offset) {
1656 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
1657}
1658
1659// register+offset
1660bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
1661 SDValue &Base, SDValue &Offset) {
1662 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
1663}
1664
1665bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
1666 unsigned int spN) const {
1667 const Value *Src = NULL;
1668 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
1669 // the classof() for MemSDNode does not include MemIntrinsicSDNode
1670 // (See SelectionDAGNodes.h). So we need to check for both.
1671 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1672 Src = mN->getSrcValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001673 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001674 Src = mN->getSrcValue();
1675 }
1676 if (!Src)
1677 return false;
1678 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
1679 return (PT->getAddressSpace() == spN);
1680 return false;
1681}
1682
1683/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1684/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00001685bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
1686 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001687 SDValue Op0, Op1;
1688 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001689 default:
1690 return true;
1691 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00001692 if (SelectDirectAddr(Op, Op0)) {
1693 OutOps.push_back(Op0);
1694 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1695 return false;
1696 }
1697 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
1698 OutOps.push_back(Op0);
1699 OutOps.push_back(Op1);
1700 return false;
1701 }
1702 break;
1703 }
1704 return true;
1705}
1706
1707// Return true if N is a undef or a constant.
1708// If N was undef, return a (i8imm 0) in Retval
1709// If N was imm, convert it to i8imm and return in Retval
1710// Note: The convert to i8imm is required, otherwise the
1711// pattern matcher inserts a bunch of IMOVi8rr to convert
1712// the imm to i8imm, and this causes instruction selection
1713// to fail.
Justin Holewinski0497ab12013-03-30 14:29:21 +00001714bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
1715 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
Justin Holewinskiae556d32012-05-04 20:18:50 +00001716 return false;
1717
1718 if (N.getOpcode() == ISD::UNDEF)
1719 Retval = CurDAG->getTargetConstant(0, MVT::i8);
1720 else {
1721 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
1722 unsigned retval = cn->getZExtValue();
1723 Retval = CurDAG->getTargetConstant(retval, MVT::i8);
1724 }
1725 return true;
1726}