1239310Sdim//===-- NVPTXISelDAGToDAG.h - A dag to dag inst selector for NVPTX --------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file defines an instruction selector for the NVPTX target.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#define DEBUG_TYPE "nvptx-isel"
15239310Sdim
16239310Sdim#include "NVPTX.h"
17239310Sdim#include "NVPTXISelLowering.h"
18239310Sdim#include "NVPTXRegisterInfo.h"
19239310Sdim#include "NVPTXTargetMachine.h"
20239310Sdim#include "llvm/CodeGen/SelectionDAGISel.h"
21249423Sdim#include "llvm/IR/Intrinsics.h"
22239310Sdim#include "llvm/Support/Compiler.h"
23239310Sdimusing namespace llvm;
24239310Sdim
25239310Sdimnamespace {
26239310Sdim
27239310Sdimclass LLVM_LIBRARY_VISIBILITY NVPTXDAGToDAGISel : public SelectionDAGISel {
28239310Sdim
29239310Sdim  // If true, generate corresponding FPCONTRACT. This is
30239310Sdim  // language dependent (i.e. CUDA and OpenCL works differently).
31239310Sdim  bool doFMADF32;
32239310Sdim  bool doFMAF64;
33239310Sdim  bool doFMAF32;
34239310Sdim  bool doFMAF64AGG;
35239310Sdim  bool doFMAF32AGG;
36239310Sdim  bool allowFMA;
37239310Sdim
38239310Sdim  // 0: use div.approx
39239310Sdim  // 1: use div.full
40239310Sdim  // 2: For sm_20 and later, ieee-compliant div.rnd.f32 can be generated;
41239310Sdim  //    Otherwise, use div.full
42239310Sdim  int do_DIVF32_PREC;
43239310Sdim
44251662Sdim  // If true, generate sqrt.rn, else generate sqrt.approx. If FTZ
45251662Sdim  // is true, then generate the corresponding FTZ version.
46251662Sdim  bool do_SQRTF32_PREC;
47251662Sdim
48239310Sdim  // If true, add .ftz to f32 instructions.
49239310Sdim  // This is only meaningful for sm_20 and later, as the default
50239310Sdim  // is not ftz.
51239310Sdim  // For sm earlier than sm_20, f32 denorms are always ftz by the
52239310Sdim  // hardware.
53239310Sdim  // We always add the .ftz modifier regardless of the sm value
54239310Sdim  // when Use32FTZ is true.
55239310Sdim  bool UseF32FTZ;
56239310Sdim
57239310Sdim  // If true, generate mul.wide from sext and mul
58239310Sdim  bool doMulWide;
59239310Sdim
60239310Sdimpublic:
61239310Sdim  explicit NVPTXDAGToDAGISel(NVPTXTargetMachine &tm,
62239310Sdim                             CodeGenOpt::Level OptLevel);
63239310Sdim
64239310Sdim  // Pass Name
65239310Sdim  virtual const char *getPassName() const {
66239310Sdim    return "NVPTX DAG->DAG Pattern Instruction Selection";
67239310Sdim  }
68239310Sdim
69239310Sdim  const NVPTXSubtarget &Subtarget;
70239310Sdim
71249423Sdim  virtual bool SelectInlineAsmMemoryOperand(
72249423Sdim      const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps);
73239310Sdimprivate:
74249423Sdim// Include the pieces autogenerated from the target description.
75239310Sdim#include "NVPTXGenDAGISel.inc"
76239310Sdim
77239310Sdim  SDNode *Select(SDNode *N);
78249423Sdim  SDNode *SelectLoad(SDNode *N);
79249423Sdim  SDNode *SelectLoadVector(SDNode *N);
80249423Sdim  SDNode *SelectLDGLDUVector(SDNode *N);
81249423Sdim  SDNode *SelectStore(SDNode *N);
82249423Sdim  SDNode *SelectStoreVector(SDNode *N);
83239310Sdim
84239310Sdim  inline SDValue getI32Imm(unsigned Imm) {
85239310Sdim    return CurDAG->getTargetConstant(Imm, MVT::i32);
86239310Sdim  }
87239310Sdim
88239310Sdim  // Match direct address complex pattern.
89239310Sdim  bool SelectDirectAddr(SDValue N, SDValue &Address);
90239310Sdim
91239310Sdim  bool SelectADDRri_imp(SDNode *OpNode, SDValue Addr, SDValue &Base,
92239310Sdim                        SDValue &Offset, MVT mvt);
93239310Sdim  bool SelectADDRri(SDNode *OpNode, SDValue Addr, SDValue &Base,
94239310Sdim                    SDValue &Offset);
95239310Sdim  bool SelectADDRri64(SDNode *OpNode, SDValue Addr, SDValue &Base,
96239310Sdim                      SDValue &Offset);
97239310Sdim
98239310Sdim  bool SelectADDRsi_imp(SDNode *OpNode, SDValue Addr, SDValue &Base,
99239310Sdim                        SDValue &Offset, MVT mvt);
100239310Sdim  bool SelectADDRsi(SDNode *OpNode, SDValue Addr, SDValue &Base,
101239310Sdim                    SDValue &Offset);
102239310Sdim  bool SelectADDRsi64(SDNode *OpNode, SDValue Addr, SDValue &Base,
103239310Sdim                      SDValue &Offset);
104239310Sdim
105239310Sdim  bool ChkMemSDNodeAddressSpace(SDNode *N, unsigned int spN) const;
106239310Sdim
107239310Sdim  bool UndefOrImm(SDValue Op, SDValue N, SDValue &Retval);
108239310Sdim
109239310Sdim};
110239310Sdim}
111