1 //===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
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 MSP430 target.
12 //===----------------------------------------------------------------------===//
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 "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
35 /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
36 /// instructions for SelectionDAG operations.
39 class MSP430DAGToDAGISel
: public SelectionDAGISel
{
40 MSP430TargetLowering
&Lowering
;
41 const MSP430Subtarget
&Subtarget
;
44 MSP430DAGToDAGISel(MSP430TargetMachine
&TM
, CodeGenOpt::Level OptLevel
)
45 : SelectionDAGISel(TM
, OptLevel
),
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"
59 SDNode
*Select(SDValue Op
);
60 bool SelectAddr(SDValue Op
, SDValue Addr
, SDValue
&Base
, SDValue
&Disp
);
66 } // end anonymous namespace
68 /// createMSP430ISelDag - This pass converts a legalized DAG into a
69 /// MSP430-specific DAG, ready for instruction scheduling.
71 FunctionPass
*llvm::createMSP430ISelDag(MSP430TargetMachine
&TM
,
72 CodeGenOpt::Level OptLevel
) {
73 return new MSP430DAGToDAGISel(TM
, OptLevel
);
76 // FIXME: This is pretty dummy routine and needs to be rewritten in the future.
77 bool MSP430DAGToDAGISel::SelectAddr(SDValue Op
, SDValue Addr
,
78 SDValue
&Base
, SDValue
&Disp
) {
79 // Try to match frame address first.
80 if (FrameIndexSDNode
*FIN
= dyn_cast
<FrameIndexSDNode
>(Addr
)) {
81 Base
= CurDAG
->getTargetFrameIndex(FIN
->getIndex(), MVT::i16
);
82 Disp
= CurDAG
->getTargetConstant(0, MVT::i16
);
86 switch (Addr
.getOpcode()) {
88 // Operand is a result from ADD with constant operand which fits into i16.
89 if (ConstantSDNode
*CN
= dyn_cast
<ConstantSDNode
>(Addr
.getOperand(1))) {
90 uint64_t CVal
= CN
->getZExtValue();
91 // Offset should fit into 16 bits.
92 if (((CVal
<< 48) >> 48) == CVal
) {
93 SDValue N0
= Addr
.getOperand(0);
94 if (FrameIndexSDNode
*FIN
= dyn_cast
<FrameIndexSDNode
>(N0
))
95 Base
= CurDAG
->getTargetFrameIndex(FIN
->getIndex(), MVT::i16
);
99 Disp
= CurDAG
->getTargetConstant(CVal
, MVT::i16
);
104 case MSP430ISD::Wrapper
:
105 SDValue N0
= Addr
.getOperand(0);
106 if (GlobalAddressSDNode
*G
= dyn_cast
<GlobalAddressSDNode
>(N0
)) {
107 Base
= CurDAG
->getTargetGlobalAddress(G
->getGlobal(),
108 MVT::i16
, G
->getOffset());
109 Disp
= CurDAG
->getTargetConstant(0, MVT::i16
);
111 } else if (ExternalSymbolSDNode
*E
= dyn_cast
<ExternalSymbolSDNode
>(N0
)) {
112 Base
= CurDAG
->getTargetExternalSymbol(E
->getSymbol(), MVT::i16
);
113 Disp
= CurDAG
->getTargetConstant(0, MVT::i16
);
119 Disp
= CurDAG
->getTargetConstant(0, MVT::i16
);
126 /// InstructionSelect - This callback is invoked by
127 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
128 void MSP430DAGToDAGISel::InstructionSelect() {
131 // Codegen the basic block.
132 DEBUG(errs() << "===== Instruction selection begins:\n");
135 DEBUG(errs() << "===== Instruction selection ends:\n");
137 CurDAG
->RemoveDeadNodes();
140 SDNode
*MSP430DAGToDAGISel::Select(SDValue Op
) {
141 SDNode
*Node
= Op
.getNode();
142 DebugLoc dl
= Op
.getDebugLoc();
144 // Dump information about the Node being selected
145 DEBUG(errs().indent(Indent
) << "Selecting: ");
146 DEBUG(Node
->dump(CurDAG
));
147 DEBUG(errs() << "\n");
150 // If we have a custom node, we already have selected!
151 if (Node
->isMachineOpcode()) {
152 DEBUG(errs().indent(Indent
-2) << "== ";
159 // Few custom selection stuff.
160 switch (Node
->getOpcode()) {
162 case ISD::FrameIndex
: {
163 assert(Op
.getValueType() == MVT::i16
);
164 int FI
= cast
<FrameIndexSDNode
>(Node
)->getIndex();
165 SDValue TFI
= CurDAG
->getTargetFrameIndex(FI
, MVT::i16
);
166 if (Node
->hasOneUse())
167 return CurDAG
->SelectNodeTo(Node
, MSP430::ADD16ri
, MVT::i16
,
168 TFI
, CurDAG
->getTargetConstant(0, MVT::i16
));
169 return CurDAG
->getTargetNode(MSP430::ADD16ri
, dl
, MVT::i16
,
170 TFI
, CurDAG
->getTargetConstant(0, MVT::i16
));
174 // Select the default instruction
175 SDNode
*ResNode
= SelectCode(Op
);
177 DEBUG(errs() << std::string(Indent
-2, ' ') << "=> ");
178 if (ResNode
== NULL
|| ResNode
== Op
.getNode())
179 DEBUG(Op
.getNode()->dump(CurDAG
));
181 DEBUG(ResNode
->dump(CurDAG
));
182 DEBUG(errs() << "\n");