1 //===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the PTX target.
12 //===----------------------------------------------------------------------===//
15 #include "PTXTargetMachine.h"
16 #include "llvm/CodeGen/SelectionDAGISel.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Support/raw_ostream.h"
23 // PTXDAGToDAGISel - PTX specific code to select PTX machine
24 // instructions for SelectionDAG operations.
25 class PTXDAGToDAGISel
: public SelectionDAGISel
{
27 PTXDAGToDAGISel(PTXTargetMachine
&TM
, CodeGenOpt::Level OptLevel
);
29 virtual const char *getPassName() const {
30 return "PTX DAG->DAG Pattern Instruction Selection";
33 SDNode
*Select(SDNode
*Node
);
35 // Complex Pattern Selectors.
36 bool SelectADDRrr(SDValue
&Addr
, SDValue
&R1
, SDValue
&R2
);
37 bool SelectADDRri(SDValue
&Addr
, SDValue
&Base
, SDValue
&Offset
);
38 bool SelectADDRii(SDValue
&Addr
, SDValue
&Base
, SDValue
&Offset
);
40 // Include the pieces auto'gened from the target description
41 #include "PTXGenDAGISel.inc"
44 SDNode
*SelectREAD_PARAM(SDNode
*Node
);
46 // We need this only because we can't match intruction BRAdp
47 // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td
48 SDNode
*SelectBRCOND(SDNode
*Node
);
50 bool isImm(const SDValue
&operand
);
51 bool SelectImm(const SDValue
&operand
, SDValue
&imm
);
53 const PTXSubtarget
& getSubtarget() const;
54 }; // class PTXDAGToDAGISel
57 // createPTXISelDag - This pass converts a legalized DAG into a
58 // PTX-specific DAG, ready for instruction scheduling
59 FunctionPass
*llvm::createPTXISelDag(PTXTargetMachine
&TM
,
60 CodeGenOpt::Level OptLevel
) {
61 return new PTXDAGToDAGISel(TM
, OptLevel
);
64 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine
&TM
,
65 CodeGenOpt::Level OptLevel
)
66 : SelectionDAGISel(TM
, OptLevel
) {}
68 SDNode
*PTXDAGToDAGISel::Select(SDNode
*Node
) {
69 switch (Node
->getOpcode()) {
70 case PTXISD::READ_PARAM
:
71 return SelectREAD_PARAM(Node
);
73 return SelectBRCOND(Node
);
75 return SelectCode(Node
);
79 SDNode
*PTXDAGToDAGISel::SelectREAD_PARAM(SDNode
*Node
) {
80 SDValue index
= Node
->getOperand(1);
81 DebugLoc dl
= Node
->getDebugLoc();
84 if (index
.getOpcode() != ISD::TargetConstant
)
85 llvm_unreachable("READ_PARAM: index is not ISD::TargetConstant");
87 if (Node
->getValueType(0) == MVT::i16
) {
88 opcode
= PTX::LDpiU16
;
90 else if (Node
->getValueType(0) == MVT::i32
) {
91 opcode
= PTX::LDpiU32
;
93 else if (Node
->getValueType(0) == MVT::i64
) {
94 opcode
= PTX::LDpiU64
;
96 else if (Node
->getValueType(0) == MVT::f32
) {
97 opcode
= PTX::LDpiF32
;
99 else if (Node
->getValueType(0) == MVT::f64
) {
100 opcode
= PTX::LDpiF64
;
103 llvm_unreachable("Unknown parameter type for ld.param");
106 return PTXInstrInfo::
107 GetPTXMachineNode(CurDAG
, opcode
, dl
, Node
->getValueType(0), index
);
110 SDNode
*PTXDAGToDAGISel::SelectBRCOND(SDNode
*Node
) {
111 assert(Node
->getNumOperands() >= 3);
113 SDValue Chain
= Node
->getOperand(0);
114 SDValue Pred
= Node
->getOperand(1);
115 SDValue Target
= Node
->getOperand(2); // branch target
116 SDValue PredOp
= CurDAG
->getTargetConstant(PTX::PRED_NORMAL
, MVT::i32
);
117 DebugLoc dl
= Node
->getDebugLoc();
119 assert(Target
.getOpcode() == ISD::BasicBlock
);
120 assert(Pred
.getValueType() == MVT::i1
);
123 SDValue Ops
[] = { Target
, Pred
, PredOp
, Chain
};
124 return CurDAG
->getMachineNode(PTX::BRAdp
, dl
, MVT::Other
, Ops
, 4);
127 // Match memory operand of the form [reg+reg]
128 bool PTXDAGToDAGISel::SelectADDRrr(SDValue
&Addr
, SDValue
&R1
, SDValue
&R2
) {
129 if (Addr
.getOpcode() != ISD::ADD
|| Addr
.getNumOperands() < 2 ||
130 isImm(Addr
.getOperand(0)) || isImm(Addr
.getOperand(1)))
133 assert(Addr
.getValueType().isSimple() && "Type must be simple");
136 R2
= CurDAG
->getTargetConstant(0, Addr
.getValueType().getSimpleVT());
141 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
142 bool PTXDAGToDAGISel::SelectADDRri(SDValue
&Addr
, SDValue
&Base
,
144 if (Addr
.getOpcode() != ISD::ADD
) {
145 // let SelectADDRii handle the [imm] case
150 assert(Addr
.getValueType().isSimple() && "Type must be simple");
153 Offset
= CurDAG
->getTargetConstant(0, Addr
.getValueType().getSimpleVT());
158 if (Addr
.getNumOperands() < 2)
161 // let SelectADDRii handle the [imm+imm] case
162 if (isImm(Addr
.getOperand(0)) && isImm(Addr
.getOperand(1)))
165 // try [reg+imm] and [imm+reg]
166 for (int i
= 0; i
< 2; i
++)
167 if (SelectImm(Addr
.getOperand(1-i
), Offset
)) {
168 Base
= Addr
.getOperand(i
);
172 // neither [reg+imm] nor [imm+reg]
176 // Match memory operand of the form [imm+imm] and [imm]
177 bool PTXDAGToDAGISel::SelectADDRii(SDValue
&Addr
, SDValue
&Base
,
180 if (Addr
.getOpcode() == ISD::ADD
) {
181 return SelectImm(Addr
.getOperand(0), Base
) &&
182 SelectImm(Addr
.getOperand(1), Offset
);
186 if (SelectImm(Addr
, Base
)) {
187 assert(Addr
.getValueType().isSimple() && "Type must be simple");
189 Offset
= CurDAG
->getTargetConstant(0, Addr
.getValueType().getSimpleVT());
197 bool PTXDAGToDAGISel::isImm(const SDValue
&operand
) {
198 return ConstantSDNode::classof(operand
.getNode());
201 bool PTXDAGToDAGISel::SelectImm(const SDValue
&operand
, SDValue
&imm
) {
202 SDNode
*node
= operand
.getNode();
203 if (!ConstantSDNode::classof(node
))
206 ConstantSDNode
*CN
= cast
<ConstantSDNode
>(node
);
207 imm
= CurDAG
->getTargetConstant(*CN
->getConstantIntValue(),
208 operand
.getValueType());
212 const PTXSubtarget
& PTXDAGToDAGISel::getSubtarget() const
214 return TM
.getSubtarget
<PTXSubtarget
>();