149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===-- NVPTXISelDAGToDAG.h - A dag to dag inst selector for NVPTX --------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file defines an instruction selector for the NVPTX target. 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#define DEBUG_TYPE "nvptx-isel" 1549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTX.h" 1749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXISelLowering.h" 1849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXRegisterInfo.h" 1949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXTargetMachine.h" 2049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/SelectionDAGISel.h" 2149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/Compiler.h" 2249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Intrinsics.h" 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm; 2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskinamespace { 2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiclass LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel { 2849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If true, generate corresponding FPCONTRACT. This is 3049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // language dependent (i.e. CUDA and OpenCL works differently). 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doFMADF32; 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doFMAF64; 3349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doFMAF32; 3449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doFMAF64AGG; 3549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doFMAF32AGG; 3649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool allowFMA; 3749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 0: use div.approx 3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 1: use div.full 4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // 2: For sm_20 and later, ieee-compliant div.rnd.f32 can be generated; 4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Otherwise, use div.full 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski int do_DIVF32_PREC; 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If true, add .ftz to f32 instructions. 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // This is only meaningful for sm_20 and later, as the default 4649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // is not ftz. 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // For sm earlier than sm_20, f32 denorms are always ftz by the 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // hardware. 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // We always add the .ftz modifier regardless of the sm value 5049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // when Use32FTZ is true. 5149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool UseF32FTZ; 5249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // If true, generate mul.wide from sext and mul 5449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool doMulWide; 5549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskipublic: 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm, 5849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski CodeGenOpt::Level OptLevel); 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Pass Name 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski virtual const char *getPassName() const { 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return "NVPTX DAG->DAG Pattern Instruction Selection"; 6349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 6449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski const NVPTXSubtarget &Subtarget; 6649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski char ConstraintCode, 6949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski std::vector<SDValue> &OutOps); 7049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiprivate: 7149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Include the pieces autogenerated from the target description. 7249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXGenDAGISel.inc" 7349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode *Select(SDNode *N); 7549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode* SelectLoad(SDNode *N); 7649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDNode* SelectStore(SDNode *N); 7749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 7849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski inline SDValue getI32Imm(unsigned Imm) { 7949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return CurDAG->getTargetConstant(Imm, MVT::i32); 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 8149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Match direct address complex pattern. 8349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectDirectAddr(SDValue N, SDValue &Address); 8449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRri_imp(SDNode *OpNode, SDValue Addr, SDValue &Base, 8649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset, MVT mvt); 8749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRri(SDNode *OpNode, SDValue Addr, SDValue &Base, 8849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset); 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRri64(SDNode *OpNode, SDValue Addr, SDValue &Base, 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset); 9149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRsi_imp(SDNode *OpNode, SDValue Addr, SDValue &Base, 9349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset, MVT mvt); 9449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRsi(SDNode *OpNode, SDValue Addr, SDValue &Base, 9549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset); 9649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool SelectADDRsi64(SDNode *OpNode, SDValue Addr, SDValue &Base, 9749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski SDValue &Offset); 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 9949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool ChkMemSDNodeAddressSpace(SDNode *N, unsigned int spN) const; 10149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski bool UndefOrImm(SDValue Op, SDValue N, SDValue &Retval); 10349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski}; 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 106