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