1 //===- BlackfinISelDAGToDAG.cpp - A dag to dag inst selector for Blackfin -===//
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 Blackfin target.
12 //===----------------------------------------------------------------------===//
15 #include "BlackfinISelLowering.h"
16 #include "BlackfinTargetMachine.h"
17 #include "BlackfinRegisterInfo.h"
18 #include "llvm/Intrinsics.h"
19 #include "llvm/CodeGen/SelectionDAGISel.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
28 //===----------------------------------------------------------------------===//
29 // Instruction Selector Implementation
30 //===----------------------------------------------------------------------===//
32 //===----------------------------------------------------------------------===//
33 /// BlackfinDAGToDAGISel - Blackfin specific code to select blackfin machine
34 /// instructions for SelectionDAG operations.
36 class BlackfinDAGToDAGISel
: public SelectionDAGISel
{
37 /// Subtarget - Keep a pointer to the Blackfin Subtarget around so that we
38 /// can make the right decision when generating code for different targets.
39 //const BlackfinSubtarget &Subtarget;
41 BlackfinDAGToDAGISel(BlackfinTargetMachine
&TM
, CodeGenOpt::Level OptLevel
)
42 : SelectionDAGISel(TM
, OptLevel
) {}
44 virtual void InstructionSelect();
46 virtual const char *getPassName() const {
47 return "Blackfin DAG->DAG Pattern Instruction Selection";
50 // Include the pieces autogenerated from the target description.
51 #include "BlackfinGenDAGISel.inc"
54 SDNode
*Select(SDValue Op
);
55 bool SelectADDRspii(SDValue Op
, SDValue Addr
,
56 SDValue
&Base
, SDValue
&Offset
);
58 // Walk the DAG after instruction selection, fixing register class issues.
59 void FixRegisterClasses(SelectionDAG
&DAG
);
61 const BlackfinInstrInfo
&getInstrInfo() {
62 return *static_cast<const BlackfinTargetMachine
&>(TM
).getInstrInfo();
64 const BlackfinRegisterInfo
*getRegisterInfo() {
65 return static_cast<const BlackfinTargetMachine
&>(TM
).getRegisterInfo();
68 } // end anonymous namespace
70 FunctionPass
*llvm::createBlackfinISelDag(BlackfinTargetMachine
&TM
,
71 CodeGenOpt::Level OptLevel
) {
72 return new BlackfinDAGToDAGISel(TM
, OptLevel
);
75 /// InstructionSelect - This callback is invoked by
76 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
77 void BlackfinDAGToDAGISel::InstructionSelect() {
78 // Select target instructions for the DAG.
80 DOUT
<< "Selected selection DAG before regclass fixup:\n";
81 DEBUG(CurDAG
->dump());
82 FixRegisterClasses(*CurDAG
);
85 SDNode
*BlackfinDAGToDAGISel::Select(SDValue Op
) {
86 SDNode
*N
= Op
.getNode();
87 DebugLoc dl
= N
->getDebugLoc();
88 if (N
->isMachineOpcode())
89 return NULL
; // Already selected.
91 switch (N
->getOpcode()) {
93 case ISD::FrameIndex
: {
94 // Selects to ADDpp FI, 0 which in turn will become ADDimm7 SP, imm or ADDpp
96 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
97 SDValue TFI
= CurDAG
->getTargetFrameIndex(FI
, MVT::i32
);
98 return CurDAG
->SelectNodeTo(N
, BF::ADDpp
, MVT::i32
, TFI
,
99 CurDAG
->getTargetConstant(0, MVT::i32
));
103 return SelectCode(Op
);
106 bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Op
,
110 FrameIndexSDNode
*FIN
= 0;
111 if ((FIN
= dyn_cast
<FrameIndexSDNode
>(Addr
))) {
112 Base
= CurDAG
->getTargetFrameIndex(FIN
->getIndex(), MVT::i32
);
113 Offset
= CurDAG
->getTargetConstant(0, MVT::i32
);
116 if (Addr
.getOpcode() == ISD::ADD
) {
117 ConstantSDNode
*CN
= 0;
118 if ((FIN
= dyn_cast
<FrameIndexSDNode
>(Addr
.getOperand(0))) &&
119 (CN
= dyn_cast
<ConstantSDNode
>(Addr
.getOperand(1))) &&
120 (CN
->getSExtValue() % 4 == 0 && CN
->getSExtValue() >= 0)) {
121 // Constant positive word offset from frame index
122 Base
= CurDAG
->getTargetFrameIndex(FIN
->getIndex(), MVT::i32
);
123 Offset
= CurDAG
->getTargetConstant(CN
->getSExtValue(), MVT::i32
);
130 static inline bool isCC(const TargetRegisterClass
*RC
) {
131 return RC
== &BF::AnyCCRegClass
|| BF::AnyCCRegClass
.hasSubClass(RC
);
134 static inline bool isDCC(const TargetRegisterClass
*RC
) {
135 return RC
== &BF::DRegClass
|| BF::DRegClass
.hasSubClass(RC
) || isCC(RC
);
138 static void UpdateNodeOperand(SelectionDAG
&DAG
,
142 SmallVector
<SDValue
, 8> ops(N
->op_begin(), N
->op_end());
144 SDValue New
= DAG
.UpdateNodeOperands(SDValue(N
, 0), ops
.data(), ops
.size());
145 DAG
.ReplaceAllUsesWith(N
, New
.getNode());
148 // After instruction selection, insert COPY_TO_REGCLASS nodes to help in
149 // choosing the proper register classes.
150 void BlackfinDAGToDAGISel::FixRegisterClasses(SelectionDAG
&DAG
) {
151 const BlackfinInstrInfo
&TII
= getInstrInfo();
152 const BlackfinRegisterInfo
*TRI
= getRegisterInfo();
153 DAG
.AssignTopologicalOrder();
154 HandleSDNode
Dummy(DAG
.getRoot());
156 for (SelectionDAG::allnodes_iterator NI
= DAG
.allnodes_begin();
157 NI
!= DAG
.allnodes_end(); ++NI
) {
158 if (NI
->use_empty() || !NI
->isMachineOpcode())
160 const TargetInstrDesc
&DefTID
= TII
.get(NI
->getMachineOpcode());
161 for (SDNode::use_iterator UI
= NI
->use_begin(); !UI
.atEnd(); ++UI
) {
162 if (!UI
->isMachineOpcode())
165 if (UI
.getUse().getResNo() >= DefTID
.getNumDefs())
167 const TargetRegisterClass
*DefRC
=
168 DefTID
.OpInfo
[UI
.getUse().getResNo()].getRegClass(TRI
);
170 const TargetInstrDesc
&UseTID
= TII
.get(UI
->getMachineOpcode());
171 if (UseTID
.getNumDefs()+UI
.getOperandNo() >= UseTID
.getNumOperands())
173 const TargetRegisterClass
*UseRC
=
174 UseTID
.OpInfo
[UseTID
.getNumDefs()+UI
.getOperandNo()].getRegClass(TRI
);
175 if (!DefRC
|| !UseRC
)
177 // We cannot copy CC <-> !(CC/D)
178 if ((isCC(DefRC
) && !isDCC(UseRC
)) || (isCC(UseRC
) && !isDCC(DefRC
))) {
180 DAG
.getTargetNode(TargetInstrInfo::COPY_TO_REGCLASS
,
184 DAG
.getTargetConstant(BF::DRegClassID
, MVT::i32
));
185 UpdateNodeOperand(DAG
, *UI
, UI
.getOperandNo(), SDValue(Copy
, 0));
189 DAG
.setRoot(Dummy
.getValue());