1 //===-- NVPTXISelDAGToDAG.cpp - A dag to dag inst selector for NVPTX ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the NVPTX target.
12 //===----------------------------------------------------------------------===//
14 #include "NVPTXISelDAGToDAG.h"
15 #include "llvm/IR/GlobalValue.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/Target/TargetIntrinsicInfo.h"
24 #define DEBUG_TYPE "nvptx-isel"
28 static cl::opt<bool> UseFMADInstruction(
29 "nvptx-mad-enable", cl::ZeroOrMore,
30 cl::desc("NVPTX Specific: Enable generating FMAD instructions"),
34 FMAContractLevel("nvptx-fma-level", cl::ZeroOrMore,
35 cl::desc("NVPTX Specific: FMA contraction (0: don't do it"
36 " 1: do it 2: do it aggressively"),
39 static cl::opt<int> UsePrecDivF32(
40 "nvptx-prec-divf32", cl::ZeroOrMore,
41 cl::desc("NVPTX Specifies: 0 use div.approx, 1 use div.full, 2 use"
42 " IEEE Compliant F32 div.rnd if avaiable."),
46 UsePrecSqrtF32("nvptx-prec-sqrtf32",
47 cl::desc("NVPTX Specific: 0 use sqrt.approx, 1 use sqrt.rn."),
50 /// createNVPTXISelDag - This pass converts a legalized DAG into a
51 /// NVPTX-specific DAG, ready for instruction scheduling.
52 FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
53 llvm::CodeGenOpt::Level OptLevel) {
54 return new NVPTXDAGToDAGISel(TM, OptLevel);
57 NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
58 CodeGenOpt::Level OptLevel)
59 : SelectionDAGISel(tm, OptLevel),
60 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
61 // Always do fma.f32 fpcontract if the target supports the instruction.
62 // Always do fma.f64 fpcontract if the target supports the instruction.
63 // Do mad.f32 is nvptx-mad-enable is specified and the target does not
66 doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32();
67 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
68 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
70 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
72 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
74 allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction;
78 doMulWide = (OptLevel > 0);
80 // Decide how to translate f32 div
81 do_DIVF32_PREC = UsePrecDivF32;
82 // Decide how to translate f32 sqrt
83 do_SQRTF32_PREC = UsePrecSqrtF32;
84 // sm less than sm_20 does not support div.rnd. Use div.full.
85 if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
90 /// Select - Select instructions not customized! Used for
91 /// expanded, promoted and normal instructions.
92 SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
94 if (N->isMachineOpcode())
95 return NULL; // Already selected.
97 SDNode *ResNode = NULL;
98 switch (N->getOpcode()) {
100 ResNode = SelectLoad(N);
103 ResNode = SelectStore(N);
105 case NVPTXISD::LoadV2:
106 case NVPTXISD::LoadV4:
107 ResNode = SelectLoadVector(N);
109 case NVPTXISD::LDGV2:
110 case NVPTXISD::LDGV4:
111 case NVPTXISD::LDUV2:
112 case NVPTXISD::LDUV4:
113 ResNode = SelectLDGLDUVector(N);
115 case NVPTXISD::StoreV2:
116 case NVPTXISD::StoreV4:
117 ResNode = SelectStoreVector(N);
124 return SelectCode(N);
127 static unsigned int getCodeAddrSpace(MemSDNode *N,
128 const NVPTXSubtarget &Subtarget) {
129 const Value *Src = N->getSrcValue();
131 return NVPTX::PTXLdStInstCode::LOCAL;
133 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
134 switch (PT->getAddressSpace()) {
135 case llvm::ADDRESS_SPACE_LOCAL:
136 return NVPTX::PTXLdStInstCode::LOCAL;
137 case llvm::ADDRESS_SPACE_GLOBAL:
138 return NVPTX::PTXLdStInstCode::GLOBAL;
139 case llvm::ADDRESS_SPACE_SHARED:
140 return NVPTX::PTXLdStInstCode::SHARED;
141 case llvm::ADDRESS_SPACE_CONST_NOT_GEN:
142 return NVPTX::PTXLdStInstCode::CONSTANT;
143 case llvm::ADDRESS_SPACE_GENERIC:
144 return NVPTX::PTXLdStInstCode::GENERIC;
145 case llvm::ADDRESS_SPACE_PARAM:
146 return NVPTX::PTXLdStInstCode::PARAM;
147 case llvm::ADDRESS_SPACE_CONST:
148 // If the arch supports generic address space, translate it to GLOBAL
150 // If the arch does not support generic address space, then the arch
151 // does not really support ADDRESS_SPACE_CONST, translate it to
152 // to CONSTANT for better performance.
153 if (Subtarget.hasGenericLdSt())
154 return NVPTX::PTXLdStInstCode::GLOBAL;
156 return NVPTX::PTXLdStInstCode::CONSTANT;
161 return NVPTX::PTXLdStInstCode::LOCAL;
164 SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
165 DebugLoc dl = N->getDebugLoc();
166 LoadSDNode *LD = cast<LoadSDNode>(N);
167 EVT LoadedVT = LD->getMemoryVT();
168 SDNode *NVPTXLD = NULL;
170 // do not support pre/post inc/dec
174 if (!LoadedVT.isSimple())
177 // Address Space Setting
178 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
181 // - .volatile is only availalble for .global and .shared
182 bool isVolatile = LD->isVolatile();
183 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
184 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
185 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
189 MVT SimpleVT = LoadedVT.getSimpleVT();
190 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
191 if (SimpleVT.isVector()) {
192 unsigned num = SimpleVT.getVectorNumElements();
194 vecType = NVPTX::PTXLdStInstCode::V2;
196 vecType = NVPTX::PTXLdStInstCode::V4;
201 // Type Setting: fromType + fromTypeWidth
203 // Sign : ISD::SEXTLOAD
204 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
206 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
207 MVT ScalarVT = SimpleVT.getScalarType();
208 unsigned fromTypeWidth = ScalarVT.getSizeInBits();
209 unsigned int fromType;
210 if ((LD->getExtensionType() == ISD::SEXTLOAD))
211 fromType = NVPTX::PTXLdStInstCode::Signed;
212 else if (ScalarVT.isFloatingPoint())
213 fromType = NVPTX::PTXLdStInstCode::Float;
215 fromType = NVPTX::PTXLdStInstCode::Unsigned;
217 // Create the machine instruction DAG
218 SDValue Chain = N->getOperand(0);
219 SDValue N1 = N->getOperand(1);
221 SDValue Offset, Base;
223 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
225 if (SelectDirectAddr(N1, Addr)) {
228 Opcode = NVPTX::LD_i8_avar;
231 Opcode = NVPTX::LD_i16_avar;
234 Opcode = NVPTX::LD_i32_avar;
237 Opcode = NVPTX::LD_i64_avar;
240 Opcode = NVPTX::LD_f32_avar;
243 Opcode = NVPTX::LD_f64_avar;
248 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
249 getI32Imm(vecType), getI32Imm(fromType),
250 getI32Imm(fromTypeWidth), Addr, Chain };
251 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
252 } else if (Subtarget.is64Bit()
253 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
254 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
257 Opcode = NVPTX::LD_i8_asi;
260 Opcode = NVPTX::LD_i16_asi;
263 Opcode = NVPTX::LD_i32_asi;
266 Opcode = NVPTX::LD_i64_asi;
269 Opcode = NVPTX::LD_f32_asi;
272 Opcode = NVPTX::LD_f64_asi;
277 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
278 getI32Imm(vecType), getI32Imm(fromType),
279 getI32Imm(fromTypeWidth), Base, Offset, Chain };
280 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
281 } else if (Subtarget.is64Bit()
282 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
283 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
284 if (Subtarget.is64Bit()) {
287 Opcode = NVPTX::LD_i8_ari_64;
290 Opcode = NVPTX::LD_i16_ari_64;
293 Opcode = NVPTX::LD_i32_ari_64;
296 Opcode = NVPTX::LD_i64_ari_64;
299 Opcode = NVPTX::LD_f32_ari_64;
302 Opcode = NVPTX::LD_f64_ari_64;
310 Opcode = NVPTX::LD_i8_ari;
313 Opcode = NVPTX::LD_i16_ari;
316 Opcode = NVPTX::LD_i32_ari;
319 Opcode = NVPTX::LD_i64_ari;
322 Opcode = NVPTX::LD_f32_ari;
325 Opcode = NVPTX::LD_f64_ari;
331 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
332 getI32Imm(vecType), getI32Imm(fromType),
333 getI32Imm(fromTypeWidth), Base, Offset, Chain };
334 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
336 if (Subtarget.is64Bit()) {
339 Opcode = NVPTX::LD_i8_areg_64;
342 Opcode = NVPTX::LD_i16_areg_64;
345 Opcode = NVPTX::LD_i32_areg_64;
348 Opcode = NVPTX::LD_i64_areg_64;
351 Opcode = NVPTX::LD_f32_areg_64;
354 Opcode = NVPTX::LD_f64_areg_64;
362 Opcode = NVPTX::LD_i8_areg;
365 Opcode = NVPTX::LD_i16_areg;
368 Opcode = NVPTX::LD_i32_areg;
371 Opcode = NVPTX::LD_i64_areg;
374 Opcode = NVPTX::LD_f32_areg;
377 Opcode = NVPTX::LD_f64_areg;
383 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
384 getI32Imm(vecType), getI32Imm(fromType),
385 getI32Imm(fromTypeWidth), N1, Chain };
386 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
389 if (NVPTXLD != NULL) {
390 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
391 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
392 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
398 SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
400 SDValue Chain = N->getOperand(0);
401 SDValue Op1 = N->getOperand(1);
402 SDValue Addr, Offset, Base;
404 DebugLoc DL = N->getDebugLoc();
406 MemSDNode *MemSD = cast<MemSDNode>(N);
407 EVT LoadedVT = MemSD->getMemoryVT();
409 if (!LoadedVT.isSimple())
412 // Address Space Setting
413 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
416 // - .volatile is only availalble for .global and .shared
417 bool IsVolatile = MemSD->isVolatile();
418 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
419 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
420 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
424 MVT SimpleVT = LoadedVT.getSimpleVT();
426 // Type Setting: fromType + fromTypeWidth
428 // Sign : ISD::SEXTLOAD
429 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
431 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
432 MVT ScalarVT = SimpleVT.getScalarType();
433 unsigned FromTypeWidth = ScalarVT.getSizeInBits();
434 unsigned int FromType;
435 // The last operand holds the original LoadSDNode::getExtensionType() value
436 unsigned ExtensionType = cast<ConstantSDNode>(
437 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
438 if (ExtensionType == ISD::SEXTLOAD)
439 FromType = NVPTX::PTXLdStInstCode::Signed;
440 else if (ScalarVT.isFloatingPoint())
441 FromType = NVPTX::PTXLdStInstCode::Float;
443 FromType = NVPTX::PTXLdStInstCode::Unsigned;
447 switch (N->getOpcode()) {
448 case NVPTXISD::LoadV2:
449 VecType = NVPTX::PTXLdStInstCode::V2;
451 case NVPTXISD::LoadV4:
452 VecType = NVPTX::PTXLdStInstCode::V4;
458 EVT EltVT = N->getValueType(0);
460 if (SelectDirectAddr(Op1, Addr)) {
461 switch (N->getOpcode()) {
464 case NVPTXISD::LoadV2:
465 switch (EltVT.getSimpleVT().SimpleTy) {
469 Opcode = NVPTX::LDV_i8_v2_avar;
472 Opcode = NVPTX::LDV_i16_v2_avar;
475 Opcode = NVPTX::LDV_i32_v2_avar;
478 Opcode = NVPTX::LDV_i64_v2_avar;
481 Opcode = NVPTX::LDV_f32_v2_avar;
484 Opcode = NVPTX::LDV_f64_v2_avar;
488 case NVPTXISD::LoadV4:
489 switch (EltVT.getSimpleVT().SimpleTy) {
493 Opcode = NVPTX::LDV_i8_v4_avar;
496 Opcode = NVPTX::LDV_i16_v4_avar;
499 Opcode = NVPTX::LDV_i32_v4_avar;
502 Opcode = NVPTX::LDV_f32_v4_avar;
508 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
509 getI32Imm(VecType), getI32Imm(FromType),
510 getI32Imm(FromTypeWidth), Addr, Chain };
511 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
512 } else if (Subtarget.is64Bit()
513 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
514 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
515 switch (N->getOpcode()) {
518 case NVPTXISD::LoadV2:
519 switch (EltVT.getSimpleVT().SimpleTy) {
523 Opcode = NVPTX::LDV_i8_v2_asi;
526 Opcode = NVPTX::LDV_i16_v2_asi;
529 Opcode = NVPTX::LDV_i32_v2_asi;
532 Opcode = NVPTX::LDV_i64_v2_asi;
535 Opcode = NVPTX::LDV_f32_v2_asi;
538 Opcode = NVPTX::LDV_f64_v2_asi;
542 case NVPTXISD::LoadV4:
543 switch (EltVT.getSimpleVT().SimpleTy) {
547 Opcode = NVPTX::LDV_i8_v4_asi;
550 Opcode = NVPTX::LDV_i16_v4_asi;
553 Opcode = NVPTX::LDV_i32_v4_asi;
556 Opcode = NVPTX::LDV_f32_v4_asi;
562 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
563 getI32Imm(VecType), getI32Imm(FromType),
564 getI32Imm(FromTypeWidth), Base, Offset, Chain };
565 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
566 } else if (Subtarget.is64Bit()
567 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
568 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
569 if (Subtarget.is64Bit()) {
570 switch (N->getOpcode()) {
573 case NVPTXISD::LoadV2:
574 switch (EltVT.getSimpleVT().SimpleTy) {
578 Opcode = NVPTX::LDV_i8_v2_ari_64;
581 Opcode = NVPTX::LDV_i16_v2_ari_64;
584 Opcode = NVPTX::LDV_i32_v2_ari_64;
587 Opcode = NVPTX::LDV_i64_v2_ari_64;
590 Opcode = NVPTX::LDV_f32_v2_ari_64;
593 Opcode = NVPTX::LDV_f64_v2_ari_64;
597 case NVPTXISD::LoadV4:
598 switch (EltVT.getSimpleVT().SimpleTy) {
602 Opcode = NVPTX::LDV_i8_v4_ari_64;
605 Opcode = NVPTX::LDV_i16_v4_ari_64;
608 Opcode = NVPTX::LDV_i32_v4_ari_64;
611 Opcode = NVPTX::LDV_f32_v4_ari_64;
617 switch (N->getOpcode()) {
620 case NVPTXISD::LoadV2:
621 switch (EltVT.getSimpleVT().SimpleTy) {
625 Opcode = NVPTX::LDV_i8_v2_ari;
628 Opcode = NVPTX::LDV_i16_v2_ari;
631 Opcode = NVPTX::LDV_i32_v2_ari;
634 Opcode = NVPTX::LDV_i64_v2_ari;
637 Opcode = NVPTX::LDV_f32_v2_ari;
640 Opcode = NVPTX::LDV_f64_v2_ari;
644 case NVPTXISD::LoadV4:
645 switch (EltVT.getSimpleVT().SimpleTy) {
649 Opcode = NVPTX::LDV_i8_v4_ari;
652 Opcode = NVPTX::LDV_i16_v4_ari;
655 Opcode = NVPTX::LDV_i32_v4_ari;
658 Opcode = NVPTX::LDV_f32_v4_ari;
665 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
666 getI32Imm(VecType), getI32Imm(FromType),
667 getI32Imm(FromTypeWidth), Base, Offset, Chain };
669 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
671 if (Subtarget.is64Bit()) {
672 switch (N->getOpcode()) {
675 case NVPTXISD::LoadV2:
676 switch (EltVT.getSimpleVT().SimpleTy) {
680 Opcode = NVPTX::LDV_i8_v2_areg_64;
683 Opcode = NVPTX::LDV_i16_v2_areg_64;
686 Opcode = NVPTX::LDV_i32_v2_areg_64;
689 Opcode = NVPTX::LDV_i64_v2_areg_64;
692 Opcode = NVPTX::LDV_f32_v2_areg_64;
695 Opcode = NVPTX::LDV_f64_v2_areg_64;
699 case NVPTXISD::LoadV4:
700 switch (EltVT.getSimpleVT().SimpleTy) {
704 Opcode = NVPTX::LDV_i8_v4_areg_64;
707 Opcode = NVPTX::LDV_i16_v4_areg_64;
710 Opcode = NVPTX::LDV_i32_v4_areg_64;
713 Opcode = NVPTX::LDV_f32_v4_areg_64;
719 switch (N->getOpcode()) {
722 case NVPTXISD::LoadV2:
723 switch (EltVT.getSimpleVT().SimpleTy) {
727 Opcode = NVPTX::LDV_i8_v2_areg;
730 Opcode = NVPTX::LDV_i16_v2_areg;
733 Opcode = NVPTX::LDV_i32_v2_areg;
736 Opcode = NVPTX::LDV_i64_v2_areg;
739 Opcode = NVPTX::LDV_f32_v2_areg;
742 Opcode = NVPTX::LDV_f64_v2_areg;
746 case NVPTXISD::LoadV4:
747 switch (EltVT.getSimpleVT().SimpleTy) {
751 Opcode = NVPTX::LDV_i8_v4_areg;
754 Opcode = NVPTX::LDV_i16_v4_areg;
757 Opcode = NVPTX::LDV_i32_v4_areg;
760 Opcode = NVPTX::LDV_f32_v4_areg;
767 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
768 getI32Imm(VecType), getI32Imm(FromType),
769 getI32Imm(FromTypeWidth), Op1, Chain };
770 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
773 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
774 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
775 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
780 SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
782 SDValue Chain = N->getOperand(0);
783 SDValue Op1 = N->getOperand(1);
785 DebugLoc DL = N->getDebugLoc();
788 EVT RetVT = N->getValueType(0);
791 if (Subtarget.is64Bit()) {
792 switch (N->getOpcode()) {
795 case NVPTXISD::LDGV2:
796 switch (RetVT.getSimpleVT().SimpleTy) {
800 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
803 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
806 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
809 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
812 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
815 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
819 case NVPTXISD::LDGV4:
820 switch (RetVT.getSimpleVT().SimpleTy) {
824 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
827 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
830 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
833 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
837 case NVPTXISD::LDUV2:
838 switch (RetVT.getSimpleVT().SimpleTy) {
842 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
845 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
848 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
851 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
854 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
857 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
861 case NVPTXISD::LDUV4:
862 switch (RetVT.getSimpleVT().SimpleTy) {
866 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
869 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
872 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
875 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
881 switch (N->getOpcode()) {
884 case NVPTXISD::LDGV2:
885 switch (RetVT.getSimpleVT().SimpleTy) {
889 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
892 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
895 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
898 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
901 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
904 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
908 case NVPTXISD::LDGV4:
909 switch (RetVT.getSimpleVT().SimpleTy) {
913 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
916 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
919 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
922 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
926 case NVPTXISD::LDUV2:
927 switch (RetVT.getSimpleVT().SimpleTy) {
931 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
934 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
937 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
940 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
943 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
946 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
950 case NVPTXISD::LDUV4:
951 switch (RetVT.getSimpleVT().SimpleTy) {
955 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
958 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
961 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
964 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
971 SDValue Ops[] = { Op1, Chain };
972 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
974 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
975 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
976 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
981 SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
982 DebugLoc dl = N->getDebugLoc();
983 StoreSDNode *ST = cast<StoreSDNode>(N);
984 EVT StoreVT = ST->getMemoryVT();
985 SDNode *NVPTXST = NULL;
987 // do not support pre/post inc/dec
991 if (!StoreVT.isSimple())
994 // Address Space Setting
995 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
998 // - .volatile is only availalble for .global and .shared
999 bool isVolatile = ST->isVolatile();
1000 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1001 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1002 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1006 MVT SimpleVT = StoreVT.getSimpleVT();
1007 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1008 if (SimpleVT.isVector()) {
1009 unsigned num = SimpleVT.getVectorNumElements();
1011 vecType = NVPTX::PTXLdStInstCode::V2;
1013 vecType = NVPTX::PTXLdStInstCode::V4;
1018 // Type Setting: toType + toTypeWidth
1019 // - for integer type, always use 'u'
1021 MVT ScalarVT = SimpleVT.getScalarType();
1022 unsigned toTypeWidth = ScalarVT.getSizeInBits();
1023 unsigned int toType;
1024 if (ScalarVT.isFloatingPoint())
1025 toType = NVPTX::PTXLdStInstCode::Float;
1027 toType = NVPTX::PTXLdStInstCode::Unsigned;
1029 // Create the machine instruction DAG
1030 SDValue Chain = N->getOperand(0);
1031 SDValue N1 = N->getOperand(1);
1032 SDValue N2 = N->getOperand(2);
1034 SDValue Offset, Base;
1036 MVT::SimpleValueType SourceVT =
1037 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1039 if (SelectDirectAddr(N2, Addr)) {
1042 Opcode = NVPTX::ST_i8_avar;
1045 Opcode = NVPTX::ST_i16_avar;
1048 Opcode = NVPTX::ST_i32_avar;
1051 Opcode = NVPTX::ST_i64_avar;
1054 Opcode = NVPTX::ST_f32_avar;
1057 Opcode = NVPTX::ST_f64_avar;
1062 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1063 getI32Imm(vecType), getI32Imm(toType),
1064 getI32Imm(toTypeWidth), Addr, Chain };
1065 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1066 } else if (Subtarget.is64Bit()
1067 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1068 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1071 Opcode = NVPTX::ST_i8_asi;
1074 Opcode = NVPTX::ST_i16_asi;
1077 Opcode = NVPTX::ST_i32_asi;
1080 Opcode = NVPTX::ST_i64_asi;
1083 Opcode = NVPTX::ST_f32_asi;
1086 Opcode = NVPTX::ST_f64_asi;
1091 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1092 getI32Imm(vecType), getI32Imm(toType),
1093 getI32Imm(toTypeWidth), Base, Offset, Chain };
1094 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1095 } else if (Subtarget.is64Bit()
1096 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1097 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1098 if (Subtarget.is64Bit()) {
1101 Opcode = NVPTX::ST_i8_ari_64;
1104 Opcode = NVPTX::ST_i16_ari_64;
1107 Opcode = NVPTX::ST_i32_ari_64;
1110 Opcode = NVPTX::ST_i64_ari_64;
1113 Opcode = NVPTX::ST_f32_ari_64;
1116 Opcode = NVPTX::ST_f64_ari_64;
1124 Opcode = NVPTX::ST_i8_ari;
1127 Opcode = NVPTX::ST_i16_ari;
1130 Opcode = NVPTX::ST_i32_ari;
1133 Opcode = NVPTX::ST_i64_ari;
1136 Opcode = NVPTX::ST_f32_ari;
1139 Opcode = NVPTX::ST_f64_ari;
1145 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1146 getI32Imm(vecType), getI32Imm(toType),
1147 getI32Imm(toTypeWidth), Base, Offset, Chain };
1148 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1150 if (Subtarget.is64Bit()) {
1153 Opcode = NVPTX::ST_i8_areg_64;
1156 Opcode = NVPTX::ST_i16_areg_64;
1159 Opcode = NVPTX::ST_i32_areg_64;
1162 Opcode = NVPTX::ST_i64_areg_64;
1165 Opcode = NVPTX::ST_f32_areg_64;
1168 Opcode = NVPTX::ST_f64_areg_64;
1176 Opcode = NVPTX::ST_i8_areg;
1179 Opcode = NVPTX::ST_i16_areg;
1182 Opcode = NVPTX::ST_i32_areg;
1185 Opcode = NVPTX::ST_i64_areg;
1188 Opcode = NVPTX::ST_f32_areg;
1191 Opcode = NVPTX::ST_f64_areg;
1197 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1198 getI32Imm(vecType), getI32Imm(toType),
1199 getI32Imm(toTypeWidth), N2, Chain };
1200 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1203 if (NVPTXST != NULL) {
1204 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1205 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1206 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1212 SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1213 SDValue Chain = N->getOperand(0);
1214 SDValue Op1 = N->getOperand(1);
1215 SDValue Addr, Offset, Base;
1217 DebugLoc DL = N->getDebugLoc();
1219 EVT EltVT = Op1.getValueType();
1220 MemSDNode *MemSD = cast<MemSDNode>(N);
1221 EVT StoreVT = MemSD->getMemoryVT();
1223 // Address Space Setting
1224 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1226 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1227 report_fatal_error("Cannot store to pointer that points to constant "
1232 // - .volatile is only availalble for .global and .shared
1233 bool IsVolatile = MemSD->isVolatile();
1234 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1235 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1236 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1239 // Type Setting: toType + toTypeWidth
1240 // - for integer type, always use 'u'
1241 assert(StoreVT.isSimple() && "Store value is not simple");
1242 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
1243 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
1245 if (ScalarVT.isFloatingPoint())
1246 ToType = NVPTX::PTXLdStInstCode::Float;
1248 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1250 SmallVector<SDValue, 12> StOps;
1254 switch (N->getOpcode()) {
1255 case NVPTXISD::StoreV2:
1256 VecType = NVPTX::PTXLdStInstCode::V2;
1257 StOps.push_back(N->getOperand(1));
1258 StOps.push_back(N->getOperand(2));
1259 N2 = N->getOperand(3);
1261 case NVPTXISD::StoreV4:
1262 VecType = NVPTX::PTXLdStInstCode::V4;
1263 StOps.push_back(N->getOperand(1));
1264 StOps.push_back(N->getOperand(2));
1265 StOps.push_back(N->getOperand(3));
1266 StOps.push_back(N->getOperand(4));
1267 N2 = N->getOperand(5);
1273 StOps.push_back(getI32Imm(IsVolatile));
1274 StOps.push_back(getI32Imm(CodeAddrSpace));
1275 StOps.push_back(getI32Imm(VecType));
1276 StOps.push_back(getI32Imm(ToType));
1277 StOps.push_back(getI32Imm(ToTypeWidth));
1279 if (SelectDirectAddr(N2, Addr)) {
1280 switch (N->getOpcode()) {
1283 case NVPTXISD::StoreV2:
1284 switch (EltVT.getSimpleVT().SimpleTy) {
1288 Opcode = NVPTX::STV_i8_v2_avar;
1291 Opcode = NVPTX::STV_i16_v2_avar;
1294 Opcode = NVPTX::STV_i32_v2_avar;
1297 Opcode = NVPTX::STV_i64_v2_avar;
1300 Opcode = NVPTX::STV_f32_v2_avar;
1303 Opcode = NVPTX::STV_f64_v2_avar;
1307 case NVPTXISD::StoreV4:
1308 switch (EltVT.getSimpleVT().SimpleTy) {
1312 Opcode = NVPTX::STV_i8_v4_avar;
1315 Opcode = NVPTX::STV_i16_v4_avar;
1318 Opcode = NVPTX::STV_i32_v4_avar;
1321 Opcode = NVPTX::STV_f32_v4_avar;
1326 StOps.push_back(Addr);
1327 } else if (Subtarget.is64Bit()
1328 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1329 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1330 switch (N->getOpcode()) {
1333 case NVPTXISD::StoreV2:
1334 switch (EltVT.getSimpleVT().SimpleTy) {
1338 Opcode = NVPTX::STV_i8_v2_asi;
1341 Opcode = NVPTX::STV_i16_v2_asi;
1344 Opcode = NVPTX::STV_i32_v2_asi;
1347 Opcode = NVPTX::STV_i64_v2_asi;
1350 Opcode = NVPTX::STV_f32_v2_asi;
1353 Opcode = NVPTX::STV_f64_v2_asi;
1357 case NVPTXISD::StoreV4:
1358 switch (EltVT.getSimpleVT().SimpleTy) {
1362 Opcode = NVPTX::STV_i8_v4_asi;
1365 Opcode = NVPTX::STV_i16_v4_asi;
1368 Opcode = NVPTX::STV_i32_v4_asi;
1371 Opcode = NVPTX::STV_f32_v4_asi;
1376 StOps.push_back(Base);
1377 StOps.push_back(Offset);
1378 } else if (Subtarget.is64Bit()
1379 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1380 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1381 if (Subtarget.is64Bit()) {
1382 switch (N->getOpcode()) {
1385 case NVPTXISD::StoreV2:
1386 switch (EltVT.getSimpleVT().SimpleTy) {
1390 Opcode = NVPTX::STV_i8_v2_ari_64;
1393 Opcode = NVPTX::STV_i16_v2_ari_64;
1396 Opcode = NVPTX::STV_i32_v2_ari_64;
1399 Opcode = NVPTX::STV_i64_v2_ari_64;
1402 Opcode = NVPTX::STV_f32_v2_ari_64;
1405 Opcode = NVPTX::STV_f64_v2_ari_64;
1409 case NVPTXISD::StoreV4:
1410 switch (EltVT.getSimpleVT().SimpleTy) {
1414 Opcode = NVPTX::STV_i8_v4_ari_64;
1417 Opcode = NVPTX::STV_i16_v4_ari_64;
1420 Opcode = NVPTX::STV_i32_v4_ari_64;
1423 Opcode = NVPTX::STV_f32_v4_ari_64;
1429 switch (N->getOpcode()) {
1432 case NVPTXISD::StoreV2:
1433 switch (EltVT.getSimpleVT().SimpleTy) {
1437 Opcode = NVPTX::STV_i8_v2_ari;
1440 Opcode = NVPTX::STV_i16_v2_ari;
1443 Opcode = NVPTX::STV_i32_v2_ari;
1446 Opcode = NVPTX::STV_i64_v2_ari;
1449 Opcode = NVPTX::STV_f32_v2_ari;
1452 Opcode = NVPTX::STV_f64_v2_ari;
1456 case NVPTXISD::StoreV4:
1457 switch (EltVT.getSimpleVT().SimpleTy) {
1461 Opcode = NVPTX::STV_i8_v4_ari;
1464 Opcode = NVPTX::STV_i16_v4_ari;
1467 Opcode = NVPTX::STV_i32_v4_ari;
1470 Opcode = NVPTX::STV_f32_v4_ari;
1476 StOps.push_back(Base);
1477 StOps.push_back(Offset);
1479 if (Subtarget.is64Bit()) {
1480 switch (N->getOpcode()) {
1483 case NVPTXISD::StoreV2:
1484 switch (EltVT.getSimpleVT().SimpleTy) {
1488 Opcode = NVPTX::STV_i8_v2_areg_64;
1491 Opcode = NVPTX::STV_i16_v2_areg_64;
1494 Opcode = NVPTX::STV_i32_v2_areg_64;
1497 Opcode = NVPTX::STV_i64_v2_areg_64;
1500 Opcode = NVPTX::STV_f32_v2_areg_64;
1503 Opcode = NVPTX::STV_f64_v2_areg_64;
1507 case NVPTXISD::StoreV4:
1508 switch (EltVT.getSimpleVT().SimpleTy) {
1512 Opcode = NVPTX::STV_i8_v4_areg_64;
1515 Opcode = NVPTX::STV_i16_v4_areg_64;
1518 Opcode = NVPTX::STV_i32_v4_areg_64;
1521 Opcode = NVPTX::STV_f32_v4_areg_64;
1527 switch (N->getOpcode()) {
1530 case NVPTXISD::StoreV2:
1531 switch (EltVT.getSimpleVT().SimpleTy) {
1535 Opcode = NVPTX::STV_i8_v2_areg;
1538 Opcode = NVPTX::STV_i16_v2_areg;
1541 Opcode = NVPTX::STV_i32_v2_areg;
1544 Opcode = NVPTX::STV_i64_v2_areg;
1547 Opcode = NVPTX::STV_f32_v2_areg;
1550 Opcode = NVPTX::STV_f64_v2_areg;
1554 case NVPTXISD::StoreV4:
1555 switch (EltVT.getSimpleVT().SimpleTy) {
1559 Opcode = NVPTX::STV_i8_v4_areg;
1562 Opcode = NVPTX::STV_i16_v4_areg;
1565 Opcode = NVPTX::STV_i32_v4_areg;
1568 Opcode = NVPTX::STV_f32_v4_areg;
1574 StOps.push_back(N2);
1577 StOps.push_back(Chain);
1579 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
1581 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1582 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1583 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1588 // SelectDirectAddr - Match a direct address for DAG.
1589 // A direct address could be a globaladdress or externalsymbol.
1590 bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
1591 // Return true if TGA or ES.
1592 if (N.getOpcode() == ISD::TargetGlobalAddress ||
1593 N.getOpcode() == ISD::TargetExternalSymbol) {
1597 if (N.getOpcode() == NVPTXISD::Wrapper) {
1598 Address = N.getOperand(0);
1601 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
1602 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
1603 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
1604 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
1605 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
1611 bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
1612 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1613 if (Addr.getOpcode() == ISD::ADD) {
1614 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1615 SDValue base = Addr.getOperand(0);
1616 if (SelectDirectAddr(base, Base)) {
1617 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1626 bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
1627 SDValue &Base, SDValue &Offset) {
1628 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
1632 bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
1633 SDValue &Base, SDValue &Offset) {
1634 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
1638 bool NVPTXDAGToDAGISel::SelectADDRri_imp(
1639 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1640 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1641 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1642 Offset = CurDAG->getTargetConstant(0, mvt);
1645 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1646 Addr.getOpcode() == ISD::TargetGlobalAddress)
1647 return false; // direct calls.
1649 if (Addr.getOpcode() == ISD::ADD) {
1650 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
1653 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1654 if (FrameIndexSDNode *FIN =
1655 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
1656 // Constant offset from frame ref.
1657 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1659 Base = Addr.getOperand(0);
1660 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1668 bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
1669 SDValue &Base, SDValue &Offset) {
1670 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
1674 bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
1675 SDValue &Base, SDValue &Offset) {
1676 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
1679 bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
1680 unsigned int spN) const {
1681 const Value *Src = NULL;
1682 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
1683 // the classof() for MemSDNode does not include MemIntrinsicSDNode
1684 // (See SelectionDAGNodes.h). So we need to check for both.
1685 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1686 Src = mN->getSrcValue();
1687 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
1688 Src = mN->getSrcValue();
1692 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
1693 return (PT->getAddressSpace() == spN);
1697 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1698 /// inline asm expressions.
1699 bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
1700 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
1702 switch (ConstraintCode) {
1706 if (SelectDirectAddr(Op, Op0)) {
1707 OutOps.push_back(Op0);
1708 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1711 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
1712 OutOps.push_back(Op0);
1713 OutOps.push_back(Op1);
1721 // Return true if N is a undef or a constant.
1722 // If N was undef, return a (i8imm 0) in Retval
1723 // If N was imm, convert it to i8imm and return in Retval
1724 // Note: The convert to i8imm is required, otherwise the
1725 // pattern matcher inserts a bunch of IMOVi8rr to convert
1726 // the imm to i8imm, and this causes instruction selection
1728 bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
1729 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
1732 if (N.getOpcode() == ISD::UNDEF)
1733 Retval = CurDAG->getTargetConstant(0, MVT::i8);
1735 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
1736 unsigned retval = cn->getZExtValue();
1737 Retval = CurDAG->getTargetConstant(retval, MVT::i8);