blob: 1ea47fc8d594d3b92aa2fe16bec149821f99d39c [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 Holewinskiae556d32012-05-04 20:18:50 +000027static cl::opt<int>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000028FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskiae556d32012-05-04 20:18:50 +000029 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
Justin Holewinski0497ab12013-03-30 14:29:21 +000030 " 1: do it 2: do it aggressively"),
31 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000032
Justin Holewinski0497ab12013-03-30 14:29:21 +000033static cl::opt<int> UsePrecDivF32(
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000034 "nvptx-prec-divf32", cl::ZeroOrMore, cl::Hidden,
Justin Holewinski0497ab12013-03-30 14:29:21 +000035 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
36 " IEEE Compliant F32 div.rnd if avaiable."),
37 cl::init(2));
Justin Holewinskiae556d32012-05-04 20:18:50 +000038
Justin Holewinski48f4ad32013-05-21 16:51:30 +000039static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000040UsePrecSqrtF32("nvptx-prec-sqrtf32", cl::Hidden,
Justin Holewinski48f4ad32013-05-21 16:51:30 +000041 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
42 cl::init(true));
43
Justin Holewinskicd069e62013-07-22 12:18:04 +000044static cl::opt<bool>
Nadav Rotem7f27e0b2013-10-18 23:38:13 +000045FtzEnabled("nvptx-f32ftz", cl::ZeroOrMore, cl::Hidden,
Justin Holewinskicd069e62013-07-22 12:18:04 +000046 cl::desc("NVPTX Specific: Flush f32 subnormals to sign-preserving zero."),
47 cl::init(false));
48
49
Justin Holewinskiae556d32012-05-04 20:18:50 +000050/// createNVPTXISelDag - This pass converts a legalized DAG into a
51/// NVPTX-specific DAG, ready for instruction scheduling.
52FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
53 llvm::CodeGenOpt::Level OptLevel) {
54 return new NVPTXDAGToDAGISel(TM, OptLevel);
55}
56
Justin Holewinskiae556d32012-05-04 20:18:50 +000057NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
58 CodeGenOpt::Level OptLevel)
Justin Holewinski0497ab12013-03-30 14:29:21 +000059 : SelectionDAGISel(tm, OptLevel),
60 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
Justin Holewinskiae556d32012-05-04 20:18:50 +000061
Justin Holewinski0497ab12013-03-30 14:29:21 +000062 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
63 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
64 doFMAF32AGG =
65 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
66 doFMAF64AGG =
67 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
Justin Holewinskiae556d32012-05-04 20:18:50 +000068
Justin Holewinskicd069e62013-07-22 12:18:04 +000069 allowFMA = (FMAContractLevel >= 1);
Benjamin Kramera25a61b2012-05-05 11:22:02 +000070
Justin Holewinskiae556d32012-05-04 20:18:50 +000071 doMulWide = (OptLevel > 0);
Justin Holewinskicd069e62013-07-22 12:18:04 +000072}
Justin Holewinskiae556d32012-05-04 20:18:50 +000073
Justin Holewinskicd069e62013-07-22 12:18:04 +000074int NVPTXDAGToDAGISel::getDivF32Level() const {
75 if (UsePrecDivF32.getNumOccurrences() > 0) {
76 // If nvptx-prec-div32=N is used on the command-line, always honor it
77 return UsePrecDivF32;
78 } else {
79 // Otherwise, use div.approx if fast math is enabled
80 if (TM.Options.UnsafeFPMath)
81 return 0;
82 else
83 return 2;
84 }
85}
Justin Holewinskiae556d32012-05-04 20:18:50 +000086
Justin Holewinskicd069e62013-07-22 12:18:04 +000087bool NVPTXDAGToDAGISel::usePrecSqrtF32() const {
88 if (UsePrecSqrtF32.getNumOccurrences() > 0) {
89 // If nvptx-prec-sqrtf32 is used on the command-line, always honor it
90 return UsePrecSqrtF32;
91 } else {
92 // Otherwise, use sqrt.approx if fast math is enabled
93 if (TM.Options.UnsafeFPMath)
94 return false;
95 else
96 return true;
97 }
98}
99
100bool NVPTXDAGToDAGISel::useF32FTZ() const {
101 if (FtzEnabled.getNumOccurrences() > 0) {
102 // If nvptx-f32ftz is used on the command-line, always honor it
103 return FtzEnabled;
104 } else {
105 const Function *F = MF->getFunction();
106 // Otherwise, check for an nvptx-f32ftz attribute on the function
107 if (F->hasFnAttribute("nvptx-f32ftz"))
108 return (F->getAttributes().getAttribute(AttributeSet::FunctionIndex,
109 "nvptx-f32ftz")
110 .getValueAsString() == "true");
111 else
112 return false;
113 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000114}
115
116/// Select - Select instructions not customized! Used for
117/// expanded, promoted and normal instructions.
Justin Holewinski0497ab12013-03-30 14:29:21 +0000118SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000119
Tim Northover31d093c2013-09-22 08:21:56 +0000120 if (N->isMachineOpcode()) {
121 N->setNodeId(-1);
Craig Topper062a2ba2014-04-25 05:30:21 +0000122 return nullptr; // Already selected.
Tim Northover31d093c2013-09-22 08:21:56 +0000123 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000124
Craig Topper062a2ba2014-04-25 05:30:21 +0000125 SDNode *ResNode = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000126 switch (N->getOpcode()) {
127 case ISD::LOAD:
128 ResNode = SelectLoad(N);
129 break;
130 case ISD::STORE:
131 ResNode = SelectStore(N);
132 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000133 case NVPTXISD::LoadV2:
134 case NVPTXISD::LoadV4:
135 ResNode = SelectLoadVector(N);
136 break;
137 case NVPTXISD::LDGV2:
138 case NVPTXISD::LDGV4:
139 case NVPTXISD::LDUV2:
140 case NVPTXISD::LDUV4:
141 ResNode = SelectLDGLDUVector(N);
142 break;
143 case NVPTXISD::StoreV2:
144 case NVPTXISD::StoreV4:
145 ResNode = SelectStoreVector(N);
146 break;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000147 case NVPTXISD::LoadParam:
148 case NVPTXISD::LoadParamV2:
149 case NVPTXISD::LoadParamV4:
150 ResNode = SelectLoadParam(N);
151 break;
152 case NVPTXISD::StoreRetval:
153 case NVPTXISD::StoreRetvalV2:
154 case NVPTXISD::StoreRetvalV4:
155 ResNode = SelectStoreRetval(N);
156 break;
157 case NVPTXISD::StoreParam:
158 case NVPTXISD::StoreParamV2:
159 case NVPTXISD::StoreParamV4:
160 case NVPTXISD::StoreParamS32:
161 case NVPTXISD::StoreParamU32:
162 ResNode = SelectStoreParam(N);
163 break;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000164 case ISD::INTRINSIC_WO_CHAIN:
165 ResNode = SelectIntrinsicNoChain(N);
166 break;
167 case NVPTXISD::Tex1DFloatI32:
168 case NVPTXISD::Tex1DFloatFloat:
169 case NVPTXISD::Tex1DFloatFloatLevel:
170 case NVPTXISD::Tex1DFloatFloatGrad:
171 case NVPTXISD::Tex1DI32I32:
172 case NVPTXISD::Tex1DI32Float:
173 case NVPTXISD::Tex1DI32FloatLevel:
174 case NVPTXISD::Tex1DI32FloatGrad:
175 case NVPTXISD::Tex1DArrayFloatI32:
176 case NVPTXISD::Tex1DArrayFloatFloat:
177 case NVPTXISD::Tex1DArrayFloatFloatLevel:
178 case NVPTXISD::Tex1DArrayFloatFloatGrad:
179 case NVPTXISD::Tex1DArrayI32I32:
180 case NVPTXISD::Tex1DArrayI32Float:
181 case NVPTXISD::Tex1DArrayI32FloatLevel:
182 case NVPTXISD::Tex1DArrayI32FloatGrad:
183 case NVPTXISD::Tex2DFloatI32:
184 case NVPTXISD::Tex2DFloatFloat:
185 case NVPTXISD::Tex2DFloatFloatLevel:
186 case NVPTXISD::Tex2DFloatFloatGrad:
187 case NVPTXISD::Tex2DI32I32:
188 case NVPTXISD::Tex2DI32Float:
189 case NVPTXISD::Tex2DI32FloatLevel:
190 case NVPTXISD::Tex2DI32FloatGrad:
191 case NVPTXISD::Tex2DArrayFloatI32:
192 case NVPTXISD::Tex2DArrayFloatFloat:
193 case NVPTXISD::Tex2DArrayFloatFloatLevel:
194 case NVPTXISD::Tex2DArrayFloatFloatGrad:
195 case NVPTXISD::Tex2DArrayI32I32:
196 case NVPTXISD::Tex2DArrayI32Float:
197 case NVPTXISD::Tex2DArrayI32FloatLevel:
198 case NVPTXISD::Tex2DArrayI32FloatGrad:
199 case NVPTXISD::Tex3DFloatI32:
200 case NVPTXISD::Tex3DFloatFloat:
201 case NVPTXISD::Tex3DFloatFloatLevel:
202 case NVPTXISD::Tex3DFloatFloatGrad:
203 case NVPTXISD::Tex3DI32I32:
204 case NVPTXISD::Tex3DI32Float:
205 case NVPTXISD::Tex3DI32FloatLevel:
206 case NVPTXISD::Tex3DI32FloatGrad:
207 ResNode = SelectTextureIntrinsic(N);
208 break;
209 case NVPTXISD::Suld1DI8Trap:
210 case NVPTXISD::Suld1DI16Trap:
211 case NVPTXISD::Suld1DI32Trap:
212 case NVPTXISD::Suld1DV2I8Trap:
213 case NVPTXISD::Suld1DV2I16Trap:
214 case NVPTXISD::Suld1DV2I32Trap:
215 case NVPTXISD::Suld1DV4I8Trap:
216 case NVPTXISD::Suld1DV4I16Trap:
217 case NVPTXISD::Suld1DV4I32Trap:
218 case NVPTXISD::Suld1DArrayI8Trap:
219 case NVPTXISD::Suld1DArrayI16Trap:
220 case NVPTXISD::Suld1DArrayI32Trap:
221 case NVPTXISD::Suld1DArrayV2I8Trap:
222 case NVPTXISD::Suld1DArrayV2I16Trap:
223 case NVPTXISD::Suld1DArrayV2I32Trap:
224 case NVPTXISD::Suld1DArrayV4I8Trap:
225 case NVPTXISD::Suld1DArrayV4I16Trap:
226 case NVPTXISD::Suld1DArrayV4I32Trap:
227 case NVPTXISD::Suld2DI8Trap:
228 case NVPTXISD::Suld2DI16Trap:
229 case NVPTXISD::Suld2DI32Trap:
230 case NVPTXISD::Suld2DV2I8Trap:
231 case NVPTXISD::Suld2DV2I16Trap:
232 case NVPTXISD::Suld2DV2I32Trap:
233 case NVPTXISD::Suld2DV4I8Trap:
234 case NVPTXISD::Suld2DV4I16Trap:
235 case NVPTXISD::Suld2DV4I32Trap:
236 case NVPTXISD::Suld2DArrayI8Trap:
237 case NVPTXISD::Suld2DArrayI16Trap:
238 case NVPTXISD::Suld2DArrayI32Trap:
239 case NVPTXISD::Suld2DArrayV2I8Trap:
240 case NVPTXISD::Suld2DArrayV2I16Trap:
241 case NVPTXISD::Suld2DArrayV2I32Trap:
242 case NVPTXISD::Suld2DArrayV4I8Trap:
243 case NVPTXISD::Suld2DArrayV4I16Trap:
244 case NVPTXISD::Suld2DArrayV4I32Trap:
245 case NVPTXISD::Suld3DI8Trap:
246 case NVPTXISD::Suld3DI16Trap:
247 case NVPTXISD::Suld3DI32Trap:
248 case NVPTXISD::Suld3DV2I8Trap:
249 case NVPTXISD::Suld3DV2I16Trap:
250 case NVPTXISD::Suld3DV2I32Trap:
251 case NVPTXISD::Suld3DV4I8Trap:
252 case NVPTXISD::Suld3DV4I16Trap:
253 case NVPTXISD::Suld3DV4I32Trap:
254 ResNode = SelectSurfaceIntrinsic(N);
255 break;
Justin Holewinskica7a4f12014-06-27 18:35:27 +0000256 case ISD::AND:
257 case ISD::SRA:
258 case ISD::SRL:
259 // Try to select BFE
260 ResNode = SelectBFE(N);
261 break;
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000262 case ISD::ADDRSPACECAST:
263 ResNode = SelectAddrSpaceCast(N);
264 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000265 default:
266 break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000267 }
268 if (ResNode)
269 return ResNode;
270 return SelectCode(N);
271}
272
Justin Holewinski0497ab12013-03-30 14:29:21 +0000273static unsigned int getCodeAddrSpace(MemSDNode *N,
274 const NVPTXSubtarget &Subtarget) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000275 const Value *Src = N->getMemOperand()->getValue();
Justin Holewinskib96d1392013-06-10 13:29:47 +0000276
Justin Holewinskiae556d32012-05-04 20:18:50 +0000277 if (!Src)
Justin Holewinskib96d1392013-06-10 13:29:47 +0000278 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000279
280 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
281 switch (PT->getAddressSpace()) {
Justin Holewinskib96d1392013-06-10 13:29:47 +0000282 case llvm::ADDRESS_SPACE_LOCAL: return NVPTX::PTXLdStInstCode::LOCAL;
283 case llvm::ADDRESS_SPACE_GLOBAL: return NVPTX::PTXLdStInstCode::GLOBAL;
284 case llvm::ADDRESS_SPACE_SHARED: return NVPTX::PTXLdStInstCode::SHARED;
285 case llvm::ADDRESS_SPACE_GENERIC: return NVPTX::PTXLdStInstCode::GENERIC;
286 case llvm::ADDRESS_SPACE_PARAM: return NVPTX::PTXLdStInstCode::PARAM;
287 case llvm::ADDRESS_SPACE_CONST: return NVPTX::PTXLdStInstCode::CONSTANT;
288 default: break;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000289 }
290 }
Justin Holewinskib96d1392013-06-10 13:29:47 +0000291 return NVPTX::PTXLdStInstCode::GENERIC;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000292}
293
Justin Holewinski30d56a72014-04-09 15:39:15 +0000294SDNode *NVPTXDAGToDAGISel::SelectIntrinsicNoChain(SDNode *N) {
295 unsigned IID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
296 switch (IID) {
297 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000298 return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +0000299 case Intrinsic::nvvm_texsurf_handle_internal:
300 return SelectTexSurfHandle(N);
301 }
302}
303
304SDNode *NVPTXDAGToDAGISel::SelectTexSurfHandle(SDNode *N) {
305 // Op 0 is the intrinsic ID
306 SDValue Wrapper = N->getOperand(1);
307 SDValue GlobalVal = Wrapper.getOperand(0);
308 return CurDAG->getMachineNode(NVPTX::texsurf_handles, SDLoc(N), MVT::i64,
309 GlobalVal);
310}
311
Justin Holewinskiba2fa6d2014-03-24 11:17:53 +0000312SDNode *NVPTXDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) {
313 SDValue Src = N->getOperand(0);
314 AddrSpaceCastSDNode *CastN = cast<AddrSpaceCastSDNode>(N);
315 unsigned SrcAddrSpace = CastN->getSrcAddressSpace();
316 unsigned DstAddrSpace = CastN->getDestAddressSpace();
317
318 assert(SrcAddrSpace != DstAddrSpace &&
319 "addrspacecast must be between different address spaces");
320
321 if (DstAddrSpace == ADDRESS_SPACE_GENERIC) {
322 // Specific to generic
323 unsigned Opc;
324 switch (SrcAddrSpace) {
325 default: report_fatal_error("Bad address space in addrspacecast");
326 case ADDRESS_SPACE_GLOBAL:
327 Opc = Subtarget.is64Bit() ? NVPTX::cvta_global_yes_64
328 : NVPTX::cvta_global_yes;
329 break;
330 case ADDRESS_SPACE_SHARED:
331 Opc = Subtarget.is64Bit() ? NVPTX::cvta_shared_yes_64
332 : NVPTX::cvta_shared_yes;
333 break;
334 case ADDRESS_SPACE_CONST:
335 Opc = Subtarget.is64Bit() ? NVPTX::cvta_const_yes_64
336 : NVPTX::cvta_const_yes;
337 break;
338 case ADDRESS_SPACE_LOCAL:
339 Opc = Subtarget.is64Bit() ? NVPTX::cvta_local_yes_64
340 : NVPTX::cvta_local_yes;
341 break;
342 }
343 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
344 } else {
345 // Generic to specific
346 if (SrcAddrSpace != 0)
347 report_fatal_error("Cannot cast between two non-generic address spaces");
348 unsigned Opc;
349 switch (DstAddrSpace) {
350 default: report_fatal_error("Bad address space in addrspacecast");
351 case ADDRESS_SPACE_GLOBAL:
352 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_global_yes_64
353 : NVPTX::cvta_to_global_yes;
354 break;
355 case ADDRESS_SPACE_SHARED:
356 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_shared_yes_64
357 : NVPTX::cvta_to_shared_yes;
358 break;
359 case ADDRESS_SPACE_CONST:
360 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_const_yes_64
361 : NVPTX::cvta_to_const_yes;
362 break;
363 case ADDRESS_SPACE_LOCAL:
364 Opc = Subtarget.is64Bit() ? NVPTX::cvta_to_local_yes_64
365 : NVPTX::cvta_to_local_yes;
366 break;
367 }
368 return CurDAG->getMachineNode(Opc, SDLoc(N), N->getValueType(0), Src);
369 }
370}
371
Justin Holewinski0497ab12013-03-30 14:29:21 +0000372SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +0000373 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000374 LoadSDNode *LD = cast<LoadSDNode>(N);
375 EVT LoadedVT = LD->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +0000376 SDNode *NVPTXLD = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000377
378 // do not support pre/post inc/dec
379 if (LD->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +0000380 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000381
382 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000383 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000384
385 // Address Space Setting
386 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
387
388 // Volatile Setting
389 // - .volatile is only availalble for .global and .shared
390 bool isVolatile = LD->isVolatile();
391 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
392 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
393 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
394 isVolatile = false;
395
396 // Vector Setting
397 MVT SimpleVT = LoadedVT.getSimpleVT();
398 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
399 if (SimpleVT.isVector()) {
400 unsigned num = SimpleVT.getVectorNumElements();
401 if (num == 2)
402 vecType = NVPTX::PTXLdStInstCode::V2;
403 else if (num == 4)
404 vecType = NVPTX::PTXLdStInstCode::V4;
405 else
Craig Topper062a2ba2014-04-25 05:30:21 +0000406 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000407 }
408
409 // Type Setting: fromType + fromTypeWidth
410 //
411 // Sign : ISD::SEXTLOAD
412 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
413 // type is integer
414 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
415 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000416 // Read at least 8 bits (predicates are stored as 8-bit values)
417 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskiae556d32012-05-04 20:18:50 +0000418 unsigned int fromType;
419 if ((LD->getExtensionType() == ISD::SEXTLOAD))
420 fromType = NVPTX::PTXLdStInstCode::Signed;
421 else if (ScalarVT.isFloatingPoint())
422 fromType = NVPTX::PTXLdStInstCode::Float;
423 else
424 fromType = NVPTX::PTXLdStInstCode::Unsigned;
425
426 // Create the machine instruction DAG
427 SDValue Chain = N->getOperand(0);
428 SDValue N1 = N->getOperand(1);
429 SDValue Addr;
430 SDValue Offset, Base;
431 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +0000432 MVT::SimpleValueType TargetVT = LD->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000433
434 if (SelectDirectAddr(N1, Addr)) {
435 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000436 case MVT::i8:
437 Opcode = NVPTX::LD_i8_avar;
438 break;
439 case MVT::i16:
440 Opcode = NVPTX::LD_i16_avar;
441 break;
442 case MVT::i32:
443 Opcode = NVPTX::LD_i32_avar;
444 break;
445 case MVT::i64:
446 Opcode = NVPTX::LD_i64_avar;
447 break;
448 case MVT::f32:
449 Opcode = NVPTX::LD_f32_avar;
450 break;
451 case MVT::f64:
452 Opcode = NVPTX::LD_f64_avar;
453 break;
454 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000455 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000456 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000457 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
458 getI32Imm(vecType), getI32Imm(fromType),
459 getI32Imm(fromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000460 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000461 } else if (Subtarget.is64Bit()
462 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
463 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000464 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000465 case MVT::i8:
466 Opcode = NVPTX::LD_i8_asi;
467 break;
468 case MVT::i16:
469 Opcode = NVPTX::LD_i16_asi;
470 break;
471 case MVT::i32:
472 Opcode = NVPTX::LD_i32_asi;
473 break;
474 case MVT::i64:
475 Opcode = NVPTX::LD_i64_asi;
476 break;
477 case MVT::f32:
478 Opcode = NVPTX::LD_f32_asi;
479 break;
480 case MVT::f64:
481 Opcode = NVPTX::LD_f64_asi;
482 break;
483 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000484 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +0000485 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000486 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
487 getI32Imm(vecType), getI32Imm(fromType),
488 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000489 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000490 } else if (Subtarget.is64Bit()
491 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
492 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000493 if (Subtarget.is64Bit()) {
494 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000495 case MVT::i8:
496 Opcode = NVPTX::LD_i8_ari_64;
497 break;
498 case MVT::i16:
499 Opcode = NVPTX::LD_i16_ari_64;
500 break;
501 case MVT::i32:
502 Opcode = NVPTX::LD_i32_ari_64;
503 break;
504 case MVT::i64:
505 Opcode = NVPTX::LD_i64_ari_64;
506 break;
507 case MVT::f32:
508 Opcode = NVPTX::LD_f32_ari_64;
509 break;
510 case MVT::f64:
511 Opcode = NVPTX::LD_f64_ari_64;
512 break;
513 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000514 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000515 }
516 } else {
517 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000518 case MVT::i8:
519 Opcode = NVPTX::LD_i8_ari;
520 break;
521 case MVT::i16:
522 Opcode = NVPTX::LD_i16_ari;
523 break;
524 case MVT::i32:
525 Opcode = NVPTX::LD_i32_ari;
526 break;
527 case MVT::i64:
528 Opcode = NVPTX::LD_i64_ari;
529 break;
530 case MVT::f32:
531 Opcode = NVPTX::LD_f32_ari;
532 break;
533 case MVT::f64:
534 Opcode = NVPTX::LD_f64_ari;
535 break;
536 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000537 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000538 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000539 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000540 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
541 getI32Imm(vecType), getI32Imm(fromType),
542 getI32Imm(fromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000543 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000544 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000545 if (Subtarget.is64Bit()) {
546 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000547 case MVT::i8:
548 Opcode = NVPTX::LD_i8_areg_64;
549 break;
550 case MVT::i16:
551 Opcode = NVPTX::LD_i16_areg_64;
552 break;
553 case MVT::i32:
554 Opcode = NVPTX::LD_i32_areg_64;
555 break;
556 case MVT::i64:
557 Opcode = NVPTX::LD_i64_areg_64;
558 break;
559 case MVT::f32:
560 Opcode = NVPTX::LD_f32_areg_64;
561 break;
562 case MVT::f64:
563 Opcode = NVPTX::LD_f64_areg_64;
564 break;
565 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000566 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000567 }
568 } else {
569 switch (TargetVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000570 case MVT::i8:
571 Opcode = NVPTX::LD_i8_areg;
572 break;
573 case MVT::i16:
574 Opcode = NVPTX::LD_i16_areg;
575 break;
576 case MVT::i32:
577 Opcode = NVPTX::LD_i32_areg;
578 break;
579 case MVT::i64:
580 Opcode = NVPTX::LD_i64_areg;
581 break;
582 case MVT::f32:
583 Opcode = NVPTX::LD_f32_areg;
584 break;
585 case MVT::f64:
586 Opcode = NVPTX::LD_f64_areg;
587 break;
588 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000589 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000590 }
Justin Holewinskiae556d32012-05-04 20:18:50 +0000591 }
Justin Holewinski0497ab12013-03-30 14:29:21 +0000592 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
593 getI32Imm(vecType), getI32Imm(fromType),
594 getI32Imm(fromTypeWidth), N1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000595 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +0000596 }
597
Craig Topper062a2ba2014-04-25 05:30:21 +0000598 if (NVPTXLD) {
Justin Holewinskiae556d32012-05-04 20:18:50 +0000599 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
600 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
601 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
602 }
603
604 return NVPTXLD;
605}
606
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000607SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
608
609 SDValue Chain = N->getOperand(0);
610 SDValue Op1 = N->getOperand(1);
611 SDValue Addr, Offset, Base;
612 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000613 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000614 SDNode *LD;
615 MemSDNode *MemSD = cast<MemSDNode>(N);
616 EVT LoadedVT = MemSD->getMemoryVT();
617
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000618 if (!LoadedVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +0000619 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000620
621 // Address Space Setting
622 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
623
624 // Volatile Setting
625 // - .volatile is only availalble for .global and .shared
626 bool IsVolatile = MemSD->isVolatile();
627 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
628 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
629 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
630 IsVolatile = false;
631
632 // Vector Setting
633 MVT SimpleVT = LoadedVT.getSimpleVT();
634
635 // Type Setting: fromType + fromTypeWidth
636 //
637 // Sign : ISD::SEXTLOAD
638 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
639 // type is integer
640 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
641 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski994d66a2013-05-30 12:22:39 +0000642 // Read at least 8 bits (predicates are stored as 8-bit values)
643 unsigned FromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000644 unsigned int FromType;
645 // The last operand holds the original LoadSDNode::getExtensionType() value
Justin Holewinski0497ab12013-03-30 14:29:21 +0000646 unsigned ExtensionType = cast<ConstantSDNode>(
647 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000648 if (ExtensionType == ISD::SEXTLOAD)
649 FromType = NVPTX::PTXLdStInstCode::Signed;
650 else if (ScalarVT.isFloatingPoint())
651 FromType = NVPTX::PTXLdStInstCode::Float;
652 else
653 FromType = NVPTX::PTXLdStInstCode::Unsigned;
654
655 unsigned VecType;
656
657 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000658 case NVPTXISD::LoadV2:
659 VecType = NVPTX::PTXLdStInstCode::V2;
660 break;
661 case NVPTXISD::LoadV4:
662 VecType = NVPTX::PTXLdStInstCode::V4;
663 break;
664 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000665 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000666 }
667
668 EVT EltVT = N->getValueType(0);
669
670 if (SelectDirectAddr(Op1, Addr)) {
671 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000672 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000673 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000674 case NVPTXISD::LoadV2:
675 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000676 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000677 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000678 case MVT::i8:
679 Opcode = NVPTX::LDV_i8_v2_avar;
680 break;
681 case MVT::i16:
682 Opcode = NVPTX::LDV_i16_v2_avar;
683 break;
684 case MVT::i32:
685 Opcode = NVPTX::LDV_i32_v2_avar;
686 break;
687 case MVT::i64:
688 Opcode = NVPTX::LDV_i64_v2_avar;
689 break;
690 case MVT::f32:
691 Opcode = NVPTX::LDV_f32_v2_avar;
692 break;
693 case MVT::f64:
694 Opcode = NVPTX::LDV_f64_v2_avar;
695 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000696 }
697 break;
698 case NVPTXISD::LoadV4:
699 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000700 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000701 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000702 case MVT::i8:
703 Opcode = NVPTX::LDV_i8_v4_avar;
704 break;
705 case MVT::i16:
706 Opcode = NVPTX::LDV_i16_v4_avar;
707 break;
708 case MVT::i32:
709 Opcode = NVPTX::LDV_i32_v4_avar;
710 break;
711 case MVT::f32:
712 Opcode = NVPTX::LDV_f32_v4_avar;
713 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000714 }
715 break;
716 }
717
Justin Holewinski0497ab12013-03-30 14:29:21 +0000718 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
719 getI32Imm(VecType), getI32Imm(FromType),
720 getI32Imm(FromTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000721 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000722 } else if (Subtarget.is64Bit()
723 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
724 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000725 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000726 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000727 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000728 case NVPTXISD::LoadV2:
729 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000730 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000731 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000732 case MVT::i8:
733 Opcode = NVPTX::LDV_i8_v2_asi;
734 break;
735 case MVT::i16:
736 Opcode = NVPTX::LDV_i16_v2_asi;
737 break;
738 case MVT::i32:
739 Opcode = NVPTX::LDV_i32_v2_asi;
740 break;
741 case MVT::i64:
742 Opcode = NVPTX::LDV_i64_v2_asi;
743 break;
744 case MVT::f32:
745 Opcode = NVPTX::LDV_f32_v2_asi;
746 break;
747 case MVT::f64:
748 Opcode = NVPTX::LDV_f64_v2_asi;
749 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000750 }
751 break;
752 case NVPTXISD::LoadV4:
753 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000754 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000755 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000756 case MVT::i8:
757 Opcode = NVPTX::LDV_i8_v4_asi;
758 break;
759 case MVT::i16:
760 Opcode = NVPTX::LDV_i16_v4_asi;
761 break;
762 case MVT::i32:
763 Opcode = NVPTX::LDV_i32_v4_asi;
764 break;
765 case MVT::f32:
766 Opcode = NVPTX::LDV_f32_v4_asi;
767 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000768 }
769 break;
770 }
771
Justin Holewinski0497ab12013-03-30 14:29:21 +0000772 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
773 getI32Imm(VecType), getI32Imm(FromType),
774 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000775 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +0000776 } else if (Subtarget.is64Bit()
777 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
778 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000779 if (Subtarget.is64Bit()) {
780 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000781 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000782 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000783 case NVPTXISD::LoadV2:
784 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000785 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000786 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000787 case MVT::i8:
788 Opcode = NVPTX::LDV_i8_v2_ari_64;
789 break;
790 case MVT::i16:
791 Opcode = NVPTX::LDV_i16_v2_ari_64;
792 break;
793 case MVT::i32:
794 Opcode = NVPTX::LDV_i32_v2_ari_64;
795 break;
796 case MVT::i64:
797 Opcode = NVPTX::LDV_i64_v2_ari_64;
798 break;
799 case MVT::f32:
800 Opcode = NVPTX::LDV_f32_v2_ari_64;
801 break;
802 case MVT::f64:
803 Opcode = NVPTX::LDV_f64_v2_ari_64;
804 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000805 }
806 break;
807 case NVPTXISD::LoadV4:
808 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000809 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000810 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000811 case MVT::i8:
812 Opcode = NVPTX::LDV_i8_v4_ari_64;
813 break;
814 case MVT::i16:
815 Opcode = NVPTX::LDV_i16_v4_ari_64;
816 break;
817 case MVT::i32:
818 Opcode = NVPTX::LDV_i32_v4_ari_64;
819 break;
820 case MVT::f32:
821 Opcode = NVPTX::LDV_f32_v4_ari_64;
822 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000823 }
824 break;
825 }
826 } else {
827 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000828 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000829 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000830 case NVPTXISD::LoadV2:
831 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000832 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000833 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000834 case MVT::i8:
835 Opcode = NVPTX::LDV_i8_v2_ari;
836 break;
837 case MVT::i16:
838 Opcode = NVPTX::LDV_i16_v2_ari;
839 break;
840 case MVT::i32:
841 Opcode = NVPTX::LDV_i32_v2_ari;
842 break;
843 case MVT::i64:
844 Opcode = NVPTX::LDV_i64_v2_ari;
845 break;
846 case MVT::f32:
847 Opcode = NVPTX::LDV_f32_v2_ari;
848 break;
849 case MVT::f64:
850 Opcode = NVPTX::LDV_f64_v2_ari;
851 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000852 }
853 break;
854 case NVPTXISD::LoadV4:
855 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000856 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000857 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000858 case MVT::i8:
859 Opcode = NVPTX::LDV_i8_v4_ari;
860 break;
861 case MVT::i16:
862 Opcode = NVPTX::LDV_i16_v4_ari;
863 break;
864 case MVT::i32:
865 Opcode = NVPTX::LDV_i32_v4_ari;
866 break;
867 case MVT::f32:
868 Opcode = NVPTX::LDV_f32_v4_ari;
869 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000870 }
871 break;
872 }
873 }
874
Justin Holewinski0497ab12013-03-30 14:29:21 +0000875 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
876 getI32Imm(VecType), getI32Imm(FromType),
877 getI32Imm(FromTypeWidth), Base, Offset, Chain };
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000878
Michael Liaob53d8962013-04-19 22:22:57 +0000879 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000880 } else {
881 if (Subtarget.is64Bit()) {
882 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000883 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000884 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000885 case NVPTXISD::LoadV2:
886 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000887 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000888 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000889 case MVT::i8:
890 Opcode = NVPTX::LDV_i8_v2_areg_64;
891 break;
892 case MVT::i16:
893 Opcode = NVPTX::LDV_i16_v2_areg_64;
894 break;
895 case MVT::i32:
896 Opcode = NVPTX::LDV_i32_v2_areg_64;
897 break;
898 case MVT::i64:
899 Opcode = NVPTX::LDV_i64_v2_areg_64;
900 break;
901 case MVT::f32:
902 Opcode = NVPTX::LDV_f32_v2_areg_64;
903 break;
904 case MVT::f64:
905 Opcode = NVPTX::LDV_f64_v2_areg_64;
906 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000907 }
908 break;
909 case NVPTXISD::LoadV4:
910 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000911 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000912 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000913 case MVT::i8:
914 Opcode = NVPTX::LDV_i8_v4_areg_64;
915 break;
916 case MVT::i16:
917 Opcode = NVPTX::LDV_i16_v4_areg_64;
918 break;
919 case MVT::i32:
920 Opcode = NVPTX::LDV_i32_v4_areg_64;
921 break;
922 case MVT::f32:
923 Opcode = NVPTX::LDV_f32_v4_areg_64;
924 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000925 }
926 break;
927 }
928 } else {
929 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000930 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000931 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000932 case NVPTXISD::LoadV2:
933 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000934 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000935 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000936 case MVT::i8:
937 Opcode = NVPTX::LDV_i8_v2_areg;
938 break;
939 case MVT::i16:
940 Opcode = NVPTX::LDV_i16_v2_areg;
941 break;
942 case MVT::i32:
943 Opcode = NVPTX::LDV_i32_v2_areg;
944 break;
945 case MVT::i64:
946 Opcode = NVPTX::LDV_i64_v2_areg;
947 break;
948 case MVT::f32:
949 Opcode = NVPTX::LDV_f32_v2_areg;
950 break;
951 case MVT::f64:
952 Opcode = NVPTX::LDV_f64_v2_areg;
953 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000954 }
955 break;
956 case NVPTXISD::LoadV4:
957 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +0000958 default:
Craig Topper062a2ba2014-04-25 05:30:21 +0000959 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +0000960 case MVT::i8:
961 Opcode = NVPTX::LDV_i8_v4_areg;
962 break;
963 case MVT::i16:
964 Opcode = NVPTX::LDV_i16_v4_areg;
965 break;
966 case MVT::i32:
967 Opcode = NVPTX::LDV_i32_v4_areg;
968 break;
969 case MVT::f32:
970 Opcode = NVPTX::LDV_f32_v4_areg;
971 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000972 }
973 break;
974 }
975 }
976
Justin Holewinski0497ab12013-03-30 14:29:21 +0000977 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
978 getI32Imm(VecType), getI32Imm(FromType),
979 getI32Imm(FromTypeWidth), Op1, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +0000980 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000981 }
982
983 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
984 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
985 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
986
987 return LD;
988}
989
990SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
991
992 SDValue Chain = N->getOperand(0);
993 SDValue Op1 = N->getOperand(1);
994 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +0000995 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +0000996 SDNode *LD;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000997 MemSDNode *Mem = cast<MemSDNode>(N);
Justin Holewinskie40e9292013-07-01 12:58:52 +0000998 SDValue Base, Offset, Addr;
Justin Holewinskif8f70912013-06-28 17:57:59 +0000999
Justin Holewinskie40e9292013-07-01 12:58:52 +00001000 EVT EltVT = Mem->getMemoryVT().getVectorElementType();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001001
Justin Holewinskie40e9292013-07-01 12:58:52 +00001002 if (SelectDirectAddr(Op1, Addr)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001003 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001004 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001005 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001006 case NVPTXISD::LDGV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001007 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001008 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001009 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001010 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001011 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001012 break;
1013 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001014 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001015 break;
1016 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001017 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001018 break;
1019 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001020 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001021 break;
1022 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001023 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001024 break;
1025 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001026 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001027 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001028 }
1029 break;
1030 case NVPTXISD::LDUV2:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001031 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001032 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001033 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001034 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001035 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001036 break;
1037 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001038 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001039 break;
1040 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001041 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001042 break;
1043 case MVT::i64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001044 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001045 break;
1046 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001047 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001048 break;
1049 case MVT::f64:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001050 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_avar;
1051 break;
1052 }
1053 break;
1054 case NVPTXISD::LDGV4:
1055 switch (EltVT.getSimpleVT().SimpleTy) {
1056 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001057 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001058 case MVT::i8:
1059 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_avar;
1060 break;
1061 case MVT::i16:
1062 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_avar;
1063 break;
1064 case MVT::i32:
1065 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_avar;
1066 break;
1067 case MVT::f32:
1068 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001069 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001070 }
1071 break;
1072 case NVPTXISD::LDUV4:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001073 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001074 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001075 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001076 case MVT::i8:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001077 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001078 break;
1079 case MVT::i16:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001080 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001081 break;
1082 case MVT::i32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001083 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001084 break;
1085 case MVT::f32:
Justin Holewinskie40e9292013-07-01 12:58:52 +00001086 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_avar;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001087 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001088 }
1089 break;
1090 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001091
1092 SDValue Ops[] = { Addr, Chain };
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001093 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskie40e9292013-07-01 12:58:52 +00001094 } else if (Subtarget.is64Bit()
1095 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
1096 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
1097 if (Subtarget.is64Bit()) {
1098 switch (N->getOpcode()) {
1099 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001100 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001101 case NVPTXISD::LDGV2:
1102 switch (EltVT.getSimpleVT().SimpleTy) {
1103 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001104 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001105 case MVT::i8:
1106 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari64;
1107 break;
1108 case MVT::i16:
1109 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari64;
1110 break;
1111 case MVT::i32:
1112 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari64;
1113 break;
1114 case MVT::i64:
1115 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari64;
1116 break;
1117 case MVT::f32:
1118 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari64;
1119 break;
1120 case MVT::f64:
1121 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari64;
1122 break;
1123 }
1124 break;
1125 case NVPTXISD::LDUV2:
1126 switch (EltVT.getSimpleVT().SimpleTy) {
1127 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001128 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001129 case MVT::i8:
1130 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari64;
1131 break;
1132 case MVT::i16:
1133 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari64;
1134 break;
1135 case MVT::i32:
1136 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari64;
1137 break;
1138 case MVT::i64:
1139 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari64;
1140 break;
1141 case MVT::f32:
1142 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari64;
1143 break;
1144 case MVT::f64:
1145 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari64;
1146 break;
1147 }
1148 break;
1149 case NVPTXISD::LDGV4:
1150 switch (EltVT.getSimpleVT().SimpleTy) {
1151 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001152 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001153 case MVT::i8:
1154 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari64;
1155 break;
1156 case MVT::i16:
1157 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari64;
1158 break;
1159 case MVT::i32:
1160 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari64;
1161 break;
1162 case MVT::f32:
1163 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari64;
1164 break;
1165 }
1166 break;
1167 case NVPTXISD::LDUV4:
1168 switch (EltVT.getSimpleVT().SimpleTy) {
1169 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001170 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001171 case MVT::i8:
1172 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari64;
1173 break;
1174 case MVT::i16:
1175 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari64;
1176 break;
1177 case MVT::i32:
1178 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari64;
1179 break;
1180 case MVT::f32:
1181 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari64;
1182 break;
1183 }
1184 break;
1185 }
1186 } else {
1187 switch (N->getOpcode()) {
1188 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001189 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001190 case NVPTXISD::LDGV2:
1191 switch (EltVT.getSimpleVT().SimpleTy) {
1192 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001193 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001194 case MVT::i8:
1195 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_ari32;
1196 break;
1197 case MVT::i16:
1198 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_ari32;
1199 break;
1200 case MVT::i32:
1201 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_ari32;
1202 break;
1203 case MVT::i64:
1204 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_ari32;
1205 break;
1206 case MVT::f32:
1207 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_ari32;
1208 break;
1209 case MVT::f64:
1210 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_ari32;
1211 break;
1212 }
1213 break;
1214 case NVPTXISD::LDUV2:
1215 switch (EltVT.getSimpleVT().SimpleTy) {
1216 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001217 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001218 case MVT::i8:
1219 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_ari32;
1220 break;
1221 case MVT::i16:
1222 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_ari32;
1223 break;
1224 case MVT::i32:
1225 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_ari32;
1226 break;
1227 case MVT::i64:
1228 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_ari32;
1229 break;
1230 case MVT::f32:
1231 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_ari32;
1232 break;
1233 case MVT::f64:
1234 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_ari32;
1235 break;
1236 }
1237 break;
1238 case NVPTXISD::LDGV4:
1239 switch (EltVT.getSimpleVT().SimpleTy) {
1240 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001241 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001242 case MVT::i8:
1243 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_ari32;
1244 break;
1245 case MVT::i16:
1246 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_ari32;
1247 break;
1248 case MVT::i32:
1249 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_ari32;
1250 break;
1251 case MVT::f32:
1252 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_ari32;
1253 break;
1254 }
1255 break;
1256 case NVPTXISD::LDUV4:
1257 switch (EltVT.getSimpleVT().SimpleTy) {
1258 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001259 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001260 case MVT::i8:
1261 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_ari32;
1262 break;
1263 case MVT::i16:
1264 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_ari32;
1265 break;
1266 case MVT::i32:
1267 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_ari32;
1268 break;
1269 case MVT::f32:
1270 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_ari32;
1271 break;
1272 }
1273 break;
1274 }
1275 }
1276
1277 SDValue Ops[] = { Base, Offset, Chain };
1278
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001279 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001280 } else {
Justin Holewinskie40e9292013-07-01 12:58:52 +00001281 if (Subtarget.is64Bit()) {
1282 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001283 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001284 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001285 case NVPTXISD::LDGV2:
1286 switch (EltVT.getSimpleVT().SimpleTy) {
1287 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001288 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001289 case MVT::i8:
1290 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg64;
1291 break;
1292 case MVT::i16:
1293 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg64;
1294 break;
1295 case MVT::i32:
1296 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg64;
1297 break;
1298 case MVT::i64:
1299 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg64;
1300 break;
1301 case MVT::f32:
1302 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg64;
1303 break;
1304 case MVT::f64:
1305 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg64;
1306 break;
1307 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001308 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001309 case NVPTXISD::LDUV2:
1310 switch (EltVT.getSimpleVT().SimpleTy) {
1311 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001312 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001313 case MVT::i8:
1314 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg64;
1315 break;
1316 case MVT::i16:
1317 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg64;
1318 break;
1319 case MVT::i32:
1320 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg64;
1321 break;
1322 case MVT::i64:
1323 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg64;
1324 break;
1325 case MVT::f32:
1326 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg64;
1327 break;
1328 case MVT::f64:
1329 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg64;
1330 break;
1331 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001332 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001333 case NVPTXISD::LDGV4:
1334 switch (EltVT.getSimpleVT().SimpleTy) {
1335 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001336 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001337 case MVT::i8:
1338 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg64;
1339 break;
1340 case MVT::i16:
1341 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg64;
1342 break;
1343 case MVT::i32:
1344 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg64;
1345 break;
1346 case MVT::f32:
1347 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg64;
1348 break;
1349 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001350 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001351 case NVPTXISD::LDUV4:
1352 switch (EltVT.getSimpleVT().SimpleTy) {
1353 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001354 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001355 case MVT::i8:
1356 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg64;
1357 break;
1358 case MVT::i16:
1359 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg64;
1360 break;
1361 case MVT::i32:
1362 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg64;
1363 break;
1364 case MVT::f32:
1365 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg64;
1366 break;
1367 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001368 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001369 }
Justin Holewinskie40e9292013-07-01 12:58:52 +00001370 } else {
1371 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001372 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001373 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001374 case NVPTXISD::LDGV2:
1375 switch (EltVT.getSimpleVT().SimpleTy) {
1376 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001377 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001378 case MVT::i8:
1379 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_areg32;
1380 break;
1381 case MVT::i16:
1382 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_areg32;
1383 break;
1384 case MVT::i32:
1385 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_areg32;
1386 break;
1387 case MVT::i64:
1388 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_areg32;
1389 break;
1390 case MVT::f32:
1391 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_areg32;
1392 break;
1393 case MVT::f64:
1394 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_areg32;
1395 break;
1396 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001397 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001398 case NVPTXISD::LDUV2:
1399 switch (EltVT.getSimpleVT().SimpleTy) {
1400 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001401 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001402 case MVT::i8:
1403 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_areg32;
1404 break;
1405 case MVT::i16:
1406 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_areg32;
1407 break;
1408 case MVT::i32:
1409 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_areg32;
1410 break;
1411 case MVT::i64:
1412 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_areg32;
1413 break;
1414 case MVT::f32:
1415 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_areg32;
1416 break;
1417 case MVT::f64:
1418 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_areg32;
1419 break;
1420 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001421 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001422 case NVPTXISD::LDGV4:
1423 switch (EltVT.getSimpleVT().SimpleTy) {
1424 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001425 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001426 case MVT::i8:
1427 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_areg32;
1428 break;
1429 case MVT::i16:
1430 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_areg32;
1431 break;
1432 case MVT::i32:
1433 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_areg32;
1434 break;
1435 case MVT::f32:
1436 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_areg32;
1437 break;
1438 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001439 break;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001440 case NVPTXISD::LDUV4:
1441 switch (EltVT.getSimpleVT().SimpleTy) {
1442 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001443 return nullptr;
Justin Holewinskie40e9292013-07-01 12:58:52 +00001444 case MVT::i8:
1445 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_areg32;
1446 break;
1447 case MVT::i16:
1448 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_areg32;
1449 break;
1450 case MVT::i32:
1451 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_areg32;
1452 break;
1453 case MVT::f32:
1454 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_areg32;
1455 break;
1456 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001457 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001458 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001459 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001460
Justin Holewinskie40e9292013-07-01 12:58:52 +00001461 SDValue Ops[] = { Op1, Chain };
Craig Topper2d2aa0c2014-04-30 07:17:30 +00001462 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
Justin Holewinskie40e9292013-07-01 12:58:52 +00001463 }
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001464
1465 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1466 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1467 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
1468
1469 return LD;
1470}
1471
Justin Holewinski0497ab12013-03-30 14:29:21 +00001472SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
Andrew Trickef9de2a2013-05-25 02:42:55 +00001473 SDLoc dl(N);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001474 StoreSDNode *ST = cast<StoreSDNode>(N);
1475 EVT StoreVT = ST->getMemoryVT();
Craig Topper062a2ba2014-04-25 05:30:21 +00001476 SDNode *NVPTXST = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001477
1478 // do not support pre/post inc/dec
1479 if (ST->isIndexed())
Craig Topper062a2ba2014-04-25 05:30:21 +00001480 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001481
1482 if (!StoreVT.isSimple())
Craig Topper062a2ba2014-04-25 05:30:21 +00001483 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001484
1485 // Address Space Setting
1486 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1487
1488 // Volatile Setting
1489 // - .volatile is only availalble for .global and .shared
1490 bool isVolatile = ST->isVolatile();
1491 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1492 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1493 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1494 isVolatile = false;
1495
1496 // Vector Setting
1497 MVT SimpleVT = StoreVT.getSimpleVT();
1498 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1499 if (SimpleVT.isVector()) {
1500 unsigned num = SimpleVT.getVectorNumElements();
1501 if (num == 2)
1502 vecType = NVPTX::PTXLdStInstCode::V2;
1503 else if (num == 4)
1504 vecType = NVPTX::PTXLdStInstCode::V4;
1505 else
Craig Topper062a2ba2014-04-25 05:30:21 +00001506 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001507 }
1508
1509 // Type Setting: toType + toTypeWidth
1510 // - for integer type, always use 'u'
1511 //
1512 MVT ScalarVT = SimpleVT.getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001513 unsigned toTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskiae556d32012-05-04 20:18:50 +00001514 unsigned int toType;
1515 if (ScalarVT.isFloatingPoint())
1516 toType = NVPTX::PTXLdStInstCode::Float;
1517 else
1518 toType = NVPTX::PTXLdStInstCode::Unsigned;
1519
1520 // Create the machine instruction DAG
1521 SDValue Chain = N->getOperand(0);
1522 SDValue N1 = N->getOperand(1);
1523 SDValue N2 = N->getOperand(2);
1524 SDValue Addr;
1525 SDValue Offset, Base;
1526 unsigned Opcode;
Craig Topperd9c27832013-08-15 02:44:19 +00001527 MVT::SimpleValueType SourceVT = N1.getNode()->getSimpleValueType(0).SimpleTy;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001528
1529 if (SelectDirectAddr(N2, Addr)) {
1530 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001531 case MVT::i8:
1532 Opcode = NVPTX::ST_i8_avar;
1533 break;
1534 case MVT::i16:
1535 Opcode = NVPTX::ST_i16_avar;
1536 break;
1537 case MVT::i32:
1538 Opcode = NVPTX::ST_i32_avar;
1539 break;
1540 case MVT::i64:
1541 Opcode = NVPTX::ST_i64_avar;
1542 break;
1543 case MVT::f32:
1544 Opcode = NVPTX::ST_f32_avar;
1545 break;
1546 case MVT::f64:
1547 Opcode = NVPTX::ST_f64_avar;
1548 break;
1549 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001550 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001551 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001552 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1553 getI32Imm(vecType), getI32Imm(toType),
1554 getI32Imm(toTypeWidth), Addr, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001555 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001556 } else if (Subtarget.is64Bit()
1557 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1558 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001559 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001560 case MVT::i8:
1561 Opcode = NVPTX::ST_i8_asi;
1562 break;
1563 case MVT::i16:
1564 Opcode = NVPTX::ST_i16_asi;
1565 break;
1566 case MVT::i32:
1567 Opcode = NVPTX::ST_i32_asi;
1568 break;
1569 case MVT::i64:
1570 Opcode = NVPTX::ST_i64_asi;
1571 break;
1572 case MVT::f32:
1573 Opcode = NVPTX::ST_f32_asi;
1574 break;
1575 case MVT::f64:
1576 Opcode = NVPTX::ST_f64_asi;
1577 break;
1578 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001579 return nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00001580 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001581 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1582 getI32Imm(vecType), getI32Imm(toType),
1583 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001584 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001585 } else if (Subtarget.is64Bit()
1586 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1587 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001588 if (Subtarget.is64Bit()) {
1589 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001590 case MVT::i8:
1591 Opcode = NVPTX::ST_i8_ari_64;
1592 break;
1593 case MVT::i16:
1594 Opcode = NVPTX::ST_i16_ari_64;
1595 break;
1596 case MVT::i32:
1597 Opcode = NVPTX::ST_i32_ari_64;
1598 break;
1599 case MVT::i64:
1600 Opcode = NVPTX::ST_i64_ari_64;
1601 break;
1602 case MVT::f32:
1603 Opcode = NVPTX::ST_f32_ari_64;
1604 break;
1605 case MVT::f64:
1606 Opcode = NVPTX::ST_f64_ari_64;
1607 break;
1608 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001609 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001610 }
1611 } else {
1612 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001613 case MVT::i8:
1614 Opcode = NVPTX::ST_i8_ari;
1615 break;
1616 case MVT::i16:
1617 Opcode = NVPTX::ST_i16_ari;
1618 break;
1619 case MVT::i32:
1620 Opcode = NVPTX::ST_i32_ari;
1621 break;
1622 case MVT::i64:
1623 Opcode = NVPTX::ST_i64_ari;
1624 break;
1625 case MVT::f32:
1626 Opcode = NVPTX::ST_f32_ari;
1627 break;
1628 case MVT::f64:
1629 Opcode = NVPTX::ST_f64_ari;
1630 break;
1631 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001632 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001633 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001634 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001635 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1636 getI32Imm(vecType), getI32Imm(toType),
1637 getI32Imm(toTypeWidth), Base, Offset, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001638 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001639 } else {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001640 if (Subtarget.is64Bit()) {
1641 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001642 case MVT::i8:
1643 Opcode = NVPTX::ST_i8_areg_64;
1644 break;
1645 case MVT::i16:
1646 Opcode = NVPTX::ST_i16_areg_64;
1647 break;
1648 case MVT::i32:
1649 Opcode = NVPTX::ST_i32_areg_64;
1650 break;
1651 case MVT::i64:
1652 Opcode = NVPTX::ST_i64_areg_64;
1653 break;
1654 case MVT::f32:
1655 Opcode = NVPTX::ST_f32_areg_64;
1656 break;
1657 case MVT::f64:
1658 Opcode = NVPTX::ST_f64_areg_64;
1659 break;
1660 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001661 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001662 }
1663 } else {
1664 switch (SourceVT) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001665 case MVT::i8:
1666 Opcode = NVPTX::ST_i8_areg;
1667 break;
1668 case MVT::i16:
1669 Opcode = NVPTX::ST_i16_areg;
1670 break;
1671 case MVT::i32:
1672 Opcode = NVPTX::ST_i32_areg;
1673 break;
1674 case MVT::i64:
1675 Opcode = NVPTX::ST_i64_areg;
1676 break;
1677 case MVT::f32:
1678 Opcode = NVPTX::ST_f32_areg;
1679 break;
1680 case MVT::f64:
1681 Opcode = NVPTX::ST_f64_areg;
1682 break;
1683 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001684 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001685 }
Justin Holewinskiae556d32012-05-04 20:18:50 +00001686 }
Justin Holewinski0497ab12013-03-30 14:29:21 +00001687 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1688 getI32Imm(vecType), getI32Imm(toType),
1689 getI32Imm(toTypeWidth), N2, Chain };
Michael Liaob53d8962013-04-19 22:22:57 +00001690 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
Justin Holewinskiae556d32012-05-04 20:18:50 +00001691 }
1692
Craig Topper062a2ba2014-04-25 05:30:21 +00001693 if (NVPTXST) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00001694 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1695 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1696 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1697 }
1698
1699 return NVPTXST;
1700}
1701
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001702SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1703 SDValue Chain = N->getOperand(0);
1704 SDValue Op1 = N->getOperand(1);
1705 SDValue Addr, Offset, Base;
1706 unsigned Opcode;
Andrew Trickef9de2a2013-05-25 02:42:55 +00001707 SDLoc DL(N);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001708 SDNode *ST;
1709 EVT EltVT = Op1.getValueType();
1710 MemSDNode *MemSD = cast<MemSDNode>(N);
1711 EVT StoreVT = MemSD->getMemoryVT();
1712
1713 // Address Space Setting
1714 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1715
1716 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1717 report_fatal_error("Cannot store to pointer that points to constant "
1718 "memory space");
1719 }
1720
1721 // Volatile Setting
1722 // - .volatile is only availalble for .global and .shared
1723 bool IsVolatile = MemSD->isVolatile();
1724 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1725 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1726 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1727 IsVolatile = false;
1728
1729 // Type Setting: toType + toTypeWidth
1730 // - for integer type, always use 'u'
1731 assert(StoreVT.isSimple() && "Store value is not simple");
1732 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
Justin Holewinski0497ab12013-03-30 14:29:21 +00001733 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001734 unsigned ToType;
1735 if (ScalarVT.isFloatingPoint())
1736 ToType = NVPTX::PTXLdStInstCode::Float;
1737 else
1738 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1739
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001740 SmallVector<SDValue, 12> StOps;
1741 SDValue N2;
1742 unsigned VecType;
1743
1744 switch (N->getOpcode()) {
1745 case NVPTXISD::StoreV2:
1746 VecType = NVPTX::PTXLdStInstCode::V2;
1747 StOps.push_back(N->getOperand(1));
1748 StOps.push_back(N->getOperand(2));
1749 N2 = N->getOperand(3);
1750 break;
1751 case NVPTXISD::StoreV4:
1752 VecType = NVPTX::PTXLdStInstCode::V4;
1753 StOps.push_back(N->getOperand(1));
1754 StOps.push_back(N->getOperand(2));
1755 StOps.push_back(N->getOperand(3));
1756 StOps.push_back(N->getOperand(4));
1757 N2 = N->getOperand(5);
1758 break;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001759 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001760 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001761 }
1762
1763 StOps.push_back(getI32Imm(IsVolatile));
1764 StOps.push_back(getI32Imm(CodeAddrSpace));
1765 StOps.push_back(getI32Imm(VecType));
1766 StOps.push_back(getI32Imm(ToType));
1767 StOps.push_back(getI32Imm(ToTypeWidth));
1768
1769 if (SelectDirectAddr(N2, Addr)) {
1770 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001771 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001772 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001773 case NVPTXISD::StoreV2:
1774 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001775 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001776 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001777 case MVT::i8:
1778 Opcode = NVPTX::STV_i8_v2_avar;
1779 break;
1780 case MVT::i16:
1781 Opcode = NVPTX::STV_i16_v2_avar;
1782 break;
1783 case MVT::i32:
1784 Opcode = NVPTX::STV_i32_v2_avar;
1785 break;
1786 case MVT::i64:
1787 Opcode = NVPTX::STV_i64_v2_avar;
1788 break;
1789 case MVT::f32:
1790 Opcode = NVPTX::STV_f32_v2_avar;
1791 break;
1792 case MVT::f64:
1793 Opcode = NVPTX::STV_f64_v2_avar;
1794 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001795 }
1796 break;
1797 case NVPTXISD::StoreV4:
1798 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001799 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001800 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001801 case MVT::i8:
1802 Opcode = NVPTX::STV_i8_v4_avar;
1803 break;
1804 case MVT::i16:
1805 Opcode = NVPTX::STV_i16_v4_avar;
1806 break;
1807 case MVT::i32:
1808 Opcode = NVPTX::STV_i32_v4_avar;
1809 break;
1810 case MVT::f32:
1811 Opcode = NVPTX::STV_f32_v4_avar;
1812 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001813 }
1814 break;
1815 }
1816 StOps.push_back(Addr);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001817 } else if (Subtarget.is64Bit()
1818 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1819 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001820 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001821 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001822 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001823 case NVPTXISD::StoreV2:
1824 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001825 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001826 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001827 case MVT::i8:
1828 Opcode = NVPTX::STV_i8_v2_asi;
1829 break;
1830 case MVT::i16:
1831 Opcode = NVPTX::STV_i16_v2_asi;
1832 break;
1833 case MVT::i32:
1834 Opcode = NVPTX::STV_i32_v2_asi;
1835 break;
1836 case MVT::i64:
1837 Opcode = NVPTX::STV_i64_v2_asi;
1838 break;
1839 case MVT::f32:
1840 Opcode = NVPTX::STV_f32_v2_asi;
1841 break;
1842 case MVT::f64:
1843 Opcode = NVPTX::STV_f64_v2_asi;
1844 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001845 }
1846 break;
1847 case NVPTXISD::StoreV4:
1848 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001849 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001850 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001851 case MVT::i8:
1852 Opcode = NVPTX::STV_i8_v4_asi;
1853 break;
1854 case MVT::i16:
1855 Opcode = NVPTX::STV_i16_v4_asi;
1856 break;
1857 case MVT::i32:
1858 Opcode = NVPTX::STV_i32_v4_asi;
1859 break;
1860 case MVT::f32:
1861 Opcode = NVPTX::STV_f32_v4_asi;
1862 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001863 }
1864 break;
1865 }
1866 StOps.push_back(Base);
1867 StOps.push_back(Offset);
Justin Holewinski0497ab12013-03-30 14:29:21 +00001868 } else if (Subtarget.is64Bit()
1869 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1870 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001871 if (Subtarget.is64Bit()) {
1872 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001873 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001874 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001875 case NVPTXISD::StoreV2:
1876 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001877 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001878 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001879 case MVT::i8:
1880 Opcode = NVPTX::STV_i8_v2_ari_64;
1881 break;
1882 case MVT::i16:
1883 Opcode = NVPTX::STV_i16_v2_ari_64;
1884 break;
1885 case MVT::i32:
1886 Opcode = NVPTX::STV_i32_v2_ari_64;
1887 break;
1888 case MVT::i64:
1889 Opcode = NVPTX::STV_i64_v2_ari_64;
1890 break;
1891 case MVT::f32:
1892 Opcode = NVPTX::STV_f32_v2_ari_64;
1893 break;
1894 case MVT::f64:
1895 Opcode = NVPTX::STV_f64_v2_ari_64;
1896 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001897 }
1898 break;
1899 case NVPTXISD::StoreV4:
1900 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001901 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001902 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001903 case MVT::i8:
1904 Opcode = NVPTX::STV_i8_v4_ari_64;
1905 break;
1906 case MVT::i16:
1907 Opcode = NVPTX::STV_i16_v4_ari_64;
1908 break;
1909 case MVT::i32:
1910 Opcode = NVPTX::STV_i32_v4_ari_64;
1911 break;
1912 case MVT::f32:
1913 Opcode = NVPTX::STV_f32_v4_ari_64;
1914 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001915 }
1916 break;
1917 }
1918 } else {
1919 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001920 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001921 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001922 case NVPTXISD::StoreV2:
1923 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001924 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001925 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001926 case MVT::i8:
1927 Opcode = NVPTX::STV_i8_v2_ari;
1928 break;
1929 case MVT::i16:
1930 Opcode = NVPTX::STV_i16_v2_ari;
1931 break;
1932 case MVT::i32:
1933 Opcode = NVPTX::STV_i32_v2_ari;
1934 break;
1935 case MVT::i64:
1936 Opcode = NVPTX::STV_i64_v2_ari;
1937 break;
1938 case MVT::f32:
1939 Opcode = NVPTX::STV_f32_v2_ari;
1940 break;
1941 case MVT::f64:
1942 Opcode = NVPTX::STV_f64_v2_ari;
1943 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001944 }
1945 break;
1946 case NVPTXISD::StoreV4:
1947 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001948 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001949 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001950 case MVT::i8:
1951 Opcode = NVPTX::STV_i8_v4_ari;
1952 break;
1953 case MVT::i16:
1954 Opcode = NVPTX::STV_i16_v4_ari;
1955 break;
1956 case MVT::i32:
1957 Opcode = NVPTX::STV_i32_v4_ari;
1958 break;
1959 case MVT::f32:
1960 Opcode = NVPTX::STV_f32_v4_ari;
1961 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001962 }
1963 break;
1964 }
1965 }
1966 StOps.push_back(Base);
1967 StOps.push_back(Offset);
1968 } else {
1969 if (Subtarget.is64Bit()) {
1970 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001971 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001972 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001973 case NVPTXISD::StoreV2:
1974 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001975 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00001976 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00001977 case MVT::i8:
1978 Opcode = NVPTX::STV_i8_v2_areg_64;
1979 break;
1980 case MVT::i16:
1981 Opcode = NVPTX::STV_i16_v2_areg_64;
1982 break;
1983 case MVT::i32:
1984 Opcode = NVPTX::STV_i32_v2_areg_64;
1985 break;
1986 case MVT::i64:
1987 Opcode = NVPTX::STV_i64_v2_areg_64;
1988 break;
1989 case MVT::f32:
1990 Opcode = NVPTX::STV_f32_v2_areg_64;
1991 break;
1992 case MVT::f64:
1993 Opcode = NVPTX::STV_f64_v2_areg_64;
1994 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00001995 }
1996 break;
1997 case NVPTXISD::StoreV4:
1998 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00001999 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002000 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002001 case MVT::i8:
2002 Opcode = NVPTX::STV_i8_v4_areg_64;
2003 break;
2004 case MVT::i16:
2005 Opcode = NVPTX::STV_i16_v4_areg_64;
2006 break;
2007 case MVT::i32:
2008 Opcode = NVPTX::STV_i32_v4_areg_64;
2009 break;
2010 case MVT::f32:
2011 Opcode = NVPTX::STV_f32_v4_areg_64;
2012 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002013 }
2014 break;
2015 }
2016 } else {
2017 switch (N->getOpcode()) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002018 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002019 return nullptr;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002020 case NVPTXISD::StoreV2:
2021 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002022 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002023 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002024 case MVT::i8:
2025 Opcode = NVPTX::STV_i8_v2_areg;
2026 break;
2027 case MVT::i16:
2028 Opcode = NVPTX::STV_i16_v2_areg;
2029 break;
2030 case MVT::i32:
2031 Opcode = NVPTX::STV_i32_v2_areg;
2032 break;
2033 case MVT::i64:
2034 Opcode = NVPTX::STV_i64_v2_areg;
2035 break;
2036 case MVT::f32:
2037 Opcode = NVPTX::STV_f32_v2_areg;
2038 break;
2039 case MVT::f64:
2040 Opcode = NVPTX::STV_f64_v2_areg;
2041 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002042 }
2043 break;
2044 case NVPTXISD::StoreV4:
2045 switch (EltVT.getSimpleVT().SimpleTy) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00002046 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002047 return nullptr;
Justin Holewinski0497ab12013-03-30 14:29:21 +00002048 case MVT::i8:
2049 Opcode = NVPTX::STV_i8_v4_areg;
2050 break;
2051 case MVT::i16:
2052 Opcode = NVPTX::STV_i16_v4_areg;
2053 break;
2054 case MVT::i32:
2055 Opcode = NVPTX::STV_i32_v4_areg;
2056 break;
2057 case MVT::f32:
2058 Opcode = NVPTX::STV_f32_v4_areg;
2059 break;
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002060 }
2061 break;
2062 }
2063 }
2064 StOps.push_back(N2);
2065 }
2066
2067 StOps.push_back(Chain);
2068
Michael Liaob53d8962013-04-19 22:22:57 +00002069 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
Justin Holewinskibe8dc642013-02-12 14:18:49 +00002070
2071 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2072 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2073 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
2074
2075 return ST;
2076}
2077
Justin Holewinskif8f70912013-06-28 17:57:59 +00002078SDNode *NVPTXDAGToDAGISel::SelectLoadParam(SDNode *Node) {
2079 SDValue Chain = Node->getOperand(0);
2080 SDValue Offset = Node->getOperand(2);
2081 SDValue Flag = Node->getOperand(3);
2082 SDLoc DL(Node);
2083 MemSDNode *Mem = cast<MemSDNode>(Node);
2084
2085 unsigned VecSize;
2086 switch (Node->getOpcode()) {
2087 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002088 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002089 case NVPTXISD::LoadParam:
2090 VecSize = 1;
2091 break;
2092 case NVPTXISD::LoadParamV2:
2093 VecSize = 2;
2094 break;
2095 case NVPTXISD::LoadParamV4:
2096 VecSize = 4;
2097 break;
2098 }
2099
2100 EVT EltVT = Node->getValueType(0);
2101 EVT MemVT = Mem->getMemoryVT();
2102
2103 unsigned Opc = 0;
2104
2105 switch (VecSize) {
2106 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002107 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002108 case 1:
2109 switch (MemVT.getSimpleVT().SimpleTy) {
2110 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002111 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002112 case MVT::i1:
2113 Opc = NVPTX::LoadParamMemI8;
2114 break;
2115 case MVT::i8:
2116 Opc = NVPTX::LoadParamMemI8;
2117 break;
2118 case MVT::i16:
2119 Opc = NVPTX::LoadParamMemI16;
2120 break;
2121 case MVT::i32:
2122 Opc = NVPTX::LoadParamMemI32;
2123 break;
2124 case MVT::i64:
2125 Opc = NVPTX::LoadParamMemI64;
2126 break;
2127 case MVT::f32:
2128 Opc = NVPTX::LoadParamMemF32;
2129 break;
2130 case MVT::f64:
2131 Opc = NVPTX::LoadParamMemF64;
2132 break;
2133 }
2134 break;
2135 case 2:
2136 switch (MemVT.getSimpleVT().SimpleTy) {
2137 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002138 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002139 case MVT::i1:
2140 Opc = NVPTX::LoadParamMemV2I8;
2141 break;
2142 case MVT::i8:
2143 Opc = NVPTX::LoadParamMemV2I8;
2144 break;
2145 case MVT::i16:
2146 Opc = NVPTX::LoadParamMemV2I16;
2147 break;
2148 case MVT::i32:
2149 Opc = NVPTX::LoadParamMemV2I32;
2150 break;
2151 case MVT::i64:
2152 Opc = NVPTX::LoadParamMemV2I64;
2153 break;
2154 case MVT::f32:
2155 Opc = NVPTX::LoadParamMemV2F32;
2156 break;
2157 case MVT::f64:
2158 Opc = NVPTX::LoadParamMemV2F64;
2159 break;
2160 }
2161 break;
2162 case 4:
2163 switch (MemVT.getSimpleVT().SimpleTy) {
2164 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002165 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002166 case MVT::i1:
2167 Opc = NVPTX::LoadParamMemV4I8;
2168 break;
2169 case MVT::i8:
2170 Opc = NVPTX::LoadParamMemV4I8;
2171 break;
2172 case MVT::i16:
2173 Opc = NVPTX::LoadParamMemV4I16;
2174 break;
2175 case MVT::i32:
2176 Opc = NVPTX::LoadParamMemV4I32;
2177 break;
2178 case MVT::f32:
2179 Opc = NVPTX::LoadParamMemV4F32;
2180 break;
2181 }
2182 break;
2183 }
2184
2185 SDVTList VTs;
2186 if (VecSize == 1) {
2187 VTs = CurDAG->getVTList(EltVT, MVT::Other, MVT::Glue);
2188 } else if (VecSize == 2) {
2189 VTs = CurDAG->getVTList(EltVT, EltVT, MVT::Other, MVT::Glue);
2190 } else {
2191 EVT EVTs[] = { EltVT, EltVT, EltVT, EltVT, MVT::Other, MVT::Glue };
Craig Topperabb4ac72014-04-16 06:10:51 +00002192 VTs = CurDAG->getVTList(EVTs);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002193 }
2194
2195 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2196
2197 SmallVector<SDValue, 2> Ops;
2198 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2199 Ops.push_back(Chain);
2200 Ops.push_back(Flag);
2201
2202 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002203 CurDAG->getMachineNode(Opc, DL, VTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002204 return Ret;
2205}
2206
2207SDNode *NVPTXDAGToDAGISel::SelectStoreRetval(SDNode *N) {
2208 SDLoc DL(N);
2209 SDValue Chain = N->getOperand(0);
2210 SDValue Offset = N->getOperand(1);
2211 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2212 MemSDNode *Mem = cast<MemSDNode>(N);
2213
2214 // How many elements do we have?
2215 unsigned NumElts = 1;
2216 switch (N->getOpcode()) {
2217 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002218 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002219 case NVPTXISD::StoreRetval:
2220 NumElts = 1;
2221 break;
2222 case NVPTXISD::StoreRetvalV2:
2223 NumElts = 2;
2224 break;
2225 case NVPTXISD::StoreRetvalV4:
2226 NumElts = 4;
2227 break;
2228 }
2229
2230 // Build vector of operands
2231 SmallVector<SDValue, 6> Ops;
2232 for (unsigned i = 0; i < NumElts; ++i)
2233 Ops.push_back(N->getOperand(i + 2));
2234 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2235 Ops.push_back(Chain);
2236
2237 // Determine target opcode
2238 // If we have an i1, use an 8-bit store. The lowering code in
2239 // NVPTXISelLowering will have already emitted an upcast.
2240 unsigned Opcode = 0;
2241 switch (NumElts) {
2242 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002243 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002244 case 1:
2245 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2246 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002247 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002248 case MVT::i1:
2249 Opcode = NVPTX::StoreRetvalI8;
2250 break;
2251 case MVT::i8:
2252 Opcode = NVPTX::StoreRetvalI8;
2253 break;
2254 case MVT::i16:
2255 Opcode = NVPTX::StoreRetvalI16;
2256 break;
2257 case MVT::i32:
2258 Opcode = NVPTX::StoreRetvalI32;
2259 break;
2260 case MVT::i64:
2261 Opcode = NVPTX::StoreRetvalI64;
2262 break;
2263 case MVT::f32:
2264 Opcode = NVPTX::StoreRetvalF32;
2265 break;
2266 case MVT::f64:
2267 Opcode = NVPTX::StoreRetvalF64;
2268 break;
2269 }
2270 break;
2271 case 2:
2272 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2273 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002274 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002275 case MVT::i1:
2276 Opcode = NVPTX::StoreRetvalV2I8;
2277 break;
2278 case MVT::i8:
2279 Opcode = NVPTX::StoreRetvalV2I8;
2280 break;
2281 case MVT::i16:
2282 Opcode = NVPTX::StoreRetvalV2I16;
2283 break;
2284 case MVT::i32:
2285 Opcode = NVPTX::StoreRetvalV2I32;
2286 break;
2287 case MVT::i64:
2288 Opcode = NVPTX::StoreRetvalV2I64;
2289 break;
2290 case MVT::f32:
2291 Opcode = NVPTX::StoreRetvalV2F32;
2292 break;
2293 case MVT::f64:
2294 Opcode = NVPTX::StoreRetvalV2F64;
2295 break;
2296 }
2297 break;
2298 case 4:
2299 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2300 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002301 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002302 case MVT::i1:
2303 Opcode = NVPTX::StoreRetvalV4I8;
2304 break;
2305 case MVT::i8:
2306 Opcode = NVPTX::StoreRetvalV4I8;
2307 break;
2308 case MVT::i16:
2309 Opcode = NVPTX::StoreRetvalV4I16;
2310 break;
2311 case MVT::i32:
2312 Opcode = NVPTX::StoreRetvalV4I32;
2313 break;
2314 case MVT::f32:
2315 Opcode = NVPTX::StoreRetvalV4F32;
2316 break;
2317 }
2318 break;
2319 }
2320
2321 SDNode *Ret =
2322 CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops);
2323 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2324 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2325 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2326
2327 return Ret;
2328}
2329
2330SDNode *NVPTXDAGToDAGISel::SelectStoreParam(SDNode *N) {
2331 SDLoc DL(N);
2332 SDValue Chain = N->getOperand(0);
2333 SDValue Param = N->getOperand(1);
2334 unsigned ParamVal = cast<ConstantSDNode>(Param)->getZExtValue();
2335 SDValue Offset = N->getOperand(2);
2336 unsigned OffsetVal = cast<ConstantSDNode>(Offset)->getZExtValue();
2337 MemSDNode *Mem = cast<MemSDNode>(N);
2338 SDValue Flag = N->getOperand(N->getNumOperands() - 1);
2339
2340 // How many elements do we have?
2341 unsigned NumElts = 1;
2342 switch (N->getOpcode()) {
2343 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002344 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002345 case NVPTXISD::StoreParamU32:
2346 case NVPTXISD::StoreParamS32:
2347 case NVPTXISD::StoreParam:
2348 NumElts = 1;
2349 break;
2350 case NVPTXISD::StoreParamV2:
2351 NumElts = 2;
2352 break;
2353 case NVPTXISD::StoreParamV4:
2354 NumElts = 4;
2355 break;
2356 }
2357
2358 // Build vector of operands
2359 SmallVector<SDValue, 8> Ops;
2360 for (unsigned i = 0; i < NumElts; ++i)
2361 Ops.push_back(N->getOperand(i + 3));
2362 Ops.push_back(CurDAG->getTargetConstant(ParamVal, MVT::i32));
2363 Ops.push_back(CurDAG->getTargetConstant(OffsetVal, MVT::i32));
2364 Ops.push_back(Chain);
2365 Ops.push_back(Flag);
2366
2367 // Determine target opcode
2368 // If we have an i1, use an 8-bit store. The lowering code in
2369 // NVPTXISelLowering will have already emitted an upcast.
2370 unsigned Opcode = 0;
2371 switch (N->getOpcode()) {
2372 default:
2373 switch (NumElts) {
2374 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002375 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002376 case 1:
2377 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2378 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002379 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002380 case MVT::i1:
2381 Opcode = NVPTX::StoreParamI8;
2382 break;
2383 case MVT::i8:
2384 Opcode = NVPTX::StoreParamI8;
2385 break;
2386 case MVT::i16:
2387 Opcode = NVPTX::StoreParamI16;
2388 break;
2389 case MVT::i32:
2390 Opcode = NVPTX::StoreParamI32;
2391 break;
2392 case MVT::i64:
2393 Opcode = NVPTX::StoreParamI64;
2394 break;
2395 case MVT::f32:
2396 Opcode = NVPTX::StoreParamF32;
2397 break;
2398 case MVT::f64:
2399 Opcode = NVPTX::StoreParamF64;
2400 break;
2401 }
2402 break;
2403 case 2:
2404 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2405 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002406 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002407 case MVT::i1:
2408 Opcode = NVPTX::StoreParamV2I8;
2409 break;
2410 case MVT::i8:
2411 Opcode = NVPTX::StoreParamV2I8;
2412 break;
2413 case MVT::i16:
2414 Opcode = NVPTX::StoreParamV2I16;
2415 break;
2416 case MVT::i32:
2417 Opcode = NVPTX::StoreParamV2I32;
2418 break;
2419 case MVT::i64:
2420 Opcode = NVPTX::StoreParamV2I64;
2421 break;
2422 case MVT::f32:
2423 Opcode = NVPTX::StoreParamV2F32;
2424 break;
2425 case MVT::f64:
2426 Opcode = NVPTX::StoreParamV2F64;
2427 break;
2428 }
2429 break;
2430 case 4:
2431 switch (Mem->getMemoryVT().getSimpleVT().SimpleTy) {
2432 default:
Craig Topper062a2ba2014-04-25 05:30:21 +00002433 return nullptr;
Justin Holewinskif8f70912013-06-28 17:57:59 +00002434 case MVT::i1:
2435 Opcode = NVPTX::StoreParamV4I8;
2436 break;
2437 case MVT::i8:
2438 Opcode = NVPTX::StoreParamV4I8;
2439 break;
2440 case MVT::i16:
2441 Opcode = NVPTX::StoreParamV4I16;
2442 break;
2443 case MVT::i32:
2444 Opcode = NVPTX::StoreParamV4I32;
2445 break;
2446 case MVT::f32:
2447 Opcode = NVPTX::StoreParamV4F32;
2448 break;
2449 }
2450 break;
2451 }
2452 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002453 // Special case: if we have a sign-extend/zero-extend node, insert the
2454 // conversion instruction first, and use that as the value operand to
2455 // the selected StoreParam node.
2456 case NVPTXISD::StoreParamU32: {
2457 Opcode = NVPTX::StoreParamI32;
2458 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2459 MVT::i32);
2460 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_u32_u16, DL,
2461 MVT::i32, Ops[0], CvtNone);
2462 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002463 break;
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002464 }
2465 case NVPTXISD::StoreParamS32: {
2466 Opcode = NVPTX::StoreParamI32;
2467 SDValue CvtNone = CurDAG->getTargetConstant(NVPTX::PTXCvtMode::NONE,
2468 MVT::i32);
2469 SDNode *Cvt = CurDAG->getMachineNode(NVPTX::CVT_s32_s16, DL,
2470 MVT::i32, Ops[0], CvtNone);
2471 Ops[0] = SDValue(Cvt, 0);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002472 break;
2473 }
Justin Holewinskidc5e3b62013-06-28 17:58:04 +00002474 }
Justin Holewinskif8f70912013-06-28 17:57:59 +00002475
Justin Holewinskidff28d22013-07-01 12:59:01 +00002476 SDVTList RetVTs = CurDAG->getVTList(MVT::Other, MVT::Glue);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002477 SDNode *Ret =
Justin Holewinskidff28d22013-07-01 12:59:01 +00002478 CurDAG->getMachineNode(Opcode, DL, RetVTs, Ops);
Justin Holewinskif8f70912013-06-28 17:57:59 +00002479 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
2480 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
2481 cast<MachineSDNode>(Ret)->setMemRefs(MemRefs0, MemRefs0 + 1);
2482
2483 return Ret;
2484}
2485
Justin Holewinski30d56a72014-04-09 15:39:15 +00002486SDNode *NVPTXDAGToDAGISel::SelectTextureIntrinsic(SDNode *N) {
2487 SDValue Chain = N->getOperand(0);
2488 SDValue TexRef = N->getOperand(1);
2489 SDValue SampRef = N->getOperand(2);
Craig Topper062a2ba2014-04-25 05:30:21 +00002490 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002491 unsigned Opc = 0;
2492 SmallVector<SDValue, 8> Ops;
2493
2494 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002495 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002496 case NVPTXISD::Tex1DFloatI32:
2497 Opc = NVPTX::TEX_1D_F32_I32;
2498 break;
2499 case NVPTXISD::Tex1DFloatFloat:
2500 Opc = NVPTX::TEX_1D_F32_F32;
2501 break;
2502 case NVPTXISD::Tex1DFloatFloatLevel:
2503 Opc = NVPTX::TEX_1D_F32_F32_LEVEL;
2504 break;
2505 case NVPTXISD::Tex1DFloatFloatGrad:
2506 Opc = NVPTX::TEX_1D_F32_F32_GRAD;
2507 break;
2508 case NVPTXISD::Tex1DI32I32:
2509 Opc = NVPTX::TEX_1D_I32_I32;
2510 break;
2511 case NVPTXISD::Tex1DI32Float:
2512 Opc = NVPTX::TEX_1D_I32_F32;
2513 break;
2514 case NVPTXISD::Tex1DI32FloatLevel:
2515 Opc = NVPTX::TEX_1D_I32_F32_LEVEL;
2516 break;
2517 case NVPTXISD::Tex1DI32FloatGrad:
2518 Opc = NVPTX::TEX_1D_I32_F32_GRAD;
2519 break;
2520 case NVPTXISD::Tex1DArrayFloatI32:
2521 Opc = NVPTX::TEX_1D_ARRAY_F32_I32;
2522 break;
2523 case NVPTXISD::Tex1DArrayFloatFloat:
2524 Opc = NVPTX::TEX_1D_ARRAY_F32_F32;
2525 break;
2526 case NVPTXISD::Tex1DArrayFloatFloatLevel:
2527 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_LEVEL;
2528 break;
2529 case NVPTXISD::Tex1DArrayFloatFloatGrad:
2530 Opc = NVPTX::TEX_1D_ARRAY_F32_F32_GRAD;
2531 break;
2532 case NVPTXISD::Tex1DArrayI32I32:
2533 Opc = NVPTX::TEX_1D_ARRAY_I32_I32;
2534 break;
2535 case NVPTXISD::Tex1DArrayI32Float:
2536 Opc = NVPTX::TEX_1D_ARRAY_I32_F32;
2537 break;
2538 case NVPTXISD::Tex1DArrayI32FloatLevel:
2539 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_LEVEL;
2540 break;
2541 case NVPTXISD::Tex1DArrayI32FloatGrad:
2542 Opc = NVPTX::TEX_1D_ARRAY_I32_F32_GRAD;
2543 break;
2544 case NVPTXISD::Tex2DFloatI32:
2545 Opc = NVPTX::TEX_2D_F32_I32;
2546 break;
2547 case NVPTXISD::Tex2DFloatFloat:
2548 Opc = NVPTX::TEX_2D_F32_F32;
2549 break;
2550 case NVPTXISD::Tex2DFloatFloatLevel:
2551 Opc = NVPTX::TEX_2D_F32_F32_LEVEL;
2552 break;
2553 case NVPTXISD::Tex2DFloatFloatGrad:
2554 Opc = NVPTX::TEX_2D_F32_F32_GRAD;
2555 break;
2556 case NVPTXISD::Tex2DI32I32:
2557 Opc = NVPTX::TEX_2D_I32_I32;
2558 break;
2559 case NVPTXISD::Tex2DI32Float:
2560 Opc = NVPTX::TEX_2D_I32_F32;
2561 break;
2562 case NVPTXISD::Tex2DI32FloatLevel:
2563 Opc = NVPTX::TEX_2D_I32_F32_LEVEL;
2564 break;
2565 case NVPTXISD::Tex2DI32FloatGrad:
2566 Opc = NVPTX::TEX_2D_I32_F32_GRAD;
2567 break;
2568 case NVPTXISD::Tex2DArrayFloatI32:
2569 Opc = NVPTX::TEX_2D_ARRAY_F32_I32;
2570 break;
2571 case NVPTXISD::Tex2DArrayFloatFloat:
2572 Opc = NVPTX::TEX_2D_ARRAY_F32_F32;
2573 break;
2574 case NVPTXISD::Tex2DArrayFloatFloatLevel:
2575 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_LEVEL;
2576 break;
2577 case NVPTXISD::Tex2DArrayFloatFloatGrad:
2578 Opc = NVPTX::TEX_2D_ARRAY_F32_F32_GRAD;
2579 break;
2580 case NVPTXISD::Tex2DArrayI32I32:
2581 Opc = NVPTX::TEX_2D_ARRAY_I32_I32;
2582 break;
2583 case NVPTXISD::Tex2DArrayI32Float:
2584 Opc = NVPTX::TEX_2D_ARRAY_I32_F32;
2585 break;
2586 case NVPTXISD::Tex2DArrayI32FloatLevel:
2587 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_LEVEL;
2588 break;
2589 case NVPTXISD::Tex2DArrayI32FloatGrad:
2590 Opc = NVPTX::TEX_2D_ARRAY_I32_F32_GRAD;
2591 break;
2592 case NVPTXISD::Tex3DFloatI32:
2593 Opc = NVPTX::TEX_3D_F32_I32;
2594 break;
2595 case NVPTXISD::Tex3DFloatFloat:
2596 Opc = NVPTX::TEX_3D_F32_F32;
2597 break;
2598 case NVPTXISD::Tex3DFloatFloatLevel:
2599 Opc = NVPTX::TEX_3D_F32_F32_LEVEL;
2600 break;
2601 case NVPTXISD::Tex3DFloatFloatGrad:
2602 Opc = NVPTX::TEX_3D_F32_F32_GRAD;
2603 break;
2604 case NVPTXISD::Tex3DI32I32:
2605 Opc = NVPTX::TEX_3D_I32_I32;
2606 break;
2607 case NVPTXISD::Tex3DI32Float:
2608 Opc = NVPTX::TEX_3D_I32_F32;
2609 break;
2610 case NVPTXISD::Tex3DI32FloatLevel:
2611 Opc = NVPTX::TEX_3D_I32_F32_LEVEL;
2612 break;
2613 case NVPTXISD::Tex3DI32FloatGrad:
2614 Opc = NVPTX::TEX_3D_I32_F32_GRAD;
2615 break;
2616 }
2617
2618 Ops.push_back(TexRef);
2619 Ops.push_back(SampRef);
2620
2621 // Copy over indices
2622 for (unsigned i = 3; i < N->getNumOperands(); ++i) {
2623 Ops.push_back(N->getOperand(i));
2624 }
2625
2626 Ops.push_back(Chain);
2627 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2628 return Ret;
2629}
2630
2631SDNode *NVPTXDAGToDAGISel::SelectSurfaceIntrinsic(SDNode *N) {
2632 SDValue Chain = N->getOperand(0);
2633 SDValue TexHandle = N->getOperand(1);
Craig Topper062a2ba2014-04-25 05:30:21 +00002634 SDNode *Ret = nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002635 unsigned Opc = 0;
2636 SmallVector<SDValue, 8> Ops;
2637 switch (N->getOpcode()) {
Craig Topper062a2ba2014-04-25 05:30:21 +00002638 default: return nullptr;
Justin Holewinski30d56a72014-04-09 15:39:15 +00002639 case NVPTXISD::Suld1DI8Trap:
2640 Opc = NVPTX::SULD_1D_I8_TRAP;
2641 Ops.push_back(TexHandle);
2642 Ops.push_back(N->getOperand(2));
2643 Ops.push_back(Chain);
2644 break;
2645 case NVPTXISD::Suld1DI16Trap:
2646 Opc = NVPTX::SULD_1D_I16_TRAP;
2647 Ops.push_back(TexHandle);
2648 Ops.push_back(N->getOperand(2));
2649 Ops.push_back(Chain);
2650 break;
2651 case NVPTXISD::Suld1DI32Trap:
2652 Opc = NVPTX::SULD_1D_I32_TRAP;
2653 Ops.push_back(TexHandle);
2654 Ops.push_back(N->getOperand(2));
2655 Ops.push_back(Chain);
2656 break;
2657 case NVPTXISD::Suld1DV2I8Trap:
2658 Opc = NVPTX::SULD_1D_V2I8_TRAP;
2659 Ops.push_back(TexHandle);
2660 Ops.push_back(N->getOperand(2));
2661 Ops.push_back(Chain);
2662 break;
2663 case NVPTXISD::Suld1DV2I16Trap:
2664 Opc = NVPTX::SULD_1D_V2I16_TRAP;
2665 Ops.push_back(TexHandle);
2666 Ops.push_back(N->getOperand(2));
2667 Ops.push_back(Chain);
2668 break;
2669 case NVPTXISD::Suld1DV2I32Trap:
2670 Opc = NVPTX::SULD_1D_V2I32_TRAP;
2671 Ops.push_back(TexHandle);
2672 Ops.push_back(N->getOperand(2));
2673 Ops.push_back(Chain);
2674 break;
2675 case NVPTXISD::Suld1DV4I8Trap:
2676 Opc = NVPTX::SULD_1D_V4I8_TRAP;
2677 Ops.push_back(TexHandle);
2678 Ops.push_back(N->getOperand(2));
2679 Ops.push_back(Chain);
2680 break;
2681 case NVPTXISD::Suld1DV4I16Trap:
2682 Opc = NVPTX::SULD_1D_V4I16_TRAP;
2683 Ops.push_back(TexHandle);
2684 Ops.push_back(N->getOperand(2));
2685 Ops.push_back(Chain);
2686 break;
2687 case NVPTXISD::Suld1DV4I32Trap:
2688 Opc = NVPTX::SULD_1D_V4I32_TRAP;
2689 Ops.push_back(TexHandle);
2690 Ops.push_back(N->getOperand(2));
2691 Ops.push_back(Chain);
2692 break;
2693 case NVPTXISD::Suld1DArrayI8Trap:
2694 Opc = NVPTX::SULD_1D_ARRAY_I8_TRAP;
2695 Ops.push_back(TexHandle);
2696 Ops.push_back(N->getOperand(2));
2697 Ops.push_back(N->getOperand(3));
2698 Ops.push_back(Chain);
2699 break;
2700 case NVPTXISD::Suld1DArrayI16Trap:
2701 Opc = NVPTX::SULD_1D_ARRAY_I16_TRAP;
2702 Ops.push_back(TexHandle);
2703 Ops.push_back(N->getOperand(2));
2704 Ops.push_back(N->getOperand(3));
2705 Ops.push_back(Chain);
2706 break;
2707 case NVPTXISD::Suld1DArrayI32Trap:
2708 Opc = NVPTX::SULD_1D_ARRAY_I32_TRAP;
2709 Ops.push_back(TexHandle);
2710 Ops.push_back(N->getOperand(2));
2711 Ops.push_back(N->getOperand(3));
2712 Ops.push_back(Chain);
2713 break;
2714 case NVPTXISD::Suld1DArrayV2I8Trap:
2715 Opc = NVPTX::SULD_1D_ARRAY_V2I8_TRAP;
2716 Ops.push_back(TexHandle);
2717 Ops.push_back(N->getOperand(2));
2718 Ops.push_back(N->getOperand(3));
2719 Ops.push_back(Chain);
2720 break;
2721 case NVPTXISD::Suld1DArrayV2I16Trap:
2722 Opc = NVPTX::SULD_1D_ARRAY_V2I16_TRAP;
2723 Ops.push_back(TexHandle);
2724 Ops.push_back(N->getOperand(2));
2725 Ops.push_back(N->getOperand(3));
2726 Ops.push_back(Chain);
2727 break;
2728 case NVPTXISD::Suld1DArrayV2I32Trap:
2729 Opc = NVPTX::SULD_1D_ARRAY_V2I32_TRAP;
2730 Ops.push_back(TexHandle);
2731 Ops.push_back(N->getOperand(2));
2732 Ops.push_back(N->getOperand(3));
2733 Ops.push_back(Chain);
2734 break;
2735 case NVPTXISD::Suld1DArrayV4I8Trap:
2736 Opc = NVPTX::SULD_1D_ARRAY_V4I8_TRAP;
2737 Ops.push_back(TexHandle);
2738 Ops.push_back(N->getOperand(2));
2739 Ops.push_back(N->getOperand(3));
2740 Ops.push_back(Chain);
2741 break;
2742 case NVPTXISD::Suld1DArrayV4I16Trap:
2743 Opc = NVPTX::SULD_1D_ARRAY_V4I16_TRAP;
2744 Ops.push_back(TexHandle);
2745 Ops.push_back(N->getOperand(2));
2746 Ops.push_back(N->getOperand(3));
2747 Ops.push_back(Chain);
2748 break;
2749 case NVPTXISD::Suld1DArrayV4I32Trap:
2750 Opc = NVPTX::SULD_1D_ARRAY_V4I32_TRAP;
2751 Ops.push_back(TexHandle);
2752 Ops.push_back(N->getOperand(2));
2753 Ops.push_back(N->getOperand(3));
2754 Ops.push_back(Chain);
2755 break;
2756 case NVPTXISD::Suld2DI8Trap:
2757 Opc = NVPTX::SULD_2D_I8_TRAP;
2758 Ops.push_back(TexHandle);
2759 Ops.push_back(N->getOperand(2));
2760 Ops.push_back(N->getOperand(3));
2761 Ops.push_back(Chain);
2762 break;
2763 case NVPTXISD::Suld2DI16Trap:
2764 Opc = NVPTX::SULD_2D_I16_TRAP;
2765 Ops.push_back(TexHandle);
2766 Ops.push_back(N->getOperand(2));
2767 Ops.push_back(N->getOperand(3));
2768 Ops.push_back(Chain);
2769 break;
2770 case NVPTXISD::Suld2DI32Trap:
2771 Opc = NVPTX::SULD_2D_I32_TRAP;
2772 Ops.push_back(TexHandle);
2773 Ops.push_back(N->getOperand(2));
2774 Ops.push_back(N->getOperand(3));
2775 Ops.push_back(Chain);
2776 break;
2777 case NVPTXISD::Suld2DV2I8Trap:
2778 Opc = NVPTX::SULD_2D_V2I8_TRAP;
2779 Ops.push_back(TexHandle);
2780 Ops.push_back(N->getOperand(2));
2781 Ops.push_back(N->getOperand(3));
2782 Ops.push_back(Chain);
2783 break;
2784 case NVPTXISD::Suld2DV2I16Trap:
2785 Opc = NVPTX::SULD_2D_V2I16_TRAP;
2786 Ops.push_back(TexHandle);
2787 Ops.push_back(N->getOperand(2));
2788 Ops.push_back(N->getOperand(3));
2789 Ops.push_back(Chain);
2790 break;
2791 case NVPTXISD::Suld2DV2I32Trap:
2792 Opc = NVPTX::SULD_2D_V2I32_TRAP;
2793 Ops.push_back(TexHandle);
2794 Ops.push_back(N->getOperand(2));
2795 Ops.push_back(N->getOperand(3));
2796 Ops.push_back(Chain);
2797 break;
2798 case NVPTXISD::Suld2DV4I8Trap:
2799 Opc = NVPTX::SULD_2D_V4I8_TRAP;
2800 Ops.push_back(TexHandle);
2801 Ops.push_back(N->getOperand(2));
2802 Ops.push_back(N->getOperand(3));
2803 Ops.push_back(Chain);
2804 break;
2805 case NVPTXISD::Suld2DV4I16Trap:
2806 Opc = NVPTX::SULD_2D_V4I16_TRAP;
2807 Ops.push_back(TexHandle);
2808 Ops.push_back(N->getOperand(2));
2809 Ops.push_back(N->getOperand(3));
2810 Ops.push_back(Chain);
2811 break;
2812 case NVPTXISD::Suld2DV4I32Trap:
2813 Opc = NVPTX::SULD_2D_V4I32_TRAP;
2814 Ops.push_back(TexHandle);
2815 Ops.push_back(N->getOperand(2));
2816 Ops.push_back(N->getOperand(3));
2817 Ops.push_back(Chain);
2818 break;
2819 case NVPTXISD::Suld2DArrayI8Trap:
2820 Opc = NVPTX::SULD_2D_ARRAY_I8_TRAP;
2821 Ops.push_back(TexHandle);
2822 Ops.push_back(N->getOperand(2));
2823 Ops.push_back(N->getOperand(3));
2824 Ops.push_back(N->getOperand(4));
2825 Ops.push_back(Chain);
2826 break;
2827 case NVPTXISD::Suld2DArrayI16Trap:
2828 Opc = NVPTX::SULD_2D_ARRAY_I16_TRAP;
2829 Ops.push_back(TexHandle);
2830 Ops.push_back(N->getOperand(2));
2831 Ops.push_back(N->getOperand(3));
2832 Ops.push_back(N->getOperand(4));
2833 Ops.push_back(Chain);
2834 break;
2835 case NVPTXISD::Suld2DArrayI32Trap:
2836 Opc = NVPTX::SULD_2D_ARRAY_I32_TRAP;
2837 Ops.push_back(TexHandle);
2838 Ops.push_back(N->getOperand(2));
2839 Ops.push_back(N->getOperand(3));
2840 Ops.push_back(N->getOperand(4));
2841 Ops.push_back(Chain);
2842 break;
2843 case NVPTXISD::Suld2DArrayV2I8Trap:
2844 Opc = NVPTX::SULD_2D_ARRAY_V2I8_TRAP;
2845 Ops.push_back(TexHandle);
2846 Ops.push_back(N->getOperand(2));
2847 Ops.push_back(N->getOperand(3));
2848 Ops.push_back(N->getOperand(4));
2849 Ops.push_back(Chain);
2850 break;
2851 case NVPTXISD::Suld2DArrayV2I16Trap:
2852 Opc = NVPTX::SULD_2D_ARRAY_V2I16_TRAP;
2853 Ops.push_back(TexHandle);
2854 Ops.push_back(N->getOperand(2));
2855 Ops.push_back(N->getOperand(3));
2856 Ops.push_back(N->getOperand(4));
2857 Ops.push_back(Chain);
2858 break;
2859 case NVPTXISD::Suld2DArrayV2I32Trap:
2860 Opc = NVPTX::SULD_2D_ARRAY_V2I32_TRAP;
2861 Ops.push_back(TexHandle);
2862 Ops.push_back(N->getOperand(2));
2863 Ops.push_back(N->getOperand(3));
2864 Ops.push_back(N->getOperand(4));
2865 Ops.push_back(Chain);
2866 break;
2867 case NVPTXISD::Suld2DArrayV4I8Trap:
2868 Opc = NVPTX::SULD_2D_ARRAY_V4I8_TRAP;
2869 Ops.push_back(TexHandle);
2870 Ops.push_back(N->getOperand(2));
2871 Ops.push_back(N->getOperand(3));
2872 Ops.push_back(N->getOperand(4));
2873 Ops.push_back(Chain);
2874 break;
2875 case NVPTXISD::Suld2DArrayV4I16Trap:
2876 Opc = NVPTX::SULD_2D_ARRAY_V4I16_TRAP;
2877 Ops.push_back(TexHandle);
2878 Ops.push_back(N->getOperand(2));
2879 Ops.push_back(N->getOperand(3));
2880 Ops.push_back(N->getOperand(4));
2881 Ops.push_back(Chain);
2882 break;
2883 case NVPTXISD::Suld2DArrayV4I32Trap:
2884 Opc = NVPTX::SULD_2D_ARRAY_V4I32_TRAP;
2885 Ops.push_back(TexHandle);
2886 Ops.push_back(N->getOperand(2));
2887 Ops.push_back(N->getOperand(3));
2888 Ops.push_back(N->getOperand(4));
2889 Ops.push_back(Chain);
2890 break;
2891 case NVPTXISD::Suld3DI8Trap:
2892 Opc = NVPTX::SULD_3D_I8_TRAP;
2893 Ops.push_back(TexHandle);
2894 Ops.push_back(N->getOperand(2));
2895 Ops.push_back(N->getOperand(3));
2896 Ops.push_back(N->getOperand(4));
2897 Ops.push_back(Chain);
2898 break;
2899 case NVPTXISD::Suld3DI16Trap:
2900 Opc = NVPTX::SULD_3D_I16_TRAP;
2901 Ops.push_back(TexHandle);
2902 Ops.push_back(N->getOperand(2));
2903 Ops.push_back(N->getOperand(3));
2904 Ops.push_back(N->getOperand(4));
2905 Ops.push_back(Chain);
2906 break;
2907 case NVPTXISD::Suld3DI32Trap:
2908 Opc = NVPTX::SULD_3D_I32_TRAP;
2909 Ops.push_back(TexHandle);
2910 Ops.push_back(N->getOperand(2));
2911 Ops.push_back(N->getOperand(3));
2912 Ops.push_back(N->getOperand(4));
2913 Ops.push_back(Chain);
2914 break;
2915 case NVPTXISD::Suld3DV2I8Trap:
2916 Opc = NVPTX::SULD_3D_V2I8_TRAP;
2917 Ops.push_back(TexHandle);
2918 Ops.push_back(N->getOperand(2));
2919 Ops.push_back(N->getOperand(3));
2920 Ops.push_back(N->getOperand(4));
2921 Ops.push_back(Chain);
2922 break;
2923 case NVPTXISD::Suld3DV2I16Trap:
2924 Opc = NVPTX::SULD_3D_V2I16_TRAP;
2925 Ops.push_back(TexHandle);
2926 Ops.push_back(N->getOperand(2));
2927 Ops.push_back(N->getOperand(3));
2928 Ops.push_back(N->getOperand(4));
2929 Ops.push_back(Chain);
2930 break;
2931 case NVPTXISD::Suld3DV2I32Trap:
2932 Opc = NVPTX::SULD_3D_V2I32_TRAP;
2933 Ops.push_back(TexHandle);
2934 Ops.push_back(N->getOperand(2));
2935 Ops.push_back(N->getOperand(3));
2936 Ops.push_back(N->getOperand(4));
2937 Ops.push_back(Chain);
2938 break;
2939 case NVPTXISD::Suld3DV4I8Trap:
2940 Opc = NVPTX::SULD_3D_V4I8_TRAP;
2941 Ops.push_back(TexHandle);
2942 Ops.push_back(N->getOperand(2));
2943 Ops.push_back(N->getOperand(3));
2944 Ops.push_back(N->getOperand(4));
2945 Ops.push_back(Chain);
2946 break;
2947 case NVPTXISD::Suld3DV4I16Trap:
2948 Opc = NVPTX::SULD_3D_V4I16_TRAP;
2949 Ops.push_back(TexHandle);
2950 Ops.push_back(N->getOperand(2));
2951 Ops.push_back(N->getOperand(3));
2952 Ops.push_back(N->getOperand(4));
2953 Ops.push_back(Chain);
2954 break;
2955 case NVPTXISD::Suld3DV4I32Trap:
2956 Opc = NVPTX::SULD_3D_V4I32_TRAP;
2957 Ops.push_back(TexHandle);
2958 Ops.push_back(N->getOperand(2));
2959 Ops.push_back(N->getOperand(3));
2960 Ops.push_back(N->getOperand(4));
2961 Ops.push_back(Chain);
2962 break;
2963 }
2964 Ret = CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
2965 return Ret;
2966}
2967
Justin Holewinskica7a4f12014-06-27 18:35:27 +00002968/// SelectBFE - Look for instruction sequences that can be made more efficient
2969/// by using the 'bfe' (bit-field extract) PTX instruction
2970SDNode *NVPTXDAGToDAGISel::SelectBFE(SDNode *N) {
2971 SDValue LHS = N->getOperand(0);
2972 SDValue RHS = N->getOperand(1);
2973 SDValue Len;
2974 SDValue Start;
2975 SDValue Val;
2976 bool IsSigned = false;
2977
2978 if (N->getOpcode() == ISD::AND) {
2979 // Canonicalize the operands
2980 // We want 'and %val, %mask'
2981 if (isa<ConstantSDNode>(LHS) && !isa<ConstantSDNode>(RHS)) {
2982 std::swap(LHS, RHS);
2983 }
2984
2985 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(RHS);
2986 if (!Mask) {
2987 // We need a constant mask on the RHS of the AND
2988 return NULL;
2989 }
2990
2991 // Extract the mask bits
2992 uint64_t MaskVal = Mask->getZExtValue();
2993 if (!isMask_64(MaskVal)) {
2994 // We *could* handle shifted masks here, but doing so would require an
2995 // 'and' operation to fix up the low-order bits so we would trade
2996 // shr+and for bfe+and, which has the same throughput
2997 return NULL;
2998 }
2999
3000 // How many bits are in our mask?
3001 uint64_t NumBits = CountTrailingOnes_64(MaskVal);
3002 Len = CurDAG->getTargetConstant(NumBits, MVT::i32);
3003
3004 if (LHS.getOpcode() == ISD::SRL || LHS.getOpcode() == ISD::SRA) {
3005 // We have a 'srl/and' pair, extract the effective start bit and length
3006 Val = LHS.getNode()->getOperand(0);
3007 Start = LHS.getNode()->getOperand(1);
3008 ConstantSDNode *StartConst = dyn_cast<ConstantSDNode>(Start);
3009 if (StartConst) {
3010 uint64_t StartVal = StartConst->getZExtValue();
3011 // How many "good" bits do we have left? "good" is defined here as bits
3012 // that exist in the original value, not shifted in.
3013 uint64_t GoodBits = Start.getValueType().getSizeInBits() - StartVal;
3014 if (NumBits > GoodBits) {
3015 // Do not handle the case where bits have been shifted in. In theory
3016 // we could handle this, but the cost is likely higher than just
3017 // emitting the srl/and pair.
3018 return NULL;
3019 }
3020 Start = CurDAG->getTargetConstant(StartVal, MVT::i32);
3021 } else {
3022 // Do not handle the case where the shift amount (can be zero if no srl
3023 // was found) is not constant. We could handle this case, but it would
3024 // require run-time logic that would be more expensive than just
3025 // emitting the srl/and pair.
3026 return NULL;
3027 }
3028 } else {
3029 // Do not handle the case where the LHS of the and is not a shift. While
3030 // it would be trivial to handle this case, it would just transform
3031 // 'and' -> 'bfe', but 'and' has higher-throughput.
3032 return NULL;
3033 }
3034 } else if (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) {
3035 if (LHS->getOpcode() == ISD::AND) {
3036 ConstantSDNode *ShiftCnst = dyn_cast<ConstantSDNode>(RHS);
3037 if (!ShiftCnst) {
3038 // Shift amount must be constant
3039 return NULL;
3040 }
3041
3042 uint64_t ShiftAmt = ShiftCnst->getZExtValue();
3043
3044 SDValue AndLHS = LHS->getOperand(0);
3045 SDValue AndRHS = LHS->getOperand(1);
3046
3047 // Canonicalize the AND to have the mask on the RHS
3048 if (isa<ConstantSDNode>(AndLHS)) {
3049 std::swap(AndLHS, AndRHS);
3050 }
3051
3052 ConstantSDNode *MaskCnst = dyn_cast<ConstantSDNode>(AndRHS);
3053 if (!MaskCnst) {
3054 // Mask must be constant
3055 return NULL;
3056 }
3057
3058 uint64_t MaskVal = MaskCnst->getZExtValue();
3059 uint64_t NumZeros;
3060 uint64_t NumBits;
3061 if (isMask_64(MaskVal)) {
3062 NumZeros = 0;
3063 // The number of bits in the result bitfield will be the number of
3064 // trailing ones (the AND) minus the number of bits we shift off
3065 NumBits = CountTrailingOnes_64(MaskVal) - ShiftAmt;
3066 } else if (isShiftedMask_64(MaskVal)) {
3067 NumZeros = countTrailingZeros(MaskVal);
3068 unsigned NumOnes = CountTrailingOnes_64(MaskVal >> NumZeros);
3069 // The number of bits in the result bitfield will be the number of
3070 // trailing zeros plus the number of set bits in the mask minus the
3071 // number of bits we shift off
3072 NumBits = NumZeros + NumOnes - ShiftAmt;
3073 } else {
3074 // This is not a mask we can handle
3075 return NULL;
3076 }
3077
3078 if (ShiftAmt < NumZeros) {
3079 // Handling this case would require extra logic that would make this
3080 // transformation non-profitable
3081 return NULL;
3082 }
3083
3084 Val = AndLHS;
3085 Start = CurDAG->getTargetConstant(ShiftAmt, MVT::i32);
3086 Len = CurDAG->getTargetConstant(NumBits, MVT::i32);
3087 } else if (LHS->getOpcode() == ISD::SHL) {
3088 // Here, we have a pattern like:
3089 //
3090 // (sra (shl val, NN), MM)
3091 // or
3092 // (srl (shl val, NN), MM)
3093 //
3094 // If MM >= NN, we can efficiently optimize this with bfe
3095 Val = LHS->getOperand(0);
3096
3097 SDValue ShlRHS = LHS->getOperand(1);
3098 ConstantSDNode *ShlCnst = dyn_cast<ConstantSDNode>(ShlRHS);
3099 if (!ShlCnst) {
3100 // Shift amount must be constant
3101 return NULL;
3102 }
3103 uint64_t InnerShiftAmt = ShlCnst->getZExtValue();
3104
3105 SDValue ShrRHS = RHS;
3106 ConstantSDNode *ShrCnst = dyn_cast<ConstantSDNode>(ShrRHS);
3107 if (!ShrCnst) {
3108 // Shift amount must be constant
3109 return NULL;
3110 }
3111 uint64_t OuterShiftAmt = ShrCnst->getZExtValue();
3112
3113 // To avoid extra codegen and be profitable, we need Outer >= Inner
3114 if (OuterShiftAmt < InnerShiftAmt) {
3115 return NULL;
3116 }
3117
3118 // If the outer shift is more than the type size, we have no bitfield to
3119 // extract (since we also check that the inner shift is <= the outer shift
3120 // then this also implies that the inner shift is < the type size)
3121 if (OuterShiftAmt >= Val.getValueType().getSizeInBits()) {
3122 return NULL;
3123 }
3124
3125 Start =
3126 CurDAG->getTargetConstant(OuterShiftAmt - InnerShiftAmt, MVT::i32);
3127 Len =
3128 CurDAG->getTargetConstant(Val.getValueType().getSizeInBits() -
3129 OuterShiftAmt, MVT::i32);
3130
3131 if (N->getOpcode() == ISD::SRA) {
3132 // If we have a arithmetic right shift, we need to use the signed bfe
3133 // variant
3134 IsSigned = true;
3135 }
3136 } else {
3137 // No can do...
3138 return NULL;
3139 }
3140 } else {
3141 // No can do...
3142 return NULL;
3143 }
3144
3145
3146 unsigned Opc;
3147 // For the BFE operations we form here from "and" and "srl", always use the
3148 // unsigned variants.
3149 if (Val.getValueType() == MVT::i32) {
3150 if (IsSigned) {
3151 Opc = NVPTX::BFE_S32rii;
3152 } else {
3153 Opc = NVPTX::BFE_U32rii;
3154 }
3155 } else if (Val.getValueType() == MVT::i64) {
3156 if (IsSigned) {
3157 Opc = NVPTX::BFE_S64rii;
3158 } else {
3159 Opc = NVPTX::BFE_U64rii;
3160 }
3161 } else {
3162 // We cannot handle this type
3163 return NULL;
3164 }
3165
3166 SDValue Ops[] = {
3167 Val, Start, Len
3168 };
3169
3170 SDNode *Ret =
3171 CurDAG->getMachineNode(Opc, SDLoc(N), N->getVTList(), Ops);
3172
3173 return Ret;
3174}
3175
Justin Holewinskiae556d32012-05-04 20:18:50 +00003176// SelectDirectAddr - Match a direct address for DAG.
3177// A direct address could be a globaladdress or externalsymbol.
3178bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
3179 // Return true if TGA or ES.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003180 if (N.getOpcode() == ISD::TargetGlobalAddress ||
3181 N.getOpcode() == ISD::TargetExternalSymbol) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003182 Address = N;
3183 return true;
3184 }
3185 if (N.getOpcode() == NVPTXISD::Wrapper) {
3186 Address = N.getOperand(0);
3187 return true;
3188 }
3189 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
3190 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
3191 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
3192 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
3193 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
3194 }
3195 return false;
3196}
3197
3198// symbol+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003199bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
3200 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003201 if (Addr.getOpcode() == ISD::ADD) {
3202 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003203 SDValue base = Addr.getOperand(0);
Justin Holewinskiae556d32012-05-04 20:18:50 +00003204 if (SelectDirectAddr(base, Base)) {
3205 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3206 return true;
3207 }
3208 }
3209 }
3210 return false;
3211}
3212
3213// symbol+offset
3214bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
3215 SDValue &Base, SDValue &Offset) {
3216 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
3217}
3218
3219// symbol+offset
3220bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
3221 SDValue &Base, SDValue &Offset) {
3222 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
3223}
3224
3225// register+offset
Justin Holewinski0497ab12013-03-30 14:29:21 +00003226bool NVPTXDAGToDAGISel::SelectADDRri_imp(
3227 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003228 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
3229 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3230 Offset = CurDAG->getTargetConstant(0, mvt);
3231 return true;
3232 }
3233 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
3234 Addr.getOpcode() == ISD::TargetGlobalAddress)
Justin Holewinski0497ab12013-03-30 14:29:21 +00003235 return false; // direct calls.
Justin Holewinskiae556d32012-05-04 20:18:50 +00003236
3237 if (Addr.getOpcode() == ISD::ADD) {
3238 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
3239 return false;
3240 }
3241 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
3242 if (FrameIndexSDNode *FIN =
Justin Holewinski0497ab12013-03-30 14:29:21 +00003243 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
Justin Holewinskiae556d32012-05-04 20:18:50 +00003244 // Constant offset from frame ref.
3245 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
3246 else
3247 Base = Addr.getOperand(0);
3248 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
3249 return true;
3250 }
3251 }
3252 return false;
3253}
3254
3255// register+offset
3256bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
3257 SDValue &Base, SDValue &Offset) {
3258 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
3259}
3260
3261// register+offset
3262bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
3263 SDValue &Base, SDValue &Offset) {
3264 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
3265}
3266
3267bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
3268 unsigned int spN) const {
Craig Topper062a2ba2014-04-25 05:30:21 +00003269 const Value *Src = nullptr;
Justin Holewinskiae556d32012-05-04 20:18:50 +00003270 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
3271 // the classof() for MemSDNode does not include MemIntrinsicSDNode
3272 // (See SelectionDAGNodes.h). So we need to check for both.
3273 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003274 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3275 return true;
3276 Src = mN->getMemOperand()->getValue();
Justin Holewinski0497ab12013-03-30 14:29:21 +00003277 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
Nick Lewyckyaad475b2014-04-15 07:22:52 +00003278 if (spN == 0 && mN->getMemOperand()->getPseudoValue())
3279 return true;
3280 Src = mN->getMemOperand()->getValue();
Justin Holewinskiae556d32012-05-04 20:18:50 +00003281 }
3282 if (!Src)
3283 return false;
3284 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
3285 return (PT->getAddressSpace() == spN);
3286 return false;
3287}
3288
3289/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
3290/// inline asm expressions.
Justin Holewinski0497ab12013-03-30 14:29:21 +00003291bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
3292 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
Justin Holewinskiae556d32012-05-04 20:18:50 +00003293 SDValue Op0, Op1;
3294 switch (ConstraintCode) {
Justin Holewinski0497ab12013-03-30 14:29:21 +00003295 default:
3296 return true;
3297 case 'm': // memory
Justin Holewinskiae556d32012-05-04 20:18:50 +00003298 if (SelectDirectAddr(Op, Op0)) {
3299 OutOps.push_back(Op0);
3300 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
3301 return false;
3302 }
3303 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
3304 OutOps.push_back(Op0);
3305 OutOps.push_back(Op1);
3306 return false;
3307 }
3308 break;
3309 }
3310 return true;
3311}