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 bool isImm(const SDValue &operand);
47 bool SelectImm(const SDValue &operand, SDValue &imm);
49 const PTXSubtarget& getSubtarget() const;
50 }; // class PTXDAGToDAGISel
53 // createPTXISelDag - This pass converts a legalized DAG into a
54 // PTX-specific DAG, ready for instruction scheduling
55 FunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
56 CodeGenOpt::Level OptLevel) {
57 return new PTXDAGToDAGISel(TM, OptLevel);
60 PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
61 CodeGenOpt::Level OptLevel)
62 : SelectionDAGISel(TM, OptLevel) {}
64 SDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
65 if (Node->getOpcode() == PTXISD::READ_PARAM)
66 return SelectREAD_PARAM(Node);
68 return SelectCode(Node);
71 SDNode *PTXDAGToDAGISel::SelectREAD_PARAM(SDNode *Node) {
72 SDValue index = Node->getOperand(1);
73 DebugLoc dl = Node->getDebugLoc();
76 if (index.getOpcode() != ISD::TargetConstant)
77 llvm_unreachable("READ_PARAM: index is not ISD::TargetConstant");
79 if (Node->getValueType(0) == MVT::i16) {
80 opcode = PTX::LDpiU16;
82 else if (Node->getValueType(0) == MVT::i32) {
83 opcode = PTX::LDpiU32;
85 else if (Node->getValueType(0) == MVT::i64) {
86 opcode = PTX::LDpiU64;
88 else if (Node->getValueType(0) == MVT::f32) {
89 opcode = PTX::LDpiF32;
91 else if (Node->getValueType(0) == MVT::f64) {
92 opcode = PTX::LDpiF64;
95 llvm_unreachable("Unknown parameter type for ld.param");
99 GetPTXMachineNode(CurDAG, opcode, dl, Node->getValueType(0), index);
102 // Match memory operand of the form [reg+reg]
103 bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) {
104 if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 ||
105 isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1)))
109 R2 = CurDAG->getTargetConstant(0, MVT::i32);
113 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
114 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
116 if (Addr.getOpcode() != ISD::ADD) {
117 // let SelectADDRii handle the [imm] case
122 Offset = CurDAG->getTargetConstant(0, MVT::i32);
126 if (Addr.getNumOperands() < 2)
129 // let SelectADDRii handle the [imm+imm] case
130 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
133 // try [reg+imm] and [imm+reg]
134 for (int i = 0; i < 2; i ++)
135 if (SelectImm(Addr.getOperand(1-i), Offset)) {
136 Base = Addr.getOperand(i);
140 // neither [reg+imm] nor [imm+reg]
144 // Match memory operand of the form [imm+imm] and [imm]
145 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
148 if (Addr.getOpcode() == ISD::ADD) {
149 return SelectImm(Addr.getOperand(0), Base) &&
150 SelectImm(Addr.getOperand(1), Offset);
154 if (SelectImm(Addr, Base)) {
155 Offset = CurDAG->getTargetConstant(0, MVT::i32);
162 bool PTXDAGToDAGISel::isImm(const SDValue &operand) {
163 return ConstantSDNode::classof(operand.getNode());
166 bool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
167 SDNode *node = operand.getNode();
168 if (!ConstantSDNode::classof(node))
171 ConstantSDNode *CN = cast<ConstantSDNode>(node);
172 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
176 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
178 return TM.getSubtarget<PTXSubtarget>();