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) {
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 // Read at least 8 bits (predicates are stored as 8-bit values)
209 unsigned fromTypeWidth = std::max(8U, ScalarVT.getSizeInBits());
210 unsigned int fromType;
211 if ((LD->getExtensionType() == ISD::SEXTLOAD))
212 fromType = NVPTX::PTXLdStInstCode::Signed;
213 else if (ScalarVT.isFloatingPoint())
214 fromType = NVPTX::PTXLdStInstCode::Float;
216 fromType = NVPTX::PTXLdStInstCode::Unsigned;
218 // Create the machine instruction DAG
219 SDValue Chain = N->getOperand(0);
220 SDValue N1 = N->getOperand(1);
222 SDValue Offset, Base;
224 MVT::SimpleValueType TargetVT = LD->getValueType(0).getSimpleVT().SimpleTy;
226 if (SelectDirectAddr(N1, Addr)) {
229 Opcode = NVPTX::LD_i8_avar;
232 Opcode = NVPTX::LD_i16_avar;
235 Opcode = NVPTX::LD_i32_avar;
238 Opcode = NVPTX::LD_i64_avar;
241 Opcode = NVPTX::LD_f32_avar;
244 Opcode = NVPTX::LD_f64_avar;
249 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
250 getI32Imm(vecType), getI32Imm(fromType),
251 getI32Imm(fromTypeWidth), Addr, Chain };
252 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
253 } else if (Subtarget.is64Bit()
254 ? SelectADDRsi64(N1.getNode(), N1, Base, Offset)
255 : SelectADDRsi(N1.getNode(), N1, Base, Offset)) {
258 Opcode = NVPTX::LD_i8_asi;
261 Opcode = NVPTX::LD_i16_asi;
264 Opcode = NVPTX::LD_i32_asi;
267 Opcode = NVPTX::LD_i64_asi;
270 Opcode = NVPTX::LD_f32_asi;
273 Opcode = NVPTX::LD_f64_asi;
278 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
279 getI32Imm(vecType), getI32Imm(fromType),
280 getI32Imm(fromTypeWidth), Base, Offset, Chain };
281 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
282 } else if (Subtarget.is64Bit()
283 ? SelectADDRri64(N1.getNode(), N1, Base, Offset)
284 : SelectADDRri(N1.getNode(), N1, Base, Offset)) {
285 if (Subtarget.is64Bit()) {
288 Opcode = NVPTX::LD_i8_ari_64;
291 Opcode = NVPTX::LD_i16_ari_64;
294 Opcode = NVPTX::LD_i32_ari_64;
297 Opcode = NVPTX::LD_i64_ari_64;
300 Opcode = NVPTX::LD_f32_ari_64;
303 Opcode = NVPTX::LD_f64_ari_64;
311 Opcode = NVPTX::LD_i8_ari;
314 Opcode = NVPTX::LD_i16_ari;
317 Opcode = NVPTX::LD_i32_ari;
320 Opcode = NVPTX::LD_i64_ari;
323 Opcode = NVPTX::LD_f32_ari;
326 Opcode = NVPTX::LD_f64_ari;
332 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
333 getI32Imm(vecType), getI32Imm(fromType),
334 getI32Imm(fromTypeWidth), Base, Offset, Chain };
335 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
337 if (Subtarget.is64Bit()) {
340 Opcode = NVPTX::LD_i8_areg_64;
343 Opcode = NVPTX::LD_i16_areg_64;
346 Opcode = NVPTX::LD_i32_areg_64;
349 Opcode = NVPTX::LD_i64_areg_64;
352 Opcode = NVPTX::LD_f32_areg_64;
355 Opcode = NVPTX::LD_f64_areg_64;
363 Opcode = NVPTX::LD_i8_areg;
366 Opcode = NVPTX::LD_i16_areg;
369 Opcode = NVPTX::LD_i32_areg;
372 Opcode = NVPTX::LD_i64_areg;
375 Opcode = NVPTX::LD_f32_areg;
378 Opcode = NVPTX::LD_f64_areg;
384 SDValue Ops[] = { getI32Imm(isVolatile), getI32Imm(codeAddrSpace),
385 getI32Imm(vecType), getI32Imm(fromType),
386 getI32Imm(fromTypeWidth), N1, Chain };
387 NVPTXLD = CurDAG->getMachineNode(Opcode, dl, TargetVT, MVT::Other, Ops);
390 if (NVPTXLD != NULL) {
391 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
392 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
393 cast<MachineSDNode>(NVPTXLD)->setMemRefs(MemRefs0, MemRefs0 + 1);
399 SDNode *NVPTXDAGToDAGISel::SelectLoadVector(SDNode *N) {
401 SDValue Chain = N->getOperand(0);
402 SDValue Op1 = N->getOperand(1);
403 SDValue Addr, Offset, Base;
407 MemSDNode *MemSD = cast<MemSDNode>(N);
408 EVT LoadedVT = MemSD->getMemoryVT();
410 if (!LoadedVT.isSimple())
413 // Address Space Setting
414 unsigned int CodeAddrSpace = getCodeAddrSpace(MemSD, Subtarget);
417 // - .volatile is only availalble for .global and .shared
418 bool IsVolatile = MemSD->isVolatile();
419 if (CodeAddrSpace != NVPTX::PTXLdStInstCode::GLOBAL &&
420 CodeAddrSpace != NVPTX::PTXLdStInstCode::SHARED &&
421 CodeAddrSpace != NVPTX::PTXLdStInstCode::GENERIC)
425 MVT SimpleVT = LoadedVT.getSimpleVT();
427 // Type Setting: fromType + fromTypeWidth
429 // Sign : ISD::SEXTLOAD
430 // Unsign : ISD::ZEXTLOAD, ISD::NON_EXTLOAD or ISD::EXTLOAD and the
432 // Float : ISD::NON_EXTLOAD or ISD::EXTLOAD and the type is float
433 MVT ScalarVT = SimpleVT.getScalarType();
434 // Read at least 8 bits (predicates are stored as 8-bit values)
435 unsigned FromTypeWidth = std::max(8U, 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);
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) {
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;
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);