Match wrapper node for address
[llvm/msp430.git] / lib / Target / MSP430 / MSP430ISelDAGToDAG.cpp
blobe564e63598a58104bdc77a54e63dc2697b058ded
1 //===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
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 MSP430 target.
12 //===----------------------------------------------------------------------===//
14 #include "MSP430.h"
15 #include "MSP430ISelLowering.h"
16 #include "MSP430TargetMachine.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Function.h"
19 #include "llvm/Intrinsics.h"
20 #include "llvm/CallingConv.h"
21 #include "llvm/Constants.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/SelectionDAG.h"
27 #include "llvm/CodeGen/SelectionDAGISel.h"
28 #include "llvm/Target/TargetLowering.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
31 #include <queue>
32 #include <set>
33 using namespace llvm;
35 /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
36 /// instructions for SelectionDAG operations.
37 ///
38 namespace {
39 class MSP430DAGToDAGISel : public SelectionDAGISel {
40 MSP430TargetLowering &Lowering;
41 const MSP430Subtarget &Subtarget;
43 public:
44 MSP430DAGToDAGISel(MSP430TargetMachine &TM)
45 : SelectionDAGISel(TM),
46 Lowering(*TM.getTargetLowering()),
47 Subtarget(*TM.getSubtargetImpl()) { }
49 virtual void InstructionSelect();
51 virtual const char *getPassName() const {
52 return "MSP430 DAG->DAG Pattern Instruction Selection";
55 // Include the pieces autogenerated from the target description.
56 #include "MSP430GenDAGISel.inc"
58 private:
59 SDNode *Select(SDValue Op);
60 bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Disp, SDValue &Base);
62 #ifndef NDEBUG
63 unsigned Indent;
64 #endif
66 } // end anonymous namespace
68 /// createMSP430ISelDag - This pass converts a legalized DAG into a
69 /// MSP430-specific DAG, ready for instruction scheduling.
70 ///
71 FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM) {
72 return new MSP430DAGToDAGISel(TM);
75 bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue Addr,
76 SDValue &Disp, SDValue &Base) {
77 // We don't support frame index stuff yet.
78 if (isa<FrameIndexSDNode>(Addr))
79 return false;
81 // Operand is a result from ADD with constant operand which fits into i16.
82 switch (Addr.getOpcode()) {
83 case ISD::ADD:
84 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
85 uint64_t CVal = CN->getZExtValue();
86 // Offset should fit into 16 bits.
87 if (((CVal << 48) >> 48) == CVal) {
88 // We don't support frame index stuff yet.
89 if (isa<FrameIndexSDNode>(Addr.getOperand(0)))
90 return false;
92 Base = Addr.getOperand(0);
93 Disp = CurDAG->getTargetConstant(CVal, MVT::i16);
95 return true;
98 break;
99 case MSP430ISD::Wrapper:
100 SDValue N0 = Addr.getOperand(0);
101 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
102 // We can match addresses of globals without any offsets
103 if (!G->getOffset()) {
104 Base = CurDAG->getTargetGlobalAddress(G->getGlobal(),
105 MVT::i16, 0);
106 Disp = CurDAG->getTargetConstant(0, MVT::i16);
108 return true;
111 break;
114 Base = Addr;
115 Disp = CurDAG->getTargetConstant(0, MVT::i16);
117 return true;
122 /// InstructionSelect - This callback is invoked by
123 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
124 void MSP430DAGToDAGISel::InstructionSelect() {
125 DEBUG(BB->dump());
127 // Select target instructions for the DAG.
128 SelectRoot(*CurDAG);
130 CurDAG->RemoveDeadNodes();
133 SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
134 SDNode *Node = Op.getNode();
136 // Dump information about the Node being selected
137 #ifndef NDEBUG
138 DOUT << std::string(Indent, ' ') << "Selecting: ";
139 DEBUG(Node->dump(CurDAG));
140 DOUT << "\n";
141 Indent += 2;
142 #endif
144 // If we have a custom node, we already have selected!
145 if (Node->isMachineOpcode()) {
146 #ifndef NDEBUG
147 DOUT << std::string(Indent-2, ' ') << "== ";
148 DEBUG(Node->dump(CurDAG));
149 DOUT << "\n";
150 Indent -= 2;
151 #endif
152 return NULL;
155 // Instruction Selection not handled by the auto-generated tablegen selection
156 // should be handled here.
157 // Something like this:
158 // unsigned Opcode = Node->getOpcode();
159 // switch (Opcode) {
160 // default: break;
161 // case ISD::Foo:
162 // return SelectFoo(Node)
163 // }
165 // Select the default instruction
166 SDNode *ResNode = SelectCode(Op);
168 #ifndef NDEBUG
169 DOUT << std::string(Indent-2, ' ') << "=> ";
170 if (ResNode == NULL || ResNode == Op.getNode())
171 DEBUG(Op.getNode()->dump(CurDAG));
172 else
173 DEBUG(ResNode->dump(CurDAG));
174 DOUT << "\n";
175 Indent -= 2;
176 #endif
178 return ResNode;