File: | lib/Target/Mips/MipsSEISelDAGToDAG.cpp |
Warning: | line 1067, column 15 1st function call argument is an uninitialized value |
1 | //===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===// | |||
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 | // Subclass of MipsDAGToDAGISel specialized for mips32/64. | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "MipsSEISelDAGToDAG.h" | |||
15 | #include "MCTargetDesc/MipsBaseInfo.h" | |||
16 | #include "Mips.h" | |||
17 | #include "MipsAnalyzeImmediate.h" | |||
18 | #include "MipsMachineFunction.h" | |||
19 | #include "MipsRegisterInfo.h" | |||
20 | #include "llvm/CodeGen/MachineConstantPool.h" | |||
21 | #include "llvm/CodeGen/MachineFrameInfo.h" | |||
22 | #include "llvm/CodeGen/MachineFunction.h" | |||
23 | #include "llvm/CodeGen/MachineInstrBuilder.h" | |||
24 | #include "llvm/CodeGen/MachineRegisterInfo.h" | |||
25 | #include "llvm/CodeGen/SelectionDAGNodes.h" | |||
26 | #include "llvm/IR/CFG.h" | |||
27 | #include "llvm/IR/Dominators.h" | |||
28 | #include "llvm/IR/GlobalValue.h" | |||
29 | #include "llvm/IR/Instructions.h" | |||
30 | #include "llvm/IR/Intrinsics.h" | |||
31 | #include "llvm/IR/Type.h" | |||
32 | #include "llvm/Support/Debug.h" | |||
33 | #include "llvm/Support/ErrorHandling.h" | |||
34 | #include "llvm/Support/raw_ostream.h" | |||
35 | #include "llvm/Target/TargetMachine.h" | |||
36 | using namespace llvm; | |||
37 | ||||
38 | #define DEBUG_TYPE"mips-isel" "mips-isel" | |||
39 | ||||
40 | bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { | |||
41 | Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget()); | |||
42 | if (Subtarget->inMips16Mode()) | |||
43 | return false; | |||
44 | return MipsDAGToDAGISel::runOnMachineFunction(MF); | |||
45 | } | |||
46 | ||||
47 | void MipsSEDAGToDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { | |||
48 | AU.addRequired<DominatorTreeWrapperPass>(); | |||
49 | SelectionDAGISel::getAnalysisUsage(AU); | |||
50 | } | |||
51 | ||||
52 | void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, | |||
53 | MachineFunction &MF) { | |||
54 | MachineInstrBuilder MIB(MF, &MI); | |||
55 | unsigned Mask = MI.getOperand(1).getImm(); | |||
56 | unsigned Flag = | |||
57 | IsDef ? RegState::ImplicitDefine : RegState::Implicit | RegState::Undef; | |||
58 | ||||
59 | if (Mask & 1) | |||
60 | MIB.addReg(Mips::DSPPos, Flag); | |||
61 | ||||
62 | if (Mask & 2) | |||
63 | MIB.addReg(Mips::DSPSCount, Flag); | |||
64 | ||||
65 | if (Mask & 4) | |||
66 | MIB.addReg(Mips::DSPCarry, Flag); | |||
67 | ||||
68 | if (Mask & 8) | |||
69 | MIB.addReg(Mips::DSPOutFlag, Flag); | |||
70 | ||||
71 | if (Mask & 16) | |||
72 | MIB.addReg(Mips::DSPCCond, Flag); | |||
73 | ||||
74 | if (Mask & 32) | |||
75 | MIB.addReg(Mips::DSPEFI, Flag); | |||
76 | } | |||
77 | ||||
78 | unsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const { | |||
79 | switch (cast<ConstantSDNode>(RegIdx)->getZExtValue()) { | |||
80 | default: | |||
81 | llvm_unreachable("Could not map int to register")::llvm::llvm_unreachable_internal("Could not map int to register" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 81); | |||
82 | case 0: return Mips::MSAIR; | |||
83 | case 1: return Mips::MSACSR; | |||
84 | case 2: return Mips::MSAAccess; | |||
85 | case 3: return Mips::MSASave; | |||
86 | case 4: return Mips::MSAModify; | |||
87 | case 5: return Mips::MSARequest; | |||
88 | case 6: return Mips::MSAMap; | |||
89 | case 7: return Mips::MSAUnmap; | |||
90 | } | |||
91 | } | |||
92 | ||||
93 | bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, | |||
94 | const MachineInstr& MI) { | |||
95 | unsigned DstReg = 0, ZeroReg = 0; | |||
96 | ||||
97 | // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0". | |||
98 | if ((MI.getOpcode() == Mips::ADDiu) && | |||
99 | (MI.getOperand(1).getReg() == Mips::ZERO) && | |||
100 | (MI.getOperand(2).isImm()) && | |||
101 | (MI.getOperand(2).getImm() == 0)) { | |||
102 | DstReg = MI.getOperand(0).getReg(); | |||
103 | ZeroReg = Mips::ZERO; | |||
104 | } else if ((MI.getOpcode() == Mips::DADDiu) && | |||
105 | (MI.getOperand(1).getReg() == Mips::ZERO_64) && | |||
106 | (MI.getOperand(2).isImm()) && | |||
107 | (MI.getOperand(2).getImm() == 0)) { | |||
108 | DstReg = MI.getOperand(0).getReg(); | |||
109 | ZeroReg = Mips::ZERO_64; | |||
110 | } | |||
111 | ||||
112 | if (!DstReg) | |||
113 | return false; | |||
114 | ||||
115 | // Replace uses with ZeroReg. | |||
116 | for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg), | |||
117 | E = MRI->use_end(); U != E;) { | |||
118 | MachineOperand &MO = *U; | |||
119 | unsigned OpNo = U.getOperandNo(); | |||
120 | MachineInstr *MI = MO.getParent(); | |||
121 | ++U; | |||
122 | ||||
123 | // Do not replace if it is a phi's operand or is tied to def operand. | |||
124 | if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo()) | |||
125 | continue; | |||
126 | ||||
127 | // Also, we have to check that the register class of the operand | |||
128 | // contains the zero register. | |||
129 | if (!MRI->getRegClass(MO.getReg())->contains(ZeroReg)) | |||
130 | continue; | |||
131 | ||||
132 | MO.setReg(ZeroReg); | |||
133 | } | |||
134 | ||||
135 | return true; | |||
136 | } | |||
137 | ||||
138 | void MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) { | |||
139 | MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); | |||
140 | ||||
141 | if (!MipsFI->globalBaseRegSet()) | |||
142 | return; | |||
143 | ||||
144 | MachineBasicBlock &MBB = MF.front(); | |||
145 | MachineBasicBlock::iterator I = MBB.begin(); | |||
146 | MachineRegisterInfo &RegInfo = MF.getRegInfo(); | |||
147 | const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); | |||
148 | DebugLoc DL; | |||
149 | unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg(); | |||
150 | const TargetRegisterClass *RC; | |||
151 | const MipsABIInfo &ABI = static_cast<const MipsTargetMachine &>(TM).getABI(); | |||
152 | RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; | |||
153 | ||||
154 | V0 = RegInfo.createVirtualRegister(RC); | |||
155 | V1 = RegInfo.createVirtualRegister(RC); | |||
156 | ||||
157 | if (ABI.IsN64()) { | |||
158 | MF.getRegInfo().addLiveIn(Mips::T9_64); | |||
159 | MBB.addLiveIn(Mips::T9_64); | |||
160 | ||||
161 | // lui $v0, %hi(%neg(%gp_rel(fname))) | |||
162 | // daddu $v1, $v0, $t9 | |||
163 | // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) | |||
164 | const GlobalValue *FName = MF.getFunction(); | |||
165 | BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0) | |||
166 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); | |||
167 | BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0) | |||
168 | .addReg(Mips::T9_64); | |||
169 | BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1) | |||
170 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); | |||
171 | return; | |||
172 | } | |||
173 | ||||
174 | if (!MF.getTarget().isPositionIndependent()) { | |||
175 | // Set global register to __gnu_local_gp. | |||
176 | // | |||
177 | // lui $v0, %hi(__gnu_local_gp) | |||
178 | // addiu $globalbasereg, $v0, %lo(__gnu_local_gp) | |||
179 | BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) | |||
180 | .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI); | |||
181 | BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0) | |||
182 | .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO); | |||
183 | return; | |||
184 | } | |||
185 | ||||
186 | MF.getRegInfo().addLiveIn(Mips::T9); | |||
187 | MBB.addLiveIn(Mips::T9); | |||
188 | ||||
189 | if (ABI.IsN32()) { | |||
190 | // lui $v0, %hi(%neg(%gp_rel(fname))) | |||
191 | // addu $v1, $v0, $t9 | |||
192 | // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) | |||
193 | const GlobalValue *FName = MF.getFunction(); | |||
194 | BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) | |||
195 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); | |||
196 | BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9); | |||
197 | BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1) | |||
198 | .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); | |||
199 | return; | |||
200 | } | |||
201 | ||||
202 | assert(ABI.IsO32())((ABI.IsO32()) ? static_cast<void> (0) : __assert_fail ( "ABI.IsO32()", "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 202, __PRETTY_FUNCTION__)); | |||
203 | ||||
204 | // For O32 ABI, the following instruction sequence is emitted to initialize | |||
205 | // the global base register: | |||
206 | // | |||
207 | // 0. lui $2, %hi(_gp_disp) | |||
208 | // 1. addiu $2, $2, %lo(_gp_disp) | |||
209 | // 2. addu $globalbasereg, $2, $t9 | |||
210 | // | |||
211 | // We emit only the last instruction here. | |||
212 | // | |||
213 | // GNU linker requires that the first two instructions appear at the beginning | |||
214 | // of a function and no instructions be inserted before or between them. | |||
215 | // The two instructions are emitted during lowering to MC layer in order to | |||
216 | // avoid any reordering. | |||
217 | // | |||
218 | // Register $2 (Mips::V0) is added to the list of live-in registers to ensure | |||
219 | // the value instruction 1 (addiu) defines is valid when instruction 2 (addu) | |||
220 | // reads it. | |||
221 | MF.getRegInfo().addLiveIn(Mips::V0); | |||
222 | MBB.addLiveIn(Mips::V0); | |||
223 | BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg) | |||
224 | .addReg(Mips::V0).addReg(Mips::T9); | |||
225 | } | |||
226 | ||||
227 | void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { | |||
228 | initGlobalBaseReg(MF); | |||
229 | ||||
230 | MachineRegisterInfo *MRI = &MF.getRegInfo(); | |||
231 | ||||
232 | for (auto &MBB: MF) { | |||
233 | for (auto &MI: MBB) { | |||
234 | switch (MI.getOpcode()) { | |||
235 | case Mips::RDDSP: | |||
236 | addDSPCtrlRegOperands(false, MI, MF); | |||
237 | break; | |||
238 | case Mips::WRDSP: | |||
239 | addDSPCtrlRegOperands(true, MI, MF); | |||
240 | break; | |||
241 | default: | |||
242 | replaceUsesWithZeroReg(MRI, MI); | |||
243 | } | |||
244 | } | |||
245 | } | |||
246 | } | |||
247 | ||||
248 | void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const { | |||
249 | SDValue InFlag = Node->getOperand(2); | |||
250 | unsigned Opc = InFlag.getOpcode(); | |||
251 | SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); | |||
252 | EVT VT = LHS.getValueType(); | |||
253 | ||||
254 | // In the base case, we can rely on the carry bit from the addsc | |||
255 | // instruction. | |||
256 | if (Opc == ISD::ADDC) { | |||
257 | SDValue Ops[3] = {LHS, RHS, InFlag}; | |||
258 | CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Ops); | |||
259 | return; | |||
260 | } | |||
261 | ||||
262 | assert(Opc == ISD::ADDE && "ISD::ADDE not in a chain of ADDE nodes!")((Opc == ISD::ADDE && "ISD::ADDE not in a chain of ADDE nodes!" ) ? static_cast<void> (0) : __assert_fail ("Opc == ISD::ADDE && \"ISD::ADDE not in a chain of ADDE nodes!\"" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 262, __PRETTY_FUNCTION__)); | |||
263 | ||||
264 | // The more complex case is when there is a chain of ISD::ADDE nodes like: | |||
265 | // (adde (adde (adde (addc a b) c) d) e). | |||
266 | // | |||
267 | // The addwc instruction does not write to the carry bit, instead it writes | |||
268 | // to bit 20 of the dsp control register. To match this series of nodes, each | |||
269 | // intermediate adde node must be expanded to write the carry bit before the | |||
270 | // addition. | |||
271 | ||||
272 | // Start by reading the overflow field for addsc and moving the value to the | |||
273 | // carry field. The usage of 1 here with MipsISD::RDDSP / Mips::WRDSP | |||
274 | // corresponds to reading/writing the entire control register to/from a GPR. | |||
275 | ||||
276 | SDValue CstOne = CurDAG->getTargetConstant(1, DL, MVT::i32); | |||
277 | ||||
278 | SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32); | |||
279 | ||||
280 | SDNode *DSPCtrlField = | |||
281 | CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32, MVT::Glue, CstOne, InFlag); | |||
282 | ||||
283 | SDNode *Carry = CurDAG->getMachineNode( | |||
284 | Mips::EXT, DL, MVT::i32, SDValue(DSPCtrlField, 0), OuFlag, CstOne); | |||
285 | ||||
286 | SDValue Ops[4] = {SDValue(DSPCtrlField, 0), | |||
287 | CurDAG->getTargetConstant(6, DL, MVT::i32), CstOne, | |||
288 | SDValue(Carry, 0)}; | |||
289 | SDNode *DSPCFWithCarry = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, Ops); | |||
290 | ||||
291 | // My reading of the the MIPS DSP 3.01 specification isn't as clear as I | |||
292 | // would like about whether bit 20 always gets overwritten by addwc. | |||
293 | // Hence take an extremely conservative view and presume it's sticky. We | |||
294 | // therefore need to clear it. | |||
295 | ||||
296 | SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
297 | ||||
298 | SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)}; | |||
299 | SDNode *DSPCtrlFinal = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps); | |||
300 | ||||
301 | SDNode *WrDSP = CurDAG->getMachineNode(Mips::WRDSP, DL, MVT::Glue, | |||
302 | SDValue(DSPCtrlFinal, 0), CstOne); | |||
303 | ||||
304 | SDValue Operands[3] = {LHS, RHS, SDValue(WrDSP, 0)}; | |||
305 | CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Operands); | |||
306 | } | |||
307 | ||||
308 | /// Match frameindex | |||
309 | bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base, | |||
310 | SDValue &Offset) const { | |||
311 | if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { | |||
312 | EVT ValTy = Addr.getValueType(); | |||
313 | ||||
314 | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); | |||
315 | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy); | |||
316 | return true; | |||
317 | } | |||
318 | return false; | |||
319 | } | |||
320 | ||||
321 | /// Match frameindex+offset and frameindex|offset | |||
322 | bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset( | |||
323 | SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits, | |||
324 | unsigned ShiftAmount = 0) const { | |||
325 | if (CurDAG->isBaseWithConstantOffset(Addr)) { | |||
326 | ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); | |||
327 | if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) { | |||
328 | EVT ValTy = Addr.getValueType(); | |||
329 | ||||
330 | // If the first operand is a FI, get the TargetFI Node | |||
331 | if (FrameIndexSDNode *FIN = | |||
332 | dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) | |||
333 | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); | |||
334 | else { | |||
335 | Base = Addr.getOperand(0); | |||
336 | // If base is a FI, additional offset calculation is done in | |||
337 | // eliminateFrameIndex, otherwise we need to check the alignment | |||
338 | if (OffsetToAlignment(CN->getZExtValue(), 1ull << ShiftAmount) != 0) | |||
339 | return false; | |||
340 | } | |||
341 | ||||
342 | Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), | |||
343 | ValTy); | |||
344 | return true; | |||
345 | } | |||
346 | } | |||
347 | return false; | |||
348 | } | |||
349 | ||||
350 | /// ComplexPattern used on MipsInstrInfo | |||
351 | /// Used on Mips Load/Store instructions | |||
352 | bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, | |||
353 | SDValue &Offset) const { | |||
354 | // if Address is FI, get the TargetFrameIndex. | |||
355 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
356 | return true; | |||
357 | ||||
358 | // on PIC code Load GA | |||
359 | if (Addr.getOpcode() == MipsISD::Wrapper) { | |||
360 | Base = Addr.getOperand(0); | |||
361 | Offset = Addr.getOperand(1); | |||
362 | return true; | |||
363 | } | |||
364 | ||||
365 | if (!TM.isPositionIndependent()) { | |||
366 | if ((Addr.getOpcode() == ISD::TargetExternalSymbol || | |||
367 | Addr.getOpcode() == ISD::TargetGlobalAddress)) | |||
368 | return false; | |||
369 | } | |||
370 | ||||
371 | // Addresses of the form FI+const or FI|const | |||
372 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) | |||
373 | return true; | |||
374 | ||||
375 | // Operand is a result from an ADD. | |||
376 | if (Addr.getOpcode() == ISD::ADD) { | |||
377 | // When loading from constant pools, load the lower address part in | |||
378 | // the instruction itself. Example, instead of: | |||
379 | // lui $2, %hi($CPI1_0) | |||
380 | // addiu $2, $2, %lo($CPI1_0) | |||
381 | // lwc1 $f0, 0($2) | |||
382 | // Generate: | |||
383 | // lui $2, %hi($CPI1_0) | |||
384 | // lwc1 $f0, %lo($CPI1_0)($2) | |||
385 | if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || | |||
386 | Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { | |||
387 | SDValue Opnd0 = Addr.getOperand(1).getOperand(0); | |||
388 | if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || | |||
389 | isa<JumpTableSDNode>(Opnd0)) { | |||
390 | Base = Addr.getOperand(0); | |||
391 | Offset = Opnd0; | |||
392 | return true; | |||
393 | } | |||
394 | } | |||
395 | } | |||
396 | ||||
397 | return false; | |||
398 | } | |||
399 | ||||
400 | /// ComplexPattern used on MipsInstrInfo | |||
401 | /// Used on Mips Load/Store instructions | |||
402 | bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, | |||
403 | SDValue &Offset) const { | |||
404 | Base = Addr; | |||
405 | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType()); | |||
406 | return true; | |||
407 | } | |||
408 | ||||
409 | bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, | |||
410 | SDValue &Offset) const { | |||
411 | return selectAddrRegImm(Addr, Base, Offset) || | |||
412 | selectAddrDefault(Addr, Base, Offset); | |||
413 | } | |||
414 | ||||
415 | bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base, | |||
416 | SDValue &Offset) const { | |||
417 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
418 | return true; | |||
419 | ||||
420 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9)) | |||
421 | return true; | |||
422 | ||||
423 | return false; | |||
424 | } | |||
425 | ||||
426 | /// Used on microMIPS LWC2, LDC2, SWC2 and SDC2 instructions (11-bit offset) | |||
427 | bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base, | |||
428 | SDValue &Offset) const { | |||
429 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
430 | return true; | |||
431 | ||||
432 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11)) | |||
433 | return true; | |||
434 | ||||
435 | return false; | |||
436 | } | |||
437 | ||||
438 | /// Used on microMIPS Load/Store unaligned instructions (12-bit offset) | |||
439 | bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, | |||
440 | SDValue &Offset) const { | |||
441 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
442 | return true; | |||
443 | ||||
444 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) | |||
445 | return true; | |||
446 | ||||
447 | return false; | |||
448 | } | |||
449 | ||||
450 | bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base, | |||
451 | SDValue &Offset) const { | |||
452 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
453 | return true; | |||
454 | ||||
455 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) | |||
456 | return true; | |||
457 | ||||
458 | return false; | |||
459 | } | |||
460 | ||||
461 | bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, | |||
462 | SDValue &Offset) const { | |||
463 | return selectAddrRegImm11(Addr, Base, Offset) || | |||
464 | selectAddrDefault(Addr, Base, Offset); | |||
465 | } | |||
466 | ||||
467 | bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, | |||
468 | SDValue &Offset) const { | |||
469 | return selectAddrRegImm12(Addr, Base, Offset) || | |||
470 | selectAddrDefault(Addr, Base, Offset); | |||
471 | } | |||
472 | ||||
473 | bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, | |||
474 | SDValue &Offset) const { | |||
475 | return selectAddrRegImm16(Addr, Base, Offset) || | |||
476 | selectAddrDefault(Addr, Base, Offset); | |||
477 | } | |||
478 | ||||
479 | bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, | |||
480 | SDValue &Offset) const { | |||
481 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) { | |||
482 | if (isa<FrameIndexSDNode>(Base)) | |||
483 | return false; | |||
484 | ||||
485 | if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Offset)) { | |||
486 | unsigned CnstOff = CN->getZExtValue(); | |||
487 | return (CnstOff == (CnstOff & 0x3c)); | |||
488 | } | |||
489 | ||||
490 | return false; | |||
491 | } | |||
492 | ||||
493 | // For all other cases where "lw" would be selected, don't select "lw16" | |||
494 | // because it would result in additional instructions to prepare operands. | |||
495 | if (selectAddrRegImm(Addr, Base, Offset)) | |||
496 | return false; | |||
497 | ||||
498 | return selectAddrDefault(Addr, Base, Offset); | |||
499 | } | |||
500 | ||||
501 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, | |||
502 | SDValue &Offset) const { | |||
503 | ||||
504 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
505 | return true; | |||
506 | ||||
507 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) | |||
508 | return true; | |||
509 | ||||
510 | return selectAddrDefault(Addr, Base, Offset); | |||
511 | } | |||
512 | ||||
513 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, | |||
514 | SDValue &Offset) const { | |||
515 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
516 | return true; | |||
517 | ||||
518 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1)) | |||
519 | return true; | |||
520 | ||||
521 | return selectAddrDefault(Addr, Base, Offset); | |||
522 | } | |||
523 | ||||
524 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, | |||
525 | SDValue &Offset) const { | |||
526 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
527 | return true; | |||
528 | ||||
529 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2)) | |||
530 | return true; | |||
531 | ||||
532 | return selectAddrDefault(Addr, Base, Offset); | |||
533 | } | |||
534 | ||||
535 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, | |||
536 | SDValue &Offset) const { | |||
537 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
538 | return true; | |||
539 | ||||
540 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3)) | |||
541 | return true; | |||
542 | ||||
543 | return selectAddrDefault(Addr, Base, Offset); | |||
544 | } | |||
545 | ||||
546 | // Select constant vector splats. | |||
547 | // | |||
548 | // Returns true and sets Imm if: | |||
549 | // * MSA is enabled | |||
550 | // * N is a ISD::BUILD_VECTOR representing a constant splat | |||
551 | bool MipsSEDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, | |||
552 | unsigned MinSizeInBits) const { | |||
553 | if (!Subtarget->hasMSA()) | |||
554 | return false; | |||
555 | ||||
556 | BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(N); | |||
557 | ||||
558 | if (!Node) | |||
559 | return false; | |||
560 | ||||
561 | APInt SplatValue, SplatUndef; | |||
562 | unsigned SplatBitSize; | |||
563 | bool HasAnyUndefs; | |||
564 | ||||
565 | if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, | |||
566 | MinSizeInBits, !Subtarget->isLittle())) | |||
567 | return false; | |||
568 | ||||
569 | Imm = SplatValue; | |||
570 | ||||
571 | return true; | |||
572 | } | |||
573 | ||||
574 | // Select constant vector splats. | |||
575 | // | |||
576 | // In addition to the requirements of selectVSplat(), this function returns | |||
577 | // true and sets Imm if: | |||
578 | // * The splat value is the same width as the elements of the vector | |||
579 | // * The splat value fits in an integer with the specified signed-ness and | |||
580 | // width. | |||
581 | // | |||
582 | // This function looks through ISD::BITCAST nodes. | |||
583 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
584 | // sometimes a shuffle in big-endian mode. | |||
585 | // | |||
586 | // It's worth noting that this function is not used as part of the selection | |||
587 | // of ldi.[bhwd] since it does not permit using the wrong-typed ldi.[bhwd] | |||
588 | // instruction to achieve the desired bit pattern. ldi.[bhwd] is selected in | |||
589 | // MipsSEDAGToDAGISel::selectNode. | |||
590 | bool MipsSEDAGToDAGISel:: | |||
591 | selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed, | |||
592 | unsigned ImmBitSize) const { | |||
593 | APInt ImmValue; | |||
594 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
595 | ||||
596 | if (N->getOpcode() == ISD::BITCAST) | |||
597 | N = N->getOperand(0); | |||
598 | ||||
599 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
600 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
601 | ||||
602 | if (( Signed && ImmValue.isSignedIntN(ImmBitSize)) || | |||
603 | (!Signed && ImmValue.isIntN(ImmBitSize))) { | |||
604 | Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy); | |||
605 | return true; | |||
606 | } | |||
607 | } | |||
608 | ||||
609 | return false; | |||
610 | } | |||
611 | ||||
612 | // Select constant vector splats. | |||
613 | bool MipsSEDAGToDAGISel:: | |||
614 | selectVSplatUimm1(SDValue N, SDValue &Imm) const { | |||
615 | return selectVSplatCommon(N, Imm, false, 1); | |||
616 | } | |||
617 | ||||
618 | bool MipsSEDAGToDAGISel:: | |||
619 | selectVSplatUimm2(SDValue N, SDValue &Imm) const { | |||
620 | return selectVSplatCommon(N, Imm, false, 2); | |||
621 | } | |||
622 | ||||
623 | bool MipsSEDAGToDAGISel:: | |||
624 | selectVSplatUimm3(SDValue N, SDValue &Imm) const { | |||
625 | return selectVSplatCommon(N, Imm, false, 3); | |||
626 | } | |||
627 | ||||
628 | // Select constant vector splats. | |||
629 | bool MipsSEDAGToDAGISel:: | |||
630 | selectVSplatUimm4(SDValue N, SDValue &Imm) const { | |||
631 | return selectVSplatCommon(N, Imm, false, 4); | |||
632 | } | |||
633 | ||||
634 | // Select constant vector splats. | |||
635 | bool MipsSEDAGToDAGISel:: | |||
636 | selectVSplatUimm5(SDValue N, SDValue &Imm) const { | |||
637 | return selectVSplatCommon(N, Imm, false, 5); | |||
638 | } | |||
639 | ||||
640 | // Select constant vector splats. | |||
641 | bool MipsSEDAGToDAGISel:: | |||
642 | selectVSplatUimm6(SDValue N, SDValue &Imm) const { | |||
643 | return selectVSplatCommon(N, Imm, false, 6); | |||
644 | } | |||
645 | ||||
646 | // Select constant vector splats. | |||
647 | bool MipsSEDAGToDAGISel:: | |||
648 | selectVSplatUimm8(SDValue N, SDValue &Imm) const { | |||
649 | return selectVSplatCommon(N, Imm, false, 8); | |||
650 | } | |||
651 | ||||
652 | // Select constant vector splats. | |||
653 | bool MipsSEDAGToDAGISel:: | |||
654 | selectVSplatSimm5(SDValue N, SDValue &Imm) const { | |||
655 | return selectVSplatCommon(N, Imm, true, 5); | |||
656 | } | |||
657 | ||||
658 | // Select constant vector splats whose value is a power of 2. | |||
659 | // | |||
660 | // In addition to the requirements of selectVSplat(), this function returns | |||
661 | // true and sets Imm if: | |||
662 | // * The splat value is the same width as the elements of the vector | |||
663 | // * The splat value is a power of two. | |||
664 | // | |||
665 | // This function looks through ISD::BITCAST nodes. | |||
666 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
667 | // sometimes a shuffle in big-endian mode. | |||
668 | bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const { | |||
669 | APInt ImmValue; | |||
670 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
671 | ||||
672 | if (N->getOpcode() == ISD::BITCAST) | |||
673 | N = N->getOperand(0); | |||
674 | ||||
675 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
676 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
677 | int32_t Log2 = ImmValue.exactLogBase2(); | |||
678 | ||||
679 | if (Log2 != -1) { | |||
680 | Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); | |||
681 | return true; | |||
682 | } | |||
683 | } | |||
684 | ||||
685 | return false; | |||
686 | } | |||
687 | ||||
688 | // Select constant vector splats whose value only has a consecutive sequence | |||
689 | // of left-most bits set (e.g. 0b11...1100...00). | |||
690 | // | |||
691 | // In addition to the requirements of selectVSplat(), this function returns | |||
692 | // true and sets Imm if: | |||
693 | // * The splat value is the same width as the elements of the vector | |||
694 | // * The splat value is a consecutive sequence of left-most bits. | |||
695 | // | |||
696 | // This function looks through ISD::BITCAST nodes. | |||
697 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
698 | // sometimes a shuffle in big-endian mode. | |||
699 | bool MipsSEDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const { | |||
700 | APInt ImmValue; | |||
701 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
702 | ||||
703 | if (N->getOpcode() == ISD::BITCAST) | |||
704 | N = N->getOperand(0); | |||
705 | ||||
706 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
707 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
708 | // Extract the run of set bits starting with bit zero from the bitwise | |||
709 | // inverse of ImmValue, and test that the inverse of this is the same | |||
710 | // as the original value. | |||
711 | if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) { | |||
712 | ||||
713 | Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N), | |||
714 | EltTy); | |||
715 | return true; | |||
716 | } | |||
717 | } | |||
718 | ||||
719 | return false; | |||
720 | } | |||
721 | ||||
722 | // Select constant vector splats whose value only has a consecutive sequence | |||
723 | // of right-most bits set (e.g. 0b00...0011...11). | |||
724 | // | |||
725 | // In addition to the requirements of selectVSplat(), this function returns | |||
726 | // true and sets Imm if: | |||
727 | // * The splat value is the same width as the elements of the vector | |||
728 | // * The splat value is a consecutive sequence of right-most bits. | |||
729 | // | |||
730 | // This function looks through ISD::BITCAST nodes. | |||
731 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
732 | // sometimes a shuffle in big-endian mode. | |||
733 | bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const { | |||
734 | APInt ImmValue; | |||
735 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
736 | ||||
737 | if (N->getOpcode() == ISD::BITCAST) | |||
738 | N = N->getOperand(0); | |||
739 | ||||
740 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
741 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
742 | // Extract the run of set bits starting with bit zero, and test that the | |||
743 | // result is the same as the original value | |||
744 | if (ImmValue == (ImmValue & ~(ImmValue + 1))) { | |||
745 | Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N), | |||
746 | EltTy); | |||
747 | return true; | |||
748 | } | |||
749 | } | |||
750 | ||||
751 | return false; | |||
752 | } | |||
753 | ||||
754 | bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, | |||
755 | SDValue &Imm) const { | |||
756 | APInt ImmValue; | |||
757 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
758 | ||||
759 | if (N->getOpcode() == ISD::BITCAST) | |||
760 | N = N->getOperand(0); | |||
761 | ||||
762 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
763 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
764 | int32_t Log2 = (~ImmValue).exactLogBase2(); | |||
765 | ||||
766 | if (Log2 != -1) { | |||
767 | Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); | |||
768 | return true; | |||
769 | } | |||
770 | } | |||
771 | ||||
772 | return false; | |||
773 | } | |||
774 | ||||
775 | bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) { | |||
776 | unsigned Opcode = Node->getOpcode(); | |||
777 | SDLoc DL(Node); | |||
778 | ||||
779 | /// | |||
780 | // Instruction Selection not handled by the auto-generated | |||
781 | // tablegen selection should be handled here. | |||
782 | /// | |||
783 | switch(Opcode) { | |||
| ||||
784 | default: break; | |||
785 | ||||
786 | case ISD::ADDE: { | |||
787 | selectAddE(Node, DL); | |||
788 | return true; | |||
789 | } | |||
790 | ||||
791 | case ISD::ConstantFP: { | |||
792 | ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); | |||
793 | if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { | |||
794 | if (Subtarget->isGP64bit()) { | |||
795 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
796 | Mips::ZERO_64, MVT::i64); | |||
797 | ReplaceNode(Node, | |||
798 | CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero)); | |||
799 | } else if (Subtarget->isFP64bit()) { | |||
800 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
801 | Mips::ZERO, MVT::i32); | |||
802 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64_64, DL, | |||
803 | MVT::f64, Zero, Zero)); | |||
804 | } else { | |||
805 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
806 | Mips::ZERO, MVT::i32); | |||
807 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64, DL, | |||
808 | MVT::f64, Zero, Zero)); | |||
809 | } | |||
810 | return true; | |||
811 | } | |||
812 | break; | |||
813 | } | |||
814 | ||||
815 | case ISD::Constant: { | |||
816 | const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); | |||
817 | int64_t Imm = CN->getSExtValue(); | |||
818 | unsigned Size = CN->getValueSizeInBits(0); | |||
819 | ||||
820 | if (isInt<32>(Imm)) | |||
821 | break; | |||
822 | ||||
823 | MipsAnalyzeImmediate AnalyzeImm; | |||
824 | ||||
825 | const MipsAnalyzeImmediate::InstSeq &Seq = | |||
826 | AnalyzeImm.Analyze(Imm, Size, false); | |||
827 | ||||
828 | MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); | |||
829 | SDLoc DL(CN); | |||
830 | SDNode *RegOpnd; | |||
831 | SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), | |||
832 | DL, MVT::i64); | |||
833 | ||||
834 | // The first instruction can be a LUi which is different from other | |||
835 | // instructions (ADDiu, ORI and SLL) in that it does not have a register | |||
836 | // operand. | |||
837 | if (Inst->Opc == Mips::LUi64) | |||
838 | RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd); | |||
839 | else | |||
840 | RegOpnd = | |||
841 | CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, | |||
842 | CurDAG->getRegister(Mips::ZERO_64, MVT::i64), | |||
843 | ImmOpnd); | |||
844 | ||||
845 | // The remaining instructions in the sequence are handled here. | |||
846 | for (++Inst; Inst != Seq.end(); ++Inst) { | |||
847 | ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), DL, | |||
848 | MVT::i64); | |||
849 | RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, | |||
850 | SDValue(RegOpnd, 0), ImmOpnd); | |||
851 | } | |||
852 | ||||
853 | ReplaceNode(Node, RegOpnd); | |||
854 | return true; | |||
855 | } | |||
856 | ||||
857 | case ISD::INTRINSIC_W_CHAIN: { | |||
858 | switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { | |||
859 | default: | |||
860 | break; | |||
861 | ||||
862 | case Intrinsic::mips_cfcmsa: { | |||
863 | SDValue ChainIn = Node->getOperand(0); | |||
864 | SDValue RegIdx = Node->getOperand(2); | |||
865 | SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL, | |||
866 | getMSACtrlReg(RegIdx), MVT::i32); | |||
867 | ReplaceNode(Node, Reg.getNode()); | |||
868 | return true; | |||
869 | } | |||
870 | } | |||
871 | break; | |||
872 | } | |||
873 | ||||
874 | case ISD::INTRINSIC_WO_CHAIN: { | |||
875 | switch (cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue()) { | |||
876 | default: | |||
877 | break; | |||
878 | ||||
879 | case Intrinsic::mips_move_v: | |||
880 | // Like an assignment but will always produce a move.v even if | |||
881 | // unnecessary. | |||
882 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::MOVE_V, DL, | |||
883 | Node->getValueType(0), | |||
884 | Node->getOperand(1))); | |||
885 | return true; | |||
886 | } | |||
887 | break; | |||
888 | } | |||
889 | ||||
890 | case ISD::INTRINSIC_VOID: { | |||
891 | switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { | |||
892 | default: | |||
893 | break; | |||
894 | ||||
895 | case Intrinsic::mips_ctcmsa: { | |||
896 | SDValue ChainIn = Node->getOperand(0); | |||
897 | SDValue RegIdx = Node->getOperand(2); | |||
898 | SDValue Value = Node->getOperand(3); | |||
899 | SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL, | |||
900 | getMSACtrlReg(RegIdx), Value); | |||
901 | ReplaceNode(Node, ChainOut.getNode()); | |||
902 | return true; | |||
903 | } | |||
904 | } | |||
905 | break; | |||
906 | } | |||
907 | ||||
908 | case MipsISD::ThreadPointer: { | |||
909 | EVT PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout()); | |||
910 | unsigned RdhwrOpc, DestReg; | |||
911 | ||||
912 | if (PtrVT == MVT::i32) { | |||
913 | RdhwrOpc = Mips::RDHWR; | |||
914 | DestReg = Mips::V1; | |||
915 | } else { | |||
916 | RdhwrOpc = Mips::RDHWR64; | |||
917 | DestReg = Mips::V1_64; | |||
918 | } | |||
919 | ||||
920 | SDNode *Rdhwr = | |||
921 | CurDAG->getMachineNode(RdhwrOpc, DL, | |||
922 | Node->getValueType(0), | |||
923 | CurDAG->getRegister(Mips::HWR29, MVT::i32)); | |||
924 | SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg, | |||
925 | SDValue(Rdhwr, 0)); | |||
926 | SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT); | |||
927 | ReplaceNode(Node, ResNode.getNode()); | |||
928 | return true; | |||
929 | } | |||
930 | ||||
931 | case ISD::BUILD_VECTOR: { | |||
932 | // Select appropriate ldi.[bhwd] instructions for constant splats of | |||
933 | // 128-bit when MSA is enabled. Fixup any register class mismatches that | |||
934 | // occur as a result. | |||
935 | // | |||
936 | // This allows the compiler to use a wider range of immediates than would | |||
937 | // otherwise be allowed. If, for example, v4i32 could only use ldi.h then | |||
938 | // it would not be possible to load { 0x01010101, 0x01010101, 0x01010101, | |||
939 | // 0x01010101 } without using a constant pool. This would be sub-optimal | |||
940 | // when // 'ldi.b wd, 1' is capable of producing that bit-pattern in the | |||
941 | // same set/ of registers. Similarly, ldi.h isn't capable of producing { | |||
942 | // 0x00000000, 0x00000001, 0x00000000, 0x00000001 } but 'ldi.d wd, 1' can. | |||
943 | ||||
944 | const MipsABIInfo &ABI = | |||
945 | static_cast<const MipsTargetMachine &>(TM).getABI(); | |||
946 | ||||
947 | BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Node); | |||
948 | APInt SplatValue, SplatUndef; | |||
949 | unsigned SplatBitSize; | |||
950 | bool HasAnyUndefs; | |||
951 | unsigned LdiOp; | |||
952 | EVT ResVecTy = BVN->getValueType(0); | |||
953 | EVT ViaVecTy; | |||
954 | ||||
955 | if (!Subtarget->hasMSA() || !BVN->getValueType(0).is128BitVector()) | |||
956 | return false; | |||
957 | ||||
958 | if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, | |||
959 | HasAnyUndefs, 8, | |||
960 | !Subtarget->isLittle())) | |||
961 | return false; | |||
962 | ||||
963 | switch (SplatBitSize) { | |||
964 | default: | |||
965 | return false; | |||
966 | case 8: | |||
967 | LdiOp = Mips::LDI_B; | |||
968 | ViaVecTy = MVT::v16i8; | |||
969 | break; | |||
970 | case 16: | |||
971 | LdiOp = Mips::LDI_H; | |||
972 | ViaVecTy = MVT::v8i16; | |||
973 | break; | |||
974 | case 32: | |||
975 | LdiOp = Mips::LDI_W; | |||
976 | ViaVecTy = MVT::v4i32; | |||
977 | break; | |||
978 | case 64: | |||
979 | LdiOp = Mips::LDI_D; | |||
980 | ViaVecTy = MVT::v2i64; | |||
981 | break; | |||
982 | } | |||
983 | ||||
984 | SDNode *Res; | |||
985 | ||||
986 | // If we have a signed 10 bit integer, we can splat it directly. | |||
987 | // | |||
988 | // If we have something bigger we can synthesize the value into a GPR and | |||
989 | // splat from there. | |||
990 | if (SplatValue.isSignedIntN(10)) { | |||
991 | SDValue Imm = CurDAG->getTargetConstant(SplatValue, DL, | |||
992 | ViaVecTy.getVectorElementType()); | |||
993 | ||||
994 | Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm); | |||
995 | } else if (SplatValue.isSignedIntN(16) && | |||
996 | ((ABI.IsO32() && SplatBitSize < 64) || | |||
997 | (ABI.IsN32() || ABI.IsN64()))) { | |||
998 | // Only handle signed 16 bit values when the element size is GPR width. | |||
999 | // MIPS64 can handle all the cases but MIPS32 would need to handle | |||
1000 | // negative cases specifically here. Instead, handle those cases as | |||
1001 | // 64bit values. | |||
1002 | ||||
1003 | bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64; | |||
1004 | const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu; | |||
1005 | const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64; | |||
1006 | SDValue ZeroVal = CurDAG->getRegister( | |||
1007 | Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT); | |||
1008 | ||||
1009 | const unsigned FILLOp = | |||
1010 | SplatBitSize == 16 | |||
1011 | ? Mips::FILL_H | |||
1012 | : (SplatBitSize == 32 ? Mips::FILL_W | |||
1013 | : (SplatBitSize == 64 ? Mips::FILL_D : 0)); | |||
1014 | ||||
1015 | assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!")((FILLOp != 0 && "Unknown FILL Op for splat synthesis!" ) ? static_cast<void> (0) : __assert_fail ("FILLOp != 0 && \"Unknown FILL Op for splat synthesis!\"" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1015, __PRETTY_FUNCTION__)); | |||
1016 | assert((!ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&(((!ABI.IsO32() || (FILLOp != Mips::FILL_D)) && "Attempting to use fill.d on MIPS32!" ) ? static_cast<void> (0) : __assert_fail ("(!ABI.IsO32() || (FILLOp != Mips::FILL_D)) && \"Attempting to use fill.d on MIPS32!\"" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1017, __PRETTY_FUNCTION__)) | |||
1017 | "Attempting to use fill.d on MIPS32!")(((!ABI.IsO32() || (FILLOp != Mips::FILL_D)) && "Attempting to use fill.d on MIPS32!" ) ? static_cast<void> (0) : __assert_fail ("(!ABI.IsO32() || (FILLOp != Mips::FILL_D)) && \"Attempting to use fill.d on MIPS32!\"" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1017, __PRETTY_FUNCTION__)); | |||
1018 | ||||
1019 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1020 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, SplatMVT); | |||
1021 | ||||
1022 | Res = CurDAG->getMachineNode(ADDiuOp, DL, SplatMVT, ZeroVal, LoVal); | |||
1023 | Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0)); | |||
1024 | ||||
1025 | } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) { | |||
1026 | // Only handle the cases where the splat size agrees with the size | |||
1027 | // of the SplatValue here. | |||
1028 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1029 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1030 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1031 | ||||
1032 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1033 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1034 | ||||
1035 | if (Hi) | |||
1036 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1037 | ||||
1038 | if (Lo) | |||
1039 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1040 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1041 | ||||
1042 | assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!")(((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!" ) ? static_cast<void> (0) : __assert_fail ("(Hi || Lo) && \"Zero case reached 32 bit case splat synthesis!\"" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1042, __PRETTY_FUNCTION__)); | |||
1043 | Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0)); | |||
1044 | ||||
1045 | } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 && | |||
1046 | (ABI.IsN32() || ABI.IsN64())) { | |||
1047 | // N32 and N64 can perform some tricks that O32 can't for signed 32 bit | |||
1048 | // integers due to having 64bit registers. lui will cause the necessary | |||
1049 | // zero/sign extension. | |||
1050 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1051 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1052 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1053 | ||||
1054 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1055 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1056 | ||||
1057 | if (Hi) | |||
1058 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1059 | ||||
1060 | if (Lo) | |||
1061 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1062 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1063 | ||||
1064 | Res = CurDAG->getMachineNode( | |||
1065 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1066 | CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64), | |||
1067 | SDValue(Res, 0), | |||
| ||||
1068 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1069 | ||||
1070 | Res = | |||
1071 | CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0)); | |||
1072 | ||||
1073 | } else if (SplatValue.isSignedIntN(64)) { | |||
1074 | // If we have a 64 bit Splat value, we perform a similar sequence to the | |||
1075 | // above: | |||
1076 | // | |||
1077 | // MIPS32: MIPS64: | |||
1078 | // lui $res, %highest(val) lui $res, %highest(val) | |||
1079 | // ori $res, $res, %higher(val) ori $res, $res, %higher(val) | |||
1080 | // lui $res2, %hi(val) lui $res2, %hi(val) | |||
1081 | // ori $res2, %res2, %lo(val) ori $res2, %res2, %lo(val) | |||
1082 | // $res3 = fill $res2 dinsu $res, $res2, 0, 32 | |||
1083 | // $res4 = insert.w $res3[1], $res fill.d $res | |||
1084 | // splat.d $res4, 0 | |||
1085 | // | |||
1086 | // The ability to use dinsu is guaranteed as MSA requires MIPSR5. This saves | |||
1087 | // having to materialize the value by shifts and ors. | |||
1088 | // | |||
1089 | // FIXME: Implement the preferred sequence for MIPS64R6: | |||
1090 | // | |||
1091 | // MIPS64R6: | |||
1092 | // ori $res, $zero, %lo(val) | |||
1093 | // daui $res, $res, %hi(val) | |||
1094 | // dahi $res, $res, %higher(val) | |||
1095 | // dati $res, $res, %highest(cal) | |||
1096 | // fill.d $res | |||
1097 | // | |||
1098 | ||||
1099 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1100 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1101 | const unsigned Higher = SplatValue.lshr(32).getLoBits(16).getZExtValue(); | |||
1102 | const unsigned Highest = SplatValue.lshr(48).getLoBits(16).getZExtValue(); | |||
1103 | ||||
1104 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1105 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1106 | SDValue HigherVal = CurDAG->getTargetConstant(Higher, DL, MVT::i32); | |||
1107 | SDValue HighestVal = CurDAG->getTargetConstant(Highest, DL, MVT::i32); | |||
1108 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1109 | ||||
1110 | // Independent of whether we're targeting MIPS64 or not, the basic | |||
1111 | // operations are the same. Also, directly use the $zero register if | |||
1112 | // the 16 bit chunk is zero. | |||
1113 | // | |||
1114 | // For optimization purposes we always synthesize the splat value as | |||
1115 | // an i32 value, then if we're targetting MIPS64, use SUBREG_TO_REG | |||
1116 | // just before combining the values with dinsu to produce an i64. This | |||
1117 | // enables SelectionDAG to aggressively share components of splat values | |||
1118 | // where possible. | |||
1119 | // | |||
1120 | // FIXME: This is the general constant synthesis problem. This code | |||
1121 | // should be factored out into a class shared between all the | |||
1122 | // classes that need it. Specifically, for a splat size of 64 | |||
1123 | // bits that's a negative number we can do better than LUi/ORi | |||
1124 | // for the upper 32bits. | |||
1125 | ||||
1126 | if (Hi) | |||
1127 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1128 | ||||
1129 | if (Lo) | |||
1130 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1131 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1132 | ||||
1133 | SDNode *HiRes; | |||
1134 | if (Highest) | |||
1135 | HiRes = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HighestVal); | |||
1136 | ||||
1137 | if (Higher) | |||
1138 | HiRes = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1139 | Highest ? SDValue(HiRes, 0) : ZeroVal, | |||
1140 | HigherVal); | |||
1141 | ||||
1142 | ||||
1143 | if (ABI.IsO32()) { | |||
1144 | Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, | |||
1145 | (Hi || Lo) ? SDValue(Res, 0) : ZeroVal); | |||
1146 | ||||
1147 | Res = CurDAG->getMachineNode( | |||
1148 | Mips::INSERT_W, DL, MVT::v4i32, SDValue(Res, 0), | |||
1149 | (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal, | |||
1150 | CurDAG->getTargetConstant(1, DL, MVT::i32)); | |||
1151 | ||||
1152 | const TargetLowering *TLI = getTargetLowering(); | |||
1153 | const TargetRegisterClass *RC = | |||
1154 | TLI->getRegClassFor(ViaVecTy.getSimpleVT()); | |||
1155 | ||||
1156 | Res = CurDAG->getMachineNode( | |||
1157 | Mips::COPY_TO_REGCLASS, DL, ViaVecTy, SDValue(Res, 0), | |||
1158 | CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32)); | |||
1159 | ||||
1160 | Res = CurDAG->getMachineNode( | |||
1161 | Mips::SPLATI_D, DL, MVT::v2i64, SDValue(Res, 0), | |||
1162 | CurDAG->getTargetConstant(0, DL, MVT::i32)); | |||
1163 | } else if (ABI.IsN64() || ABI.IsN32()) { | |||
1164 | ||||
1165 | SDValue Zero64Val = CurDAG->getRegister(Mips::ZERO_64, MVT::i64); | |||
1166 | const bool HiResNonZero = Highest || Higher; | |||
1167 | const bool ResNonZero = Hi || Lo; | |||
1168 | ||||
1169 | if (HiResNonZero) | |||
1170 | HiRes = CurDAG->getMachineNode( | |||
1171 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1172 | CurDAG->getTargetConstant(((Highest >> 15) & 0x1), DL, MVT::i64), | |||
1173 | SDValue(HiRes, 0), | |||
1174 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1175 | ||||
1176 | if (ResNonZero) | |||
1177 | Res = CurDAG->getMachineNode( | |||
1178 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1179 | CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64), | |||
1180 | SDValue(Res, 0), | |||
1181 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1182 | ||||
1183 | // We have 3 cases: | |||
1184 | // The HiRes is nonzero but Res is $zero => dsll32 HiRes, 0 | |||
1185 | // The Res is nonzero but HiRes is $zero => dinsu Res, $zero, 32, 32 | |||
1186 | // Both are non zero => dinsu Res, HiRes, 32, 32 | |||
1187 | // | |||
1188 | // The obvious "missing" case is when both are zero, but that case is | |||
1189 | // handled by the ldi case. | |||
1190 | if (ResNonZero) { | |||
1191 | IntegerType *Int32Ty = | |||
1192 | IntegerType::get(MF->getFunction()->getContext(), 32); | |||
1193 | const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32); | |||
1194 | SDValue Ops[4] = {HiResNonZero ? SDValue(HiRes, 0) : Zero64Val, | |||
1195 | CurDAG->getConstant(*Const32, DL, MVT::i32), | |||
1196 | CurDAG->getConstant(*Const32, DL, MVT::i32), | |||
1197 | SDValue(Res, 0)}; | |||
1198 | ||||
1199 | Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops); | |||
1200 | } else if (HiResNonZero) { | |||
1201 | Res = CurDAG->getMachineNode( | |||
1202 | Mips::DSLL32, DL, MVT::i64, SDValue(HiRes, 0), | |||
1203 | CurDAG->getTargetConstant(0, DL, MVT::i32)); | |||
1204 | } else | |||
1205 | llvm_unreachable(::llvm::llvm_unreachable_internal("Zero splat value handled by non-zero 64bit splat synthesis!" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1206) | |||
1206 | "Zero splat value handled by non-zero 64bit splat synthesis!")::llvm::llvm_unreachable_internal("Zero splat value handled by non-zero 64bit splat synthesis!" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1206); | |||
1207 | ||||
1208 | Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0)); | |||
1209 | } else | |||
1210 | llvm_unreachable("Unknown ABI in MipsISelDAGToDAG!")::llvm::llvm_unreachable_internal("Unknown ABI in MipsISelDAGToDAG!" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1210); | |||
1211 | ||||
1212 | } else | |||
1213 | return false; | |||
1214 | ||||
1215 | if (ResVecTy != ViaVecTy) { | |||
1216 | // If LdiOp is writing to a different register class to ResVecTy, then | |||
1217 | // fix it up here. This COPY_TO_REGCLASS should never cause a move.v | |||
1218 | // since the source and destination register sets contain the same | |||
1219 | // registers. | |||
1220 | const TargetLowering *TLI = getTargetLowering(); | |||
1221 | MVT ResVecTySimple = ResVecTy.getSimpleVT(); | |||
1222 | const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple); | |||
1223 | Res = CurDAG->getMachineNode(Mips::COPY_TO_REGCLASS, DL, | |||
1224 | ResVecTy, SDValue(Res, 0), | |||
1225 | CurDAG->getTargetConstant(RC->getID(), DL, | |||
1226 | MVT::i32)); | |||
1227 | } | |||
1228 | ||||
1229 | ReplaceNode(Node, Res); | |||
1230 | return true; | |||
1231 | } | |||
1232 | ||||
1233 | } | |||
1234 | ||||
1235 | return false; | |||
1236 | } | |||
1237 | ||||
1238 | bool MipsSEDAGToDAGISel:: | |||
1239 | SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, | |||
1240 | std::vector<SDValue> &OutOps) { | |||
1241 | SDValue Base, Offset; | |||
1242 | ||||
1243 | switch(ConstraintID) { | |||
1244 | default: | |||
1245 | llvm_unreachable("Unexpected asm memory constraint")::llvm::llvm_unreachable_internal("Unexpected asm memory constraint" , "/build/llvm-toolchain-snapshot-6.0~svn317267/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1245); | |||
1246 | // All memory constraints can at least accept raw pointers. | |||
1247 | case InlineAsm::Constraint_i: | |||
1248 | OutOps.push_back(Op); | |||
1249 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1250 | return false; | |||
1251 | case InlineAsm::Constraint_m: | |||
1252 | if (selectAddrRegImm16(Op, Base, Offset)) { | |||
1253 | OutOps.push_back(Base); | |||
1254 | OutOps.push_back(Offset); | |||
1255 | return false; | |||
1256 | } | |||
1257 | OutOps.push_back(Op); | |||
1258 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1259 | return false; | |||
1260 | case InlineAsm::Constraint_R: | |||
1261 | // The 'R' constraint is supposed to be much more complicated than this. | |||
1262 | // However, it's becoming less useful due to architectural changes and | |||
1263 | // ought to be replaced by other constraints such as 'ZC'. | |||
1264 | // For now, support 9-bit signed offsets which is supportable by all | |||
1265 | // subtargets for all instructions. | |||
1266 | if (selectAddrRegImm9(Op, Base, Offset)) { | |||
1267 | OutOps.push_back(Base); | |||
1268 | OutOps.push_back(Offset); | |||
1269 | return false; | |||
1270 | } | |||
1271 | OutOps.push_back(Op); | |||
1272 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1273 | return false; | |||
1274 | case InlineAsm::Constraint_ZC: | |||
1275 | // ZC matches whatever the pref, ll, and sc instructions can handle for the | |||
1276 | // given subtarget. | |||
1277 | if (Subtarget->inMicroMipsMode()) { | |||
1278 | // On microMIPS, they can handle 12-bit offsets. | |||
1279 | if (selectAddrRegImm12(Op, Base, Offset)) { | |||
1280 | OutOps.push_back(Base); | |||
1281 | OutOps.push_back(Offset); | |||
1282 | return false; | |||
1283 | } | |||
1284 | } else if (Subtarget->hasMips32r6()) { | |||
1285 | // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets. | |||
1286 | if (selectAddrRegImm9(Op, Base, Offset)) { | |||
1287 | OutOps.push_back(Base); | |||
1288 | OutOps.push_back(Offset); | |||
1289 | return false; | |||
1290 | } | |||
1291 | } else if (selectAddrRegImm16(Op, Base, Offset)) { | |||
1292 | // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets. | |||
1293 | OutOps.push_back(Base); | |||
1294 | OutOps.push_back(Offset); | |||
1295 | return false; | |||
1296 | } | |||
1297 | // In all cases, 0-bit offsets are acceptable. | |||
1298 | OutOps.push_back(Op); | |||
1299 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1300 | return false; | |||
1301 | } | |||
1302 | return true; | |||
1303 | } | |||
1304 | ||||
1305 | FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM, | |||
1306 | CodeGenOpt::Level OptLevel) { | |||
1307 | return new MipsSEDAGToDAGISel(TM, OptLevel); | |||
1308 | } |