ptx: add ld instruction
[oota-llvm.git] / lib / Target / PTX / PTXISelDAGToDAG.cpp
1 //===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines an instruction selector for the PTX target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PTX.h"
15 #include "PTXTargetMachine.h"
16 #include "llvm/CodeGen/SelectionDAGISel.h"
17 #include "llvm/DerivedTypes.h"
18
19 using namespace llvm;
20
21 namespace {
22 // PTXDAGToDAGISel - PTX specific code to select PTX machine
23 // instructions for SelectionDAG operations.
24 class PTXDAGToDAGISel : public SelectionDAGISel {
25   public:
26     PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel);
27
28     virtual const char *getPassName() const {
29       return "PTX DAG->DAG Pattern Instruction Selection";
30     }
31
32     SDNode *Select(SDNode *Node);
33
34     // Complex Pattern Selectors.
35     bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
36     bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
37
38     // Include the pieces auto'gened from the target description
39 #include "PTXGenDAGISel.inc"
40
41   private:
42     bool isImm (const SDValue &operand);
43     bool SelectImm (const SDValue &operand, SDValue &imm);
44 }; // class PTXDAGToDAGISel
45 } // namespace
46
47 // createPTXISelDag - This pass converts a legalized DAG into a
48 // PTX-specific DAG, ready for instruction scheduling
49 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
50                                      CodeGenOpt::Level OptLevel) {
51   return new PTXDAGToDAGISel(TM, OptLevel);
52 }
53
54 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
55                                  CodeGenOpt::Level OptLevel)
56   : SelectionDAGISel(TM, OptLevel) {}
57
58 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
59   // SelectCode() is auto'gened
60   return SelectCode(Node);
61 }
62
63 // Match memory operand of the form [reg+reg] and [reg+imm]
64 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
65                                    SDValue &Offset) {
66   if (Addr.getNumOperands() >= 2 &&
67       isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
68     return false; // let SelectADDRii handle the [imm+imm] case
69
70   // try [reg+imm] and [imm+reg]
71   if (Addr.getOpcode() == ISD::ADD)
72     for (int i = 0; i < 2; i ++)
73       if (SelectImm(Addr.getOperand(1-i), Offset)) {
74         Base = Addr.getOperand(i);
75         return true;
76       }
77
78   // okay, it's [reg+reg]
79   Base = Addr;
80   Offset = CurDAG->getTargetConstant(0, MVT::i32);
81   return true;
82 }
83
84 // Match memory operand of the form [imm+imm] and [imm]
85 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
86                                    SDValue &Offset) {
87   if (Addr.getOpcode() == ISD::ADD) {
88     return SelectImm(Addr.getOperand(0), Base) &&
89            SelectImm(Addr.getOperand(1), Offset);
90   }
91
92   if (SelectImm(Addr, Base)) {
93     Offset = CurDAG->getTargetConstant(0, MVT::i32);
94     return true;
95   }
96
97   return false;
98 }
99
100 bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
101   return ConstantSDNode::classof(operand.getNode());
102 }
103
104 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
105   SDNode *node = operand.getNode();
106   if (!ConstantSDNode::classof(node))
107     return false;
108
109   ConstantSDNode *CN = cast<ConstantSDNode>(node);
110   imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
111   return true;
112 }