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"
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.
133 DOUT
<< "===== Instruction selection begins:\n";
138 DOUT
<< "===== Instruction selection ends:\n";
141 CurDAG
->RemoveDeadNodes();
144 SDNode
*MSP430DAGToDAGISel::Select(SDValue Op
) {
145 SDNode
*Node
= Op
.getNode();
146 DebugLoc dl
= Op
.getDebugLoc();
148 // Dump information about the Node being selected
150 DOUT
<< std::string(Indent
, ' ') << "Selecting: ";
151 DEBUG(Node
->dump(CurDAG
));
156 // If we have a custom node, we already have selected!
157 if (Node
->isMachineOpcode()) {
159 DOUT
<< std::string(Indent
-2, ' ') << "== ";
160 DEBUG(Node
->dump(CurDAG
));
167 // Few custom selection stuff.
168 switch (Node
->getOpcode()) {
170 case ISD::FrameIndex
: {
171 assert(Op
.getValueType() == MVT::i16
);
172 int FI
= cast
<FrameIndexSDNode
>(Node
)->getIndex();
173 SDValue TFI
= CurDAG
->getTargetFrameIndex(FI
, MVT::i16
);
174 if (Node
->hasOneUse())
175 return CurDAG
->SelectNodeTo(Node
, MSP430::ADD16ri
, MVT::i16
,
176 TFI
, CurDAG
->getTargetConstant(0, MVT::i16
));
177 return CurDAG
->getTargetNode(MSP430::ADD16ri
, dl
, MVT::i16
,
178 TFI
, CurDAG
->getTargetConstant(0, MVT::i16
));
182 // Select the default instruction
183 SDNode
*ResNode
= SelectCode(Op
);
186 DOUT
<< std::string(Indent
-2, ' ') << "=> ";
187 if (ResNode
== NULL
|| ResNode
== Op
.getNode())
188 DEBUG(Op
.getNode()->dump(CurDAG
));
190 DEBUG(ResNode
->dump(CurDAG
));