File: | lib/Target/Mips/MipsSEISelDAGToDAG.cpp |
Warning: | line 1137, column 15 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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-8~svn350071/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-8~svn350071/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 | case Mips::BuildPairF64_64: | |||
242 | case Mips::ExtractElementF64_64: | |||
243 | if (!Subtarget->useOddSPReg()) { | |||
244 | MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true)); | |||
245 | break; | |||
246 | } | |||
247 | LLVM_FALLTHROUGH[[clang::fallthrough]]; | |||
248 | case Mips::BuildPairF64: | |||
249 | case Mips::ExtractElementF64: | |||
250 | if (Subtarget->isABI_FPXX() && !Subtarget->hasMTHC1()) | |||
251 | MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true)); | |||
252 | break; | |||
253 | default: | |||
254 | replaceUsesWithZeroReg(MRI, MI); | |||
255 | } | |||
256 | } | |||
257 | } | |||
258 | } | |||
259 | ||||
260 | void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const { | |||
261 | SDValue InFlag = Node->getOperand(2); | |||
262 | unsigned Opc = InFlag.getOpcode(); | |||
263 | SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); | |||
264 | EVT VT = LHS.getValueType(); | |||
265 | ||||
266 | // In the base case, we can rely on the carry bit from the addsc | |||
267 | // instruction. | |||
268 | if (Opc == ISD::ADDC) { | |||
269 | SDValue Ops[3] = {LHS, RHS, InFlag}; | |||
270 | CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Ops); | |||
271 | return; | |||
272 | } | |||
273 | ||||
274 | 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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 274, __PRETTY_FUNCTION__)); | |||
275 | ||||
276 | // The more complex case is when there is a chain of ISD::ADDE nodes like: | |||
277 | // (adde (adde (adde (addc a b) c) d) e). | |||
278 | // | |||
279 | // The addwc instruction does not write to the carry bit, instead it writes | |||
280 | // to bit 20 of the dsp control register. To match this series of nodes, each | |||
281 | // intermediate adde node must be expanded to write the carry bit before the | |||
282 | // addition. | |||
283 | ||||
284 | // Start by reading the overflow field for addsc and moving the value to the | |||
285 | // carry field. The usage of 1 here with MipsISD::RDDSP / Mips::WRDSP | |||
286 | // corresponds to reading/writing the entire control register to/from a GPR. | |||
287 | ||||
288 | SDValue CstOne = CurDAG->getTargetConstant(1, DL, MVT::i32); | |||
289 | ||||
290 | SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32); | |||
291 | ||||
292 | SDNode *DSPCtrlField = | |||
293 | CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32, MVT::Glue, CstOne, InFlag); | |||
294 | ||||
295 | SDNode *Carry = CurDAG->getMachineNode( | |||
296 | Mips::EXT, DL, MVT::i32, SDValue(DSPCtrlField, 0), OuFlag, CstOne); | |||
297 | ||||
298 | SDValue Ops[4] = {SDValue(DSPCtrlField, 0), | |||
299 | CurDAG->getTargetConstant(6, DL, MVT::i32), CstOne, | |||
300 | SDValue(Carry, 0)}; | |||
301 | SDNode *DSPCFWithCarry = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, Ops); | |||
302 | ||||
303 | // My reading of the MIPS DSP 3.01 specification isn't as clear as I | |||
304 | // would like about whether bit 20 always gets overwritten by addwc. | |||
305 | // Hence take an extremely conservative view and presume it's sticky. We | |||
306 | // therefore need to clear it. | |||
307 | ||||
308 | SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
309 | ||||
310 | SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)}; | |||
311 | SDNode *DSPCtrlFinal = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps); | |||
312 | ||||
313 | SDNode *WrDSP = CurDAG->getMachineNode(Mips::WRDSP, DL, MVT::Glue, | |||
314 | SDValue(DSPCtrlFinal, 0), CstOne); | |||
315 | ||||
316 | SDValue Operands[3] = {LHS, RHS, SDValue(WrDSP, 0)}; | |||
317 | CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Operands); | |||
318 | } | |||
319 | ||||
320 | /// Match frameindex | |||
321 | bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base, | |||
322 | SDValue &Offset) const { | |||
323 | if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { | |||
324 | EVT ValTy = Addr.getValueType(); | |||
325 | ||||
326 | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); | |||
327 | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy); | |||
328 | return true; | |||
329 | } | |||
330 | return false; | |||
331 | } | |||
332 | ||||
333 | /// Match frameindex+offset and frameindex|offset | |||
334 | bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset( | |||
335 | SDValue Addr, SDValue &Base, SDValue &Offset, unsigned OffsetBits, | |||
336 | unsigned ShiftAmount = 0) const { | |||
337 | if (CurDAG->isBaseWithConstantOffset(Addr)) { | |||
338 | ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); | |||
339 | if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) { | |||
340 | EVT ValTy = Addr.getValueType(); | |||
341 | ||||
342 | // If the first operand is a FI, get the TargetFI Node | |||
343 | if (FrameIndexSDNode *FIN = | |||
344 | dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) | |||
345 | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); | |||
346 | else { | |||
347 | Base = Addr.getOperand(0); | |||
348 | // If base is a FI, additional offset calculation is done in | |||
349 | // eliminateFrameIndex, otherwise we need to check the alignment | |||
350 | if (OffsetToAlignment(CN->getZExtValue(), 1ull << ShiftAmount) != 0) | |||
351 | return false; | |||
352 | } | |||
353 | ||||
354 | Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), | |||
355 | ValTy); | |||
356 | return true; | |||
357 | } | |||
358 | } | |||
359 | return false; | |||
360 | } | |||
361 | ||||
362 | /// ComplexPattern used on MipsInstrInfo | |||
363 | /// Used on Mips Load/Store instructions | |||
364 | bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, | |||
365 | SDValue &Offset) const { | |||
366 | // if Address is FI, get the TargetFrameIndex. | |||
367 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
368 | return true; | |||
369 | ||||
370 | // on PIC code Load GA | |||
371 | if (Addr.getOpcode() == MipsISD::Wrapper) { | |||
372 | Base = Addr.getOperand(0); | |||
373 | Offset = Addr.getOperand(1); | |||
374 | return true; | |||
375 | } | |||
376 | ||||
377 | if (!TM.isPositionIndependent()) { | |||
378 | if ((Addr.getOpcode() == ISD::TargetExternalSymbol || | |||
379 | Addr.getOpcode() == ISD::TargetGlobalAddress)) | |||
380 | return false; | |||
381 | } | |||
382 | ||||
383 | // Addresses of the form FI+const or FI|const | |||
384 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) | |||
385 | return true; | |||
386 | ||||
387 | // Operand is a result from an ADD. | |||
388 | if (Addr.getOpcode() == ISD::ADD) { | |||
389 | // When loading from constant pools, load the lower address part in | |||
390 | // the instruction itself. Example, instead of: | |||
391 | // lui $2, %hi($CPI1_0) | |||
392 | // addiu $2, $2, %lo($CPI1_0) | |||
393 | // lwc1 $f0, 0($2) | |||
394 | // Generate: | |||
395 | // lui $2, %hi($CPI1_0) | |||
396 | // lwc1 $f0, %lo($CPI1_0)($2) | |||
397 | if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || | |||
398 | Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { | |||
399 | SDValue Opnd0 = Addr.getOperand(1).getOperand(0); | |||
400 | if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || | |||
401 | isa<JumpTableSDNode>(Opnd0)) { | |||
402 | Base = Addr.getOperand(0); | |||
403 | Offset = Opnd0; | |||
404 | return true; | |||
405 | } | |||
406 | } | |||
407 | } | |||
408 | ||||
409 | return false; | |||
410 | } | |||
411 | ||||
412 | /// ComplexPattern used on MipsInstrInfo | |||
413 | /// Used on Mips Load/Store instructions | |||
414 | bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, | |||
415 | SDValue &Offset) const { | |||
416 | Base = Addr; | |||
417 | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType()); | |||
418 | return true; | |||
419 | } | |||
420 | ||||
421 | bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, | |||
422 | SDValue &Offset) const { | |||
423 | return selectAddrRegImm(Addr, Base, Offset) || | |||
424 | selectAddrDefault(Addr, Base, Offset); | |||
425 | } | |||
426 | ||||
427 | bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base, | |||
428 | SDValue &Offset) const { | |||
429 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
430 | return true; | |||
431 | ||||
432 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9)) | |||
433 | return true; | |||
434 | ||||
435 | return false; | |||
436 | } | |||
437 | ||||
438 | /// Used on microMIPS LWC2, LDC2, SWC2 and SDC2 instructions (11-bit offset) | |||
439 | bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base, | |||
440 | SDValue &Offset) const { | |||
441 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
442 | return true; | |||
443 | ||||
444 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11)) | |||
445 | return true; | |||
446 | ||||
447 | return false; | |||
448 | } | |||
449 | ||||
450 | /// Used on microMIPS Load/Store unaligned instructions (12-bit offset) | |||
451 | bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, | |||
452 | SDValue &Offset) const { | |||
453 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
454 | return true; | |||
455 | ||||
456 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12)) | |||
457 | return true; | |||
458 | ||||
459 | return false; | |||
460 | } | |||
461 | ||||
462 | bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base, | |||
463 | SDValue &Offset) const { | |||
464 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
465 | return true; | |||
466 | ||||
467 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) | |||
468 | return true; | |||
469 | ||||
470 | return false; | |||
471 | } | |||
472 | ||||
473 | bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base, | |||
474 | SDValue &Offset) const { | |||
475 | return selectAddrRegImm11(Addr, Base, Offset) || | |||
476 | selectAddrDefault(Addr, Base, Offset); | |||
477 | } | |||
478 | ||||
479 | bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base, | |||
480 | SDValue &Offset) const { | |||
481 | return selectAddrRegImm12(Addr, Base, Offset) || | |||
482 | selectAddrDefault(Addr, Base, Offset); | |||
483 | } | |||
484 | ||||
485 | bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base, | |||
486 | SDValue &Offset) const { | |||
487 | return selectAddrRegImm16(Addr, Base, Offset) || | |||
488 | selectAddrDefault(Addr, Base, Offset); | |||
489 | } | |||
490 | ||||
491 | bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base, | |||
492 | SDValue &Offset) const { | |||
493 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) { | |||
494 | if (isa<FrameIndexSDNode>(Base)) | |||
495 | return false; | |||
496 | ||||
497 | if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Offset)) { | |||
498 | unsigned CnstOff = CN->getZExtValue(); | |||
499 | return (CnstOff == (CnstOff & 0x3c)); | |||
500 | } | |||
501 | ||||
502 | return false; | |||
503 | } | |||
504 | ||||
505 | // For all other cases where "lw" would be selected, don't select "lw16" | |||
506 | // because it would result in additional instructions to prepare operands. | |||
507 | if (selectAddrRegImm(Addr, Base, Offset)) | |||
508 | return false; | |||
509 | ||||
510 | return selectAddrDefault(Addr, Base, Offset); | |||
511 | } | |||
512 | ||||
513 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base, | |||
514 | SDValue &Offset) const { | |||
515 | ||||
516 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
517 | return true; | |||
518 | ||||
519 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10)) | |||
520 | return true; | |||
521 | ||||
522 | return selectAddrDefault(Addr, Base, Offset); | |||
523 | } | |||
524 | ||||
525 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base, | |||
526 | SDValue &Offset) const { | |||
527 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
528 | return true; | |||
529 | ||||
530 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1)) | |||
531 | return true; | |||
532 | ||||
533 | return selectAddrDefault(Addr, Base, Offset); | |||
534 | } | |||
535 | ||||
536 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base, | |||
537 | SDValue &Offset) const { | |||
538 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
539 | return true; | |||
540 | ||||
541 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2)) | |||
542 | return true; | |||
543 | ||||
544 | return selectAddrDefault(Addr, Base, Offset); | |||
545 | } | |||
546 | ||||
547 | bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base, | |||
548 | SDValue &Offset) const { | |||
549 | if (selectAddrFrameIndex(Addr, Base, Offset)) | |||
550 | return true; | |||
551 | ||||
552 | if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3)) | |||
553 | return true; | |||
554 | ||||
555 | return selectAddrDefault(Addr, Base, Offset); | |||
556 | } | |||
557 | ||||
558 | // Select constant vector splats. | |||
559 | // | |||
560 | // Returns true and sets Imm if: | |||
561 | // * MSA is enabled | |||
562 | // * N is a ISD::BUILD_VECTOR representing a constant splat | |||
563 | bool MipsSEDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm, | |||
564 | unsigned MinSizeInBits) const { | |||
565 | if (!Subtarget->hasMSA()) | |||
566 | return false; | |||
567 | ||||
568 | BuildVectorSDNode *Node = dyn_cast<BuildVectorSDNode>(N); | |||
569 | ||||
570 | if (!Node) | |||
571 | return false; | |||
572 | ||||
573 | APInt SplatValue, SplatUndef; | |||
574 | unsigned SplatBitSize; | |||
575 | bool HasAnyUndefs; | |||
576 | ||||
577 | if (!Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, | |||
578 | MinSizeInBits, !Subtarget->isLittle())) | |||
579 | return false; | |||
580 | ||||
581 | Imm = SplatValue; | |||
582 | ||||
583 | return true; | |||
584 | } | |||
585 | ||||
586 | // Select constant vector splats. | |||
587 | // | |||
588 | // In addition to the requirements of selectVSplat(), this function returns | |||
589 | // true and sets Imm if: | |||
590 | // * The splat value is the same width as the elements of the vector | |||
591 | // * The splat value fits in an integer with the specified signed-ness and | |||
592 | // width. | |||
593 | // | |||
594 | // This function looks through ISD::BITCAST nodes. | |||
595 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
596 | // sometimes a shuffle in big-endian mode. | |||
597 | // | |||
598 | // It's worth noting that this function is not used as part of the selection | |||
599 | // of ldi.[bhwd] since it does not permit using the wrong-typed ldi.[bhwd] | |||
600 | // instruction to achieve the desired bit pattern. ldi.[bhwd] is selected in | |||
601 | // MipsSEDAGToDAGISel::selectNode. | |||
602 | bool MipsSEDAGToDAGISel:: | |||
603 | selectVSplatCommon(SDValue N, SDValue &Imm, bool Signed, | |||
604 | unsigned ImmBitSize) const { | |||
605 | APInt ImmValue; | |||
606 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
607 | ||||
608 | if (N->getOpcode() == ISD::BITCAST) | |||
609 | N = N->getOperand(0); | |||
610 | ||||
611 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
612 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
613 | ||||
614 | if (( Signed && ImmValue.isSignedIntN(ImmBitSize)) || | |||
615 | (!Signed && ImmValue.isIntN(ImmBitSize))) { | |||
616 | Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy); | |||
617 | return true; | |||
618 | } | |||
619 | } | |||
620 | ||||
621 | return false; | |||
622 | } | |||
623 | ||||
624 | // Select constant vector splats. | |||
625 | bool MipsSEDAGToDAGISel:: | |||
626 | selectVSplatUimm1(SDValue N, SDValue &Imm) const { | |||
627 | return selectVSplatCommon(N, Imm, false, 1); | |||
628 | } | |||
629 | ||||
630 | bool MipsSEDAGToDAGISel:: | |||
631 | selectVSplatUimm2(SDValue N, SDValue &Imm) const { | |||
632 | return selectVSplatCommon(N, Imm, false, 2); | |||
633 | } | |||
634 | ||||
635 | bool MipsSEDAGToDAGISel:: | |||
636 | selectVSplatUimm3(SDValue N, SDValue &Imm) const { | |||
637 | return selectVSplatCommon(N, Imm, false, 3); | |||
638 | } | |||
639 | ||||
640 | // Select constant vector splats. | |||
641 | bool MipsSEDAGToDAGISel:: | |||
642 | selectVSplatUimm4(SDValue N, SDValue &Imm) const { | |||
643 | return selectVSplatCommon(N, Imm, false, 4); | |||
644 | } | |||
645 | ||||
646 | // Select constant vector splats. | |||
647 | bool MipsSEDAGToDAGISel:: | |||
648 | selectVSplatUimm5(SDValue N, SDValue &Imm) const { | |||
649 | return selectVSplatCommon(N, Imm, false, 5); | |||
650 | } | |||
651 | ||||
652 | // Select constant vector splats. | |||
653 | bool MipsSEDAGToDAGISel:: | |||
654 | selectVSplatUimm6(SDValue N, SDValue &Imm) const { | |||
655 | return selectVSplatCommon(N, Imm, false, 6); | |||
656 | } | |||
657 | ||||
658 | // Select constant vector splats. | |||
659 | bool MipsSEDAGToDAGISel:: | |||
660 | selectVSplatUimm8(SDValue N, SDValue &Imm) const { | |||
661 | return selectVSplatCommon(N, Imm, false, 8); | |||
662 | } | |||
663 | ||||
664 | // Select constant vector splats. | |||
665 | bool MipsSEDAGToDAGISel:: | |||
666 | selectVSplatSimm5(SDValue N, SDValue &Imm) const { | |||
667 | return selectVSplatCommon(N, Imm, true, 5); | |||
668 | } | |||
669 | ||||
670 | // Select constant vector splats whose value is a power of 2. | |||
671 | // | |||
672 | // In addition to the requirements of selectVSplat(), this function returns | |||
673 | // true and sets Imm if: | |||
674 | // * The splat value is the same width as the elements of the vector | |||
675 | // * The splat value is a power of two. | |||
676 | // | |||
677 | // This function looks through ISD::BITCAST nodes. | |||
678 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
679 | // sometimes a shuffle in big-endian mode. | |||
680 | bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const { | |||
681 | APInt ImmValue; | |||
682 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
683 | ||||
684 | if (N->getOpcode() == ISD::BITCAST) | |||
685 | N = N->getOperand(0); | |||
686 | ||||
687 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
688 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
689 | int32_t Log2 = ImmValue.exactLogBase2(); | |||
690 | ||||
691 | if (Log2 != -1) { | |||
692 | Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); | |||
693 | return true; | |||
694 | } | |||
695 | } | |||
696 | ||||
697 | return false; | |||
698 | } | |||
699 | ||||
700 | // Select constant vector splats whose value only has a consecutive sequence | |||
701 | // of left-most bits set (e.g. 0b11...1100...00). | |||
702 | // | |||
703 | // In addition to the requirements of selectVSplat(), this function returns | |||
704 | // true and sets Imm if: | |||
705 | // * The splat value is the same width as the elements of the vector | |||
706 | // * The splat value is a consecutive sequence of left-most bits. | |||
707 | // | |||
708 | // This function looks through ISD::BITCAST nodes. | |||
709 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
710 | // sometimes a shuffle in big-endian mode. | |||
711 | bool MipsSEDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const { | |||
712 | APInt ImmValue; | |||
713 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
714 | ||||
715 | if (N->getOpcode() == ISD::BITCAST) | |||
716 | N = N->getOperand(0); | |||
717 | ||||
718 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
719 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
720 | // Extract the run of set bits starting with bit zero from the bitwise | |||
721 | // inverse of ImmValue, and test that the inverse of this is the same | |||
722 | // as the original value. | |||
723 | if (ImmValue == ~(~ImmValue & ~(~ImmValue + 1))) { | |||
724 | ||||
725 | Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N), | |||
726 | EltTy); | |||
727 | return true; | |||
728 | } | |||
729 | } | |||
730 | ||||
731 | return false; | |||
732 | } | |||
733 | ||||
734 | // Select constant vector splats whose value only has a consecutive sequence | |||
735 | // of right-most bits set (e.g. 0b00...0011...11). | |||
736 | // | |||
737 | // In addition to the requirements of selectVSplat(), this function returns | |||
738 | // true and sets Imm if: | |||
739 | // * The splat value is the same width as the elements of the vector | |||
740 | // * The splat value is a consecutive sequence of right-most bits. | |||
741 | // | |||
742 | // This function looks through ISD::BITCAST nodes. | |||
743 | // TODO: This might not be appropriate for big-endian MSA since BITCAST is | |||
744 | // sometimes a shuffle in big-endian mode. | |||
745 | bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const { | |||
746 | APInt ImmValue; | |||
747 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
748 | ||||
749 | if (N->getOpcode() == ISD::BITCAST) | |||
750 | N = N->getOperand(0); | |||
751 | ||||
752 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
753 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
754 | // Extract the run of set bits starting with bit zero, and test that the | |||
755 | // result is the same as the original value | |||
756 | if (ImmValue == (ImmValue & ~(ImmValue + 1))) { | |||
757 | Imm = CurDAG->getTargetConstant(ImmValue.countPopulation() - 1, SDLoc(N), | |||
758 | EltTy); | |||
759 | return true; | |||
760 | } | |||
761 | } | |||
762 | ||||
763 | return false; | |||
764 | } | |||
765 | ||||
766 | bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, | |||
767 | SDValue &Imm) const { | |||
768 | APInt ImmValue; | |||
769 | EVT EltTy = N->getValueType(0).getVectorElementType(); | |||
770 | ||||
771 | if (N->getOpcode() == ISD::BITCAST) | |||
772 | N = N->getOperand(0); | |||
773 | ||||
774 | if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) && | |||
775 | ImmValue.getBitWidth() == EltTy.getSizeInBits()) { | |||
776 | int32_t Log2 = (~ImmValue).exactLogBase2(); | |||
777 | ||||
778 | if (Log2 != -1) { | |||
779 | Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy); | |||
780 | return true; | |||
781 | } | |||
782 | } | |||
783 | ||||
784 | return false; | |||
785 | } | |||
786 | ||||
787 | bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) { | |||
788 | unsigned Opcode = Node->getOpcode(); | |||
789 | SDLoc DL(Node); | |||
790 | ||||
791 | /// | |||
792 | // Instruction Selection not handled by the auto-generated | |||
793 | // tablegen selection should be handled here. | |||
794 | /// | |||
795 | switch(Opcode) { | |||
| ||||
796 | default: break; | |||
797 | ||||
798 | case ISD::ADDE: { | |||
799 | selectAddE(Node, DL); | |||
800 | return true; | |||
801 | } | |||
802 | ||||
803 | case ISD::ConstantFP: { | |||
804 | ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); | |||
805 | if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { | |||
806 | if (Subtarget->isGP64bit()) { | |||
807 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
808 | Mips::ZERO_64, MVT::i64); | |||
809 | ReplaceNode(Node, | |||
810 | CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero)); | |||
811 | } else if (Subtarget->isFP64bit()) { | |||
812 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
813 | Mips::ZERO, MVT::i32); | |||
814 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64_64, DL, | |||
815 | MVT::f64, Zero, Zero)); | |||
816 | } else { | |||
817 | SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | |||
818 | Mips::ZERO, MVT::i32); | |||
819 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::BuildPairF64, DL, | |||
820 | MVT::f64, Zero, Zero)); | |||
821 | } | |||
822 | return true; | |||
823 | } | |||
824 | break; | |||
825 | } | |||
826 | ||||
827 | case ISD::Constant: { | |||
828 | const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); | |||
829 | int64_t Imm = CN->getSExtValue(); | |||
830 | unsigned Size = CN->getValueSizeInBits(0); | |||
831 | ||||
832 | if (isInt<32>(Imm)) | |||
833 | break; | |||
834 | ||||
835 | MipsAnalyzeImmediate AnalyzeImm; | |||
836 | ||||
837 | const MipsAnalyzeImmediate::InstSeq &Seq = | |||
838 | AnalyzeImm.Analyze(Imm, Size, false); | |||
839 | ||||
840 | MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); | |||
841 | SDLoc DL(CN); | |||
842 | SDNode *RegOpnd; | |||
843 | SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), | |||
844 | DL, MVT::i64); | |||
845 | ||||
846 | // The first instruction can be a LUi which is different from other | |||
847 | // instructions (ADDiu, ORI and SLL) in that it does not have a register | |||
848 | // operand. | |||
849 | if (Inst->Opc == Mips::LUi64) | |||
850 | RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd); | |||
851 | else | |||
852 | RegOpnd = | |||
853 | CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, | |||
854 | CurDAG->getRegister(Mips::ZERO_64, MVT::i64), | |||
855 | ImmOpnd); | |||
856 | ||||
857 | // The remaining instructions in the sequence are handled here. | |||
858 | for (++Inst; Inst != Seq.end(); ++Inst) { | |||
859 | ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), DL, | |||
860 | MVT::i64); | |||
861 | RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, | |||
862 | SDValue(RegOpnd, 0), ImmOpnd); | |||
863 | } | |||
864 | ||||
865 | ReplaceNode(Node, RegOpnd); | |||
866 | return true; | |||
867 | } | |||
868 | ||||
869 | case ISD::INTRINSIC_W_CHAIN: { | |||
870 | switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { | |||
871 | default: | |||
872 | break; | |||
873 | ||||
874 | case Intrinsic::mips_cfcmsa: { | |||
875 | SDValue ChainIn = Node->getOperand(0); | |||
876 | SDValue RegIdx = Node->getOperand(2); | |||
877 | SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL, | |||
878 | getMSACtrlReg(RegIdx), MVT::i32); | |||
879 | ReplaceNode(Node, Reg.getNode()); | |||
880 | return true; | |||
881 | } | |||
882 | } | |||
883 | break; | |||
884 | } | |||
885 | ||||
886 | case ISD::INTRINSIC_WO_CHAIN: { | |||
887 | switch (cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue()) { | |||
888 | default: | |||
889 | break; | |||
890 | ||||
891 | case Intrinsic::mips_move_v: | |||
892 | // Like an assignment but will always produce a move.v even if | |||
893 | // unnecessary. | |||
894 | ReplaceNode(Node, CurDAG->getMachineNode(Mips::MOVE_V, DL, | |||
895 | Node->getValueType(0), | |||
896 | Node->getOperand(1))); | |||
897 | return true; | |||
898 | } | |||
899 | break; | |||
900 | } | |||
901 | ||||
902 | case ISD::INTRINSIC_VOID: { | |||
903 | switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { | |||
904 | default: | |||
905 | break; | |||
906 | ||||
907 | case Intrinsic::mips_ctcmsa: { | |||
908 | SDValue ChainIn = Node->getOperand(0); | |||
909 | SDValue RegIdx = Node->getOperand(2); | |||
910 | SDValue Value = Node->getOperand(3); | |||
911 | SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL, | |||
912 | getMSACtrlReg(RegIdx), Value); | |||
913 | ReplaceNode(Node, ChainOut.getNode()); | |||
914 | return true; | |||
915 | } | |||
916 | } | |||
917 | break; | |||
918 | } | |||
919 | ||||
920 | // Manually match MipsISD::Ins nodes to get the correct instruction. It has | |||
921 | // to be done in this fashion so that we respect the differences between | |||
922 | // dins and dinsm, as the difference is that the size operand has the range | |||
923 | // 0 < size <= 32 for dins while dinsm has the range 2 <= size <= 64 which | |||
924 | // means SelectionDAGISel would have to test all the operands at once to | |||
925 | // match the instruction. | |||
926 | case MipsISD::Ins: { | |||
927 | ||||
928 | // Sanity checking for the node operands. | |||
929 | if (Node->getValueType(0) != MVT::i32 && Node->getValueType(0) != MVT::i64) | |||
930 | return false; | |||
931 | ||||
932 | if (Node->getNumOperands() != 4) | |||
933 | return false; | |||
934 | ||||
935 | if (Node->getOperand(1)->getOpcode() != ISD::Constant || | |||
936 | Node->getOperand(2)->getOpcode() != ISD::Constant) | |||
937 | return false; | |||
938 | ||||
939 | MVT ResTy = Node->getSimpleValueType(0); | |||
940 | uint64_t Pos = Node->getConstantOperandVal(1); | |||
941 | uint64_t Size = Node->getConstantOperandVal(2); | |||
942 | ||||
943 | // Size has to be >0 for 'ins', 'dins' and 'dinsu'. | |||
944 | if (!Size) | |||
945 | return false; | |||
946 | ||||
947 | if (Pos + Size > 64) | |||
948 | return false; | |||
949 | ||||
950 | if (ResTy != MVT::i32 && ResTy != MVT::i64) | |||
951 | return false; | |||
952 | ||||
953 | unsigned Opcode = 0; | |||
954 | if (ResTy == MVT::i32) { | |||
955 | if (Pos + Size <= 32) | |||
956 | Opcode = Mips::INS; | |||
957 | } else { | |||
958 | if (Pos + Size <= 32) | |||
959 | Opcode = Mips::DINS; | |||
960 | else if (Pos < 32 && 1 < Size) | |||
961 | Opcode = Mips::DINSM; | |||
962 | else | |||
963 | Opcode = Mips::DINSU; | |||
964 | } | |||
965 | ||||
966 | if (Opcode) { | |||
967 | SDValue Ops[4] = { | |||
968 | Node->getOperand(0), CurDAG->getTargetConstant(Pos, DL, MVT::i32), | |||
969 | CurDAG->getTargetConstant(Size, DL, MVT::i32), Node->getOperand(3)}; | |||
970 | ||||
971 | ReplaceNode(Node, CurDAG->getMachineNode(Opcode, DL, ResTy, Ops)); | |||
972 | return true; | |||
973 | } | |||
974 | ||||
975 | return false; | |||
976 | } | |||
977 | ||||
978 | case MipsISD::ThreadPointer: { | |||
979 | EVT PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout()); | |||
980 | unsigned RdhwrOpc, DestReg; | |||
981 | ||||
982 | if (PtrVT == MVT::i32) { | |||
983 | RdhwrOpc = Mips::RDHWR; | |||
984 | DestReg = Mips::V1; | |||
985 | } else { | |||
986 | RdhwrOpc = Mips::RDHWR64; | |||
987 | DestReg = Mips::V1_64; | |||
988 | } | |||
989 | ||||
990 | SDNode *Rdhwr = | |||
991 | CurDAG->getMachineNode(RdhwrOpc, DL, Node->getValueType(0), | |||
992 | CurDAG->getRegister(Mips::HWR29, MVT::i32), | |||
993 | CurDAG->getTargetConstant(0, DL, MVT::i32)); | |||
994 | SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg, | |||
995 | SDValue(Rdhwr, 0)); | |||
996 | SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT); | |||
997 | ReplaceNode(Node, ResNode.getNode()); | |||
998 | return true; | |||
999 | } | |||
1000 | ||||
1001 | case ISD::BUILD_VECTOR: { | |||
1002 | // Select appropriate ldi.[bhwd] instructions for constant splats of | |||
1003 | // 128-bit when MSA is enabled. Fixup any register class mismatches that | |||
1004 | // occur as a result. | |||
1005 | // | |||
1006 | // This allows the compiler to use a wider range of immediates than would | |||
1007 | // otherwise be allowed. If, for example, v4i32 could only use ldi.h then | |||
1008 | // it would not be possible to load { 0x01010101, 0x01010101, 0x01010101, | |||
1009 | // 0x01010101 } without using a constant pool. This would be sub-optimal | |||
1010 | // when // 'ldi.b wd, 1' is capable of producing that bit-pattern in the | |||
1011 | // same set/ of registers. Similarly, ldi.h isn't capable of producing { | |||
1012 | // 0x00000000, 0x00000001, 0x00000000, 0x00000001 } but 'ldi.d wd, 1' can. | |||
1013 | ||||
1014 | const MipsABIInfo &ABI = | |||
1015 | static_cast<const MipsTargetMachine &>(TM).getABI(); | |||
1016 | ||||
1017 | BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Node); | |||
1018 | APInt SplatValue, SplatUndef; | |||
1019 | unsigned SplatBitSize; | |||
1020 | bool HasAnyUndefs; | |||
1021 | unsigned LdiOp; | |||
1022 | EVT ResVecTy = BVN->getValueType(0); | |||
1023 | EVT ViaVecTy; | |||
1024 | ||||
1025 | if (!Subtarget->hasMSA() || !BVN->getValueType(0).is128BitVector()) | |||
1026 | return false; | |||
1027 | ||||
1028 | if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, | |||
1029 | HasAnyUndefs, 8, | |||
1030 | !Subtarget->isLittle())) | |||
1031 | return false; | |||
1032 | ||||
1033 | switch (SplatBitSize) { | |||
1034 | default: | |||
1035 | return false; | |||
1036 | case 8: | |||
1037 | LdiOp = Mips::LDI_B; | |||
1038 | ViaVecTy = MVT::v16i8; | |||
1039 | break; | |||
1040 | case 16: | |||
1041 | LdiOp = Mips::LDI_H; | |||
1042 | ViaVecTy = MVT::v8i16; | |||
1043 | break; | |||
1044 | case 32: | |||
1045 | LdiOp = Mips::LDI_W; | |||
1046 | ViaVecTy = MVT::v4i32; | |||
1047 | break; | |||
1048 | case 64: | |||
1049 | LdiOp = Mips::LDI_D; | |||
1050 | ViaVecTy = MVT::v2i64; | |||
1051 | break; | |||
1052 | } | |||
1053 | ||||
1054 | SDNode *Res; | |||
1055 | ||||
1056 | // If we have a signed 10 bit integer, we can splat it directly. | |||
1057 | // | |||
1058 | // If we have something bigger we can synthesize the value into a GPR and | |||
1059 | // splat from there. | |||
1060 | if (SplatValue.isSignedIntN(10)) { | |||
1061 | SDValue Imm = CurDAG->getTargetConstant(SplatValue, DL, | |||
1062 | ViaVecTy.getVectorElementType()); | |||
1063 | ||||
1064 | Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm); | |||
1065 | } else if (SplatValue.isSignedIntN(16) && | |||
1066 | ((ABI.IsO32() && SplatBitSize < 64) || | |||
1067 | (ABI.IsN32() || ABI.IsN64()))) { | |||
1068 | // Only handle signed 16 bit values when the element size is GPR width. | |||
1069 | // MIPS64 can handle all the cases but MIPS32 would need to handle | |||
1070 | // negative cases specifically here. Instead, handle those cases as | |||
1071 | // 64bit values. | |||
1072 | ||||
1073 | bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64; | |||
1074 | const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu; | |||
1075 | const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64; | |||
1076 | SDValue ZeroVal = CurDAG->getRegister( | |||
1077 | Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT); | |||
1078 | ||||
1079 | const unsigned FILLOp = | |||
1080 | SplatBitSize == 16 | |||
1081 | ? Mips::FILL_H | |||
1082 | : (SplatBitSize == 32 ? Mips::FILL_W | |||
1083 | : (SplatBitSize == 64 ? Mips::FILL_D : 0)); | |||
1084 | ||||
1085 | 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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1085, __PRETTY_FUNCTION__)); | |||
1086 | 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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1087, __PRETTY_FUNCTION__)) | |||
1087 | "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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1087, __PRETTY_FUNCTION__)); | |||
1088 | ||||
1089 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1090 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, SplatMVT); | |||
1091 | ||||
1092 | Res = CurDAG->getMachineNode(ADDiuOp, DL, SplatMVT, ZeroVal, LoVal); | |||
1093 | Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0)); | |||
1094 | ||||
1095 | } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) { | |||
1096 | // Only handle the cases where the splat size agrees with the size | |||
1097 | // of the SplatValue here. | |||
1098 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1099 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1100 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1101 | ||||
1102 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1103 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1104 | ||||
1105 | if (Hi) | |||
1106 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1107 | ||||
1108 | if (Lo) | |||
1109 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1110 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1111 | ||||
1112 | 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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1112, __PRETTY_FUNCTION__)); | |||
1113 | Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0)); | |||
1114 | ||||
1115 | } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 && | |||
1116 | (ABI.IsN32() || ABI.IsN64())) { | |||
1117 | // N32 and N64 can perform some tricks that O32 can't for signed 32 bit | |||
1118 | // integers due to having 64bit registers. lui will cause the necessary | |||
1119 | // zero/sign extension. | |||
1120 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1121 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1122 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1123 | ||||
1124 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1125 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1126 | ||||
1127 | if (Hi) | |||
1128 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1129 | ||||
1130 | if (Lo) | |||
1131 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1132 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1133 | ||||
1134 | Res = CurDAG->getMachineNode( | |||
1135 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1136 | CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64), | |||
1137 | SDValue(Res, 0), | |||
| ||||
1138 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1139 | ||||
1140 | Res = | |||
1141 | CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0)); | |||
1142 | ||||
1143 | } else if (SplatValue.isSignedIntN(64)) { | |||
1144 | // If we have a 64 bit Splat value, we perform a similar sequence to the | |||
1145 | // above: | |||
1146 | // | |||
1147 | // MIPS32: MIPS64: | |||
1148 | // lui $res, %highest(val) lui $res, %highest(val) | |||
1149 | // ori $res, $res, %higher(val) ori $res, $res, %higher(val) | |||
1150 | // lui $res2, %hi(val) lui $res2, %hi(val) | |||
1151 | // ori $res2, %res2, %lo(val) ori $res2, %res2, %lo(val) | |||
1152 | // $res3 = fill $res2 dinsu $res, $res2, 0, 32 | |||
1153 | // $res4 = insert.w $res3[1], $res fill.d $res | |||
1154 | // splat.d $res4, 0 | |||
1155 | // | |||
1156 | // The ability to use dinsu is guaranteed as MSA requires MIPSR5. This saves | |||
1157 | // having to materialize the value by shifts and ors. | |||
1158 | // | |||
1159 | // FIXME: Implement the preferred sequence for MIPS64R6: | |||
1160 | // | |||
1161 | // MIPS64R6: | |||
1162 | // ori $res, $zero, %lo(val) | |||
1163 | // daui $res, $res, %hi(val) | |||
1164 | // dahi $res, $res, %higher(val) | |||
1165 | // dati $res, $res, %highest(cal) | |||
1166 | // fill.d $res | |||
1167 | // | |||
1168 | ||||
1169 | const unsigned Lo = SplatValue.getLoBits(16).getZExtValue(); | |||
1170 | const unsigned Hi = SplatValue.lshr(16).getLoBits(16).getZExtValue(); | |||
1171 | const unsigned Higher = SplatValue.lshr(32).getLoBits(16).getZExtValue(); | |||
1172 | const unsigned Highest = SplatValue.lshr(48).getLoBits(16).getZExtValue(); | |||
1173 | ||||
1174 | SDValue LoVal = CurDAG->getTargetConstant(Lo, DL, MVT::i32); | |||
1175 | SDValue HiVal = CurDAG->getTargetConstant(Hi, DL, MVT::i32); | |||
1176 | SDValue HigherVal = CurDAG->getTargetConstant(Higher, DL, MVT::i32); | |||
1177 | SDValue HighestVal = CurDAG->getTargetConstant(Highest, DL, MVT::i32); | |||
1178 | SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32); | |||
1179 | ||||
1180 | // Independent of whether we're targeting MIPS64 or not, the basic | |||
1181 | // operations are the same. Also, directly use the $zero register if | |||
1182 | // the 16 bit chunk is zero. | |||
1183 | // | |||
1184 | // For optimization purposes we always synthesize the splat value as | |||
1185 | // an i32 value, then if we're targetting MIPS64, use SUBREG_TO_REG | |||
1186 | // just before combining the values with dinsu to produce an i64. This | |||
1187 | // enables SelectionDAG to aggressively share components of splat values | |||
1188 | // where possible. | |||
1189 | // | |||
1190 | // FIXME: This is the general constant synthesis problem. This code | |||
1191 | // should be factored out into a class shared between all the | |||
1192 | // classes that need it. Specifically, for a splat size of 64 | |||
1193 | // bits that's a negative number we can do better than LUi/ORi | |||
1194 | // for the upper 32bits. | |||
1195 | ||||
1196 | if (Hi) | |||
1197 | Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal); | |||
1198 | ||||
1199 | if (Lo) | |||
1200 | Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1201 | Hi ? SDValue(Res, 0) : ZeroVal, LoVal); | |||
1202 | ||||
1203 | SDNode *HiRes; | |||
1204 | if (Highest) | |||
1205 | HiRes = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HighestVal); | |||
1206 | ||||
1207 | if (Higher) | |||
1208 | HiRes = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32, | |||
1209 | Highest ? SDValue(HiRes, 0) : ZeroVal, | |||
1210 | HigherVal); | |||
1211 | ||||
1212 | ||||
1213 | if (ABI.IsO32()) { | |||
1214 | Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, | |||
1215 | (Hi || Lo) ? SDValue(Res, 0) : ZeroVal); | |||
1216 | ||||
1217 | Res = CurDAG->getMachineNode( | |||
1218 | Mips::INSERT_W, DL, MVT::v4i32, SDValue(Res, 0), | |||
1219 | (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal, | |||
1220 | CurDAG->getTargetConstant(1, DL, MVT::i32)); | |||
1221 | ||||
1222 | const TargetLowering *TLI = getTargetLowering(); | |||
1223 | const TargetRegisterClass *RC = | |||
1224 | TLI->getRegClassFor(ViaVecTy.getSimpleVT()); | |||
1225 | ||||
1226 | Res = CurDAG->getMachineNode( | |||
1227 | Mips::COPY_TO_REGCLASS, DL, ViaVecTy, SDValue(Res, 0), | |||
1228 | CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32)); | |||
1229 | ||||
1230 | Res = CurDAG->getMachineNode( | |||
1231 | Mips::SPLATI_D, DL, MVT::v2i64, SDValue(Res, 0), | |||
1232 | CurDAG->getTargetConstant(0, DL, MVT::i32)); | |||
1233 | } else if (ABI.IsN64() || ABI.IsN32()) { | |||
1234 | ||||
1235 | SDValue Zero64Val = CurDAG->getRegister(Mips::ZERO_64, MVT::i64); | |||
1236 | const bool HiResNonZero = Highest || Higher; | |||
1237 | const bool ResNonZero = Hi || Lo; | |||
1238 | ||||
1239 | if (HiResNonZero) | |||
1240 | HiRes = CurDAG->getMachineNode( | |||
1241 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1242 | CurDAG->getTargetConstant(((Highest >> 15) & 0x1), DL, MVT::i64), | |||
1243 | SDValue(HiRes, 0), | |||
1244 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1245 | ||||
1246 | if (ResNonZero) | |||
1247 | Res = CurDAG->getMachineNode( | |||
1248 | Mips::SUBREG_TO_REG, DL, MVT::i64, | |||
1249 | CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64), | |||
1250 | SDValue(Res, 0), | |||
1251 | CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64)); | |||
1252 | ||||
1253 | // We have 3 cases: | |||
1254 | // The HiRes is nonzero but Res is $zero => dsll32 HiRes, 0 | |||
1255 | // The Res is nonzero but HiRes is $zero => dinsu Res, $zero, 32, 32 | |||
1256 | // Both are non zero => dinsu Res, HiRes, 32, 32 | |||
1257 | // | |||
1258 | // The obvious "missing" case is when both are zero, but that case is | |||
1259 | // handled by the ldi case. | |||
1260 | if (ResNonZero) { | |||
1261 | IntegerType *Int32Ty = | |||
1262 | IntegerType::get(MF->getFunction().getContext(), 32); | |||
1263 | const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32); | |||
1264 | SDValue Ops[4] = {HiResNonZero ? SDValue(HiRes, 0) : Zero64Val, | |||
1265 | CurDAG->getConstant(*Const32, DL, MVT::i32), | |||
1266 | CurDAG->getConstant(*Const32, DL, MVT::i32), | |||
1267 | SDValue(Res, 0)}; | |||
1268 | ||||
1269 | Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops); | |||
1270 | } else if (HiResNonZero) { | |||
1271 | Res = CurDAG->getMachineNode( | |||
1272 | Mips::DSLL32, DL, MVT::i64, SDValue(HiRes, 0), | |||
1273 | CurDAG->getTargetConstant(0, DL, MVT::i32)); | |||
1274 | } else | |||
1275 | llvm_unreachable(::llvm::llvm_unreachable_internal("Zero splat value handled by non-zero 64bit splat synthesis!" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1276) | |||
1276 | "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-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1276); | |||
1277 | ||||
1278 | Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0)); | |||
1279 | } else | |||
1280 | llvm_unreachable("Unknown ABI in MipsISelDAGToDAG!")::llvm::llvm_unreachable_internal("Unknown ABI in MipsISelDAGToDAG!" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1280); | |||
1281 | ||||
1282 | } else | |||
1283 | return false; | |||
1284 | ||||
1285 | if (ResVecTy != ViaVecTy) { | |||
1286 | // If LdiOp is writing to a different register class to ResVecTy, then | |||
1287 | // fix it up here. This COPY_TO_REGCLASS should never cause a move.v | |||
1288 | // since the source and destination register sets contain the same | |||
1289 | // registers. | |||
1290 | const TargetLowering *TLI = getTargetLowering(); | |||
1291 | MVT ResVecTySimple = ResVecTy.getSimpleVT(); | |||
1292 | const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple); | |||
1293 | Res = CurDAG->getMachineNode(Mips::COPY_TO_REGCLASS, DL, | |||
1294 | ResVecTy, SDValue(Res, 0), | |||
1295 | CurDAG->getTargetConstant(RC->getID(), DL, | |||
1296 | MVT::i32)); | |||
1297 | } | |||
1298 | ||||
1299 | ReplaceNode(Node, Res); | |||
1300 | return true; | |||
1301 | } | |||
1302 | ||||
1303 | } | |||
1304 | ||||
1305 | return false; | |||
1306 | } | |||
1307 | ||||
1308 | bool MipsSEDAGToDAGISel:: | |||
1309 | SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, | |||
1310 | std::vector<SDValue> &OutOps) { | |||
1311 | SDValue Base, Offset; | |||
1312 | ||||
1313 | switch(ConstraintID) { | |||
1314 | default: | |||
1315 | llvm_unreachable("Unexpected asm memory constraint")::llvm::llvm_unreachable_internal("Unexpected asm memory constraint" , "/build/llvm-toolchain-snapshot-8~svn350071/lib/Target/Mips/MipsSEISelDAGToDAG.cpp" , 1315); | |||
1316 | // All memory constraints can at least accept raw pointers. | |||
1317 | case InlineAsm::Constraint_i: | |||
1318 | OutOps.push_back(Op); | |||
1319 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1320 | return false; | |||
1321 | case InlineAsm::Constraint_m: | |||
1322 | if (selectAddrRegImm16(Op, Base, Offset)) { | |||
1323 | OutOps.push_back(Base); | |||
1324 | OutOps.push_back(Offset); | |||
1325 | return false; | |||
1326 | } | |||
1327 | OutOps.push_back(Op); | |||
1328 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1329 | return false; | |||
1330 | case InlineAsm::Constraint_R: | |||
1331 | // The 'R' constraint is supposed to be much more complicated than this. | |||
1332 | // However, it's becoming less useful due to architectural changes and | |||
1333 | // ought to be replaced by other constraints such as 'ZC'. | |||
1334 | // For now, support 9-bit signed offsets which is supportable by all | |||
1335 | // subtargets for all instructions. | |||
1336 | if (selectAddrRegImm9(Op, Base, Offset)) { | |||
1337 | OutOps.push_back(Base); | |||
1338 | OutOps.push_back(Offset); | |||
1339 | return false; | |||
1340 | } | |||
1341 | OutOps.push_back(Op); | |||
1342 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1343 | return false; | |||
1344 | case InlineAsm::Constraint_ZC: | |||
1345 | // ZC matches whatever the pref, ll, and sc instructions can handle for the | |||
1346 | // given subtarget. | |||
1347 | if (Subtarget->inMicroMipsMode()) { | |||
1348 | // On microMIPS, they can handle 12-bit offsets. | |||
1349 | if (selectAddrRegImm12(Op, Base, Offset)) { | |||
1350 | OutOps.push_back(Base); | |||
1351 | OutOps.push_back(Offset); | |||
1352 | return false; | |||
1353 | } | |||
1354 | } else if (Subtarget->hasMips32r6()) { | |||
1355 | // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets. | |||
1356 | if (selectAddrRegImm9(Op, Base, Offset)) { | |||
1357 | OutOps.push_back(Base); | |||
1358 | OutOps.push_back(Offset); | |||
1359 | return false; | |||
1360 | } | |||
1361 | } else if (selectAddrRegImm16(Op, Base, Offset)) { | |||
1362 | // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets. | |||
1363 | OutOps.push_back(Base); | |||
1364 | OutOps.push_back(Offset); | |||
1365 | return false; | |||
1366 | } | |||
1367 | // In all cases, 0-bit offsets are acceptable. | |||
1368 | OutOps.push_back(Op); | |||
1369 | OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32)); | |||
1370 | return false; | |||
1371 | } | |||
1372 | return true; | |||
1373 | } | |||
1374 | ||||
1375 | FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM, | |||
1376 | CodeGenOpt::Level OptLevel) { | |||
1377 | return new MipsSEDAGToDAGISel(TM, OptLevel); | |||
1378 | } |