blob: 1107236332d14cfff34ce7c3dd1fffd9a60d9f38 [file] [log] [blame]
Eric Christopher50880d02010-09-18 18:52:28 +00001//===-- 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"
Che-Liang Chiou3f8e6172010-11-30 07:34:44 +000017#include "llvm/DerivedTypes.h"
Eric Christopher50880d02010-09-18 18:52:28 +000018
19using namespace llvm;
20
21namespace {
22// PTXDAGToDAGISel - PTX specific code to select PTX machine
23// instructions for SelectionDAG operations.
24class 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
Che-Liang Chiou3f8e6172010-11-30 07:34:44 +000034 // Complex Pattern Selectors.
35 bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
36 bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
37
Eric Christopher50880d02010-09-18 18:52:28 +000038 // Include the pieces auto'gened from the target description
39#include "PTXGenDAGISel.inc"
40
Che-Liang Chiou3f8e6172010-11-30 07:34:44 +000041 private:
42 bool isImm (const SDValue &operand);
43 bool SelectImm (const SDValue &operand, SDValue &imm);
Eric Christopher50880d02010-09-18 18:52:28 +000044}; // class PTXDAGToDAGISel
45} // namespace
46
47// createPTXISelDag - This pass converts a legalized DAG into a
48// PTX-specific DAG, ready for instruction scheduling
49FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
50 CodeGenOpt::Level OptLevel) {
51 return new PTXDAGToDAGISel(TM, OptLevel);
52}
53
54PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
55 CodeGenOpt::Level OptLevel)
56 : SelectionDAGISel(TM, OptLevel) {}
57
58SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
59 // SelectCode() is auto'gened
60 return SelectCode(Node);
61}
Che-Liang Chiou3f8e6172010-11-30 07:34:44 +000062
63// Match memory operand of the form [reg+reg] and [reg+imm]
64bool 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]
85bool 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
100bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
101 return ConstantSDNode::classof(operand.getNode());
102}
103
104bool 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}