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."),
45 /// createNVPTXISelDag - This pass converts a legalized DAG into a
46 /// NVPTX-specific DAG, ready for instruction scheduling.
47 FunctionPass *llvm::createNVPTXISelDag(NVPTXTargetMachine &TM,
48 llvm::CodeGenOpt::Level OptLevel) {
49 return new NVPTXDAGToDAGISel(TM, OptLevel);
52 NVPTXDAGToDAGISel::NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
53 CodeGenOpt::Level OptLevel)
54 : SelectionDAGISel(tm, OptLevel),
55 Subtarget(tm.getSubtarget<NVPTXSubtarget>()) {
56 // Always do fma.f32 fpcontract if the target supports the instruction.
57 // Always do fma.f64 fpcontract if the target supports the instruction.
58 // Do mad.f32 is nvptx-mad-enable is specified and the target does not
61 doFMADF32 = (OptLevel > 0) && UseFMADInstruction && !Subtarget.hasFMAF32();
62 doFMAF32 = (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel >= 1);
63 doFMAF64 = (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel >= 1);
65 (OptLevel > 0) && Subtarget.hasFMAF32() && (FMAContractLevel == 2);
67 (OptLevel > 0) && Subtarget.hasFMAF64() && (FMAContractLevel == 2);
69 allowFMA = (FMAContractLevel >= 1) || UseFMADInstruction;
73 doMulWide = (OptLevel > 0);
75 // Decide how to translate f32 div
76 do_DIVF32_PREC = UsePrecDivF32;
77 // sm less than sm_20 does not support div.rnd. Use div.full.
78 if (do_DIVF32_PREC == 2 && !Subtarget.reqPTX20())
83 /// Select - Select instructions not customized! Used for
84 /// expanded, promoted and normal instructions.
85 SDNode *NVPTXDAGToDAGISel::Select(SDNode *N) {
87 if (N->isMachineOpcode())
88 return NULL; // Already selected.
90 SDNode *ResNode = NULL;
91 switch (N->getOpcode()) {
93 ResNode = SelectLoad(N);
96 ResNode = SelectStore(N);
98 case NVPTXISD::LoadV2:
99 case NVPTXISD::LoadV4:
100 ResNode = SelectLoadVector(N);
102 case NVPTXISD::LDGV2:
103 case NVPTXISD::LDGV4:
104 case NVPTXISD::LDUV2:
105 case NVPTXISD::LDUV4:
106 ResNode = SelectLDGLDUVector(N);
108 case NVPTXISD::StoreV2:
109 case NVPTXISD::StoreV4:
110 ResNode = SelectStoreVector(N);
117 return SelectCode(N);
120 static unsigned int getCodeAddrSpace(MemSDNode *N,
121 const NVPTXSubtarget &Subtarget) {
122 const Value *Src = N->getSrcValue();
124 return NVPTX::PTXLdStInstCode::LOCAL;
126 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
127 switch (PT->getAddressSpace()) {
128 case llvm::ADDRESS_SPACE_LOCAL:
129 return NVPTX::PTXLdStInstCode::LOCAL;
130 case llvm::ADDRESS_SPACE_GLOBAL:
131 return NVPTX::PTXLdStInstCode::GLOBAL;
132 case llvm::ADDRESS_SPACE_SHARED:
133 return NVPTX::PTXLdStInstCode::SHARED;
134 case llvm::ADDRESS_SPACE_CONST_NOT_GEN:
135 return NVPTX::PTXLdStInstCode::CONSTANT;
136 case llvm::ADDRESS_SPACE_GENERIC:
137 return NVPTX::PTXLdStInstCode::GENERIC;
138 case llvm::ADDRESS_SPACE_PARAM:
139 return NVPTX::PTXLdStInstCode::PARAM;
140 case llvm::ADDRESS_SPACE_CONST:
141 // If the arch supports generic address space, translate it to GLOBAL
143 // If the arch does not support generic address space, then the arch
144 // does not really support ADDRESS_SPACE_CONST, translate it to
145 // to CONSTANT for better performance.
146 if (Subtarget.hasGenericLdSt())
147 return NVPTX::PTXLdStInstCode::GLOBAL;
149 return NVPTX::PTXLdStInstCode::CONSTANT;
154 return NVPTX::PTXLdStInstCode::LOCAL;
157 SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
158 DebugLoc dl = N->getDebugLoc();
159 LoadSDNode *LD = cast<LoadSDNode>(N);
160 EVT LoadedVT = LD->getMemoryVT();
161 SDNode *NVPTXLD = NULL;
163 // do not support pre/post inc/dec
167 if (!LoadedVT.isSimple())
170 // Address Space Setting
171 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
174 // - .volatile is only availalble for .global and .shared
175 bool isVolatile = LD->isVolatile();
176 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
177 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
178 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
182 MVT SimpleVT = LoadedVT.getSimpleVT();
183 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
184 if (SimpleVT.isVector()) {
185 unsigned num = SimpleVT.getVectorNumElements();
187 vecType = NVPTX::PTXLdStInstCode::V2;
189 vecType = NVPTX::PTXLdStInstCode::V4;
194 // Type Setting: fromType + fromTypeWidth
196 // Sign : ISD::SEXTLOAD
197 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
199 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
200 MVT ScalarVT = SimpleVT.getScalarType();
201 unsigned fromTypeWidth = ScalarVT.getSizeInBits();
202 unsigned int fromType;
203 if ((LD->getExtensionType() == ISD::SEXTLOAD))
204 fromType = NVPTX::PTXLdStInstCode::Signed;
205 else if (ScalarVT.isFloatingPoint())
206 fromType = NVPTX::PTXLdStInstCode::Float;
208 fromType = NVPTX::PTXLdStInstCode::Unsigned;
210 // Create the machine instruction DAG
211 SDValue Chain = N->getOperand(0);
212 SDValue N1 = N->getOperand(1);
214 SDValue Offset, Base;
216 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
218 if (SelectDirectAddr(N1, Addr)) {
221 Opcode = NVPTX::LD_i8_avar;
224 Opcode = NVPTX::LD_i16_avar;
227 Opcode = NVPTX::LD_i32_avar;
230 Opcode = NVPTX::LD_i64_avar;
233 Opcode = NVPTX::LD_f32_avar;
236 Opcode = NVPTX::LD_f64_avar;
241 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
242 getI32Imm(vecType), getI32Imm(fromType),
243 getI32Imm(fromTypeWidth), Addr, Chain };
244 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops, 7);
245 } else if (Subtarget.is64Bit()
246 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
247 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
250 Opcode = NVPTX::LD_i8_asi;
253 Opcode = NVPTX::LD_i16_asi;
256 Opcode = NVPTX::LD_i32_asi;
259 Opcode = NVPTX::LD_i64_asi;
262 Opcode = NVPTX::LD_f32_asi;
265 Opcode = NVPTX::LD_f64_asi;
270 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
271 getI32Imm(vecType), getI32Imm(fromType),
272 getI32Imm(fromTypeWidth), Base, Offset, Chain };
273 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops, 8);
274 } else if (Subtarget.is64Bit()
275 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
276 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
277 if (Subtarget.is64Bit()) {
280 Opcode = NVPTX::LD_i8_ari_64;
283 Opcode = NVPTX::LD_i16_ari_64;
286 Opcode = NVPTX::LD_i32_ari_64;
289 Opcode = NVPTX::LD_i64_ari_64;
292 Opcode = NVPTX::LD_f32_ari_64;
295 Opcode = NVPTX::LD_f64_ari_64;
303 Opcode = NVPTX::LD_i8_ari;
306 Opcode = NVPTX::LD_i16_ari;
309 Opcode = NVPTX::LD_i32_ari;
312 Opcode = NVPTX::LD_i64_ari;
315 Opcode = NVPTX::LD_f32_ari;
318 Opcode = NVPTX::LD_f64_ari;
324 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
325 getI32Imm(vecType), getI32Imm(fromType),
326 getI32Imm(fromTypeWidth), Base, Offset, Chain };
327 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops, 8);
329 if (Subtarget.is64Bit()) {
332 Opcode = NVPTX::LD_i8_areg_64;
335 Opcode = NVPTX::LD_i16_areg_64;
338 Opcode = NVPTX::LD_i32_areg_64;
341 Opcode = NVPTX::LD_i64_areg_64;
344 Opcode = NVPTX::LD_f32_areg_64;
347 Opcode = NVPTX::LD_f64_areg_64;
355 Opcode = NVPTX::LD_i8_areg;
358 Opcode = NVPTX::LD_i16_areg;
361 Opcode = NVPTX::LD_i32_areg;
364 Opcode = NVPTX::LD_i64_areg;
367 Opcode = NVPTX::LD_f32_areg;
370 Opcode = NVPTX::LD_f64_areg;
376 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
377 getI32Imm(vecType), getI32Imm(fromType),
378 getI32Imm(fromTypeWidth), N1, Chain };
379 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops, 7);
382 if (NVPTXLD != NULL) {
383 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
384 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
385 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
391 SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
393 SDValue Chain = N->getOperand(0);
394 SDValue Op1 = N->getOperand(1);
395 SDValue Addr, Offset, Base;
397 DebugLoc DL = N->getDebugLoc();
399 MemSDNode *MemSD = cast<MemSDNode>(N);
400 EVT LoadedVT = MemSD->getMemoryVT();
402 if (!LoadedVT.isSimple())
405 // Address Space Setting
406 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
409 // - .volatile is only availalble for .global and .shared
410 bool IsVolatile = MemSD->isVolatile();
411 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
412 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
413 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
417 MVT SimpleVT = LoadedVT.getSimpleVT();
419 // Type Setting: fromType + fromTypeWidth
421 // Sign : ISD::SEXTLOAD
422 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
424 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
425 MVT ScalarVT = SimpleVT.getScalarType();
426 unsigned FromTypeWidth = ScalarVT.getSizeInBits();
427 unsigned int FromType;
428 // The last operand holds the original LoadSDNode::getExtensionType() value
429 unsigned ExtensionType = cast<ConstantSDNode>(
430 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
431 if (ExtensionType == ISD::SEXTLOAD)
432 FromType = NVPTX::PTXLdStInstCode::Signed;
433 else if (ScalarVT.isFloatingPoint())
434 FromType = NVPTX::PTXLdStInstCode::Float;
436 FromType = NVPTX::PTXLdStInstCode::Unsigned;
440 switch (N->getOpcode()) {
441 case NVPTXISD::LoadV2:
442 VecType = NVPTX::PTXLdStInstCode::V2;
444 case NVPTXISD::LoadV4:
445 VecType = NVPTX::PTXLdStInstCode::V4;
451 EVT EltVT = N->getValueType(0);
453 if (SelectDirectAddr(Op1, Addr)) {
454 switch (N->getOpcode()) {
457 case NVPTXISD::LoadV2:
458 switch (EltVT.getSimpleVT().SimpleTy) {
462 Opcode = NVPTX::LDV_i8_v2_avar;
465 Opcode = NVPTX::LDV_i16_v2_avar;
468 Opcode = NVPTX::LDV_i32_v2_avar;
471 Opcode = NVPTX::LDV_i64_v2_avar;
474 Opcode = NVPTX::LDV_f32_v2_avar;
477 Opcode = NVPTX::LDV_f64_v2_avar;
481 case NVPTXISD::LoadV4:
482 switch (EltVT.getSimpleVT().SimpleTy) {
486 Opcode = NVPTX::LDV_i8_v4_avar;
489 Opcode = NVPTX::LDV_i16_v4_avar;
492 Opcode = NVPTX::LDV_i32_v4_avar;
495 Opcode = NVPTX::LDV_f32_v4_avar;
501 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
502 getI32Imm(VecType), getI32Imm(FromType),
503 getI32Imm(FromTypeWidth), Addr, Chain };
504 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops, 7);
505 } else if (Subtarget.is64Bit()
506 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
507 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
508 switch (N->getOpcode()) {
511 case NVPTXISD::LoadV2:
512 switch (EltVT.getSimpleVT().SimpleTy) {
516 Opcode = NVPTX::LDV_i8_v2_asi;
519 Opcode = NVPTX::LDV_i16_v2_asi;
522 Opcode = NVPTX::LDV_i32_v2_asi;
525 Opcode = NVPTX::LDV_i64_v2_asi;
528 Opcode = NVPTX::LDV_f32_v2_asi;
531 Opcode = NVPTX::LDV_f64_v2_asi;
535 case NVPTXISD::LoadV4:
536 switch (EltVT.getSimpleVT().SimpleTy) {
540 Opcode = NVPTX::LDV_i8_v4_asi;
543 Opcode = NVPTX::LDV_i16_v4_asi;
546 Opcode = NVPTX::LDV_i32_v4_asi;
549 Opcode = NVPTX::LDV_f32_v4_asi;
555 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
556 getI32Imm(VecType), getI32Imm(FromType),
557 getI32Imm(FromTypeWidth), Base, Offset, Chain };
558 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops, 8);
559 } else if (Subtarget.is64Bit()
560 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
561 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
562 if (Subtarget.is64Bit()) {
563 switch (N->getOpcode()) {
566 case NVPTXISD::LoadV2:
567 switch (EltVT.getSimpleVT().SimpleTy) {
571 Opcode = NVPTX::LDV_i8_v2_ari_64;
574 Opcode = NVPTX::LDV_i16_v2_ari_64;
577 Opcode = NVPTX::LDV_i32_v2_ari_64;
580 Opcode = NVPTX::LDV_i64_v2_ari_64;
583 Opcode = NVPTX::LDV_f32_v2_ari_64;
586 Opcode = NVPTX::LDV_f64_v2_ari_64;
590 case NVPTXISD::LoadV4:
591 switch (EltVT.getSimpleVT().SimpleTy) {
595 Opcode = NVPTX::LDV_i8_v4_ari_64;
598 Opcode = NVPTX::LDV_i16_v4_ari_64;
601 Opcode = NVPTX::LDV_i32_v4_ari_64;
604 Opcode = NVPTX::LDV_f32_v4_ari_64;
610 switch (N->getOpcode()) {
613 case NVPTXISD::LoadV2:
614 switch (EltVT.getSimpleVT().SimpleTy) {
618 Opcode = NVPTX::LDV_i8_v2_ari;
621 Opcode = NVPTX::LDV_i16_v2_ari;
624 Opcode = NVPTX::LDV_i32_v2_ari;
627 Opcode = NVPTX::LDV_i64_v2_ari;
630 Opcode = NVPTX::LDV_f32_v2_ari;
633 Opcode = NVPTX::LDV_f64_v2_ari;
637 case NVPTXISD::LoadV4:
638 switch (EltVT.getSimpleVT().SimpleTy) {
642 Opcode = NVPTX::LDV_i8_v4_ari;
645 Opcode = NVPTX::LDV_i16_v4_ari;
648 Opcode = NVPTX::LDV_i32_v4_ari;
651 Opcode = NVPTX::LDV_f32_v4_ari;
658 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
659 getI32Imm(VecType), getI32Imm(FromType),
660 getI32Imm(FromTypeWidth), Base, Offset, Chain };
662 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops, 8);
664 if (Subtarget.is64Bit()) {
665 switch (N->getOpcode()) {
668 case NVPTXISD::LoadV2:
669 switch (EltVT.getSimpleVT().SimpleTy) {
673 Opcode = NVPTX::LDV_i8_v2_areg_64;
676 Opcode = NVPTX::LDV_i16_v2_areg_64;
679 Opcode = NVPTX::LDV_i32_v2_areg_64;
682 Opcode = NVPTX::LDV_i64_v2_areg_64;
685 Opcode = NVPTX::LDV_f32_v2_areg_64;
688 Opcode = NVPTX::LDV_f64_v2_areg_64;
692 case NVPTXISD::LoadV4:
693 switch (EltVT.getSimpleVT().SimpleTy) {
697 Opcode = NVPTX::LDV_i8_v4_areg_64;
700 Opcode = NVPTX::LDV_i16_v4_areg_64;
703 Opcode = NVPTX::LDV_i32_v4_areg_64;
706 Opcode = NVPTX::LDV_f32_v4_areg_64;
712 switch (N->getOpcode()) {
715 case NVPTXISD::LoadV2:
716 switch (EltVT.getSimpleVT().SimpleTy) {
720 Opcode = NVPTX::LDV_i8_v2_areg;
723 Opcode = NVPTX::LDV_i16_v2_areg;
726 Opcode = NVPTX::LDV_i32_v2_areg;
729 Opcode = NVPTX::LDV_i64_v2_areg;
732 Opcode = NVPTX::LDV_f32_v2_areg;
735 Opcode = NVPTX::LDV_f64_v2_areg;
739 case NVPTXISD::LoadV4:
740 switch (EltVT.getSimpleVT().SimpleTy) {
744 Opcode = NVPTX::LDV_i8_v4_areg;
747 Opcode = NVPTX::LDV_i16_v4_areg;
750 Opcode = NVPTX::LDV_i32_v4_areg;
753 Opcode = NVPTX::LDV_f32_v4_areg;
760 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
761 getI32Imm(VecType), getI32Imm(FromType),
762 getI32Imm(FromTypeWidth), Op1, Chain };
763 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops, 7);
766 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
767 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
768 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
773 SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
775 SDValue Chain = N->getOperand(0);
776 SDValue Op1 = N->getOperand(1);
778 DebugLoc DL = N->getDebugLoc();
781 EVT RetVT = N->getValueType(0);
784 if (Subtarget.is64Bit()) {
785 switch (N->getOpcode()) {
788 case NVPTXISD::LDGV2:
789 switch (RetVT.getSimpleVT().SimpleTy) {
793 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
796 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
799 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
802 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
805 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
808 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
812 case NVPTXISD::LDGV4:
813 switch (RetVT.getSimpleVT().SimpleTy) {
817 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
820 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
823 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
826 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
830 case NVPTXISD::LDUV2:
831 switch (RetVT.getSimpleVT().SimpleTy) {
835 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
838 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
841 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
844 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
847 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
850 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
854 case NVPTXISD::LDUV4:
855 switch (RetVT.getSimpleVT().SimpleTy) {
859 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
862 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
865 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
868 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
874 switch (N->getOpcode()) {
877 case NVPTXISD::LDGV2:
878 switch (RetVT.getSimpleVT().SimpleTy) {
882 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
885 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
888 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
891 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
894 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
897 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
901 case NVPTXISD::LDGV4:
902 switch (RetVT.getSimpleVT().SimpleTy) {
906 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
909 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
912 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
915 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
919 case NVPTXISD::LDUV2:
920 switch (RetVT.getSimpleVT().SimpleTy) {
924 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
927 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
930 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
933 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
936 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
939 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
943 case NVPTXISD::LDUV4:
944 switch (RetVT.getSimpleVT().SimpleTy) {
948 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
951 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
954 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
957 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
964 SDValue Ops[] = { Op1, Chain };
965 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), &Ops[0], 2);
967 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
968 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
969 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
974 SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
975 DebugLoc dl = N->getDebugLoc();
976 StoreSDNode *ST = cast<StoreSDNode>(N);
977 EVT StoreVT = ST->getMemoryVT();
978 SDNode *NVPTXST = NULL;
980 // do not support pre/post inc/dec
984 if (!StoreVT.isSimple())
987 // Address Space Setting
988 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
991 // - .volatile is only availalble for .global and .shared
992 bool isVolatile = ST->isVolatile();
993 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
994 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
995 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
999 MVT SimpleVT = StoreVT.getSimpleVT();
1000 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1001 if (SimpleVT.isVector()) {
1002 unsigned num = SimpleVT.getVectorNumElements();
1004 vecType = NVPTX::PTXLdStInstCode::V2;
1006 vecType = NVPTX::PTXLdStInstCode::V4;
1011 // Type Setting: toType + toTypeWidth
1012 // - for integer type, always use 'u'
1014 MVT ScalarVT = SimpleVT.getScalarType();
1015 unsigned toTypeWidth = ScalarVT.getSizeInBits();
1016 unsigned int toType;
1017 if (ScalarVT.isFloatingPoint())
1018 toType = NVPTX::PTXLdStInstCode::Float;
1020 toType = NVPTX::PTXLdStInstCode::Unsigned;
1022 // Create the machine instruction DAG
1023 SDValue Chain = N->getOperand(0);
1024 SDValue N1 = N->getOperand(1);
1025 SDValue N2 = N->getOperand(2);
1027 SDValue Offset, Base;
1029 MVT::SimpleValueType SourceVT =
1030 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1032 if (SelectDirectAddr(N2, Addr)) {
1035 Opcode = NVPTX::ST_i8_avar;
1038 Opcode = NVPTX::ST_i16_avar;
1041 Opcode = NVPTX::ST_i32_avar;
1044 Opcode = NVPTX::ST_i64_avar;
1047 Opcode = NVPTX::ST_f32_avar;
1050 Opcode = NVPTX::ST_f64_avar;
1055 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1056 getI32Imm(vecType), getI32Imm(toType),
1057 getI32Imm(toTypeWidth), Addr, Chain };
1058 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 8);
1059 } else if (Subtarget.is64Bit()
1060 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1061 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1064 Opcode = NVPTX::ST_i8_asi;
1067 Opcode = NVPTX::ST_i16_asi;
1070 Opcode = NVPTX::ST_i32_asi;
1073 Opcode = NVPTX::ST_i64_asi;
1076 Opcode = NVPTX::ST_f32_asi;
1079 Opcode = NVPTX::ST_f64_asi;
1084 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1085 getI32Imm(vecType), getI32Imm(toType),
1086 getI32Imm(toTypeWidth), Base, Offset, Chain };
1087 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 9);
1088 } else if (Subtarget.is64Bit()
1089 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1090 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1091 if (Subtarget.is64Bit()) {
1094 Opcode = NVPTX::ST_i8_ari_64;
1097 Opcode = NVPTX::ST_i16_ari_64;
1100 Opcode = NVPTX::ST_i32_ari_64;
1103 Opcode = NVPTX::ST_i64_ari_64;
1106 Opcode = NVPTX::ST_f32_ari_64;
1109 Opcode = NVPTX::ST_f64_ari_64;
1117 Opcode = NVPTX::ST_i8_ari;
1120 Opcode = NVPTX::ST_i16_ari;
1123 Opcode = NVPTX::ST_i32_ari;
1126 Opcode = NVPTX::ST_i64_ari;
1129 Opcode = NVPTX::ST_f32_ari;
1132 Opcode = NVPTX::ST_f64_ari;
1138 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1139 getI32Imm(vecType), getI32Imm(toType),
1140 getI32Imm(toTypeWidth), Base, Offset, Chain };
1141 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 9);
1143 if (Subtarget.is64Bit()) {
1146 Opcode = NVPTX::ST_i8_areg_64;
1149 Opcode = NVPTX::ST_i16_areg_64;
1152 Opcode = NVPTX::ST_i32_areg_64;
1155 Opcode = NVPTX::ST_i64_areg_64;
1158 Opcode = NVPTX::ST_f32_areg_64;
1161 Opcode = NVPTX::ST_f64_areg_64;
1169 Opcode = NVPTX::ST_i8_areg;
1172 Opcode = NVPTX::ST_i16_areg;
1175 Opcode = NVPTX::ST_i32_areg;
1178 Opcode = NVPTX::ST_i64_areg;
1181 Opcode = NVPTX::ST_f32_areg;
1184 Opcode = NVPTX::ST_f64_areg;
1190 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1191 getI32Imm(vecType), getI32Imm(toType),
1192 getI32Imm(toTypeWidth), N2, Chain };
1193 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops, 8);
1196 if (NVPTXST != NULL) {
1197 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1198 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1199 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1205 SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1206 SDValue Chain = N->getOperand(0);
1207 SDValue Op1 = N->getOperand(1);
1208 SDValue Addr, Offset, Base;
1210 DebugLoc DL = N->getDebugLoc();
1212 EVT EltVT = Op1.getValueType();
1213 MemSDNode *MemSD = cast<MemSDNode>(N);
1214 EVT StoreVT = MemSD->getMemoryVT();
1216 // Address Space Setting
1217 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1219 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1220 report_fatal_error("Cannot store to pointer that points to constant "
1225 // - .volatile is only availalble for .global and .shared
1226 bool IsVolatile = MemSD->isVolatile();
1227 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1228 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1229 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1232 // Type Setting: toType + toTypeWidth
1233 // - for integer type, always use 'u'
1234 assert(StoreVT.isSimple() && "Store value is not simple");
1235 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
1236 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
1238 if (ScalarVT.isFloatingPoint())
1239 ToType = NVPTX::PTXLdStInstCode::Float;
1241 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1243 SmallVector<SDValue, 12> StOps;
1247 switch (N->getOpcode()) {
1248 case NVPTXISD::StoreV2:
1249 VecType = NVPTX::PTXLdStInstCode::V2;
1250 StOps.push_back(N->getOperand(1));
1251 StOps.push_back(N->getOperand(2));
1252 N2 = N->getOperand(3);
1254 case NVPTXISD::StoreV4:
1255 VecType = NVPTX::PTXLdStInstCode::V4;
1256 StOps.push_back(N->getOperand(1));
1257 StOps.push_back(N->getOperand(2));
1258 StOps.push_back(N->getOperand(3));
1259 StOps.push_back(N->getOperand(4));
1260 N2 = N->getOperand(5);
1266 StOps.push_back(getI32Imm(IsVolatile));
1267 StOps.push_back(getI32Imm(CodeAddrSpace));
1268 StOps.push_back(getI32Imm(VecType));
1269 StOps.push_back(getI32Imm(ToType));
1270 StOps.push_back(getI32Imm(ToTypeWidth));
1272 if (SelectDirectAddr(N2, Addr)) {
1273 switch (N->getOpcode()) {
1276 case NVPTXISD::StoreV2:
1277 switch (EltVT.getSimpleVT().SimpleTy) {
1281 Opcode = NVPTX::STV_i8_v2_avar;
1284 Opcode = NVPTX::STV_i16_v2_avar;
1287 Opcode = NVPTX::STV_i32_v2_avar;
1290 Opcode = NVPTX::STV_i64_v2_avar;
1293 Opcode = NVPTX::STV_f32_v2_avar;
1296 Opcode = NVPTX::STV_f64_v2_avar;
1300 case NVPTXISD::StoreV4:
1301 switch (EltVT.getSimpleVT().SimpleTy) {
1305 Opcode = NVPTX::STV_i8_v4_avar;
1308 Opcode = NVPTX::STV_i16_v4_avar;
1311 Opcode = NVPTX::STV_i32_v4_avar;
1314 Opcode = NVPTX::STV_f32_v4_avar;
1319 StOps.push_back(Addr);
1320 } else if (Subtarget.is64Bit()
1321 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1322 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1323 switch (N->getOpcode()) {
1326 case NVPTXISD::StoreV2:
1327 switch (EltVT.getSimpleVT().SimpleTy) {
1331 Opcode = NVPTX::STV_i8_v2_asi;
1334 Opcode = NVPTX::STV_i16_v2_asi;
1337 Opcode = NVPTX::STV_i32_v2_asi;
1340 Opcode = NVPTX::STV_i64_v2_asi;
1343 Opcode = NVPTX::STV_f32_v2_asi;
1346 Opcode = NVPTX::STV_f64_v2_asi;
1350 case NVPTXISD::StoreV4:
1351 switch (EltVT.getSimpleVT().SimpleTy) {
1355 Opcode = NVPTX::STV_i8_v4_asi;
1358 Opcode = NVPTX::STV_i16_v4_asi;
1361 Opcode = NVPTX::STV_i32_v4_asi;
1364 Opcode = NVPTX::STV_f32_v4_asi;
1369 StOps.push_back(Base);
1370 StOps.push_back(Offset);
1371 } else if (Subtarget.is64Bit()
1372 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1373 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1374 if (Subtarget.is64Bit()) {
1375 switch (N->getOpcode()) {
1378 case NVPTXISD::StoreV2:
1379 switch (EltVT.getSimpleVT().SimpleTy) {
1383 Opcode = NVPTX::STV_i8_v2_ari_64;
1386 Opcode = NVPTX::STV_i16_v2_ari_64;
1389 Opcode = NVPTX::STV_i32_v2_ari_64;
1392 Opcode = NVPTX::STV_i64_v2_ari_64;
1395 Opcode = NVPTX::STV_f32_v2_ari_64;
1398 Opcode = NVPTX::STV_f64_v2_ari_64;
1402 case NVPTXISD::StoreV4:
1403 switch (EltVT.getSimpleVT().SimpleTy) {
1407 Opcode = NVPTX::STV_i8_v4_ari_64;
1410 Opcode = NVPTX::STV_i16_v4_ari_64;
1413 Opcode = NVPTX::STV_i32_v4_ari_64;
1416 Opcode = NVPTX::STV_f32_v4_ari_64;
1422 switch (N->getOpcode()) {
1425 case NVPTXISD::StoreV2:
1426 switch (EltVT.getSimpleVT().SimpleTy) {
1430 Opcode = NVPTX::STV_i8_v2_ari;
1433 Opcode = NVPTX::STV_i16_v2_ari;
1436 Opcode = NVPTX::STV_i32_v2_ari;
1439 Opcode = NVPTX::STV_i64_v2_ari;
1442 Opcode = NVPTX::STV_f32_v2_ari;
1445 Opcode = NVPTX::STV_f64_v2_ari;
1449 case NVPTXISD::StoreV4:
1450 switch (EltVT.getSimpleVT().SimpleTy) {
1454 Opcode = NVPTX::STV_i8_v4_ari;
1457 Opcode = NVPTX::STV_i16_v4_ari;
1460 Opcode = NVPTX::STV_i32_v4_ari;
1463 Opcode = NVPTX::STV_f32_v4_ari;
1469 StOps.push_back(Base);
1470 StOps.push_back(Offset);
1472 if (Subtarget.is64Bit()) {
1473 switch (N->getOpcode()) {
1476 case NVPTXISD::StoreV2:
1477 switch (EltVT.getSimpleVT().SimpleTy) {
1481 Opcode = NVPTX::STV_i8_v2_areg_64;
1484 Opcode = NVPTX::STV_i16_v2_areg_64;
1487 Opcode = NVPTX::STV_i32_v2_areg_64;
1490 Opcode = NVPTX::STV_i64_v2_areg_64;
1493 Opcode = NVPTX::STV_f32_v2_areg_64;
1496 Opcode = NVPTX::STV_f64_v2_areg_64;
1500 case NVPTXISD::StoreV4:
1501 switch (EltVT.getSimpleVT().SimpleTy) {
1505 Opcode = NVPTX::STV_i8_v4_areg_64;
1508 Opcode = NVPTX::STV_i16_v4_areg_64;
1511 Opcode = NVPTX::STV_i32_v4_areg_64;
1514 Opcode = NVPTX::STV_f32_v4_areg_64;
1520 switch (N->getOpcode()) {
1523 case NVPTXISD::StoreV2:
1524 switch (EltVT.getSimpleVT().SimpleTy) {
1528 Opcode = NVPTX::STV_i8_v2_areg;
1531 Opcode = NVPTX::STV_i16_v2_areg;
1534 Opcode = NVPTX::STV_i32_v2_areg;
1537 Opcode = NVPTX::STV_i64_v2_areg;
1540 Opcode = NVPTX::STV_f32_v2_areg;
1543 Opcode = NVPTX::STV_f64_v2_areg;
1547 case NVPTXISD::StoreV4:
1548 switch (EltVT.getSimpleVT().SimpleTy) {
1552 Opcode = NVPTX::STV_i8_v4_areg;
1555 Opcode = NVPTX::STV_i16_v4_areg;
1558 Opcode = NVPTX::STV_i32_v4_areg;
1561 Opcode = NVPTX::STV_f32_v4_areg;
1567 StOps.push_back(N2);
1570 StOps.push_back(Chain);
1572 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, &StOps[0], StOps.size());
1574 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1575 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1576 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1581 // SelectDirectAddr - Match a direct address for DAG.
1582 // A direct address could be a globaladdress or externalsymbol.
1583 bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
1584 // Return true if TGA or ES.
1585 if (N.getOpcode() == ISD::TargetGlobalAddress ||
1586 N.getOpcode() == ISD::TargetExternalSymbol) {
1590 if (N.getOpcode() == NVPTXISD::Wrapper) {
1591 Address = N.getOperand(0);
1594 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
1595 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
1596 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
1597 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
1598 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
1604 bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
1605 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1606 if (Addr.getOpcode() == ISD::ADD) {
1607 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1608 SDValue base = Addr.getOperand(0);
1609 if (SelectDirectAddr(base, Base)) {
1610 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1619 bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
1620 SDValue &Base, SDValue &Offset) {
1621 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
1625 bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
1626 SDValue &Base, SDValue &Offset) {
1627 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
1631 bool NVPTXDAGToDAGISel::SelectADDRri_imp(
1632 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1633 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1634 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1635 Offset = CurDAG->getTargetConstant(0, mvt);
1638 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1639 Addr.getOpcode() == ISD::TargetGlobalAddress)
1640 return false; // direct calls.
1642 if (Addr.getOpcode() == ISD::ADD) {
1643 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
1646 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1647 if (FrameIndexSDNode *FIN =
1648 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
1649 // Constant offset from frame ref.
1650 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1652 Base = Addr.getOperand(0);
1653 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1661 bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
1662 SDValue &Base, SDValue &Offset) {
1663 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
1667 bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
1668 SDValue &Base, SDValue &Offset) {
1669 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
1672 bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
1673 unsigned int spN) const {
1674 const Value *Src = NULL;
1675 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
1676 // the classof() for MemSDNode does not include MemIntrinsicSDNode
1677 // (See SelectionDAGNodes.h). So we need to check for both.
1678 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1679 Src = mN->getSrcValue();
1680 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
1681 Src = mN->getSrcValue();
1685 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
1686 return (PT->getAddressSpace() == spN);
1690 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1691 /// inline asm expressions.
1692 bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
1693 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
1695 switch (ConstraintCode) {
1699 if (SelectDirectAddr(Op, Op0)) {
1700 OutOps.push_back(Op0);
1701 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1704 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
1705 OutOps.push_back(Op0);
1706 OutOps.push_back(Op1);
1714 // Return true if N is a undef or a constant.
1715 // If N was undef, return a (i8imm 0) in Retval
1716 // If N was imm, convert it to i8imm and return in Retval
1717 // Note: The convert to i8imm is required, otherwise the
1718 // pattern matcher inserts a bunch of IMOVi8rr to convert
1719 // the imm to i8imm, and this causes instruction selection
1721 bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
1722 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
1725 if (N.getOpcode() == ISD::UNDEF)
1726 Retval = CurDAG->getTargetConstant(0, MVT::i8);
1728 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
1729 unsigned retval = cn->getZExtValue();
1730 Retval = CurDAG->getTargetConstant(retval, MVT::i8);