1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
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 MIPS target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MipsISelDAGToDAG.h"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "Mips.h"
17 #include "Mips16ISelDAGToDAG.h"
18 #include "MipsMachineFunction.h"
19 #include "MipsRegisterInfo.h"
20 #include "MipsSEISelDAGToDAG.h"
21 #include "llvm/CodeGen/MachineConstantPool.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/SelectionDAGNodes.h"
27 #include "llvm/CodeGen/StackProtector.h"
28 #include "llvm/IR/CFG.h"
29 #include "llvm/IR/GlobalValue.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/Type.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Target/TargetMachine.h"
37 using namespace llvm;
38
39 #define DEBUG_TYPE "mips-isel"
40
41 //===----------------------------------------------------------------------===//
42 // Instruction Selector Implementation
43 //===----------------------------------------------------------------------===//
44
45 //===----------------------------------------------------------------------===//
46 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
47 // instructions for SelectionDAG operations.
48 //===----------------------------------------------------------------------===//
49
getAnalysisUsage(AnalysisUsage & AU) const50 void MipsDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
51 // There are multiple MipsDAGToDAGISel instances added to the pass pipeline.
52 // We need to preserve StackProtector for the next one.
53 AU.addPreserved<StackProtector>();
54 SelectionDAGISel::getAnalysisUsage(AU);
55 }
56
runOnMachineFunction(MachineFunction & MF)57 bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
58 Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
59 bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
60
61 processFunctionAfterISel(MF);
62
63 return Ret;
64 }
65
66 /// getGlobalBaseReg - Output the instructions required to put the
67 /// GOT address into a register.
getGlobalBaseReg()68 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
69 unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
70 return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy(
71 CurDAG->getDataLayout()))
72 .getNode();
73 }
74
75 /// ComplexPattern used on MipsInstrInfo
76 /// Used on Mips Load/Store instructions
selectAddrRegImm(SDValue Addr,SDValue & Base,SDValue & Offset) const77 bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
78 SDValue &Offset) const {
79 llvm_unreachable("Unimplemented function.");
80 return false;
81 }
82
selectAddrDefault(SDValue Addr,SDValue & Base,SDValue & Offset) const83 bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
84 SDValue &Offset) const {
85 llvm_unreachable("Unimplemented function.");
86 return false;
87 }
88
selectIntAddr(SDValue Addr,SDValue & Base,SDValue & Offset) const89 bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
90 SDValue &Offset) const {
91 llvm_unreachable("Unimplemented function.");
92 return false;
93 }
94
selectIntAddr11MM(SDValue Addr,SDValue & Base,SDValue & Offset) const95 bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,
96 SDValue &Offset) const {
97 llvm_unreachable("Unimplemented function.");
98 return false;
99 }
100
selectIntAddr12MM(SDValue Addr,SDValue & Base,SDValue & Offset) const101 bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,
102 SDValue &Offset) const {
103 llvm_unreachable("Unimplemented function.");
104 return false;
105 }
106
selectIntAddr16MM(SDValue Addr,SDValue & Base,SDValue & Offset) const107 bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,
108 SDValue &Offset) const {
109 llvm_unreachable("Unimplemented function.");
110 return false;
111 }
112
selectIntAddrLSL2MM(SDValue Addr,SDValue & Base,SDValue & Offset) const113 bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
114 SDValue &Offset) const {
115 llvm_unreachable("Unimplemented function.");
116 return false;
117 }
118
selectIntAddrSImm10(SDValue Addr,SDValue & Base,SDValue & Offset) const119 bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,
120 SDValue &Offset) const {
121 llvm_unreachable("Unimplemented function.");
122 return false;
123 }
124
selectIntAddrSImm10Lsl1(SDValue Addr,SDValue & Base,SDValue & Offset) const125 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
126 SDValue &Offset) const {
127 llvm_unreachable("Unimplemented function.");
128 return false;
129 }
130
selectIntAddrSImm10Lsl2(SDValue Addr,SDValue & Base,SDValue & Offset) const131 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
132 SDValue &Offset) const {
133 llvm_unreachable("Unimplemented function.");
134 return false;
135 }
136
selectIntAddrSImm10Lsl3(SDValue Addr,SDValue & Base,SDValue & Offset) const137 bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
138 SDValue &Offset) const {
139 llvm_unreachable("Unimplemented function.");
140 return false;
141 }
142
selectAddr16(SDValue Addr,SDValue & Base,SDValue & Offset)143 bool MipsDAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base,
144 SDValue &Offset) {
145 llvm_unreachable("Unimplemented function.");
146 return false;
147 }
148
selectAddr16SP(SDValue Addr,SDValue & Base,SDValue & Offset)149 bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base,
150 SDValue &Offset) {
151 llvm_unreachable("Unimplemented function.");
152 return false;
153 }
154
selectVSplat(SDNode * N,APInt & Imm,unsigned MinSizeInBits) const155 bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
156 unsigned MinSizeInBits) const {
157 llvm_unreachable("Unimplemented function.");
158 return false;
159 }
160
selectVSplatUimm1(SDValue N,SDValue & Imm) const161 bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
162 llvm_unreachable("Unimplemented function.");
163 return false;
164 }
165
selectVSplatUimm2(SDValue N,SDValue & Imm) const166 bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
167 llvm_unreachable("Unimplemented function.");
168 return false;
169 }
170
selectVSplatUimm3(SDValue N,SDValue & Imm) const171 bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
172 llvm_unreachable("Unimplemented function.");
173 return false;
174 }
175
selectVSplatUimm4(SDValue N,SDValue & Imm) const176 bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
177 llvm_unreachable("Unimplemented function.");
178 return false;
179 }
180
selectVSplatUimm5(SDValue N,SDValue & Imm) const181 bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
182 llvm_unreachable("Unimplemented function.");
183 return false;
184 }
185
selectVSplatUimm6(SDValue N,SDValue & Imm) const186 bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
187 llvm_unreachable("Unimplemented function.");
188 return false;
189 }
190
selectVSplatUimm8(SDValue N,SDValue & Imm) const191 bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
192 llvm_unreachable("Unimplemented function.");
193 return false;
194 }
195
selectVSplatSimm5(SDValue N,SDValue & Imm) const196 bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
197 llvm_unreachable("Unimplemented function.");
198 return false;
199 }
200
selectVSplatUimmPow2(SDValue N,SDValue & Imm) const201 bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
202 llvm_unreachable("Unimplemented function.");
203 return false;
204 }
205
selectVSplatUimmInvPow2(SDValue N,SDValue & Imm) const206 bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
207 llvm_unreachable("Unimplemented function.");
208 return false;
209 }
210
selectVSplatMaskL(SDValue N,SDValue & Imm) const211 bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
212 llvm_unreachable("Unimplemented function.");
213 return false;
214 }
215
selectVSplatMaskR(SDValue N,SDValue & Imm) const216 bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
217 llvm_unreachable("Unimplemented function.");
218 return false;
219 }
220
221 /// Select instructions not customized! Used for
222 /// expanded, promoted and normal instructions
Select(SDNode * Node)223 void MipsDAGToDAGISel::Select(SDNode *Node) {
224 unsigned Opcode = Node->getOpcode();
225
226 // If we have a custom node, we already have selected!
227 if (Node->isMachineOpcode()) {
228 LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
229 Node->setNodeId(-1);
230 return;
231 }
232
233 // See if subclasses can handle this node.
234 if (trySelect(Node))
235 return;
236
237 switch(Opcode) {
238 default: break;
239
240 // Get target GOT address.
241 case ISD::GLOBAL_OFFSET_TABLE:
242 ReplaceNode(Node, getGlobalBaseReg());
243 return;
244
245 #ifndef NDEBUG
246 case ISD::LOAD:
247 case ISD::STORE:
248 assert((Subtarget->systemSupportsUnalignedAccess() ||
249 cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
250 cast<MemSDNode>(Node)->getAlignment()) &&
251 "Unexpected unaligned loads/stores.");
252 break;
253 #endif
254 }
255
256 // Select the default instruction
257 SelectCode(Node);
258 }
259
260 bool MipsDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue & Op,unsigned ConstraintID,std::vector<SDValue> & OutOps)261 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
262 std::vector<SDValue> &OutOps) {
263 // All memory constraints can at least accept raw pointers.
264 switch(ConstraintID) {
265 default:
266 llvm_unreachable("Unexpected asm memory constraint");
267 case InlineAsm::Constraint_i:
268 case InlineAsm::Constraint_m:
269 case InlineAsm::Constraint_R:
270 case InlineAsm::Constraint_ZC:
271 OutOps.push_back(Op);
272 return false;
273 }
274 return true;
275 }
276