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"
22 // PTXDAGToDAGISel - PTX specific code to select PTX machine
23 // instructions for SelectionDAG operations.
24 class PTXDAGToDAGISel : public SelectionDAGISel {
26 PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel);
28 virtual const char *getPassName() const {
29 return "PTX DAG->DAG Pattern Instruction Selection";
32 SDNode *Select(SDNode *Node);
34 // Complex Pattern Selectors.
35 bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2);
36 bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
37 bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
39 // Include the pieces auto'gened from the target description
40 #include "PTXGenDAGISel.inc"
43 bool isImm(const SDValue &operand);
44 bool SelectImm(const SDValue &operand, SDValue &imm);
45 }; // class PTXDAGToDAGISel
48 // createPTXISelDag - This pass converts a legalized DAG into a
49 // PTX-specific DAG, ready for instruction scheduling
50 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
51 CodeGenOpt::Level OptLevel) {
52 return new PTXDAGToDAGISel(TM, OptLevel);
55 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
56 CodeGenOpt::Level OptLevel)
57 : SelectionDAGISel(TM, OptLevel) {}
59 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
60 // SelectCode() is auto'gened
61 return SelectCode(Node);
64 // Match memory operand of the form [reg+reg]
65 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) {
66 if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 ||
67 isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1)))
71 R2 = CurDAG->getTargetConstant(0, MVT::i32);
75 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
76 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
78 if (Addr.getOpcode() != ISD::ADD) {
79 // let SelectADDRii handle the [imm] case
84 Offset = CurDAG->getTargetConstant(0, MVT::i32);
88 if (Addr.getNumOperands() < 2)
91 // let SelectADDRii handle the [imm+imm] case
92 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
95 // try [reg+imm] and [imm+reg]
96 for (int i = 0; i < 2; i ++)
97 if (SelectImm(Addr.getOperand(1-i), Offset)) {
98 Base = Addr.getOperand(i);
102 // neither [reg+imm] nor [imm+reg]
106 // Match memory operand of the form [imm+imm] and [imm]
107 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
110 if (Addr.getOpcode() == ISD::ADD) {
111 return SelectImm(Addr.getOperand(0), Base) &&
112 SelectImm(Addr.getOperand(1), Offset);
116 if (SelectImm(Addr, Base)) {
117 Offset = CurDAG->getTargetConstant(0, MVT::i32);
124 bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
125 return ConstantSDNode::classof(operand.getNode());
128 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
129 SDNode *node = operand.getNode();
130 if (!ConstantSDNode::classof(node))
133 ConstantSDNode *CN = cast<ConstantSDNode>(node);
134 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);