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