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()) {
96 return NULL; // Already selected.
99 SDNode *ResNode = NULL;
100 switch (N->getOpcode()) {
102 ResNode = SelectLoad(N);
105 ResNode = SelectStore(N);
107 case NVPTXISD::LoadV2:
108 case NVPTXISD::LoadV4:
109 ResNode = SelectLoadVector(N);
111 case NVPTXISD::LDGV2:
112 case NVPTXISD::LDGV4:
113 case NVPTXISD::LDUV2:
114 case NVPTXISD::LDUV4:
115 ResNode = SelectLDGLDUVector(N);
117 case NVPTXISD::StoreV2:
118 case NVPTXISD::StoreV4:
119 ResNode = SelectStoreVector(N);
126 return SelectCode(N);
129 static unsigned int getCodeAddrSpace(MemSDNode *N,
130 const NVPTXSubtarget &Subtarget) {
131 const Value *Src = N->getSrcValue();
133 return NVPTX::PTXLdStInstCode::LOCAL;
135 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType())) {
136 switch (PT->getAddressSpace()) {
137 case llvm::ADDRESS_SPACE_LOCAL:
138 return NVPTX::PTXLdStInstCode::LOCAL;
139 case llvm::ADDRESS_SPACE_GLOBAL:
140 return NVPTX::PTXLdStInstCode::GLOBAL;
141 case llvm::ADDRESS_SPACE_SHARED:
142 return NVPTX::PTXLdStInstCode::SHARED;
143 case llvm::ADDRESS_SPACE_CONST_NOT_GEN:
144 return NVPTX::PTXLdStInstCode::CONSTANT;
145 case llvm::ADDRESS_SPACE_GENERIC:
146 return NVPTX::PTXLdStInstCode::GENERIC;
147 case llvm::ADDRESS_SPACE_PARAM:
148 return NVPTX::PTXLdStInstCode::PARAM;
149 case llvm::ADDRESS_SPACE_CONST:
150 // If the arch supports generic address space, translate it to GLOBAL
152 // If the arch does not support generic address space, then the arch
153 // does not really support ADDRESS_SPACE_CONST, translate it to
154 // to CONSTANT for better performance.
155 if (Subtarget.hasGenericLdSt())
156 return NVPTX::PTXLdStInstCode::GLOBAL;
158 return NVPTX::PTXLdStInstCode::CONSTANT;
163 return NVPTX::PTXLdStInstCode::LOCAL;
166 SDNode *NVPTXDAGToDAGISel::SelectLoad(SDNode *N) {
167 DebugLoc dl = N->getDebugLoc();
168 LoadSDNode *LD = cast<LoadSDNode>(N);
169 EVT LoadedVT = LD->getMemoryVT();
170 SDNode *NVPTXLD = NULL;
172 // do not support pre/post inc/dec
176 if (!LoadedVT.isSimple())
179 // Address Space Setting
180 unsigned int codeAddrSpace = getCodeAddrSpace(LD, Subtarget);
183 // - .volatile is only availalble for .global and .shared
184 bool isVolatile = LD->isVolatile();
185 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
186 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
187 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
191 MVT SimpleVT = LoadedVT.getSimpleVT();
192 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
193 if (SimpleVT.isVector()) {
194 unsigned num = SimpleVT.getVectorNumElements();
196 vecType = NVPTX::PTXLdStInstCode::V2;
198 vecType = NVPTX::PTXLdStInstCode::V4;
203 // Type Setting: fromType + fromTypeWidth
205 // Sign : ISD::SEXTLOAD
206 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
208 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
209 MVT ScalarVT = SimpleVT.getScalarType();
210 unsigned fromTypeWidth = ScalarVT.getSizeInBits();
211 unsigned int fromType;
212 if ((LD->getExtensionType() == ISD::SEXTLOAD))
213 fromType = NVPTX::PTXLdStInstCode::Signed;
214 else if (ScalarVT.isFloatingPoint())
215 fromType = NVPTX::PTXLdStInstCode::Float;
217 fromType = NVPTX::PTXLdStInstCode::Unsigned;
219 // Create the machine instruction DAG
220 SDValue Chain = N->getOperand(0);
221 SDValue N1 = N->getOperand(1);
223 SDValue Offset, Base;
225 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
227 if (SelectDirectAddr(N1, Addr)) {
230 Opcode = NVPTX::LD_i8_avar;
233 Opcode = NVPTX::LD_i16_avar;
236 Opcode = NVPTX::LD_i32_avar;
239 Opcode = NVPTX::LD_i64_avar;
242 Opcode = NVPTX::LD_f32_avar;
245 Opcode = NVPTX::LD_f64_avar;
250 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
251 getI32Imm(vecType), getI32Imm(fromType),
252 getI32Imm(fromTypeWidth), Addr, Chain };
253 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
254 } else if (Subtarget.is64Bit()
255 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
256 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
259 Opcode = NVPTX::LD_i8_asi;
262 Opcode = NVPTX::LD_i16_asi;
265 Opcode = NVPTX::LD_i32_asi;
268 Opcode = NVPTX::LD_i64_asi;
271 Opcode = NVPTX::LD_f32_asi;
274 Opcode = NVPTX::LD_f64_asi;
279 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
280 getI32Imm(vecType), getI32Imm(fromType),
281 getI32Imm(fromTypeWidth), Base, Offset, Chain };
282 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
283 } else if (Subtarget.is64Bit()
284 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
285 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
286 if (Subtarget.is64Bit()) {
289 Opcode = NVPTX::LD_i8_ari_64;
292 Opcode = NVPTX::LD_i16_ari_64;
295 Opcode = NVPTX::LD_i32_ari_64;
298 Opcode = NVPTX::LD_i64_ari_64;
301 Opcode = NVPTX::LD_f32_ari_64;
304 Opcode = NVPTX::LD_f64_ari_64;
312 Opcode = NVPTX::LD_i8_ari;
315 Opcode = NVPTX::LD_i16_ari;
318 Opcode = NVPTX::LD_i32_ari;
321 Opcode = NVPTX::LD_i64_ari;
324 Opcode = NVPTX::LD_f32_ari;
327 Opcode = NVPTX::LD_f64_ari;
333 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
334 getI32Imm(vecType), getI32Imm(fromType),
335 getI32Imm(fromTypeWidth), Base, Offset, Chain };
336 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
338 if (Subtarget.is64Bit()) {
341 Opcode = NVPTX::LD_i8_areg_64;
344 Opcode = NVPTX::LD_i16_areg_64;
347 Opcode = NVPTX::LD_i32_areg_64;
350 Opcode = NVPTX::LD_i64_areg_64;
353 Opcode = NVPTX::LD_f32_areg_64;
356 Opcode = NVPTX::LD_f64_areg_64;
364 Opcode = NVPTX::LD_i8_areg;
367 Opcode = NVPTX::LD_i16_areg;
370 Opcode = NVPTX::LD_i32_areg;
373 Opcode = NVPTX::LD_i64_areg;
376 Opcode = NVPTX::LD_f32_areg;
379 Opcode = NVPTX::LD_f64_areg;
385 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
386 getI32Imm(vecType), getI32Imm(fromType),
387 getI32Imm(fromTypeWidth), N1, Chain };
388 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
391 if (NVPTXLD != NULL) {
392 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
393 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
394 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
400 SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
402 SDValue Chain = N->getOperand(0);
403 SDValue Op1 = N->getOperand(1);
404 SDValue Addr, Offset, Base;
406 DebugLoc DL = N->getDebugLoc();
408 MemSDNode *MemSD = cast<MemSDNode>(N);
409 EVT LoadedVT = MemSD->getMemoryVT();
411 if (!LoadedVT.isSimple())
414 // Address Space Setting
415 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
418 // - .volatile is only availalble for .global and .shared
419 bool IsVolatile = MemSD->isVolatile();
420 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
421 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
422 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
426 MVT SimpleVT = LoadedVT.getSimpleVT();
428 // Type Setting: fromType + fromTypeWidth
430 // Sign : ISD::SEXTLOAD
431 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
433 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
434 MVT ScalarVT = SimpleVT.getScalarType();
435 unsigned FromTypeWidth = ScalarVT.getSizeInBits();
436 unsigned int FromType;
437 // The last operand holds the original LoadSDNode::getExtensionType() value
438 unsigned ExtensionType = cast<ConstantSDNode>(
439 N->getOperand(N->getNumOperands() - 1))->getZExtValue();
440 if (ExtensionType == ISD::SEXTLOAD)
441 FromType = NVPTX::PTXLdStInstCode::Signed;
442 else if (ScalarVT.isFloatingPoint())
443 FromType = NVPTX::PTXLdStInstCode::Float;
445 FromType = NVPTX::PTXLdStInstCode::Unsigned;
449 switch (N->getOpcode()) {
450 case NVPTXISD::LoadV2:
451 VecType = NVPTX::PTXLdStInstCode::V2;
453 case NVPTXISD::LoadV4:
454 VecType = NVPTX::PTXLdStInstCode::V4;
460 EVT EltVT = N->getValueType(0);
462 if (SelectDirectAddr(Op1, Addr)) {
463 switch (N->getOpcode()) {
466 case NVPTXISD::LoadV2:
467 switch (EltVT.getSimpleVT().SimpleTy) {
471 Opcode = NVPTX::LDV_i8_v2_avar;
474 Opcode = NVPTX::LDV_i16_v2_avar;
477 Opcode = NVPTX::LDV_i32_v2_avar;
480 Opcode = NVPTX::LDV_i64_v2_avar;
483 Opcode = NVPTX::LDV_f32_v2_avar;
486 Opcode = NVPTX::LDV_f64_v2_avar;
490 case NVPTXISD::LoadV4:
491 switch (EltVT.getSimpleVT().SimpleTy) {
495 Opcode = NVPTX::LDV_i8_v4_avar;
498 Opcode = NVPTX::LDV_i16_v4_avar;
501 Opcode = NVPTX::LDV_i32_v4_avar;
504 Opcode = NVPTX::LDV_f32_v4_avar;
510 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
511 getI32Imm(VecType), getI32Imm(FromType),
512 getI32Imm(FromTypeWidth), Addr, Chain };
513 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
514 } else if (Subtarget.is64Bit()
515 ? SelectADDRsi64(Op1.getNode(), Op1, Base, Offset)
516 : SelectADDRsi(Op1.getNode(), Op1, Base, Offset)) {
517 switch (N->getOpcode()) {
520 case NVPTXISD::LoadV2:
521 switch (EltVT.getSimpleVT().SimpleTy) {
525 Opcode = NVPTX::LDV_i8_v2_asi;
528 Opcode = NVPTX::LDV_i16_v2_asi;
531 Opcode = NVPTX::LDV_i32_v2_asi;
534 Opcode = NVPTX::LDV_i64_v2_asi;
537 Opcode = NVPTX::LDV_f32_v2_asi;
540 Opcode = NVPTX::LDV_f64_v2_asi;
544 case NVPTXISD::LoadV4:
545 switch (EltVT.getSimpleVT().SimpleTy) {
549 Opcode = NVPTX::LDV_i8_v4_asi;
552 Opcode = NVPTX::LDV_i16_v4_asi;
555 Opcode = NVPTX::LDV_i32_v4_asi;
558 Opcode = NVPTX::LDV_f32_v4_asi;
564 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
565 getI32Imm(VecType), getI32Imm(FromType),
566 getI32Imm(FromTypeWidth), Base, Offset, Chain };
567 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
568 } else if (Subtarget.is64Bit()
569 ? SelectADDRri64(Op1.getNode(), Op1, Base, Offset)
570 : SelectADDRri(Op1.getNode(), Op1, Base, Offset)) {
571 if (Subtarget.is64Bit()) {
572 switch (N->getOpcode()) {
575 case NVPTXISD::LoadV2:
576 switch (EltVT.getSimpleVT().SimpleTy) {
580 Opcode = NVPTX::LDV_i8_v2_ari_64;
583 Opcode = NVPTX::LDV_i16_v2_ari_64;
586 Opcode = NVPTX::LDV_i32_v2_ari_64;
589 Opcode = NVPTX::LDV_i64_v2_ari_64;
592 Opcode = NVPTX::LDV_f32_v2_ari_64;
595 Opcode = NVPTX::LDV_f64_v2_ari_64;
599 case NVPTXISD::LoadV4:
600 switch (EltVT.getSimpleVT().SimpleTy) {
604 Opcode = NVPTX::LDV_i8_v4_ari_64;
607 Opcode = NVPTX::LDV_i16_v4_ari_64;
610 Opcode = NVPTX::LDV_i32_v4_ari_64;
613 Opcode = NVPTX::LDV_f32_v4_ari_64;
619 switch (N->getOpcode()) {
622 case NVPTXISD::LoadV2:
623 switch (EltVT.getSimpleVT().SimpleTy) {
627 Opcode = NVPTX::LDV_i8_v2_ari;
630 Opcode = NVPTX::LDV_i16_v2_ari;
633 Opcode = NVPTX::LDV_i32_v2_ari;
636 Opcode = NVPTX::LDV_i64_v2_ari;
639 Opcode = NVPTX::LDV_f32_v2_ari;
642 Opcode = NVPTX::LDV_f64_v2_ari;
646 case NVPTXISD::LoadV4:
647 switch (EltVT.getSimpleVT().SimpleTy) {
651 Opcode = NVPTX::LDV_i8_v4_ari;
654 Opcode = NVPTX::LDV_i16_v4_ari;
657 Opcode = NVPTX::LDV_i32_v4_ari;
660 Opcode = NVPTX::LDV_f32_v4_ari;
667 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
668 getI32Imm(VecType), getI32Imm(FromType),
669 getI32Imm(FromTypeWidth), Base, Offset, Chain };
671 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
673 if (Subtarget.is64Bit()) {
674 switch (N->getOpcode()) {
677 case NVPTXISD::LoadV2:
678 switch (EltVT.getSimpleVT().SimpleTy) {
682 Opcode = NVPTX::LDV_i8_v2_areg_64;
685 Opcode = NVPTX::LDV_i16_v2_areg_64;
688 Opcode = NVPTX::LDV_i32_v2_areg_64;
691 Opcode = NVPTX::LDV_i64_v2_areg_64;
694 Opcode = NVPTX::LDV_f32_v2_areg_64;
697 Opcode = NVPTX::LDV_f64_v2_areg_64;
701 case NVPTXISD::LoadV4:
702 switch (EltVT.getSimpleVT().SimpleTy) {
706 Opcode = NVPTX::LDV_i8_v4_areg_64;
709 Opcode = NVPTX::LDV_i16_v4_areg_64;
712 Opcode = NVPTX::LDV_i32_v4_areg_64;
715 Opcode = NVPTX::LDV_f32_v4_areg_64;
721 switch (N->getOpcode()) {
724 case NVPTXISD::LoadV2:
725 switch (EltVT.getSimpleVT().SimpleTy) {
729 Opcode = NVPTX::LDV_i8_v2_areg;
732 Opcode = NVPTX::LDV_i16_v2_areg;
735 Opcode = NVPTX::LDV_i32_v2_areg;
738 Opcode = NVPTX::LDV_i64_v2_areg;
741 Opcode = NVPTX::LDV_f32_v2_areg;
744 Opcode = NVPTX::LDV_f64_v2_areg;
748 case NVPTXISD::LoadV4:
749 switch (EltVT.getSimpleVT().SimpleTy) {
753 Opcode = NVPTX::LDV_i8_v4_areg;
756 Opcode = NVPTX::LDV_i16_v4_areg;
759 Opcode = NVPTX::LDV_i32_v4_areg;
762 Opcode = NVPTX::LDV_f32_v4_areg;
769 SDValue Ops[] = { getI32Imm(IsVolatile), getI32Imm(CodeAddrSpace),
770 getI32Imm(VecType), getI32Imm(FromType),
771 getI32Imm(FromTypeWidth), Op1, Chain };
772 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
775 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
776 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
777 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
782 SDNode *NVPTXDAGToDAGISel::SelectLDGLDUVector(SDNode *N) {
784 SDValue Chain = N->getOperand(0);
785 SDValue Op1 = N->getOperand(1);
787 DebugLoc DL = N->getDebugLoc();
790 EVT RetVT = N->getValueType(0);
793 if (Subtarget.is64Bit()) {
794 switch (N->getOpcode()) {
797 case NVPTXISD::LDGV2:
798 switch (RetVT.getSimpleVT().SimpleTy) {
802 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_64;
805 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_64;
808 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_64;
811 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_64;
814 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_64;
817 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_64;
821 case NVPTXISD::LDGV4:
822 switch (RetVT.getSimpleVT().SimpleTy) {
826 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_64;
829 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_64;
832 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_64;
835 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_64;
839 case NVPTXISD::LDUV2:
840 switch (RetVT.getSimpleVT().SimpleTy) {
844 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_64;
847 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_64;
850 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_64;
853 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_64;
856 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_64;
859 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_64;
863 case NVPTXISD::LDUV4:
864 switch (RetVT.getSimpleVT().SimpleTy) {
868 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_64;
871 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_64;
874 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_64;
877 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_64;
883 switch (N->getOpcode()) {
886 case NVPTXISD::LDGV2:
887 switch (RetVT.getSimpleVT().SimpleTy) {
891 Opcode = NVPTX::INT_PTX_LDG_G_v2i8_ELE_32;
894 Opcode = NVPTX::INT_PTX_LDG_G_v2i16_ELE_32;
897 Opcode = NVPTX::INT_PTX_LDG_G_v2i32_ELE_32;
900 Opcode = NVPTX::INT_PTX_LDG_G_v2i64_ELE_32;
903 Opcode = NVPTX::INT_PTX_LDG_G_v2f32_ELE_32;
906 Opcode = NVPTX::INT_PTX_LDG_G_v2f64_ELE_32;
910 case NVPTXISD::LDGV4:
911 switch (RetVT.getSimpleVT().SimpleTy) {
915 Opcode = NVPTX::INT_PTX_LDG_G_v4i8_ELE_32;
918 Opcode = NVPTX::INT_PTX_LDG_G_v4i16_ELE_32;
921 Opcode = NVPTX::INT_PTX_LDG_G_v4i32_ELE_32;
924 Opcode = NVPTX::INT_PTX_LDG_G_v4f32_ELE_32;
928 case NVPTXISD::LDUV2:
929 switch (RetVT.getSimpleVT().SimpleTy) {
933 Opcode = NVPTX::INT_PTX_LDU_G_v2i8_ELE_32;
936 Opcode = NVPTX::INT_PTX_LDU_G_v2i16_ELE_32;
939 Opcode = NVPTX::INT_PTX_LDU_G_v2i32_ELE_32;
942 Opcode = NVPTX::INT_PTX_LDU_G_v2i64_ELE_32;
945 Opcode = NVPTX::INT_PTX_LDU_G_v2f32_ELE_32;
948 Opcode = NVPTX::INT_PTX_LDU_G_v2f64_ELE_32;
952 case NVPTXISD::LDUV4:
953 switch (RetVT.getSimpleVT().SimpleTy) {
957 Opcode = NVPTX::INT_PTX_LDU_G_v4i8_ELE_32;
960 Opcode = NVPTX::INT_PTX_LDU_G_v4i16_ELE_32;
963 Opcode = NVPTX::INT_PTX_LDU_G_v4i32_ELE_32;
966 Opcode = NVPTX::INT_PTX_LDU_G_v4f32_ELE_32;
973 SDValue Ops[] = { Op1, Chain };
974 LD = CurDAG->getMachineNode(Opcode, DL, N->getVTList(), Ops);
976 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
977 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
978 cast<MachineSDNode>(LD)->setMemRefs(MemRefs0, MemRefs0 + 1);
983 SDNode *NVPTXDAGToDAGISel::SelectStore(SDNode *N) {
984 DebugLoc dl = N->getDebugLoc();
985 StoreSDNode *ST = cast<StoreSDNode>(N);
986 EVT StoreVT = ST->getMemoryVT();
987 SDNode *NVPTXST = NULL;
989 // do not support pre/post inc/dec
993 if (!StoreVT.isSimple())
996 // Address Space Setting
997 unsigned int codeAddrSpace = getCodeAddrSpace(ST, Subtarget);
1000 // - .volatile is only availalble for .global and .shared
1001 bool isVolatile = ST->isVolatile();
1002 if (codeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1003 codeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1004 codeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1008 MVT SimpleVT = StoreVT.getSimpleVT();
1009 unsigned vecType = NVPTX::PTXLdStInstCode::Scalar;
1010 if (SimpleVT.isVector()) {
1011 unsigned num = SimpleVT.getVectorNumElements();
1013 vecType = NVPTX::PTXLdStInstCode::V2;
1015 vecType = NVPTX::PTXLdStInstCode::V4;
1020 // Type Setting: toType + toTypeWidth
1021 // - for integer type, always use 'u'
1023 MVT ScalarVT = SimpleVT.getScalarType();
1024 unsigned toTypeWidth = ScalarVT.getSizeInBits();
1025 unsigned int toType;
1026 if (ScalarVT.isFloatingPoint())
1027 toType = NVPTX::PTXLdStInstCode::Float;
1029 toType = NVPTX::PTXLdStInstCode::Unsigned;
1031 // Create the machine instruction DAG
1032 SDValue Chain = N->getOperand(0);
1033 SDValue N1 = N->getOperand(1);
1034 SDValue N2 = N->getOperand(2);
1036 SDValue Offset, Base;
1038 MVT::SimpleValueType SourceVT =
1039 N1.getNode()->getValueType(0).getSimpleVT().SimpleTy;
1041 if (SelectDirectAddr(N2, Addr)) {
1044 Opcode = NVPTX::ST_i8_avar;
1047 Opcode = NVPTX::ST_i16_avar;
1050 Opcode = NVPTX::ST_i32_avar;
1053 Opcode = NVPTX::ST_i64_avar;
1056 Opcode = NVPTX::ST_f32_avar;
1059 Opcode = NVPTX::ST_f64_avar;
1064 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1065 getI32Imm(vecType), getI32Imm(toType),
1066 getI32Imm(toTypeWidth), Addr, Chain };
1067 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1068 } else if (Subtarget.is64Bit()
1069 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1070 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1073 Opcode = NVPTX::ST_i8_asi;
1076 Opcode = NVPTX::ST_i16_asi;
1079 Opcode = NVPTX::ST_i32_asi;
1082 Opcode = NVPTX::ST_i64_asi;
1085 Opcode = NVPTX::ST_f32_asi;
1088 Opcode = NVPTX::ST_f64_asi;
1093 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1094 getI32Imm(vecType), getI32Imm(toType),
1095 getI32Imm(toTypeWidth), Base, Offset, Chain };
1096 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1097 } else if (Subtarget.is64Bit()
1098 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1099 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1100 if (Subtarget.is64Bit()) {
1103 Opcode = NVPTX::ST_i8_ari_64;
1106 Opcode = NVPTX::ST_i16_ari_64;
1109 Opcode = NVPTX::ST_i32_ari_64;
1112 Opcode = NVPTX::ST_i64_ari_64;
1115 Opcode = NVPTX::ST_f32_ari_64;
1118 Opcode = NVPTX::ST_f64_ari_64;
1126 Opcode = NVPTX::ST_i8_ari;
1129 Opcode = NVPTX::ST_i16_ari;
1132 Opcode = NVPTX::ST_i32_ari;
1135 Opcode = NVPTX::ST_i64_ari;
1138 Opcode = NVPTX::ST_f32_ari;
1141 Opcode = NVPTX::ST_f64_ari;
1147 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1148 getI32Imm(vecType), getI32Imm(toType),
1149 getI32Imm(toTypeWidth), Base, Offset, Chain };
1150 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1152 if (Subtarget.is64Bit()) {
1155 Opcode = NVPTX::ST_i8_areg_64;
1158 Opcode = NVPTX::ST_i16_areg_64;
1161 Opcode = NVPTX::ST_i32_areg_64;
1164 Opcode = NVPTX::ST_i64_areg_64;
1167 Opcode = NVPTX::ST_f32_areg_64;
1170 Opcode = NVPTX::ST_f64_areg_64;
1178 Opcode = NVPTX::ST_i8_areg;
1181 Opcode = NVPTX::ST_i16_areg;
1184 Opcode = NVPTX::ST_i32_areg;
1187 Opcode = NVPTX::ST_i64_areg;
1190 Opcode = NVPTX::ST_f32_areg;
1193 Opcode = NVPTX::ST_f64_areg;
1199 SDValue Ops[] = { N1, getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
1200 getI32Imm(vecType), getI32Imm(toType),
1201 getI32Imm(toTypeWidth), N2, Chain };
1202 NVPTXST = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops);
1205 if (NVPTXST != NULL) {
1206 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1207 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1208 cast<MachineSDNode>(NVPTXST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1214 SDNode *NVPTXDAGToDAGISel::SelectStoreVector(SDNode *N) {
1215 SDValue Chain = N->getOperand(0);
1216 SDValue Op1 = N->getOperand(1);
1217 SDValue Addr, Offset, Base;
1219 DebugLoc DL = N->getDebugLoc();
1221 EVT EltVT = Op1.getValueType();
1222 MemSDNode *MemSD = cast<MemSDNode>(N);
1223 EVT StoreVT = MemSD->getMemoryVT();
1225 // Address Space Setting
1226 unsigned CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
1228 if (CodeAddrSpace == NVPTX::PTXLdStInstCode::CONSTANT) {
1229 report_fatal_error("Cannot store to pointer that points to constant "
1234 // - .volatile is only availalble for .global and .shared
1235 bool IsVolatile = MemSD->isVolatile();
1236 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
1237 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
1238 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
1241 // Type Setting: toType + toTypeWidth
1242 // - for integer type, always use 'u'
1243 assert(StoreVT.isSimple() && "Store value is not simple");
1244 MVT ScalarVT = StoreVT.getSimpleVT().getScalarType();
1245 unsigned ToTypeWidth = ScalarVT.getSizeInBits();
1247 if (ScalarVT.isFloatingPoint())
1248 ToType = NVPTX::PTXLdStInstCode::Float;
1250 ToType = NVPTX::PTXLdStInstCode::Unsigned;
1252 SmallVector<SDValue, 12> StOps;
1256 switch (N->getOpcode()) {
1257 case NVPTXISD::StoreV2:
1258 VecType = NVPTX::PTXLdStInstCode::V2;
1259 StOps.push_back(N->getOperand(1));
1260 StOps.push_back(N->getOperand(2));
1261 N2 = N->getOperand(3);
1263 case NVPTXISD::StoreV4:
1264 VecType = NVPTX::PTXLdStInstCode::V4;
1265 StOps.push_back(N->getOperand(1));
1266 StOps.push_back(N->getOperand(2));
1267 StOps.push_back(N->getOperand(3));
1268 StOps.push_back(N->getOperand(4));
1269 N2 = N->getOperand(5);
1275 StOps.push_back(getI32Imm(IsVolatile));
1276 StOps.push_back(getI32Imm(CodeAddrSpace));
1277 StOps.push_back(getI32Imm(VecType));
1278 StOps.push_back(getI32Imm(ToType));
1279 StOps.push_back(getI32Imm(ToTypeWidth));
1281 if (SelectDirectAddr(N2, Addr)) {
1282 switch (N->getOpcode()) {
1285 case NVPTXISD::StoreV2:
1286 switch (EltVT.getSimpleVT().SimpleTy) {
1290 Opcode = NVPTX::STV_i8_v2_avar;
1293 Opcode = NVPTX::STV_i16_v2_avar;
1296 Opcode = NVPTX::STV_i32_v2_avar;
1299 Opcode = NVPTX::STV_i64_v2_avar;
1302 Opcode = NVPTX::STV_f32_v2_avar;
1305 Opcode = NVPTX::STV_f64_v2_avar;
1309 case NVPTXISD::StoreV4:
1310 switch (EltVT.getSimpleVT().SimpleTy) {
1314 Opcode = NVPTX::STV_i8_v4_avar;
1317 Opcode = NVPTX::STV_i16_v4_avar;
1320 Opcode = NVPTX::STV_i32_v4_avar;
1323 Opcode = NVPTX::STV_f32_v4_avar;
1328 StOps.push_back(Addr);
1329 } else if (Subtarget.is64Bit()
1330 ? SelectADDRsi64(N2.getNode(), N2, Base, Offset)
1331 : SelectADDRsi(N2.getNode(), N2, Base, Offset)) {
1332 switch (N->getOpcode()) {
1335 case NVPTXISD::StoreV2:
1336 switch (EltVT.getSimpleVT().SimpleTy) {
1340 Opcode = NVPTX::STV_i8_v2_asi;
1343 Opcode = NVPTX::STV_i16_v2_asi;
1346 Opcode = NVPTX::STV_i32_v2_asi;
1349 Opcode = NVPTX::STV_i64_v2_asi;
1352 Opcode = NVPTX::STV_f32_v2_asi;
1355 Opcode = NVPTX::STV_f64_v2_asi;
1359 case NVPTXISD::StoreV4:
1360 switch (EltVT.getSimpleVT().SimpleTy) {
1364 Opcode = NVPTX::STV_i8_v4_asi;
1367 Opcode = NVPTX::STV_i16_v4_asi;
1370 Opcode = NVPTX::STV_i32_v4_asi;
1373 Opcode = NVPTX::STV_f32_v4_asi;
1378 StOps.push_back(Base);
1379 StOps.push_back(Offset);
1380 } else if (Subtarget.is64Bit()
1381 ? SelectADDRri64(N2.getNode(), N2, Base, Offset)
1382 : SelectADDRri(N2.getNode(), N2, Base, Offset)) {
1383 if (Subtarget.is64Bit()) {
1384 switch (N->getOpcode()) {
1387 case NVPTXISD::StoreV2:
1388 switch (EltVT.getSimpleVT().SimpleTy) {
1392 Opcode = NVPTX::STV_i8_v2_ari_64;
1395 Opcode = NVPTX::STV_i16_v2_ari_64;
1398 Opcode = NVPTX::STV_i32_v2_ari_64;
1401 Opcode = NVPTX::STV_i64_v2_ari_64;
1404 Opcode = NVPTX::STV_f32_v2_ari_64;
1407 Opcode = NVPTX::STV_f64_v2_ari_64;
1411 case NVPTXISD::StoreV4:
1412 switch (EltVT.getSimpleVT().SimpleTy) {
1416 Opcode = NVPTX::STV_i8_v4_ari_64;
1419 Opcode = NVPTX::STV_i16_v4_ari_64;
1422 Opcode = NVPTX::STV_i32_v4_ari_64;
1425 Opcode = NVPTX::STV_f32_v4_ari_64;
1431 switch (N->getOpcode()) {
1434 case NVPTXISD::StoreV2:
1435 switch (EltVT.getSimpleVT().SimpleTy) {
1439 Opcode = NVPTX::STV_i8_v2_ari;
1442 Opcode = NVPTX::STV_i16_v2_ari;
1445 Opcode = NVPTX::STV_i32_v2_ari;
1448 Opcode = NVPTX::STV_i64_v2_ari;
1451 Opcode = NVPTX::STV_f32_v2_ari;
1454 Opcode = NVPTX::STV_f64_v2_ari;
1458 case NVPTXISD::StoreV4:
1459 switch (EltVT.getSimpleVT().SimpleTy) {
1463 Opcode = NVPTX::STV_i8_v4_ari;
1466 Opcode = NVPTX::STV_i16_v4_ari;
1469 Opcode = NVPTX::STV_i32_v4_ari;
1472 Opcode = NVPTX::STV_f32_v4_ari;
1478 StOps.push_back(Base);
1479 StOps.push_back(Offset);
1481 if (Subtarget.is64Bit()) {
1482 switch (N->getOpcode()) {
1485 case NVPTXISD::StoreV2:
1486 switch (EltVT.getSimpleVT().SimpleTy) {
1490 Opcode = NVPTX::STV_i8_v2_areg_64;
1493 Opcode = NVPTX::STV_i16_v2_areg_64;
1496 Opcode = NVPTX::STV_i32_v2_areg_64;
1499 Opcode = NVPTX::STV_i64_v2_areg_64;
1502 Opcode = NVPTX::STV_f32_v2_areg_64;
1505 Opcode = NVPTX::STV_f64_v2_areg_64;
1509 case NVPTXISD::StoreV4:
1510 switch (EltVT.getSimpleVT().SimpleTy) {
1514 Opcode = NVPTX::STV_i8_v4_areg_64;
1517 Opcode = NVPTX::STV_i16_v4_areg_64;
1520 Opcode = NVPTX::STV_i32_v4_areg_64;
1523 Opcode = NVPTX::STV_f32_v4_areg_64;
1529 switch (N->getOpcode()) {
1532 case NVPTXISD::StoreV2:
1533 switch (EltVT.getSimpleVT().SimpleTy) {
1537 Opcode = NVPTX::STV_i8_v2_areg;
1540 Opcode = NVPTX::STV_i16_v2_areg;
1543 Opcode = NVPTX::STV_i32_v2_areg;
1546 Opcode = NVPTX::STV_i64_v2_areg;
1549 Opcode = NVPTX::STV_f32_v2_areg;
1552 Opcode = NVPTX::STV_f64_v2_areg;
1556 case NVPTXISD::StoreV4:
1557 switch (EltVT.getSimpleVT().SimpleTy) {
1561 Opcode = NVPTX::STV_i8_v4_areg;
1564 Opcode = NVPTX::STV_i16_v4_areg;
1567 Opcode = NVPTX::STV_i32_v4_areg;
1570 Opcode = NVPTX::STV_f32_v4_areg;
1576 StOps.push_back(N2);
1579 StOps.push_back(Chain);
1581 ST = CurDAG->getMachineNode(Opcode, DL, MVT::Other, StOps);
1583 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
1584 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
1585 cast<MachineSDNode>(ST)->setMemRefs(MemRefs0, MemRefs0 + 1);
1590 // SelectDirectAddr - Match a direct address for DAG.
1591 // A direct address could be a globaladdress or externalsymbol.
1592 bool NVPTXDAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
1593 // Return true if TGA or ES.
1594 if (N.getOpcode() == ISD::TargetGlobalAddress ||
1595 N.getOpcode() == ISD::TargetExternalSymbol) {
1599 if (N.getOpcode() == NVPTXISD::Wrapper) {
1600 Address = N.getOperand(0);
1603 if (N.getOpcode() == ISD::INTRINSIC_WO_CHAIN) {
1604 unsigned IID = cast<ConstantSDNode>(N.getOperand(0))->getZExtValue();
1605 if (IID == Intrinsic::nvvm_ptr_gen_to_param)
1606 if (N.getOperand(1).getOpcode() == NVPTXISD::MoveParam)
1607 return (SelectDirectAddr(N.getOperand(1).getOperand(0), Address));
1613 bool NVPTXDAGToDAGISel::SelectADDRsi_imp(
1614 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1615 if (Addr.getOpcode() == ISD::ADD) {
1616 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1617 SDValue base = Addr.getOperand(0);
1618 if (SelectDirectAddr(base, Base)) {
1619 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1628 bool NVPTXDAGToDAGISel::SelectADDRsi(SDNode *OpNode, SDValue Addr,
1629 SDValue &Base, SDValue &Offset) {
1630 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i32);
1634 bool NVPTXDAGToDAGISel::SelectADDRsi64(SDNode *OpNode, SDValue Addr,
1635 SDValue &Base, SDValue &Offset) {
1636 return SelectADDRsi_imp(OpNode, Addr, Base, Offset, MVT::i64);
1640 bool NVPTXDAGToDAGISel::SelectADDRri_imp(
1641 SDNode *OpNode, SDValue Addr, SDValue &Base, SDValue &Offset, MVT mvt) {
1642 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1643 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1644 Offset = CurDAG->getTargetConstant(0, mvt);
1647 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1648 Addr.getOpcode() == ISD::TargetGlobalAddress)
1649 return false; // direct calls.
1651 if (Addr.getOpcode() == ISD::ADD) {
1652 if (SelectDirectAddr(Addr.getOperand(0), Addr)) {
1655 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
1656 if (FrameIndexSDNode *FIN =
1657 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
1658 // Constant offset from frame ref.
1659 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), mvt);
1661 Base = Addr.getOperand(0);
1662 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), mvt);
1670 bool NVPTXDAGToDAGISel::SelectADDRri(SDNode *OpNode, SDValue Addr,
1671 SDValue &Base, SDValue &Offset) {
1672 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i32);
1676 bool NVPTXDAGToDAGISel::SelectADDRri64(SDNode *OpNode, SDValue Addr,
1677 SDValue &Base, SDValue &Offset) {
1678 return SelectADDRri_imp(OpNode, Addr, Base, Offset, MVT::i64);
1681 bool NVPTXDAGToDAGISel::ChkMemSDNodeAddressSpace(SDNode *N,
1682 unsigned int spN) const {
1683 const Value *Src = NULL;
1684 // Even though MemIntrinsicSDNode is a subclas of MemSDNode,
1685 // the classof() for MemSDNode does not include MemIntrinsicSDNode
1686 // (See SelectionDAGNodes.h). So we need to check for both.
1687 if (MemSDNode *mN = dyn_cast<MemSDNode>(N)) {
1688 Src = mN->getSrcValue();
1689 } else if (MemSDNode *mN = dyn_cast<MemIntrinsicSDNode>(N)) {
1690 Src = mN->getSrcValue();
1694 if (const PointerType *PT = dyn_cast<PointerType>(Src->getType()))
1695 return (PT->getAddressSpace() == spN);
1699 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
1700 /// inline asm expressions.
1701 bool NVPTXDAGToDAGISel::SelectInlineAsmMemoryOperand(
1702 const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) {
1704 switch (ConstraintCode) {
1708 if (SelectDirectAddr(Op, Op0)) {
1709 OutOps.push_back(Op0);
1710 OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
1713 if (SelectADDRri(Op.getNode(), Op, Op0, Op1)) {
1714 OutOps.push_back(Op0);
1715 OutOps.push_back(Op1);
1723 // Return true if N is a undef or a constant.
1724 // If N was undef, return a (i8imm 0) in Retval
1725 // If N was imm, convert it to i8imm and return in Retval
1726 // Note: The convert to i8imm is required, otherwise the
1727 // pattern matcher inserts a bunch of IMOVi8rr to convert
1728 // the imm to i8imm, and this causes instruction selection
1730 bool NVPTXDAGToDAGISel::UndefOrImm(SDValue Op, SDValue N, SDValue &Retval) {
1731 if (!(N.getOpcode() == ISD::UNDEF) && !(N.getOpcode() == ISD::Constant))
1734 if (N.getOpcode() == ISD::UNDEF)
1735 Retval = CurDAG->getTargetConstant(0, MVT::i8);
1737 ConstantSDNode *cn = cast<ConstantSDNode>(N.getNode());
1738 unsigned retval = cn->getZExtValue();
1739 Retval = CurDAG->getTargetConstant(retval, MVT::i8);