blob: 21e4ba5c02e27d555a297a875e39b73b4b811e79 [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
Justin Holewinskiae556d32012-05-04 20:18:50 +000023using namespace llvm;
24
Chandler Carruth84e68b22014-04-22 02:41:26 +000025#define DEBUG_TYPE "nvptx-isel"
26
Justin Holewinskieafe26d2014-06-27 18:35:37 +000027unsigned FMAContractLevel = 0;
28
29static cl::opt<unsigned, true>
30FMAContractLevelOpt("nvptx-fma-level", cl::ZeroOrMore, cl::Hidden,
31 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
32 " 1: do it 2: do it aggressively"),
33 cl::location(FMAContractLevel),
34 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000035
Justin Holewinski0497ab12013-03-30 14:29:21 +000036static cl::opt<int> UsePrecDivF32(
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000037 "nvptx-prec-divf32", cl::ZeroOrMore, cl::Hidden,
Justin Holewinski0497ab12013-03-30 14:29:21 +000038 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
39 " IEEE Compliant F32 div.rnd if avaiable."),
40 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000041
Justin Holewinski48f4ad32013-05-21 16:51:30 +000042static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000043UsePrecSqrtF32("nvptx-prec-sqrtf32", cl::Hidden,
Justin Holewinski48f4ad32013-05-21 16:51:30 +000044 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
45 cl::init(true));
46
Justin Holewinskicd069e62013-07-22 12:18:04 +000047static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000048FtzEnabled("nvptx-f32ftz", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskicd069e62013-07-22 12:18:04 +000049 cl::desc("NVPTX Specific: Flush f32 subnormals to sign-preserving zero."),
50 cl::init(false));
51
52
Justin Holewinskiae556d32012-05-04 20:18:50 +000053/// createNVPTXISelDag - This pass converts a legalized DAG into a
54/// NVPTX-specific DAG, ready for instruction scheduling.
55FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
56 llvm::CodeGenOpt::Level OptLevel) {
57 return new NVPTXDAGToDAGISel(TM, OptLevel);
58}
59
Justin Holewinskiae556d32012-05-04 20:18:50 +000060NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
61 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000062 : SelectionDAGISel(tm, OptLevel),
63 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000064
Justin Holewinski0497ab12013-03-30 14:29:21 +000065 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
66 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
67 doFMAF32AGG =
68 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
69 doFMAF64AGG =
70 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000071
Justin Holewinskicd069e62013-07-22 12:18:04 +000072 allowFMA = (FMAContractLevel >= 1);
Benjamin Kramera25a61b2012-05-05 11:22:02 +000073
Justin Holewinskiae556d32012-05-04 20:18:50 +000074 doMulWide = (OptLevel > 0);
Justin Holewinskicd069e62013-07-22 12:18:04 +000075}
Justin Holewinskiae556d32012-05-04 20:18:50 +000076
Justin Holewinskicd069e62013-07-22 12:18:04 +000077int NVPTXDAGToDAGISel::getDivF32Level() const {
78 if (UsePrecDivF32.getNumOccurrences() > 0) {
79 // If nvptx-prec-div32=N is used on the command-line, always honor it
80 return UsePrecDivF32;
81 } else {
82 // Otherwise, use div.approx if fast math is enabled
83 if (TM.Options.UnsafeFPMath)
84 return 0;
85 else
86 return 2;
87 }
88}
Justin Holewinskiae556d32012-05-04 20:18:50 +000089
Justin Holewinskicd069e62013-07-22 12:18:04 +000090bool NVPTXDAGToDAGISel::usePrecSqrtF32() const {
91 if (UsePrecSqrtF32.getNumOccurrences() > 0) {
92 // If nvptx-prec-sqrtf32 is used on the command-line, always honor it
93 return UsePrecSqrtF32;
94 } else {
95 // Otherwise, use sqrt.approx if fast math is enabled
96 if (TM.Options.UnsafeFPMath)
97 return false;
98 else
99 return true;
100 }
101}
102
103bool NVPTXDAGToDAGISel::useF32FTZ() const {
104 if (FtzEnabled.getNumOccurrences() > 0) {
105 // If nvptx-f32ftz is used on the command-line, always honor it
106 return FtzEnabled;
107 } else {
108 const Function *F = MF->getFunction();
109 // Otherwise, check for an nvptx-f32ftz attribute on the function
110 if (F->hasFnAttribute("nvptx-f32ftz"))
111 return (F->getAttributes().getAttribute(AttributeSet::FunctionIndex,
112 "nvptx-f32ftz")
113 .getValueAsString() == "true");
114 else
115 return false;
116 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000117}
118
119/// Select - Select instructions not customized! Used for
120/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +0000121SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000122
Tim Northover31d093c2013-09-22 08:21:56 +0000123 if (N->isMachineOpcode()) {
124 N->setNodeId(-1);
Craig Topper062a2ba2014-04-25 05:30:21 +0000125 return nullptr; // Already selected.
Tim Northover31d093c2013-09-22 08:21:56 +0000126 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000127
Craig Topper062a2ba2014-04-25 05:30:21 +0000128 SDNode *ResNode = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000129 switch (N->getOpcode()) {
130 case ISD::LOAD:
131 ResNode = SelectLoad(N);
132 break;
133 case ISD::STORE:
134 ResNode = SelectStore(N);
135 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000136 case NVPTXISD::LoadV2:
137 case NVPTXISD::LoadV4:
138 ResNode = SelectLoadVector(N);
139 break;
140 case NVPTXISD::LDGV2:
141 case NVPTXISD::LDGV4:
142 case NVPTXISD::LDUV2:
143 case NVPTXISD::LDUV4:
144 ResNode = SelectLDGLDUVector(N);
145 break;
146 case NVPTXISD::StoreV2:
147 case NVPTXISD::StoreV4:
148 ResNode = SelectStoreVector(N);
149 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000150 case NVPTXISD::LoadParam:
151 case NVPTXISD::LoadParamV2:
152 case NVPTXISD::LoadParamV4:
153 ResNode = SelectLoadParam(N);
154 break;
155 case NVPTXISD::StoreRetval:
156 case NVPTXISD::StoreRetvalV2:
157 case NVPTXISD::StoreRetvalV4:
158 ResNode = SelectStoreRetval(N);
159 break;
160 case NVPTXISD::StoreParam:
161 case NVPTXISD::StoreParamV2:
162 case NVPTXISD::StoreParamV4:
163 case NVPTXISD::StoreParamS32:
164 case NVPTXISD::StoreParamU32:
165 ResNode = SelectStoreParam(N);
166 break;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000167 case ISD::INTRINSIC_WO_CHAIN:
168 ResNode = SelectIntrinsicNoChain(N);
169 break;
170 case NVPTXISD::Tex1DFloatI32:
171 case NVPTXISD::Tex1DFloatFloat:
172 case NVPTXISD::Tex1DFloatFloatLevel:
173 case NVPTXISD::Tex1DFloatFloatGrad:
174 case NVPTXISD::Tex1DI32I32:
175 case NVPTXISD::Tex1DI32Float:
176 case NVPTXISD::Tex1DI32FloatLevel:
177 case NVPTXISD::Tex1DI32FloatGrad:
178 case NVPTXISD::Tex1DArrayFloatI32:
179 case NVPTXISD::Tex1DArrayFloatFloat:
180 case NVPTXISD::Tex1DArrayFloatFloatLevel:
181 case NVPTXISD::Tex1DArrayFloatFloatGrad:
182 case NVPTXISD::Tex1DArrayI32I32:
183 case NVPTXISD::Tex1DArrayI32Float:
184 case NVPTXISD::Tex1DArrayI32FloatLevel:
185 case NVPTXISD::Tex1DArrayI32FloatGrad:
186 case NVPTXISD::Tex2DFloatI32:
187 case NVPTXISD::Tex2DFloatFloat:
188 case NVPTXISD::Tex2DFloatFloatLevel:
189 case NVPTXISD::Tex2DFloatFloatGrad:
190 case NVPTXISD::Tex2DI32I32:
191 case NVPTXISD::Tex2DI32Float:
192 case NVPTXISD::Tex2DI32FloatLevel:
193 case NVPTXISD::Tex2DI32FloatGrad:
194 case NVPTXISD::Tex2DArrayFloatI32:
195 case NVPTXISD::Tex2DArrayFloatFloat:
196 case NVPTXISD::Tex2DArrayFloatFloatLevel:
197 case NVPTXISD::Tex2DArrayFloatFloatGrad:
198 case NVPTXISD::Tex2DArrayI32I32:
199 case NVPTXISD::Tex2DArrayI32Float:
200 case NVPTXISD::Tex2DArrayI32FloatLevel:
201 case NVPTXISD::Tex2DArrayI32FloatGrad:
202 case NVPTXISD::Tex3DFloatI32:
203 case NVPTXISD::Tex3DFloatFloat:
204 case NVPTXISD::Tex3DFloatFloatLevel:
205 case NVPTXISD::Tex3DFloatFloatGrad:
206 case NVPTXISD::Tex3DI32I32:
207 case NVPTXISD::Tex3DI32Float:
208 case NVPTXISD::Tex3DI32FloatLevel:
209 case NVPTXISD::Tex3DI32FloatGrad:
210 ResNode = SelectTextureIntrinsic(N);
211 break;
212 case NVPTXISD::Suld1DI8Trap:
213 case NVPTXISD::Suld1DI16Trap:
214 case NVPTXISD::Suld1DI32Trap:
215 case NVPTXISD::Suld1DV2I8Trap:
216 case NVPTXISD::Suld1DV2I16Trap:
217 case NVPTXISD::Suld1DV2I32Trap:
218 case NVPTXISD::Suld1DV4I8Trap:
219 case NVPTXISD::Suld1DV4I16Trap:
220 case NVPTXISD::Suld1DV4I32Trap:
221 case NVPTXISD::Suld1DArrayI8Trap:
222 case NVPTXISD::Suld1DArrayI16Trap:
223 case NVPTXISD::Suld1DArrayI32Trap:
224 case NVPTXISD::Suld1DArrayV2I8Trap:
225 case NVPTXISD::Suld1DArrayV2I16Trap:
226 case NVPTXISD::Suld1DArrayV2I32Trap:
227 case NVPTXISD::Suld1DArrayV4I8Trap:
228 case NVPTXISD::Suld1DArrayV4I16Trap:
229 case NVPTXISD::Suld1DArrayV4I32Trap:
230 case NVPTXISD::Suld2DI8Trap:
231 case NVPTXISD::Suld2DI16Trap:
232 case NVPTXISD::Suld2DI32Trap:
233 case NVPTXISD::Suld2DV2I8Trap:
234 case NVPTXISD::Suld2DV2I16Trap:
235 case NVPTXISD::Suld2DV2I32Trap:
236 case NVPTXISD::Suld2DV4I8Trap:
237 case NVPTXISD::Suld2DV4I16Trap:
238 case NVPTXISD::Suld2DV4I32Trap:
239 case NVPTXISD::Suld2DArrayI8Trap:
240 case NVPTXISD::Suld2DArrayI16Trap:
241 case NVPTXISD::Suld2DArrayI32Trap:
242 case NVPTXISD::Suld2DArrayV2I8Trap:
243 case NVPTXISD::Suld2DArrayV2I16Trap:
244 case NVPTXISD::Suld2DArrayV2I32Trap:
245 case NVPTXISD::Suld2DArrayV4I8Trap:
246 case NVPTXISD::Suld2DArrayV4I16Trap:
247 case NVPTXISD::Suld2DArrayV4I32Trap:
248 case NVPTXISD::Suld3DI8Trap:
249 case NVPTXISD::Suld3DI16Trap:
250 case NVPTXISD::Suld3DI32Trap:
251 case NVPTXISD::Suld3DV2I8Trap:
252 case NVPTXISD::Suld3DV2I16Trap:
253 case NVPTXISD::Suld3DV2I32Trap:
254 case NVPTXISD::Suld3DV4I8Trap:
255 case NVPTXISD::Suld3DV4I16Trap:
256 case NVPTXISD::Suld3DV4I32Trap:
257 ResNode = SelectSurfaceIntrinsic(N);
258 break;
Justin Holewinskica7a4f12014-06-27 18:35:27 +0000259 case ISD::AND:
260 case ISD::SRA:
261 case ISD::SRL:
262 // Try to select BFE
263 ResNode = SelectBFE(N);
264 break;
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000265 case ISD::ADDRSPACECAST:
266 ResNode = SelectAddrSpaceCast(N);
267 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000268 default:
269 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000270 }
271 if (ResNode)
272 return ResNode;
273 return SelectCode(N);
274}
275
Justin Holewinski0497ab12013-03-30 14:29:21 +0000276static unsigned int getCodeAddrSpace(MemSDNode *N,
277 const NVPTXSubtarget &Subtarget) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000278 const Value *Src = N->getMemOperand()->getValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000279
Justin Holewinskiae556d32012-05-04 20:18:50 +0000280 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000281 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000282
283 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
284 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000285 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
286 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
287 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
288 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
289 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
290 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
291 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000292 }
293 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000294 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000295}
296
Justin Holewinski30d56a72014-04-09 15:39:15 +0000297SDNode *NVPTXDAGToDAGISel::SelectIntrinsicNoChain(SDNode *N) {
298 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
299 switch (IID) {
300 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000301 return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000302 case Intrinsic::nvvm_texsurf_handle_internal:
303 return SelectTexSurfHandle(N);
304 }
305}
306
307SDNode *NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
308 // Op 0 is the intrinsic ID
309 SDValue Wrapper = N->getOperand(1);
310 SDValue GlobalVal = Wrapper.getOperand(0);
311 return CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N), MVT::i64,
312 GlobalVal);
313}
314
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000315SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
316 SDValue Src = N->getOperand(0);
317 AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
318 unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
319 unsigned DstAddrSpace = CastN->getDestAddressSpace();
320
321 assert(SrcAddrSpace != DstAddrSpace &&
322 "addrspacecast must be between different address spaces");
323
324 if (DstAddrSpace == ADDRESS_SPACE_GENERIC) {
325 // Specific to generic
326 unsigned Opc;
327 switch (SrcAddrSpace) {
328 default: report_fatal_error("Bad address space in addrspacecast");
329 case ADDRESS_SPACE_GLOBAL:
330 Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64
331 : NVPTX::cvta_global_yes;
332 break;
333 case ADDRESS_SPACE_SHARED:
334 Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64
335 : NVPTX::cvta_shared_yes;
336 break;
337 case ADDRESS_SPACE_CONST:
338 Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64
339 : NVPTX::cvta_const_yes;
340 break;
341 case ADDRESS_SPACE_LOCAL:
342 Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64
343 : NVPTX::cvta_local_yes;
344 break;
345 }
346 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
347 } else {
348 // Generic to specific
349 if (SrcAddrSpace != 0)
350 report_fatal_error("Cannot cast between two non-generic address spaces");
351 unsigned Opc;
352 switch (DstAddrSpace) {
353 default: report_fatal_error("Bad address space in addrspacecast");
354 case ADDRESS_SPACE_GLOBAL:
355 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64
356 : NVPTX::cvta_to_global_yes;
357 break;
358 case ADDRESS_SPACE_SHARED:
359 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64
360 : NVPTX::cvta_to_shared_yes;
361 break;
362 case ADDRESS_SPACE_CONST:
363 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64
364 : NVPTX::cvta_to_const_yes;
365 break;
366 case ADDRESS_SPACE_LOCAL:
367 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64
368 : NVPTX::cvta_to_local_yes;
369 break;
370 }
371 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
372 }
373}
374
Justin Holewinski0497ab12013-03-30 14:29:21 +0000375SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000376 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000377 LoadSDNode *LD = cast<LoadSDNode>(N);
378 EVT LoadedVT = LD->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +0000379 SDNode *NVPTXLD = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000380
381 // do not support pre/post inc/dec
382 if (LD->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +0000383 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000384
385 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000386 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000387
388 // Address Space Setting
389 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
390
391 // Volatile Setting
392 // - .volatile is only availalble for .global and .shared
393 bool isVolatile = LD->isVolatile();
394 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
395 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
396 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
397 isVolatile = false;
398
399 // Vector Setting
400 MVT SimpleVT = LoadedVT.getSimpleVT();
401 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
402 if (SimpleVT.isVector()) {
403 unsigned num = SimpleVT.getVectorNumElements();
404 if (num == 2)
405 vecType = NVPTX::PTXLdStInstCode::V2;
406 else if (num == 4)
407 vecType = NVPTX::PTXLdStInstCode::V4;
408 else
Craig Topper062a2ba2014-04-25 05:30:21 +0000409 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000410 }
411
412 // Type Setting: fromType + fromTypeWidth
413 //
414 // Sign : ISD::SEXTLOAD
415 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
416 // type is integer
417 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
418 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000419 // Read at least 8 bits (predicates are stored as 8-bit values)
420 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000421 unsigned int fromType;
422 if ((LD->getExtensionType() == ISD::SEXTLOAD))
423 fromType = NVPTX::PTXLdStInstCode::Signed;
424 else if (ScalarVT.isFloatingPoint())
425 fromType = NVPTX::PTXLdStInstCode::Float;
426 else
427 fromType = NVPTX::PTXLdStInstCode::Unsigned;
428
429 // Create the machine instruction DAG
430 SDValue Chain = N->getOperand(0);
431 SDValue N1 = N->getOperand(1);
432 SDValue Addr;
433 SDValue Offset, Base;
434 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000435 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000436
437 if (SelectDirectAddr(N1, Addr)) {
438 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000439 case MVT::i8:
440 Opcode = NVPTX::LD_i8_avar;
441 break;
442 case MVT::i16:
443 Opcode = NVPTX::LD_i16_avar;
444 break;
445 case MVT::i32:
446 Opcode = NVPTX::LD_i32_avar;
447 break;
448 case MVT::i64:
449 Opcode = NVPTX::LD_i64_avar;
450 break;
451 case MVT::f32:
452 Opcode = NVPTX::LD_f32_avar;
453 break;
454 case MVT::f64:
455 Opcode = NVPTX::LD_f64_avar;
456 break;
457 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000458 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000459 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000460 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
461 getI32Imm(vecType), getI32Imm(fromType),
462 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000463 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000464 } else if (Subtarget.is64Bit()
465 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
466 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000467 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000468 case MVT::i8:
469 Opcode = NVPTX::LD_i8_asi;
470 break;
471 case MVT::i16:
472 Opcode = NVPTX::LD_i16_asi;
473 break;
474 case MVT::i32:
475 Opcode = NVPTX::LD_i32_asi;
476 break;
477 case MVT::i64:
478 Opcode = NVPTX::LD_i64_asi;
479 break;
480 case MVT::f32:
481 Opcode = NVPTX::LD_f32_asi;
482 break;
483 case MVT::f64:
484 Opcode = NVPTX::LD_f64_asi;
485 break;
486 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000487 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000488 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000489 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
490 getI32Imm(vecType), getI32Imm(fromType),
491 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000492 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000493 } else if (Subtarget.is64Bit()
494 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
495 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000496 if (Subtarget.is64Bit()) {
497 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000498 case MVT::i8:
499 Opcode = NVPTX::LD_i8_ari_64;
500 break;
501 case MVT::i16:
502 Opcode = NVPTX::LD_i16_ari_64;
503 break;
504 case MVT::i32:
505 Opcode = NVPTX::LD_i32_ari_64;
506 break;
507 case MVT::i64:
508 Opcode = NVPTX::LD_i64_ari_64;
509 break;
510 case MVT::f32:
511 Opcode = NVPTX::LD_f32_ari_64;
512 break;
513 case MVT::f64:
514 Opcode = NVPTX::LD_f64_ari_64;
515 break;
516 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000517 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000518 }
519 } else {
520 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000521 case MVT::i8:
522 Opcode = NVPTX::LD_i8_ari;
523 break;
524 case MVT::i16:
525 Opcode = NVPTX::LD_i16_ari;
526 break;
527 case MVT::i32:
528 Opcode = NVPTX::LD_i32_ari;
529 break;
530 case MVT::i64:
531 Opcode = NVPTX::LD_i64_ari;
532 break;
533 case MVT::f32:
534 Opcode = NVPTX::LD_f32_ari;
535 break;
536 case MVT::f64:
537 Opcode = NVPTX::LD_f64_ari;
538 break;
539 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000540 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000541 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000542 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000543 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
544 getI32Imm(vecType), getI32Imm(fromType),
545 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000546 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000547 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000548 if (Subtarget.is64Bit()) {
549 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000550 case MVT::i8:
551 Opcode = NVPTX::LD_i8_areg_64;
552 break;
553 case MVT::i16:
554 Opcode = NVPTX::LD_i16_areg_64;
555 break;
556 case MVT::i32:
557 Opcode = NVPTX::LD_i32_areg_64;
558 break;
559 case MVT::i64:
560 Opcode = NVPTX::LD_i64_areg_64;
561 break;
562 case MVT::f32:
563 Opcode = NVPTX::LD_f32_areg_64;
564 break;
565 case MVT::f64:
566 Opcode = NVPTX::LD_f64_areg_64;
567 break;
568 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000569 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000570 }
571 } else {
572 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000573 case MVT::i8:
574 Opcode = NVPTX::LD_i8_areg;
575 break;
576 case MVT::i16:
577 Opcode = NVPTX::LD_i16_areg;
578 break;
579 case MVT::i32:
580 Opcode = NVPTX::LD_i32_areg;
581 break;
582 case MVT::i64:
583 Opcode = NVPTX::LD_i64_areg;
584 break;
585 case MVT::f32:
586 Opcode = NVPTX::LD_f32_areg;
587 break;
588 case MVT::f64:
589 Opcode = NVPTX::LD_f64_areg;
590 break;
591 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000592 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000593 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000594 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000595 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
596 getI32Imm(vecType), getI32Imm(fromType),
597 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000598 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000599 }
600
Craig Topper062a2ba2014-04-25 05:30:21 +0000601 if (NVPTXLD) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000602 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
603 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
604 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
605 }
606
607 return NVPTXLD;
608}
609
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000610SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
611
612 SDValue Chain = N->getOperand(0);
613 SDValue Op1 = N->getOperand(1);
614 SDValue Addr, Offset, Base;
615 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000616 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000617 SDNode *LD;
618 MemSDNode *MemSD = cast<MemSDNode>(N);
619 EVT LoadedVT = MemSD->getMemoryVT();
620
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000621 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000622 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000623
624 // Address Space Setting
625 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
626
627 // Volatile Setting
628 // - .volatile is only availalble for .global and .shared
629 bool IsVolatile = MemSD->isVolatile();
630 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
631 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
632 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
633 IsVolatile = false;
634
635 // Vector Setting
636 MVT SimpleVT = LoadedVT.getSimpleVT();
637
638 // Type Setting: fromType + fromTypeWidth
639 //
640 // Sign : ISD::SEXTLOAD
641 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
642 // type is integer
643 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
644 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000645 // Read at least 8 bits (predicates are stored as 8-bit values)
646 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000647 unsigned int FromType;
648 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000649 unsigned ExtensionType = cast<ConstantSDNode>(
650 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000651 if (ExtensionType == ISD::SEXTLOAD)
652 FromType = NVPTX::PTXLdStInstCode::Signed;
653 else if (ScalarVT.isFloatingPoint())
654 FromType = NVPTX::PTXLdStInstCode::Float;
655 else
656 FromType = NVPTX::PTXLdStInstCode::Unsigned;
657
658 unsigned VecType;
659
660 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000661 case NVPTXISD::LoadV2:
662 VecType = NVPTX::PTXLdStInstCode::V2;
663 break;
664 case NVPTXISD::LoadV4:
665 VecType = NVPTX::PTXLdStInstCode::V4;
666 break;
667 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000668 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000669 }
670
671 EVT EltVT = N->getValueType(0);
672
673 if (SelectDirectAddr(Op1, Addr)) {
674 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000675 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000676 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000677 case NVPTXISD::LoadV2:
678 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000679 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000680 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000681 case MVT::i8:
682 Opcode = NVPTX::LDV_i8_v2_avar;
683 break;
684 case MVT::i16:
685 Opcode = NVPTX::LDV_i16_v2_avar;
686 break;
687 case MVT::i32:
688 Opcode = NVPTX::LDV_i32_v2_avar;
689 break;
690 case MVT::i64:
691 Opcode = NVPTX::LDV_i64_v2_avar;
692 break;
693 case MVT::f32:
694 Opcode = NVPTX::LDV_f32_v2_avar;
695 break;
696 case MVT::f64:
697 Opcode = NVPTX::LDV_f64_v2_avar;
698 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000699 }
700 break;
701 case NVPTXISD::LoadV4:
702 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000703 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000704 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000705 case MVT::i8:
706 Opcode = NVPTX::LDV_i8_v4_avar;
707 break;
708 case MVT::i16:
709 Opcode = NVPTX::LDV_i16_v4_avar;
710 break;
711 case MVT::i32:
712 Opcode = NVPTX::LDV_i32_v4_avar;
713 break;
714 case MVT::f32:
715 Opcode = NVPTX::LDV_f32_v4_avar;
716 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000717 }
718 break;
719 }
720
Justin Holewinski0497ab12013-03-30 14:29:21 +0000721 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
722 getI32Imm(VecType), getI32Imm(FromType),
723 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000724 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000725 } else if (Subtarget.is64Bit()
726 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
727 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000728 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000729 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000730 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000731 case NVPTXISD::LoadV2:
732 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000733 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000734 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000735 case MVT::i8:
736 Opcode = NVPTX::LDV_i8_v2_asi;
737 break;
738 case MVT::i16:
739 Opcode = NVPTX::LDV_i16_v2_asi;
740 break;
741 case MVT::i32:
742 Opcode = NVPTX::LDV_i32_v2_asi;
743 break;
744 case MVT::i64:
745 Opcode = NVPTX::LDV_i64_v2_asi;
746 break;
747 case MVT::f32:
748 Opcode = NVPTX::LDV_f32_v2_asi;
749 break;
750 case MVT::f64:
751 Opcode = NVPTX::LDV_f64_v2_asi;
752 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000753 }
754 break;
755 case NVPTXISD::LoadV4:
756 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000757 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000758 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000759 case MVT::i8:
760 Opcode = NVPTX::LDV_i8_v4_asi;
761 break;
762 case MVT::i16:
763 Opcode = NVPTX::LDV_i16_v4_asi;
764 break;
765 case MVT::i32:
766 Opcode = NVPTX::LDV_i32_v4_asi;
767 break;
768 case MVT::f32:
769 Opcode = NVPTX::LDV_f32_v4_asi;
770 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000771 }
772 break;
773 }
774
Justin Holewinski0497ab12013-03-30 14:29:21 +0000775 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
776 getI32Imm(VecType), getI32Imm(FromType),
777 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000778 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000779 } else if (Subtarget.is64Bit()
780 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
781 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000782 if (Subtarget.is64Bit()) {
783 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000784 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000785 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000786 case NVPTXISD::LoadV2:
787 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000788 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000789 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000790 case MVT::i8:
791 Opcode = NVPTX::LDV_i8_v2_ari_64;
792 break;
793 case MVT::i16:
794 Opcode = NVPTX::LDV_i16_v2_ari_64;
795 break;
796 case MVT::i32:
797 Opcode = NVPTX::LDV_i32_v2_ari_64;
798 break;
799 case MVT::i64:
800 Opcode = NVPTX::LDV_i64_v2_ari_64;
801 break;
802 case MVT::f32:
803 Opcode = NVPTX::LDV_f32_v2_ari_64;
804 break;
805 case MVT::f64:
806 Opcode = NVPTX::LDV_f64_v2_ari_64;
807 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000808 }
809 break;
810 case NVPTXISD::LoadV4:
811 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000812 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000813 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000814 case MVT::i8:
815 Opcode = NVPTX::LDV_i8_v4_ari_64;
816 break;
817 case MVT::i16:
818 Opcode = NVPTX::LDV_i16_v4_ari_64;
819 break;
820 case MVT::i32:
821 Opcode = NVPTX::LDV_i32_v4_ari_64;
822 break;
823 case MVT::f32:
824 Opcode = NVPTX::LDV_f32_v4_ari_64;
825 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000826 }
827 break;
828 }
829 } else {
830 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000831 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000832 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000833 case NVPTXISD::LoadV2:
834 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000835 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000836 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000837 case MVT::i8:
838 Opcode = NVPTX::LDV_i8_v2_ari;
839 break;
840 case MVT::i16:
841 Opcode = NVPTX::LDV_i16_v2_ari;
842 break;
843 case MVT::i32:
844 Opcode = NVPTX::LDV_i32_v2_ari;
845 break;
846 case MVT::i64:
847 Opcode = NVPTX::LDV_i64_v2_ari;
848 break;
849 case MVT::f32:
850 Opcode = NVPTX::LDV_f32_v2_ari;
851 break;
852 case MVT::f64:
853 Opcode = NVPTX::LDV_f64_v2_ari;
854 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000855 }
856 break;
857 case NVPTXISD::LoadV4:
858 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000859 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000860 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000861 case MVT::i8:
862 Opcode = NVPTX::LDV_i8_v4_ari;
863 break;
864 case MVT::i16:
865 Opcode = NVPTX::LDV_i16_v4_ari;
866 break;
867 case MVT::i32:
868 Opcode = NVPTX::LDV_i32_v4_ari;
869 break;
870 case MVT::f32:
871 Opcode = NVPTX::LDV_f32_v4_ari;
872 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000873 }
874 break;
875 }
876 }
877
Justin Holewinski0497ab12013-03-30 14:29:21 +0000878 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
879 getI32Imm(VecType), getI32Imm(FromType),
880 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000881
Michael Liaob53d8962013-04-19 22:22:57 +0000882 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000883 } else {
884 if (Subtarget.is64Bit()) {
885 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000886 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000887 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000888 case NVPTXISD::LoadV2:
889 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000890 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000891 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000892 case MVT::i8:
893 Opcode = NVPTX::LDV_i8_v2_areg_64;
894 break;
895 case MVT::i16:
896 Opcode = NVPTX::LDV_i16_v2_areg_64;
897 break;
898 case MVT::i32:
899 Opcode = NVPTX::LDV_i32_v2_areg_64;
900 break;
901 case MVT::i64:
902 Opcode = NVPTX::LDV_i64_v2_areg_64;
903 break;
904 case MVT::f32:
905 Opcode = NVPTX::LDV_f32_v2_areg_64;
906 break;
907 case MVT::f64:
908 Opcode = NVPTX::LDV_f64_v2_areg_64;
909 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000910 }
911 break;
912 case NVPTXISD::LoadV4:
913 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000914 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000915 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000916 case MVT::i8:
917 Opcode = NVPTX::LDV_i8_v4_areg_64;
918 break;
919 case MVT::i16:
920 Opcode = NVPTX::LDV_i16_v4_areg_64;
921 break;
922 case MVT::i32:
923 Opcode = NVPTX::LDV_i32_v4_areg_64;
924 break;
925 case MVT::f32:
926 Opcode = NVPTX::LDV_f32_v4_areg_64;
927 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000928 }
929 break;
930 }
931 } else {
932 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000933 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000934 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000935 case NVPTXISD::LoadV2:
936 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000937 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000938 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000939 case MVT::i8:
940 Opcode = NVPTX::LDV_i8_v2_areg;
941 break;
942 case MVT::i16:
943 Opcode = NVPTX::LDV_i16_v2_areg;
944 break;
945 case MVT::i32:
946 Opcode = NVPTX::LDV_i32_v2_areg;
947 break;
948 case MVT::i64:
949 Opcode = NVPTX::LDV_i64_v2_areg;
950 break;
951 case MVT::f32:
952 Opcode = NVPTX::LDV_f32_v2_areg;
953 break;
954 case MVT::f64:
955 Opcode = NVPTX::LDV_f64_v2_areg;
956 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000957 }
958 break;
959 case NVPTXISD::LoadV4:
960 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000961 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000962 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000963 case MVT::i8:
964 Opcode = NVPTX::LDV_i8_v4_areg;
965 break;
966 case MVT::i16:
967 Opcode = NVPTX::LDV_i16_v4_areg;
968 break;
969 case MVT::i32:
970 Opcode = NVPTX::LDV_i32_v4_areg;
971 break;
972 case MVT::f32:
973 Opcode = NVPTX::LDV_f32_v4_areg;
974 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000975 }
976 break;
977 }
978 }
979
Justin Holewinski0497ab12013-03-30 14:29:21 +0000980 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
981 getI32Imm(VecType), getI32Imm(FromType),
982 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000983 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000984 }
985
986 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
987 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
988 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
989
990 return LD;
991}
992
993SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
994
995 SDValue Chain = N->getOperand(0);
996 SDValue Op1 = N->getOperand(1);
997 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000998 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000999 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +00001000 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +00001001 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00001002
Justin Holewinskie40e9292013-07-01 12:58:52 +00001003 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001004
Justin Holewinskie40e9292013-07-01 12:58:52 +00001005 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001006 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001007 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001008 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001009 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001010 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001011 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001012 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001013 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001014 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001015 break;
1016 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001017 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001018 break;
1019 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001020 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001021 break;
1022 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001023 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001024 break;
1025 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001026 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001027 break;
1028 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001029 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001030 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001031 }
1032 break;
1033 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001034 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001035 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001036 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001037 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001038 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001039 break;
1040 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001041 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001042 break;
1043 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001044 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001045 break;
1046 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001047 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001048 break;
1049 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001050 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001051 break;
1052 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001053 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
1054 break;
1055 }
1056 break;
1057 case NVPTXISD::LDGV4:
1058 switch (EltVT.getSimpleVT().SimpleTy) {
1059 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001060 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001061 case MVT::i8:
1062 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
1063 break;
1064 case MVT::i16:
1065 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
1066 break;
1067 case MVT::i32:
1068 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
1069 break;
1070 case MVT::f32:
1071 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001072 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001073 }
1074 break;
1075 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001076 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001077 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001078 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001079 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001080 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001081 break;
1082 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001083 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001084 break;
1085 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001086 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001087 break;
1088 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001089 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001090 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001091 }
1092 break;
1093 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001094
1095 SDValue Ops[] = { Addr, Chain };
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001096 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskie40e9292013-07-01 12:58:52 +00001097 } else if (Subtarget.is64Bit()
1098 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
1099 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
1100 if (Subtarget.is64Bit()) {
1101 switch (N->getOpcode()) {
1102 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001103 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001104 case NVPTXISD::LDGV2:
1105 switch (EltVT.getSimpleVT().SimpleTy) {
1106 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001107 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001108 case MVT::i8:
1109 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
1110 break;
1111 case MVT::i16:
1112 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
1113 break;
1114 case MVT::i32:
1115 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
1116 break;
1117 case MVT::i64:
1118 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
1119 break;
1120 case MVT::f32:
1121 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
1122 break;
1123 case MVT::f64:
1124 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
1125 break;
1126 }
1127 break;
1128 case NVPTXISD::LDUV2:
1129 switch (EltVT.getSimpleVT().SimpleTy) {
1130 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001131 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001132 case MVT::i8:
1133 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
1134 break;
1135 case MVT::i16:
1136 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
1137 break;
1138 case MVT::i32:
1139 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
1140 break;
1141 case MVT::i64:
1142 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
1143 break;
1144 case MVT::f32:
1145 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
1146 break;
1147 case MVT::f64:
1148 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
1149 break;
1150 }
1151 break;
1152 case NVPTXISD::LDGV4:
1153 switch (EltVT.getSimpleVT().SimpleTy) {
1154 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001155 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001156 case MVT::i8:
1157 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
1158 break;
1159 case MVT::i16:
1160 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
1161 break;
1162 case MVT::i32:
1163 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
1164 break;
1165 case MVT::f32:
1166 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
1167 break;
1168 }
1169 break;
1170 case NVPTXISD::LDUV4:
1171 switch (EltVT.getSimpleVT().SimpleTy) {
1172 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001173 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001174 case MVT::i8:
1175 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
1176 break;
1177 case MVT::i16:
1178 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
1179 break;
1180 case MVT::i32:
1181 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1182 break;
1183 case MVT::f32:
1184 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1185 break;
1186 }
1187 break;
1188 }
1189 } else {
1190 switch (N->getOpcode()) {
1191 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001192 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001193 case NVPTXISD::LDGV2:
1194 switch (EltVT.getSimpleVT().SimpleTy) {
1195 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001196 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001197 case MVT::i8:
1198 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1199 break;
1200 case MVT::i16:
1201 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1202 break;
1203 case MVT::i32:
1204 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1205 break;
1206 case MVT::i64:
1207 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1208 break;
1209 case MVT::f32:
1210 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1211 break;
1212 case MVT::f64:
1213 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1214 break;
1215 }
1216 break;
1217 case NVPTXISD::LDUV2:
1218 switch (EltVT.getSimpleVT().SimpleTy) {
1219 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001220 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001221 case MVT::i8:
1222 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1223 break;
1224 case MVT::i16:
1225 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1226 break;
1227 case MVT::i32:
1228 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1229 break;
1230 case MVT::i64:
1231 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1232 break;
1233 case MVT::f32:
1234 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1235 break;
1236 case MVT::f64:
1237 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1238 break;
1239 }
1240 break;
1241 case NVPTXISD::LDGV4:
1242 switch (EltVT.getSimpleVT().SimpleTy) {
1243 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001244 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001245 case MVT::i8:
1246 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1247 break;
1248 case MVT::i16:
1249 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1250 break;
1251 case MVT::i32:
1252 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1253 break;
1254 case MVT::f32:
1255 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1256 break;
1257 }
1258 break;
1259 case NVPTXISD::LDUV4:
1260 switch (EltVT.getSimpleVT().SimpleTy) {
1261 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001262 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001263 case MVT::i8:
1264 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1265 break;
1266 case MVT::i16:
1267 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1268 break;
1269 case MVT::i32:
1270 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1271 break;
1272 case MVT::f32:
1273 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1274 break;
1275 }
1276 break;
1277 }
1278 }
1279
1280 SDValue Ops[] = { Base, Offset, Chain };
1281
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001282 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001283 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001284 if (Subtarget.is64Bit()) {
1285 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001286 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001287 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001288 case NVPTXISD::LDGV2:
1289 switch (EltVT.getSimpleVT().SimpleTy) {
1290 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001291 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001292 case MVT::i8:
1293 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1294 break;
1295 case MVT::i16:
1296 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1297 break;
1298 case MVT::i32:
1299 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1300 break;
1301 case MVT::i64:
1302 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1303 break;
1304 case MVT::f32:
1305 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1306 break;
1307 case MVT::f64:
1308 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1309 break;
1310 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001311 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001312 case NVPTXISD::LDUV2:
1313 switch (EltVT.getSimpleVT().SimpleTy) {
1314 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001315 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001316 case MVT::i8:
1317 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1318 break;
1319 case MVT::i16:
1320 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1321 break;
1322 case MVT::i32:
1323 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1324 break;
1325 case MVT::i64:
1326 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1327 break;
1328 case MVT::f32:
1329 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1330 break;
1331 case MVT::f64:
1332 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1333 break;
1334 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001335 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001336 case NVPTXISD::LDGV4:
1337 switch (EltVT.getSimpleVT().SimpleTy) {
1338 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001339 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001340 case MVT::i8:
1341 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1342 break;
1343 case MVT::i16:
1344 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1345 break;
1346 case MVT::i32:
1347 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1348 break;
1349 case MVT::f32:
1350 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1351 break;
1352 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001353 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001354 case NVPTXISD::LDUV4:
1355 switch (EltVT.getSimpleVT().SimpleTy) {
1356 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001357 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001358 case MVT::i8:
1359 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1360 break;
1361 case MVT::i16:
1362 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1363 break;
1364 case MVT::i32:
1365 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1366 break;
1367 case MVT::f32:
1368 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1369 break;
1370 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001371 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001372 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001373 } else {
1374 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001375 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001376 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001377 case NVPTXISD::LDGV2:
1378 switch (EltVT.getSimpleVT().SimpleTy) {
1379 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001380 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001381 case MVT::i8:
1382 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1383 break;
1384 case MVT::i16:
1385 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1386 break;
1387 case MVT::i32:
1388 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1389 break;
1390 case MVT::i64:
1391 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1392 break;
1393 case MVT::f32:
1394 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1395 break;
1396 case MVT::f64:
1397 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1398 break;
1399 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001400 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001401 case NVPTXISD::LDUV2:
1402 switch (EltVT.getSimpleVT().SimpleTy) {
1403 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001404 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001405 case MVT::i8:
1406 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1407 break;
1408 case MVT::i16:
1409 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1410 break;
1411 case MVT::i32:
1412 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1413 break;
1414 case MVT::i64:
1415 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1416 break;
1417 case MVT::f32:
1418 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1419 break;
1420 case MVT::f64:
1421 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1422 break;
1423 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001424 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001425 case NVPTXISD::LDGV4:
1426 switch (EltVT.getSimpleVT().SimpleTy) {
1427 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001428 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001429 case MVT::i8:
1430 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1431 break;
1432 case MVT::i16:
1433 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1434 break;
1435 case MVT::i32:
1436 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1437 break;
1438 case MVT::f32:
1439 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1440 break;
1441 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001442 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001443 case NVPTXISD::LDUV4:
1444 switch (EltVT.getSimpleVT().SimpleTy) {
1445 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001446 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001447 case MVT::i8:
1448 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1449 break;
1450 case MVT::i16:
1451 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1452 break;
1453 case MVT::i32:
1454 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1455 break;
1456 case MVT::f32:
1457 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1458 break;
1459 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001460 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001461 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001462 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001463
Justin Holewinskie40e9292013-07-01 12:58:52 +00001464 SDValue Ops[] = { Op1, Chain };
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001465 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskie40e9292013-07-01 12:58:52 +00001466 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001467
1468 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1469 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1470 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1471
1472 return LD;
1473}
1474
Justin Holewinski0497ab12013-03-30 14:29:21 +00001475SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001476 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001477 StoreSDNode *ST = cast<StoreSDNode>(N);
1478 EVT StoreVT = ST->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +00001479 SDNode *NVPTXST = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001480
1481 // do not support pre/post inc/dec
1482 if (ST->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +00001483 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001484
1485 if (!StoreVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +00001486 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001487
1488 // Address Space Setting
1489 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1490
1491 // Volatile Setting
1492 // - .volatile is only availalble for .global and .shared
1493 bool isVolatile = ST->isVolatile();
1494 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1495 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1496 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1497 isVolatile = false;
1498
1499 // Vector Setting
1500 MVT SimpleVT = StoreVT.getSimpleVT();
1501 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1502 if (SimpleVT.isVector()) {
1503 unsigned num = SimpleVT.getVectorNumElements();
1504 if (num == 2)
1505 vecType = NVPTX::PTXLdStInstCode::V2;
1506 else if (num == 4)
1507 vecType = NVPTX::PTXLdStInstCode::V4;
1508 else
Craig Topper062a2ba2014-04-25 05:30:21 +00001509 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001510 }
1511
1512 // Type Setting: toType + toTypeWidth
1513 // - for integer type, always use 'u'
1514 //
1515 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001516 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001517 unsigned int toType;
1518 if (ScalarVT.isFloatingPoint())
1519 toType = NVPTX::PTXLdStInstCode::Float;
1520 else
1521 toType = NVPTX::PTXLdStInstCode::Unsigned;
1522
1523 // Create the machine instruction DAG
1524 SDValue Chain = N->getOperand(0);
1525 SDValue N1 = N->getOperand(1);
1526 SDValue N2 = N->getOperand(2);
1527 SDValue Addr;
1528 SDValue Offset, Base;
1529 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001530 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001531
1532 if (SelectDirectAddr(N2, Addr)) {
1533 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001534 case MVT::i8:
1535 Opcode = NVPTX::ST_i8_avar;
1536 break;
1537 case MVT::i16:
1538 Opcode = NVPTX::ST_i16_avar;
1539 break;
1540 case MVT::i32:
1541 Opcode = NVPTX::ST_i32_avar;
1542 break;
1543 case MVT::i64:
1544 Opcode = NVPTX::ST_i64_avar;
1545 break;
1546 case MVT::f32:
1547 Opcode = NVPTX::ST_f32_avar;
1548 break;
1549 case MVT::f64:
1550 Opcode = NVPTX::ST_f64_avar;
1551 break;
1552 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001553 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001554 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001555 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1556 getI32Imm(vecType), getI32Imm(toType),
1557 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001558 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001559 } else if (Subtarget.is64Bit()
1560 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1561 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001562 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001563 case MVT::i8:
1564 Opcode = NVPTX::ST_i8_asi;
1565 break;
1566 case MVT::i16:
1567 Opcode = NVPTX::ST_i16_asi;
1568 break;
1569 case MVT::i32:
1570 Opcode = NVPTX::ST_i32_asi;
1571 break;
1572 case MVT::i64:
1573 Opcode = NVPTX::ST_i64_asi;
1574 break;
1575 case MVT::f32:
1576 Opcode = NVPTX::ST_f32_asi;
1577 break;
1578 case MVT::f64:
1579 Opcode = NVPTX::ST_f64_asi;
1580 break;
1581 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001582 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001583 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001584 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1585 getI32Imm(vecType), getI32Imm(toType),
1586 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001587 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001588 } else if (Subtarget.is64Bit()
1589 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1590 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001591 if (Subtarget.is64Bit()) {
1592 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001593 case MVT::i8:
1594 Opcode = NVPTX::ST_i8_ari_64;
1595 break;
1596 case MVT::i16:
1597 Opcode = NVPTX::ST_i16_ari_64;
1598 break;
1599 case MVT::i32:
1600 Opcode = NVPTX::ST_i32_ari_64;
1601 break;
1602 case MVT::i64:
1603 Opcode = NVPTX::ST_i64_ari_64;
1604 break;
1605 case MVT::f32:
1606 Opcode = NVPTX::ST_f32_ari_64;
1607 break;
1608 case MVT::f64:
1609 Opcode = NVPTX::ST_f64_ari_64;
1610 break;
1611 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001612 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001613 }
1614 } else {
1615 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001616 case MVT::i8:
1617 Opcode = NVPTX::ST_i8_ari;
1618 break;
1619 case MVT::i16:
1620 Opcode = NVPTX::ST_i16_ari;
1621 break;
1622 case MVT::i32:
1623 Opcode = NVPTX::ST_i32_ari;
1624 break;
1625 case MVT::i64:
1626 Opcode = NVPTX::ST_i64_ari;
1627 break;
1628 case MVT::f32:
1629 Opcode = NVPTX::ST_f32_ari;
1630 break;
1631 case MVT::f64:
1632 Opcode = NVPTX::ST_f64_ari;
1633 break;
1634 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001635 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001636 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001637 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001638 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1639 getI32Imm(vecType), getI32Imm(toType),
1640 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001641 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001642 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001643 if (Subtarget.is64Bit()) {
1644 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001645 case MVT::i8:
1646 Opcode = NVPTX::ST_i8_areg_64;
1647 break;
1648 case MVT::i16:
1649 Opcode = NVPTX::ST_i16_areg_64;
1650 break;
1651 case MVT::i32:
1652 Opcode = NVPTX::ST_i32_areg_64;
1653 break;
1654 case MVT::i64:
1655 Opcode = NVPTX::ST_i64_areg_64;
1656 break;
1657 case MVT::f32:
1658 Opcode = NVPTX::ST_f32_areg_64;
1659 break;
1660 case MVT::f64:
1661 Opcode = NVPTX::ST_f64_areg_64;
1662 break;
1663 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001664 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001665 }
1666 } else {
1667 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001668 case MVT::i8:
1669 Opcode = NVPTX::ST_i8_areg;
1670 break;
1671 case MVT::i16:
1672 Opcode = NVPTX::ST_i16_areg;
1673 break;
1674 case MVT::i32:
1675 Opcode = NVPTX::ST_i32_areg;
1676 break;
1677 case MVT::i64:
1678 Opcode = NVPTX::ST_i64_areg;
1679 break;
1680 case MVT::f32:
1681 Opcode = NVPTX::ST_f32_areg;
1682 break;
1683 case MVT::f64:
1684 Opcode = NVPTX::ST_f64_areg;
1685 break;
1686 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001687 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001688 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001689 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001690 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1691 getI32Imm(vecType), getI32Imm(toType),
1692 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001693 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001694 }
1695
Craig Topper062a2ba2014-04-25 05:30:21 +00001696 if (NVPTXST) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001697 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1698 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1699 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1700 }
1701
1702 return NVPTXST;
1703}
1704
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001705SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1706 SDValue Chain = N->getOperand(0);
1707 SDValue Op1 = N->getOperand(1);
1708 SDValue Addr, Offset, Base;
1709 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001710 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001711 SDNode *ST;
1712 EVT EltVT = Op1.getValueType();
1713 MemSDNode *MemSD = cast<MemSDNode>(N);
1714 EVT StoreVT = MemSD->getMemoryVT();
1715
1716 // Address Space Setting
1717 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1718
1719 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1720 report_fatal_error("Cannot store to pointer that points to constant "
1721 "memory space");
1722 }
1723
1724 // Volatile Setting
1725 // - .volatile is only availalble for .global and .shared
1726 bool IsVolatile = MemSD->isVolatile();
1727 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1728 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1729 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1730 IsVolatile = false;
1731
1732 // Type Setting: toType + toTypeWidth
1733 // - for integer type, always use 'u'
1734 assert(StoreVT.isSimple() && "Store value is not simple");
1735 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001736 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001737 unsigned ToType;
1738 if (ScalarVT.isFloatingPoint())
1739 ToType = NVPTX::PTXLdStInstCode::Float;
1740 else
1741 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1742
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001743 SmallVector<SDValue, 12> StOps;
1744 SDValue N2;
1745 unsigned VecType;
1746
1747 switch (N->getOpcode()) {
1748 case NVPTXISD::StoreV2:
1749 VecType = NVPTX::PTXLdStInstCode::V2;
1750 StOps.push_back(N->getOperand(1));
1751 StOps.push_back(N->getOperand(2));
1752 N2 = N->getOperand(3);
1753 break;
1754 case NVPTXISD::StoreV4:
1755 VecType = NVPTX::PTXLdStInstCode::V4;
1756 StOps.push_back(N->getOperand(1));
1757 StOps.push_back(N->getOperand(2));
1758 StOps.push_back(N->getOperand(3));
1759 StOps.push_back(N->getOperand(4));
1760 N2 = N->getOperand(5);
1761 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001762 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001763 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001764 }
1765
1766 StOps.push_back(getI32Imm(IsVolatile));
1767 StOps.push_back(getI32Imm(CodeAddrSpace));
1768 StOps.push_back(getI32Imm(VecType));
1769 StOps.push_back(getI32Imm(ToType));
1770 StOps.push_back(getI32Imm(ToTypeWidth));
1771
1772 if (SelectDirectAddr(N2, Addr)) {
1773 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001774 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001775 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001776 case NVPTXISD::StoreV2:
1777 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001778 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001779 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001780 case MVT::i8:
1781 Opcode = NVPTX::STV_i8_v2_avar;
1782 break;
1783 case MVT::i16:
1784 Opcode = NVPTX::STV_i16_v2_avar;
1785 break;
1786 case MVT::i32:
1787 Opcode = NVPTX::STV_i32_v2_avar;
1788 break;
1789 case MVT::i64:
1790 Opcode = NVPTX::STV_i64_v2_avar;
1791 break;
1792 case MVT::f32:
1793 Opcode = NVPTX::STV_f32_v2_avar;
1794 break;
1795 case MVT::f64:
1796 Opcode = NVPTX::STV_f64_v2_avar;
1797 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001798 }
1799 break;
1800 case NVPTXISD::StoreV4:
1801 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001802 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001803 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001804 case MVT::i8:
1805 Opcode = NVPTX::STV_i8_v4_avar;
1806 break;
1807 case MVT::i16:
1808 Opcode = NVPTX::STV_i16_v4_avar;
1809 break;
1810 case MVT::i32:
1811 Opcode = NVPTX::STV_i32_v4_avar;
1812 break;
1813 case MVT::f32:
1814 Opcode = NVPTX::STV_f32_v4_avar;
1815 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001816 }
1817 break;
1818 }
1819 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001820 } else if (Subtarget.is64Bit()
1821 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1822 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001823 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001824 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001825 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001826 case NVPTXISD::StoreV2:
1827 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001828 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001829 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001830 case MVT::i8:
1831 Opcode = NVPTX::STV_i8_v2_asi;
1832 break;
1833 case MVT::i16:
1834 Opcode = NVPTX::STV_i16_v2_asi;
1835 break;
1836 case MVT::i32:
1837 Opcode = NVPTX::STV_i32_v2_asi;
1838 break;
1839 case MVT::i64:
1840 Opcode = NVPTX::STV_i64_v2_asi;
1841 break;
1842 case MVT::f32:
1843 Opcode = NVPTX::STV_f32_v2_asi;
1844 break;
1845 case MVT::f64:
1846 Opcode = NVPTX::STV_f64_v2_asi;
1847 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001848 }
1849 break;
1850 case NVPTXISD::StoreV4:
1851 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001852 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001853 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001854 case MVT::i8:
1855 Opcode = NVPTX::STV_i8_v4_asi;
1856 break;
1857 case MVT::i16:
1858 Opcode = NVPTX::STV_i16_v4_asi;
1859 break;
1860 case MVT::i32:
1861 Opcode = NVPTX::STV_i32_v4_asi;
1862 break;
1863 case MVT::f32:
1864 Opcode = NVPTX::STV_f32_v4_asi;
1865 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001866 }
1867 break;
1868 }
1869 StOps.push_back(Base);
1870 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001871 } else if (Subtarget.is64Bit()
1872 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1873 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001874 if (Subtarget.is64Bit()) {
1875 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001876 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001877 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001878 case NVPTXISD::StoreV2:
1879 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001880 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001881 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001882 case MVT::i8:
1883 Opcode = NVPTX::STV_i8_v2_ari_64;
1884 break;
1885 case MVT::i16:
1886 Opcode = NVPTX::STV_i16_v2_ari_64;
1887 break;
1888 case MVT::i32:
1889 Opcode = NVPTX::STV_i32_v2_ari_64;
1890 break;
1891 case MVT::i64:
1892 Opcode = NVPTX::STV_i64_v2_ari_64;
1893 break;
1894 case MVT::f32:
1895 Opcode = NVPTX::STV_f32_v2_ari_64;
1896 break;
1897 case MVT::f64:
1898 Opcode = NVPTX::STV_f64_v2_ari_64;
1899 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001900 }
1901 break;
1902 case NVPTXISD::StoreV4:
1903 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001904 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001905 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001906 case MVT::i8:
1907 Opcode = NVPTX::STV_i8_v4_ari_64;
1908 break;
1909 case MVT::i16:
1910 Opcode = NVPTX::STV_i16_v4_ari_64;
1911 break;
1912 case MVT::i32:
1913 Opcode = NVPTX::STV_i32_v4_ari_64;
1914 break;
1915 case MVT::f32:
1916 Opcode = NVPTX::STV_f32_v4_ari_64;
1917 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001918 }
1919 break;
1920 }
1921 } else {
1922 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001923 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001924 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001925 case NVPTXISD::StoreV2:
1926 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001927 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001928 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001929 case MVT::i8:
1930 Opcode = NVPTX::STV_i8_v2_ari;
1931 break;
1932 case MVT::i16:
1933 Opcode = NVPTX::STV_i16_v2_ari;
1934 break;
1935 case MVT::i32:
1936 Opcode = NVPTX::STV_i32_v2_ari;
1937 break;
1938 case MVT::i64:
1939 Opcode = NVPTX::STV_i64_v2_ari;
1940 break;
1941 case MVT::f32:
1942 Opcode = NVPTX::STV_f32_v2_ari;
1943 break;
1944 case MVT::f64:
1945 Opcode = NVPTX::STV_f64_v2_ari;
1946 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001947 }
1948 break;
1949 case NVPTXISD::StoreV4:
1950 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001951 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001952 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001953 case MVT::i8:
1954 Opcode = NVPTX::STV_i8_v4_ari;
1955 break;
1956 case MVT::i16:
1957 Opcode = NVPTX::STV_i16_v4_ari;
1958 break;
1959 case MVT::i32:
1960 Opcode = NVPTX::STV_i32_v4_ari;
1961 break;
1962 case MVT::f32:
1963 Opcode = NVPTX::STV_f32_v4_ari;
1964 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001965 }
1966 break;
1967 }
1968 }
1969 StOps.push_back(Base);
1970 StOps.push_back(Offset);
1971 } else {
1972 if (Subtarget.is64Bit()) {
1973 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001974 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001975 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001976 case NVPTXISD::StoreV2:
1977 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001978 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001979 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001980 case MVT::i8:
1981 Opcode = NVPTX::STV_i8_v2_areg_64;
1982 break;
1983 case MVT::i16:
1984 Opcode = NVPTX::STV_i16_v2_areg_64;
1985 break;
1986 case MVT::i32:
1987 Opcode = NVPTX::STV_i32_v2_areg_64;
1988 break;
1989 case MVT::i64:
1990 Opcode = NVPTX::STV_i64_v2_areg_64;
1991 break;
1992 case MVT::f32:
1993 Opcode = NVPTX::STV_f32_v2_areg_64;
1994 break;
1995 case MVT::f64:
1996 Opcode = NVPTX::STV_f64_v2_areg_64;
1997 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001998 }
1999 break;
2000 case NVPTXISD::StoreV4:
2001 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002002 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002003 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002004 case MVT::i8:
2005 Opcode = NVPTX::STV_i8_v4_areg_64;
2006 break;
2007 case MVT::i16:
2008 Opcode = NVPTX::STV_i16_v4_areg_64;
2009 break;
2010 case MVT::i32:
2011 Opcode = NVPTX::STV_i32_v4_areg_64;
2012 break;
2013 case MVT::f32:
2014 Opcode = NVPTX::STV_f32_v4_areg_64;
2015 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002016 }
2017 break;
2018 }
2019 } else {
2020 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002021 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002022 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002023 case NVPTXISD::StoreV2:
2024 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002025 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002026 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002027 case MVT::i8:
2028 Opcode = NVPTX::STV_i8_v2_areg;
2029 break;
2030 case MVT::i16:
2031 Opcode = NVPTX::STV_i16_v2_areg;
2032 break;
2033 case MVT::i32:
2034 Opcode = NVPTX::STV_i32_v2_areg;
2035 break;
2036 case MVT::i64:
2037 Opcode = NVPTX::STV_i64_v2_areg;
2038 break;
2039 case MVT::f32:
2040 Opcode = NVPTX::STV_f32_v2_areg;
2041 break;
2042 case MVT::f64:
2043 Opcode = NVPTX::STV_f64_v2_areg;
2044 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002045 }
2046 break;
2047 case NVPTXISD::StoreV4:
2048 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002049 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002050 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002051 case MVT::i8:
2052 Opcode = NVPTX::STV_i8_v4_areg;
2053 break;
2054 case MVT::i16:
2055 Opcode = NVPTX::STV_i16_v4_areg;
2056 break;
2057 case MVT::i32:
2058 Opcode = NVPTX::STV_i32_v4_areg;
2059 break;
2060 case MVT::f32:
2061 Opcode = NVPTX::STV_f32_v4_areg;
2062 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002063 }
2064 break;
2065 }
2066 }
2067 StOps.push_back(N2);
2068 }
2069
2070 StOps.push_back(Chain);
2071
Michael Liaob53d8962013-04-19 22:22:57 +00002072 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002073
2074 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2075 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2076 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
2077
2078 return ST;
2079}
2080
Justin Holewinskif8f70912013-06-28 17:57:59 +00002081SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
2082 SDValue Chain = Node->getOperand(0);
2083 SDValue Offset = Node->getOperand(2);
2084 SDValue Flag = Node->getOperand(3);
2085 SDLoc DL(Node);
2086 MemSDNode *Mem = cast<MemSDNode>(Node);
2087
2088 unsigned VecSize;
2089 switch (Node->getOpcode()) {
2090 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002091 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002092 case NVPTXISD::LoadParam:
2093 VecSize = 1;
2094 break;
2095 case NVPTXISD::LoadParamV2:
2096 VecSize = 2;
2097 break;
2098 case NVPTXISD::LoadParamV4:
2099 VecSize = 4;
2100 break;
2101 }
2102
2103 EVT EltVT = Node->getValueType(0);
2104 EVT MemVT = Mem->getMemoryVT();
2105
2106 unsigned Opc = 0;
2107
2108 switch (VecSize) {
2109 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002110 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002111 case 1:
2112 switch (MemVT.getSimpleVT().SimpleTy) {
2113 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002114 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002115 case MVT::i1:
2116 Opc = NVPTX::LoadParamMemI8;
2117 break;
2118 case MVT::i8:
2119 Opc = NVPTX::LoadParamMemI8;
2120 break;
2121 case MVT::i16:
2122 Opc = NVPTX::LoadParamMemI16;
2123 break;
2124 case MVT::i32:
2125 Opc = NVPTX::LoadParamMemI32;
2126 break;
2127 case MVT::i64:
2128 Opc = NVPTX::LoadParamMemI64;
2129 break;
2130 case MVT::f32:
2131 Opc = NVPTX::LoadParamMemF32;
2132 break;
2133 case MVT::f64:
2134 Opc = NVPTX::LoadParamMemF64;
2135 break;
2136 }
2137 break;
2138 case 2:
2139 switch (MemVT.getSimpleVT().SimpleTy) {
2140 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002141 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002142 case MVT::i1:
2143 Opc = NVPTX::LoadParamMemV2I8;
2144 break;
2145 case MVT::i8:
2146 Opc = NVPTX::LoadParamMemV2I8;
2147 break;
2148 case MVT::i16:
2149 Opc = NVPTX::LoadParamMemV2I16;
2150 break;
2151 case MVT::i32:
2152 Opc = NVPTX::LoadParamMemV2I32;
2153 break;
2154 case MVT::i64:
2155 Opc = NVPTX::LoadParamMemV2I64;
2156 break;
2157 case MVT::f32:
2158 Opc = NVPTX::LoadParamMemV2F32;
2159 break;
2160 case MVT::f64:
2161 Opc = NVPTX::LoadParamMemV2F64;
2162 break;
2163 }
2164 break;
2165 case 4:
2166 switch (MemVT.getSimpleVT().SimpleTy) {
2167 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002168 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002169 case MVT::i1:
2170 Opc = NVPTX::LoadParamMemV4I8;
2171 break;
2172 case MVT::i8:
2173 Opc = NVPTX::LoadParamMemV4I8;
2174 break;
2175 case MVT::i16:
2176 Opc = NVPTX::LoadParamMemV4I16;
2177 break;
2178 case MVT::i32:
2179 Opc = NVPTX::LoadParamMemV4I32;
2180 break;
2181 case MVT::f32:
2182 Opc = NVPTX::LoadParamMemV4F32;
2183 break;
2184 }
2185 break;
2186 }
2187
2188 SDVTList VTs;
2189 if (VecSize == 1) {
2190 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2191 } else if (VecSize == 2) {
2192 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2193 } else {
2194 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
Craig Topperabb4ac72014-04-16 06:10:51 +00002195 VTs = CurDAG->getVTList(EVTs);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002196 }
2197
2198 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2199
2200 SmallVector<SDValue, 2> Ops;
2201 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2202 Ops.push_back(Chain);
2203 Ops.push_back(Flag);
2204
2205 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002206 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002207 return Ret;
2208}
2209
2210SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2211 SDLoc DL(N);
2212 SDValue Chain = N->getOperand(0);
2213 SDValue Offset = N->getOperand(1);
2214 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2215 MemSDNode *Mem = cast<MemSDNode>(N);
2216
2217 // How many elements do we have?
2218 unsigned NumElts = 1;
2219 switch (N->getOpcode()) {
2220 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002221 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002222 case NVPTXISD::StoreRetval:
2223 NumElts = 1;
2224 break;
2225 case NVPTXISD::StoreRetvalV2:
2226 NumElts = 2;
2227 break;
2228 case NVPTXISD::StoreRetvalV4:
2229 NumElts = 4;
2230 break;
2231 }
2232
2233 // Build vector of operands
2234 SmallVector<SDValue, 6> Ops;
2235 for (unsigned i = 0; i < NumElts; ++i)
2236 Ops.push_back(N->getOperand(i + 2));
2237 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2238 Ops.push_back(Chain);
2239
2240 // Determine target opcode
2241 // If we have an i1, use an 8-bit store. The lowering code in
2242 // NVPTXISelLowering will have already emitted an upcast.
2243 unsigned Opcode = 0;
2244 switch (NumElts) {
2245 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002246 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002247 case 1:
2248 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2249 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002250 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002251 case MVT::i1:
2252 Opcode = NVPTX::StoreRetvalI8;
2253 break;
2254 case MVT::i8:
2255 Opcode = NVPTX::StoreRetvalI8;
2256 break;
2257 case MVT::i16:
2258 Opcode = NVPTX::StoreRetvalI16;
2259 break;
2260 case MVT::i32:
2261 Opcode = NVPTX::StoreRetvalI32;
2262 break;
2263 case MVT::i64:
2264 Opcode = NVPTX::StoreRetvalI64;
2265 break;
2266 case MVT::f32:
2267 Opcode = NVPTX::StoreRetvalF32;
2268 break;
2269 case MVT::f64:
2270 Opcode = NVPTX::StoreRetvalF64;
2271 break;
2272 }
2273 break;
2274 case 2:
2275 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2276 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002277 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002278 case MVT::i1:
2279 Opcode = NVPTX::StoreRetvalV2I8;
2280 break;
2281 case MVT::i8:
2282 Opcode = NVPTX::StoreRetvalV2I8;
2283 break;
2284 case MVT::i16:
2285 Opcode = NVPTX::StoreRetvalV2I16;
2286 break;
2287 case MVT::i32:
2288 Opcode = NVPTX::StoreRetvalV2I32;
2289 break;
2290 case MVT::i64:
2291 Opcode = NVPTX::StoreRetvalV2I64;
2292 break;
2293 case MVT::f32:
2294 Opcode = NVPTX::StoreRetvalV2F32;
2295 break;
2296 case MVT::f64:
2297 Opcode = NVPTX::StoreRetvalV2F64;
2298 break;
2299 }
2300 break;
2301 case 4:
2302 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2303 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002304 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002305 case MVT::i1:
2306 Opcode = NVPTX::StoreRetvalV4I8;
2307 break;
2308 case MVT::i8:
2309 Opcode = NVPTX::StoreRetvalV4I8;
2310 break;
2311 case MVT::i16:
2312 Opcode = NVPTX::StoreRetvalV4I16;
2313 break;
2314 case MVT::i32:
2315 Opcode = NVPTX::StoreRetvalV4I32;
2316 break;
2317 case MVT::f32:
2318 Opcode = NVPTX::StoreRetvalV4F32;
2319 break;
2320 }
2321 break;
2322 }
2323
2324 SDNode *Ret =
2325 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2326 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2327 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2328 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2329
2330 return Ret;
2331}
2332
2333SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2334 SDLoc DL(N);
2335 SDValue Chain = N->getOperand(0);
2336 SDValue Param = N->getOperand(1);
2337 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2338 SDValue Offset = N->getOperand(2);
2339 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2340 MemSDNode *Mem = cast<MemSDNode>(N);
2341 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2342
2343 // How many elements do we have?
2344 unsigned NumElts = 1;
2345 switch (N->getOpcode()) {
2346 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002347 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002348 case NVPTXISD::StoreParamU32:
2349 case NVPTXISD::StoreParamS32:
2350 case NVPTXISD::StoreParam:
2351 NumElts = 1;
2352 break;
2353 case NVPTXISD::StoreParamV2:
2354 NumElts = 2;
2355 break;
2356 case NVPTXISD::StoreParamV4:
2357 NumElts = 4;
2358 break;
2359 }
2360
2361 // Build vector of operands
2362 SmallVector<SDValue, 8> Ops;
2363 for (unsigned i = 0; i < NumElts; ++i)
2364 Ops.push_back(N->getOperand(i + 3));
2365 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2366 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2367 Ops.push_back(Chain);
2368 Ops.push_back(Flag);
2369
2370 // Determine target opcode
2371 // If we have an i1, use an 8-bit store. The lowering code in
2372 // NVPTXISelLowering will have already emitted an upcast.
2373 unsigned Opcode = 0;
2374 switch (N->getOpcode()) {
2375 default:
2376 switch (NumElts) {
2377 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002378 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002379 case 1:
2380 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2381 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002382 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002383 case MVT::i1:
2384 Opcode = NVPTX::StoreParamI8;
2385 break;
2386 case MVT::i8:
2387 Opcode = NVPTX::StoreParamI8;
2388 break;
2389 case MVT::i16:
2390 Opcode = NVPTX::StoreParamI16;
2391 break;
2392 case MVT::i32:
2393 Opcode = NVPTX::StoreParamI32;
2394 break;
2395 case MVT::i64:
2396 Opcode = NVPTX::StoreParamI64;
2397 break;
2398 case MVT::f32:
2399 Opcode = NVPTX::StoreParamF32;
2400 break;
2401 case MVT::f64:
2402 Opcode = NVPTX::StoreParamF64;
2403 break;
2404 }
2405 break;
2406 case 2:
2407 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2408 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002409 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002410 case MVT::i1:
2411 Opcode = NVPTX::StoreParamV2I8;
2412 break;
2413 case MVT::i8:
2414 Opcode = NVPTX::StoreParamV2I8;
2415 break;
2416 case MVT::i16:
2417 Opcode = NVPTX::StoreParamV2I16;
2418 break;
2419 case MVT::i32:
2420 Opcode = NVPTX::StoreParamV2I32;
2421 break;
2422 case MVT::i64:
2423 Opcode = NVPTX::StoreParamV2I64;
2424 break;
2425 case MVT::f32:
2426 Opcode = NVPTX::StoreParamV2F32;
2427 break;
2428 case MVT::f64:
2429 Opcode = NVPTX::StoreParamV2F64;
2430 break;
2431 }
2432 break;
2433 case 4:
2434 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2435 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002436 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002437 case MVT::i1:
2438 Opcode = NVPTX::StoreParamV4I8;
2439 break;
2440 case MVT::i8:
2441 Opcode = NVPTX::StoreParamV4I8;
2442 break;
2443 case MVT::i16:
2444 Opcode = NVPTX::StoreParamV4I16;
2445 break;
2446 case MVT::i32:
2447 Opcode = NVPTX::StoreParamV4I32;
2448 break;
2449 case MVT::f32:
2450 Opcode = NVPTX::StoreParamV4F32;
2451 break;
2452 }
2453 break;
2454 }
2455 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002456 // Special case: if we have a sign-extend/zero-extend node, insert the
2457 // conversion instruction first, and use that as the value operand to
2458 // the selected StoreParam node.
2459 case NVPTXISD::StoreParamU32: {
2460 Opcode = NVPTX::StoreParamI32;
2461 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2462 MVT::i32);
2463 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2464 MVT::i32, Ops[0], CvtNone);
2465 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002466 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002467 }
2468 case NVPTXISD::StoreParamS32: {
2469 Opcode = NVPTX::StoreParamI32;
2470 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2471 MVT::i32);
2472 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2473 MVT::i32, Ops[0], CvtNone);
2474 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002475 break;
2476 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002477 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002478
Justin Holewinskidff28d22013-07-01 12:59:01 +00002479 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002480 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002481 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002482 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2483 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2484 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2485
2486 return Ret;
2487}
2488
Justin Holewinski30d56a72014-04-09 15:39:15 +00002489SDNode *NVPTXDAGToDAGISel::SelectTextureIntrinsic(SDNode *N) {
2490 SDValue Chain = N->getOperand(0);
2491 SDValue TexRef = N->getOperand(1);
2492 SDValue SampRef = N->getOperand(2);
Craig Topper062a2ba2014-04-25 05:30:21 +00002493 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002494 unsigned Opc = 0;
2495 SmallVector<SDValue, 8> Ops;
2496
2497 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002498 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002499 case NVPTXISD::Tex1DFloatI32:
2500 Opc = NVPTX::TEX_1D_F32_I32;
2501 break;
2502 case NVPTXISD::Tex1DFloatFloat:
2503 Opc = NVPTX::TEX_1D_F32_F32;
2504 break;
2505 case NVPTXISD::Tex1DFloatFloatLevel:
2506 Opc = NVPTX::TEX_1D_F32_F32_LEVEL;
2507 break;
2508 case NVPTXISD::Tex1DFloatFloatGrad:
2509 Opc = NVPTX::TEX_1D_F32_F32_GRAD;
2510 break;
2511 case NVPTXISD::Tex1DI32I32:
2512 Opc = NVPTX::TEX_1D_I32_I32;
2513 break;
2514 case NVPTXISD::Tex1DI32Float:
2515 Opc = NVPTX::TEX_1D_I32_F32;
2516 break;
2517 case NVPTXISD::Tex1DI32FloatLevel:
2518 Opc = NVPTX::TEX_1D_I32_F32_LEVEL;
2519 break;
2520 case NVPTXISD::Tex1DI32FloatGrad:
2521 Opc = NVPTX::TEX_1D_I32_F32_GRAD;
2522 break;
2523 case NVPTXISD::Tex1DArrayFloatI32:
2524 Opc = NVPTX::TEX_1D_ARRAY_F32_I32;
2525 break;
2526 case NVPTXISD::Tex1DArrayFloatFloat:
2527 Opc = NVPTX::TEX_1D_ARRAY_F32_F32;
2528 break;
2529 case NVPTXISD::Tex1DArrayFloatFloatLevel:
2530 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_LEVEL;
2531 break;
2532 case NVPTXISD::Tex1DArrayFloatFloatGrad:
2533 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_GRAD;
2534 break;
2535 case NVPTXISD::Tex1DArrayI32I32:
2536 Opc = NVPTX::TEX_1D_ARRAY_I32_I32;
2537 break;
2538 case NVPTXISD::Tex1DArrayI32Float:
2539 Opc = NVPTX::TEX_1D_ARRAY_I32_F32;
2540 break;
2541 case NVPTXISD::Tex1DArrayI32FloatLevel:
2542 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_LEVEL;
2543 break;
2544 case NVPTXISD::Tex1DArrayI32FloatGrad:
2545 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_GRAD;
2546 break;
2547 case NVPTXISD::Tex2DFloatI32:
2548 Opc = NVPTX::TEX_2D_F32_I32;
2549 break;
2550 case NVPTXISD::Tex2DFloatFloat:
2551 Opc = NVPTX::TEX_2D_F32_F32;
2552 break;
2553 case NVPTXISD::Tex2DFloatFloatLevel:
2554 Opc = NVPTX::TEX_2D_F32_F32_LEVEL;
2555 break;
2556 case NVPTXISD::Tex2DFloatFloatGrad:
2557 Opc = NVPTX::TEX_2D_F32_F32_GRAD;
2558 break;
2559 case NVPTXISD::Tex2DI32I32:
2560 Opc = NVPTX::TEX_2D_I32_I32;
2561 break;
2562 case NVPTXISD::Tex2DI32Float:
2563 Opc = NVPTX::TEX_2D_I32_F32;
2564 break;
2565 case NVPTXISD::Tex2DI32FloatLevel:
2566 Opc = NVPTX::TEX_2D_I32_F32_LEVEL;
2567 break;
2568 case NVPTXISD::Tex2DI32FloatGrad:
2569 Opc = NVPTX::TEX_2D_I32_F32_GRAD;
2570 break;
2571 case NVPTXISD::Tex2DArrayFloatI32:
2572 Opc = NVPTX::TEX_2D_ARRAY_F32_I32;
2573 break;
2574 case NVPTXISD::Tex2DArrayFloatFloat:
2575 Opc = NVPTX::TEX_2D_ARRAY_F32_F32;
2576 break;
2577 case NVPTXISD::Tex2DArrayFloatFloatLevel:
2578 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_LEVEL;
2579 break;
2580 case NVPTXISD::Tex2DArrayFloatFloatGrad:
2581 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_GRAD;
2582 break;
2583 case NVPTXISD::Tex2DArrayI32I32:
2584 Opc = NVPTX::TEX_2D_ARRAY_I32_I32;
2585 break;
2586 case NVPTXISD::Tex2DArrayI32Float:
2587 Opc = NVPTX::TEX_2D_ARRAY_I32_F32;
2588 break;
2589 case NVPTXISD::Tex2DArrayI32FloatLevel:
2590 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_LEVEL;
2591 break;
2592 case NVPTXISD::Tex2DArrayI32FloatGrad:
2593 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_GRAD;
2594 break;
2595 case NVPTXISD::Tex3DFloatI32:
2596 Opc = NVPTX::TEX_3D_F32_I32;
2597 break;
2598 case NVPTXISD::Tex3DFloatFloat:
2599 Opc = NVPTX::TEX_3D_F32_F32;
2600 break;
2601 case NVPTXISD::Tex3DFloatFloatLevel:
2602 Opc = NVPTX::TEX_3D_F32_F32_LEVEL;
2603 break;
2604 case NVPTXISD::Tex3DFloatFloatGrad:
2605 Opc = NVPTX::TEX_3D_F32_F32_GRAD;
2606 break;
2607 case NVPTXISD::Tex3DI32I32:
2608 Opc = NVPTX::TEX_3D_I32_I32;
2609 break;
2610 case NVPTXISD::Tex3DI32Float:
2611 Opc = NVPTX::TEX_3D_I32_F32;
2612 break;
2613 case NVPTXISD::Tex3DI32FloatLevel:
2614 Opc = NVPTX::TEX_3D_I32_F32_LEVEL;
2615 break;
2616 case NVPTXISD::Tex3DI32FloatGrad:
2617 Opc = NVPTX::TEX_3D_I32_F32_GRAD;
2618 break;
2619 }
2620
2621 Ops.push_back(TexRef);
2622 Ops.push_back(SampRef);
2623
2624 // Copy over indices
2625 for (unsigned i = 3; i < N->getNumOperands(); ++i) {
2626 Ops.push_back(N->getOperand(i));
2627 }
2628
2629 Ops.push_back(Chain);
2630 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2631 return Ret;
2632}
2633
2634SDNode *NVPTXDAGToDAGISel::SelectSurfaceIntrinsic(SDNode *N) {
2635 SDValue Chain = N->getOperand(0);
2636 SDValue TexHandle = N->getOperand(1);
Craig Topper062a2ba2014-04-25 05:30:21 +00002637 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002638 unsigned Opc = 0;
2639 SmallVector<SDValue, 8> Ops;
2640 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002641 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002642 case NVPTXISD::Suld1DI8Trap:
2643 Opc = NVPTX::SULD_1D_I8_TRAP;
2644 Ops.push_back(TexHandle);
2645 Ops.push_back(N->getOperand(2));
2646 Ops.push_back(Chain);
2647 break;
2648 case NVPTXISD::Suld1DI16Trap:
2649 Opc = NVPTX::SULD_1D_I16_TRAP;
2650 Ops.push_back(TexHandle);
2651 Ops.push_back(N->getOperand(2));
2652 Ops.push_back(Chain);
2653 break;
2654 case NVPTXISD::Suld1DI32Trap:
2655 Opc = NVPTX::SULD_1D_I32_TRAP;
2656 Ops.push_back(TexHandle);
2657 Ops.push_back(N->getOperand(2));
2658 Ops.push_back(Chain);
2659 break;
2660 case NVPTXISD::Suld1DV2I8Trap:
2661 Opc = NVPTX::SULD_1D_V2I8_TRAP;
2662 Ops.push_back(TexHandle);
2663 Ops.push_back(N->getOperand(2));
2664 Ops.push_back(Chain);
2665 break;
2666 case NVPTXISD::Suld1DV2I16Trap:
2667 Opc = NVPTX::SULD_1D_V2I16_TRAP;
2668 Ops.push_back(TexHandle);
2669 Ops.push_back(N->getOperand(2));
2670 Ops.push_back(Chain);
2671 break;
2672 case NVPTXISD::Suld1DV2I32Trap:
2673 Opc = NVPTX::SULD_1D_V2I32_TRAP;
2674 Ops.push_back(TexHandle);
2675 Ops.push_back(N->getOperand(2));
2676 Ops.push_back(Chain);
2677 break;
2678 case NVPTXISD::Suld1DV4I8Trap:
2679 Opc = NVPTX::SULD_1D_V4I8_TRAP;
2680 Ops.push_back(TexHandle);
2681 Ops.push_back(N->getOperand(2));
2682 Ops.push_back(Chain);
2683 break;
2684 case NVPTXISD::Suld1DV4I16Trap:
2685 Opc = NVPTX::SULD_1D_V4I16_TRAP;
2686 Ops.push_back(TexHandle);
2687 Ops.push_back(N->getOperand(2));
2688 Ops.push_back(Chain);
2689 break;
2690 case NVPTXISD::Suld1DV4I32Trap:
2691 Opc = NVPTX::SULD_1D_V4I32_TRAP;
2692 Ops.push_back(TexHandle);
2693 Ops.push_back(N->getOperand(2));
2694 Ops.push_back(Chain);
2695 break;
2696 case NVPTXISD::Suld1DArrayI8Trap:
2697 Opc = NVPTX::SULD_1D_ARRAY_I8_TRAP;
2698 Ops.push_back(TexHandle);
2699 Ops.push_back(N->getOperand(2));
2700 Ops.push_back(N->getOperand(3));
2701 Ops.push_back(Chain);
2702 break;
2703 case NVPTXISD::Suld1DArrayI16Trap:
2704 Opc = NVPTX::SULD_1D_ARRAY_I16_TRAP;
2705 Ops.push_back(TexHandle);
2706 Ops.push_back(N->getOperand(2));
2707 Ops.push_back(N->getOperand(3));
2708 Ops.push_back(Chain);
2709 break;
2710 case NVPTXISD::Suld1DArrayI32Trap:
2711 Opc = NVPTX::SULD_1D_ARRAY_I32_TRAP;
2712 Ops.push_back(TexHandle);
2713 Ops.push_back(N->getOperand(2));
2714 Ops.push_back(N->getOperand(3));
2715 Ops.push_back(Chain);
2716 break;
2717 case NVPTXISD::Suld1DArrayV2I8Trap:
2718 Opc = NVPTX::SULD_1D_ARRAY_V2I8_TRAP;
2719 Ops.push_back(TexHandle);
2720 Ops.push_back(N->getOperand(2));
2721 Ops.push_back(N->getOperand(3));
2722 Ops.push_back(Chain);
2723 break;
2724 case NVPTXISD::Suld1DArrayV2I16Trap:
2725 Opc = NVPTX::SULD_1D_ARRAY_V2I16_TRAP;
2726 Ops.push_back(TexHandle);
2727 Ops.push_back(N->getOperand(2));
2728 Ops.push_back(N->getOperand(3));
2729 Ops.push_back(Chain);
2730 break;
2731 case NVPTXISD::Suld1DArrayV2I32Trap:
2732 Opc = NVPTX::SULD_1D_ARRAY_V2I32_TRAP;
2733 Ops.push_back(TexHandle);
2734 Ops.push_back(N->getOperand(2));
2735 Ops.push_back(N->getOperand(3));
2736 Ops.push_back(Chain);
2737 break;
2738 case NVPTXISD::Suld1DArrayV4I8Trap:
2739 Opc = NVPTX::SULD_1D_ARRAY_V4I8_TRAP;
2740 Ops.push_back(TexHandle);
2741 Ops.push_back(N->getOperand(2));
2742 Ops.push_back(N->getOperand(3));
2743 Ops.push_back(Chain);
2744 break;
2745 case NVPTXISD::Suld1DArrayV4I16Trap:
2746 Opc = NVPTX::SULD_1D_ARRAY_V4I16_TRAP;
2747 Ops.push_back(TexHandle);
2748 Ops.push_back(N->getOperand(2));
2749 Ops.push_back(N->getOperand(3));
2750 Ops.push_back(Chain);
2751 break;
2752 case NVPTXISD::Suld1DArrayV4I32Trap:
2753 Opc = NVPTX::SULD_1D_ARRAY_V4I32_TRAP;
2754 Ops.push_back(TexHandle);
2755 Ops.push_back(N->getOperand(2));
2756 Ops.push_back(N->getOperand(3));
2757 Ops.push_back(Chain);
2758 break;
2759 case NVPTXISD::Suld2DI8Trap:
2760 Opc = NVPTX::SULD_2D_I8_TRAP;
2761 Ops.push_back(TexHandle);
2762 Ops.push_back(N->getOperand(2));
2763 Ops.push_back(N->getOperand(3));
2764 Ops.push_back(Chain);
2765 break;
2766 case NVPTXISD::Suld2DI16Trap:
2767 Opc = NVPTX::SULD_2D_I16_TRAP;
2768 Ops.push_back(TexHandle);
2769 Ops.push_back(N->getOperand(2));
2770 Ops.push_back(N->getOperand(3));
2771 Ops.push_back(Chain);
2772 break;
2773 case NVPTXISD::Suld2DI32Trap:
2774 Opc = NVPTX::SULD_2D_I32_TRAP;
2775 Ops.push_back(TexHandle);
2776 Ops.push_back(N->getOperand(2));
2777 Ops.push_back(N->getOperand(3));
2778 Ops.push_back(Chain);
2779 break;
2780 case NVPTXISD::Suld2DV2I8Trap:
2781 Opc = NVPTX::SULD_2D_V2I8_TRAP;
2782 Ops.push_back(TexHandle);
2783 Ops.push_back(N->getOperand(2));
2784 Ops.push_back(N->getOperand(3));
2785 Ops.push_back(Chain);
2786 break;
2787 case NVPTXISD::Suld2DV2I16Trap:
2788 Opc = NVPTX::SULD_2D_V2I16_TRAP;
2789 Ops.push_back(TexHandle);
2790 Ops.push_back(N->getOperand(2));
2791 Ops.push_back(N->getOperand(3));
2792 Ops.push_back(Chain);
2793 break;
2794 case NVPTXISD::Suld2DV2I32Trap:
2795 Opc = NVPTX::SULD_2D_V2I32_TRAP;
2796 Ops.push_back(TexHandle);
2797 Ops.push_back(N->getOperand(2));
2798 Ops.push_back(N->getOperand(3));
2799 Ops.push_back(Chain);
2800 break;
2801 case NVPTXISD::Suld2DV4I8Trap:
2802 Opc = NVPTX::SULD_2D_V4I8_TRAP;
2803 Ops.push_back(TexHandle);
2804 Ops.push_back(N->getOperand(2));
2805 Ops.push_back(N->getOperand(3));
2806 Ops.push_back(Chain);
2807 break;
2808 case NVPTXISD::Suld2DV4I16Trap:
2809 Opc = NVPTX::SULD_2D_V4I16_TRAP;
2810 Ops.push_back(TexHandle);
2811 Ops.push_back(N->getOperand(2));
2812 Ops.push_back(N->getOperand(3));
2813 Ops.push_back(Chain);
2814 break;
2815 case NVPTXISD::Suld2DV4I32Trap:
2816 Opc = NVPTX::SULD_2D_V4I32_TRAP;
2817 Ops.push_back(TexHandle);
2818 Ops.push_back(N->getOperand(2));
2819 Ops.push_back(N->getOperand(3));
2820 Ops.push_back(Chain);
2821 break;
2822 case NVPTXISD::Suld2DArrayI8Trap:
2823 Opc = NVPTX::SULD_2D_ARRAY_I8_TRAP;
2824 Ops.push_back(TexHandle);
2825 Ops.push_back(N->getOperand(2));
2826 Ops.push_back(N->getOperand(3));
2827 Ops.push_back(N->getOperand(4));
2828 Ops.push_back(Chain);
2829 break;
2830 case NVPTXISD::Suld2DArrayI16Trap:
2831 Opc = NVPTX::SULD_2D_ARRAY_I16_TRAP;
2832 Ops.push_back(TexHandle);
2833 Ops.push_back(N->getOperand(2));
2834 Ops.push_back(N->getOperand(3));
2835 Ops.push_back(N->getOperand(4));
2836 Ops.push_back(Chain);
2837 break;
2838 case NVPTXISD::Suld2DArrayI32Trap:
2839 Opc = NVPTX::SULD_2D_ARRAY_I32_TRAP;
2840 Ops.push_back(TexHandle);
2841 Ops.push_back(N->getOperand(2));
2842 Ops.push_back(N->getOperand(3));
2843 Ops.push_back(N->getOperand(4));
2844 Ops.push_back(Chain);
2845 break;
2846 case NVPTXISD::Suld2DArrayV2I8Trap:
2847 Opc = NVPTX::SULD_2D_ARRAY_V2I8_TRAP;
2848 Ops.push_back(TexHandle);
2849 Ops.push_back(N->getOperand(2));
2850 Ops.push_back(N->getOperand(3));
2851 Ops.push_back(N->getOperand(4));
2852 Ops.push_back(Chain);
2853 break;
2854 case NVPTXISD::Suld2DArrayV2I16Trap:
2855 Opc = NVPTX::SULD_2D_ARRAY_V2I16_TRAP;
2856 Ops.push_back(TexHandle);
2857 Ops.push_back(N->getOperand(2));
2858 Ops.push_back(N->getOperand(3));
2859 Ops.push_back(N->getOperand(4));
2860 Ops.push_back(Chain);
2861 break;
2862 case NVPTXISD::Suld2DArrayV2I32Trap:
2863 Opc = NVPTX::SULD_2D_ARRAY_V2I32_TRAP;
2864 Ops.push_back(TexHandle);
2865 Ops.push_back(N->getOperand(2));
2866 Ops.push_back(N->getOperand(3));
2867 Ops.push_back(N->getOperand(4));
2868 Ops.push_back(Chain);
2869 break;
2870 case NVPTXISD::Suld2DArrayV4I8Trap:
2871 Opc = NVPTX::SULD_2D_ARRAY_V4I8_TRAP;
2872 Ops.push_back(TexHandle);
2873 Ops.push_back(N->getOperand(2));
2874 Ops.push_back(N->getOperand(3));
2875 Ops.push_back(N->getOperand(4));
2876 Ops.push_back(Chain);
2877 break;
2878 case NVPTXISD::Suld2DArrayV4I16Trap:
2879 Opc = NVPTX::SULD_2D_ARRAY_V4I16_TRAP;
2880 Ops.push_back(TexHandle);
2881 Ops.push_back(N->getOperand(2));
2882 Ops.push_back(N->getOperand(3));
2883 Ops.push_back(N->getOperand(4));
2884 Ops.push_back(Chain);
2885 break;
2886 case NVPTXISD::Suld2DArrayV4I32Trap:
2887 Opc = NVPTX::SULD_2D_ARRAY_V4I32_TRAP;
2888 Ops.push_back(TexHandle);
2889 Ops.push_back(N->getOperand(2));
2890 Ops.push_back(N->getOperand(3));
2891 Ops.push_back(N->getOperand(4));
2892 Ops.push_back(Chain);
2893 break;
2894 case NVPTXISD::Suld3DI8Trap:
2895 Opc = NVPTX::SULD_3D_I8_TRAP;
2896 Ops.push_back(TexHandle);
2897 Ops.push_back(N->getOperand(2));
2898 Ops.push_back(N->getOperand(3));
2899 Ops.push_back(N->getOperand(4));
2900 Ops.push_back(Chain);
2901 break;
2902 case NVPTXISD::Suld3DI16Trap:
2903 Opc = NVPTX::SULD_3D_I16_TRAP;
2904 Ops.push_back(TexHandle);
2905 Ops.push_back(N->getOperand(2));
2906 Ops.push_back(N->getOperand(3));
2907 Ops.push_back(N->getOperand(4));
2908 Ops.push_back(Chain);
2909 break;
2910 case NVPTXISD::Suld3DI32Trap:
2911 Opc = NVPTX::SULD_3D_I32_TRAP;
2912 Ops.push_back(TexHandle);
2913 Ops.push_back(N->getOperand(2));
2914 Ops.push_back(N->getOperand(3));
2915 Ops.push_back(N->getOperand(4));
2916 Ops.push_back(Chain);
2917 break;
2918 case NVPTXISD::Suld3DV2I8Trap:
2919 Opc = NVPTX::SULD_3D_V2I8_TRAP;
2920 Ops.push_back(TexHandle);
2921 Ops.push_back(N->getOperand(2));
2922 Ops.push_back(N->getOperand(3));
2923 Ops.push_back(N->getOperand(4));
2924 Ops.push_back(Chain);
2925 break;
2926 case NVPTXISD::Suld3DV2I16Trap:
2927 Opc = NVPTX::SULD_3D_V2I16_TRAP;
2928 Ops.push_back(TexHandle);
2929 Ops.push_back(N->getOperand(2));
2930 Ops.push_back(N->getOperand(3));
2931 Ops.push_back(N->getOperand(4));
2932 Ops.push_back(Chain);
2933 break;
2934 case NVPTXISD::Suld3DV2I32Trap:
2935 Opc = NVPTX::SULD_3D_V2I32_TRAP;
2936 Ops.push_back(TexHandle);
2937 Ops.push_back(N->getOperand(2));
2938 Ops.push_back(N->getOperand(3));
2939 Ops.push_back(N->getOperand(4));
2940 Ops.push_back(Chain);
2941 break;
2942 case NVPTXISD::Suld3DV4I8Trap:
2943 Opc = NVPTX::SULD_3D_V4I8_TRAP;
2944 Ops.push_back(TexHandle);
2945 Ops.push_back(N->getOperand(2));
2946 Ops.push_back(N->getOperand(3));
2947 Ops.push_back(N->getOperand(4));
2948 Ops.push_back(Chain);
2949 break;
2950 case NVPTXISD::Suld3DV4I16Trap:
2951 Opc = NVPTX::SULD_3D_V4I16_TRAP;
2952 Ops.push_back(TexHandle);
2953 Ops.push_back(N->getOperand(2));
2954 Ops.push_back(N->getOperand(3));
2955 Ops.push_back(N->getOperand(4));
2956 Ops.push_back(Chain);
2957 break;
2958 case NVPTXISD::Suld3DV4I32Trap:
2959 Opc = NVPTX::SULD_3D_V4I32_TRAP;
2960 Ops.push_back(TexHandle);
2961 Ops.push_back(N->getOperand(2));
2962 Ops.push_back(N->getOperand(3));
2963 Ops.push_back(N->getOperand(4));
2964 Ops.push_back(Chain);
2965 break;
2966 }
2967 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2968 return Ret;
2969}
2970
Justin Holewinskica7a4f12014-06-27 18:35:27 +00002971/// SelectBFE - Look for instruction sequences that can be made more efficient
2972/// by using the 'bfe' (bit-field extract) PTX instruction
2973SDNode *NVPTXDAGToDAGISel::SelectBFE(SDNode *N) {
2974 SDValue LHS = N->getOperand(0);
2975 SDValue RHS = N->getOperand(1);
2976 SDValue Len;
2977 SDValue Start;
2978 SDValue Val;
2979 bool IsSigned = false;
2980
2981 if (N->getOpcode() == ISD::AND) {
2982 // Canonicalize the operands
2983 // We want 'and %val, %mask'
2984 if (isa<ConstantSDNode>(LHS) && !isa<ConstantSDNode>(RHS)) {
2985 std::swap(LHS, RHS);
2986 }
2987
2988 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(RHS);
2989 if (!Mask) {
2990 // We need a constant mask on the RHS of the AND
2991 return NULL;
2992 }
2993
2994 // Extract the mask bits
2995 uint64_t MaskVal = Mask->getZExtValue();
2996 if (!isMask_64(MaskVal)) {
2997 // We *could* handle shifted masks here, but doing so would require an
2998 // 'and' operation to fix up the low-order bits so we would trade
2999 // shr+and for bfe+and, which has the same throughput
3000 return NULL;
3001 }
3002
3003 // How many bits are in our mask?
3004 uint64_t NumBits = CountTrailingOnes_64(MaskVal);
3005 Len = CurDAG->getTargetConstant(NumBits, MVT::i32);
3006
3007 if (LHS.getOpcode() == ISD::SRL || LHS.getOpcode() == ISD::SRA) {
3008 // We have a 'srl/and' pair, extract the effective start bit and length
3009 Val = LHS.getNode()->getOperand(0);
3010 Start = LHS.getNode()->getOperand(1);
3011 ConstantSDNode *StartConst = dyn_cast<ConstantSDNode>(Start);
3012 if (StartConst) {
3013 uint64_t StartVal = StartConst->getZExtValue();
3014 // How many "good" bits do we have left? "good" is defined here as bits
3015 // that exist in the original value, not shifted in.
3016 uint64_t GoodBits = Start.getValueType().getSizeInBits() - StartVal;
3017 if (NumBits > GoodBits) {
3018 // Do not handle the case where bits have been shifted in. In theory
3019 // we could handle this, but the cost is likely higher than just
3020 // emitting the srl/and pair.
3021 return NULL;
3022 }
3023 Start = CurDAG->getTargetConstant(StartVal, MVT::i32);
3024 } else {
3025 // Do not handle the case where the shift amount (can be zero if no srl
3026 // was found) is not constant. We could handle this case, but it would
3027 // require run-time logic that would be more expensive than just
3028 // emitting the srl/and pair.
3029 return NULL;
3030 }
3031 } else {
3032 // Do not handle the case where the LHS of the and is not a shift. While
3033 // it would be trivial to handle this case, it would just transform
3034 // 'and' -> 'bfe', but 'and' has higher-throughput.
3035 return NULL;
3036 }
3037 } else if (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) {
3038 if (LHS->getOpcode() == ISD::AND) {
3039 ConstantSDNode *ShiftCnst = dyn_cast<ConstantSDNode>(RHS);
3040 if (!ShiftCnst) {
3041 // Shift amount must be constant
3042 return NULL;
3043 }
3044
3045 uint64_t ShiftAmt = ShiftCnst->getZExtValue();
3046
3047 SDValue AndLHS = LHS->getOperand(0);
3048 SDValue AndRHS = LHS->getOperand(1);
3049
3050 // Canonicalize the AND to have the mask on the RHS
3051 if (isa<ConstantSDNode>(AndLHS)) {
3052 std::swap(AndLHS, AndRHS);
3053 }
3054
3055 ConstantSDNode *MaskCnst = dyn_cast<ConstantSDNode>(AndRHS);
3056 if (!MaskCnst) {
3057 // Mask must be constant
3058 return NULL;
3059 }
3060
3061 uint64_t MaskVal = MaskCnst->getZExtValue();
3062 uint64_t NumZeros;
3063 uint64_t NumBits;
3064 if (isMask_64(MaskVal)) {
3065 NumZeros = 0;
3066 // The number of bits in the result bitfield will be the number of
3067 // trailing ones (the AND) minus the number of bits we shift off
3068 NumBits = CountTrailingOnes_64(MaskVal) - ShiftAmt;
3069 } else if (isShiftedMask_64(MaskVal)) {
3070 NumZeros = countTrailingZeros(MaskVal);
3071 unsigned NumOnes = CountTrailingOnes_64(MaskVal >> NumZeros);
3072 // The number of bits in the result bitfield will be the number of
3073 // trailing zeros plus the number of set bits in the mask minus the
3074 // number of bits we shift off
3075 NumBits = NumZeros + NumOnes - ShiftAmt;
3076 } else {
3077 // This is not a mask we can handle
3078 return NULL;
3079 }
3080
3081 if (ShiftAmt < NumZeros) {
3082 // Handling this case would require extra logic that would make this
3083 // transformation non-profitable
3084 return NULL;
3085 }
3086
3087 Val = AndLHS;
3088 Start = CurDAG->getTargetConstant(ShiftAmt, MVT::i32);
3089 Len = CurDAG->getTargetConstant(NumBits, MVT::i32);
3090 } else if (LHS->getOpcode() == ISD::SHL) {
3091 // Here, we have a pattern like:
3092 //
3093 // (sra (shl val, NN), MM)
3094 // or
3095 // (srl (shl val, NN), MM)
3096 //
3097 // If MM >= NN, we can efficiently optimize this with bfe
3098 Val = LHS->getOperand(0);
3099
3100 SDValue ShlRHS = LHS->getOperand(1);
3101 ConstantSDNode *ShlCnst = dyn_cast<ConstantSDNode>(ShlRHS);
3102 if (!ShlCnst) {
3103 // Shift amount must be constant
3104 return NULL;
3105 }
3106 uint64_t InnerShiftAmt = ShlCnst->getZExtValue();
3107
3108 SDValue ShrRHS = RHS;
3109 ConstantSDNode *ShrCnst = dyn_cast<ConstantSDNode>(ShrRHS);
3110 if (!ShrCnst) {
3111 // Shift amount must be constant
3112 return NULL;
3113 }
3114 uint64_t OuterShiftAmt = ShrCnst->getZExtValue();
3115
3116 // To avoid extra codegen and be profitable, we need Outer >= Inner
3117 if (OuterShiftAmt < InnerShiftAmt) {
3118 return NULL;
3119 }
3120
3121 // If the outer shift is more than the type size, we have no bitfield to
3122 // extract (since we also check that the inner shift is <= the outer shift
3123 // then this also implies that the inner shift is < the type size)
3124 if (OuterShiftAmt >= Val.getValueType().getSizeInBits()) {
3125 return NULL;
3126 }
3127
3128 Start =
3129 CurDAG->getTargetConstant(OuterShiftAmt - InnerShiftAmt, MVT::i32);
3130 Len =
3131 CurDAG->getTargetConstant(Val.getValueType().getSizeInBits() -
3132 OuterShiftAmt, MVT::i32);
3133
3134 if (N->getOpcode() == ISD::SRA) {
3135 // If we have a arithmetic right shift, we need to use the signed bfe
3136 // variant
3137 IsSigned = true;
3138 }
3139 } else {
3140 // No can do...
3141 return NULL;
3142 }
3143 } else {
3144 // No can do...
3145 return NULL;
3146 }
3147
3148
3149 unsigned Opc;
3150 // For the BFE operations we form here from "and" and "srl", always use the
3151 // unsigned variants.
3152 if (Val.getValueType() == MVT::i32) {
3153 if (IsSigned) {
3154 Opc = NVPTX::BFE_S32rii;
3155 } else {
3156 Opc = NVPTX::BFE_U32rii;
3157 }
3158 } else if (Val.getValueType() == MVT::i64) {
3159 if (IsSigned) {
3160 Opc = NVPTX::BFE_S64rii;
3161 } else {
3162 Opc = NVPTX::BFE_U64rii;
3163 }
3164 } else {
3165 // We cannot handle this type
3166 return NULL;
3167 }
3168
3169 SDValue Ops[] = {
3170 Val, Start, Len
3171 };
3172
3173 SDNode *Ret =
3174 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
3175
3176 return Ret;
3177}
3178
Justin Holewinskiae556d32012-05-04 20:18:50 +00003179// SelectDirectAddr - Match a direct address for DAG.
3180// A direct address could be a globaladdress or externalsymbol.
3181bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
3182 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003183 if (N.getOpcode() == ISD::TargetGlobalAddress ||
3184 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003185 Address = N;
3186 return true;
3187 }
3188 if (N.getOpcode() == NVPTXISD::Wrapper) {
3189 Address = N.getOperand(0);
3190 return true;
3191 }
3192 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
3193 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
3194 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
3195 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
3196 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
3197 }
3198 return false;
3199}
3200
3201// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003202bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
3203 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003204 if (Addr.getOpcode() == ISD::ADD) {
3205 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003206 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00003207 if (SelectDirectAddr(base, Base)) {
3208 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3209 return true;
3210 }
3211 }
3212 }
3213 return false;
3214}
3215
3216// symbol+offset
3217bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
3218 SDValue &Base, SDValue &Offset) {
3219 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
3220}
3221
3222// symbol+offset
3223bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
3224 SDValue &Base, SDValue &Offset) {
3225 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
3226}
3227
3228// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003229bool NVPTXDAGToDAGISel::SelectADDRri_imp(
3230 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003231 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
3232 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3233 Offset = CurDAG->getTargetConstant(0, mvt);
3234 return true;
3235 }
3236 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
3237 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00003238 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00003239
3240 if (Addr.getOpcode() == ISD::ADD) {
3241 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
3242 return false;
3243 }
3244 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
3245 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00003246 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00003247 // Constant offset from frame ref.
3248 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3249 else
3250 Base = Addr.getOperand(0);
3251 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3252 return true;
3253 }
3254 }
3255 return false;
3256}
3257
3258// register+offset
3259bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
3260 SDValue &Base, SDValue &Offset) {
3261 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
3262}
3263
3264// register+offset
3265bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
3266 SDValue &Base, SDValue &Offset) {
3267 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
3268}
3269
3270bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
3271 unsigned int spN) const {
Craig Topper062a2ba2014-04-25 05:30:21 +00003272 const Value *Src = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00003273 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
3274 // the classof() for MemSDNode does not include MemIntrinsicSDNode
3275 // (See SelectionDAGNodes.h). So we need to check for both.
3276 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003277 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3278 return true;
3279 Src = mN->getMemOperand()->getValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00003280 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003281 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3282 return true;
3283 Src = mN->getMemOperand()->getValue();
Justin Holewinskiae556d32012-05-04 20:18:50 +00003284 }
3285 if (!Src)
3286 return false;
3287 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
3288 return (PT->getAddressSpace() == spN);
3289 return false;
3290}
3291
3292/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3293/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003294bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
3295 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003296 SDValue Op0, Op1;
3297 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003298 default:
3299 return true;
3300 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00003301 if (SelectDirectAddr(Op, Op0)) {
3302 OutOps.push_back(Op0);
3303 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
3304 return false;
3305 }
3306 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
3307 OutOps.push_back(Op0);
3308 OutOps.push_back(Op1);
3309 return false;
3310 }
3311 break;
3312 }
3313 return true;
3314}