Use %ull here.
[llvm/stm8.git] / lib / Target / PTX / PTXISelDAGToDAG.cpp
blobb3c85da7b4461662a967dff06d872f1a1b68bcbb
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.
12 //===----------------------------------------------------------------------===//
14 #include "PTX.h"
15 #include "PTXTargetMachine.h"
16 #include "llvm/CodeGen/SelectionDAGISel.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Support/raw_ostream.h"
20 using namespace llvm;
22 namespace {
23 // PTXDAGToDAGISel - PTX specific code to select PTX machine
24 // instructions for SelectionDAG operations.
25 class PTXDAGToDAGISel : public SelectionDAGISel {
26 public:
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"
43 private:
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
55 } // namespace
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);
72 case ISD::BRCOND:
73 return SelectBRCOND(Node);
74 default:
75 return SelectCode(Node);
79 SDNode *PTXDAGToDAGISel::SelectREAD_PARAM(SDNode *Node) {
80 SDValue index = Node->getOperand(1);
81 DebugLoc dl = Node->getDebugLoc();
82 unsigned opcode;
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;
102 else {
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);
122 // Emit BRAdp
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)))
131 return false;
133 assert(Addr.getValueType().isSimple() && "Type must be simple");
135 R1 = Addr;
136 R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
138 return true;
141 // Match memory operand of the form [reg], [imm+reg], and [reg+imm]
142 bool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
143 SDValue &Offset) {
144 if (Addr.getOpcode() != ISD::ADD) {
145 // let SelectADDRii handle the [imm] case
146 if (isImm(Addr))
147 return false;
148 // it is [reg]
150 assert(Addr.getValueType().isSimple() && "Type must be simple");
152 Base = Addr;
153 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
155 return true;
158 if (Addr.getNumOperands() < 2)
159 return false;
161 // let SelectADDRii handle the [imm+imm] case
162 if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
163 return false;
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);
169 return true;
172 // neither [reg+imm] nor [imm+reg]
173 return false;
176 // Match memory operand of the form [imm+imm] and [imm]
177 bool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
178 SDValue &Offset) {
179 // is [imm+imm]?
180 if (Addr.getOpcode() == ISD::ADD) {
181 return SelectImm(Addr.getOperand(0), Base) &&
182 SelectImm(Addr.getOperand(1), Offset);
185 // is [imm]?
186 if (SelectImm(Addr, Base)) {
187 assert(Addr.getValueType().isSimple() && "Type must be simple");
189 Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT());
191 return true;
194 return false;
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))
204 return false;
206 ConstantSDNode *CN = cast<ConstantSDNode>(node);
207 imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(),
208 operand.getValueType());
209 return true;
212 const PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const
214 return TM.getSubtarget<PTXSubtarget>();