blob: fae294ce40ac2c7f8c330630b8ad6a117525dc9a [file] [log] [blame]
Akira Hatanaka042b7962013-03-14 19:09:52 +00001//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
Akira Hatanaka5ac065a2013-03-13 00:54:29 +00002//
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 MipsTargetLowering specialized for mips32/64.
11//
12//===----------------------------------------------------------------------===//
13#include "MipsSEISelLowering.h"
14#include "MipsRegisterInfo.h"
15#include "MipsTargetMachine.h"
16#include "llvm/CodeGen/MachineInstrBuilder.h"
17#include "llvm/CodeGen/MachineRegisterInfo.h"
Akira Hatanaka4e0980a2013-04-13 02:13:30 +000018#include "llvm/IR/Intrinsics.h"
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000019#include "llvm/Support/CommandLine.h"
20#include "llvm/Target/TargetInstrInfo.h"
21
22using namespace llvm;
23
24static cl::opt<bool>
25EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
26 cl::desc("MIPS: Enable tail calls."), cl::init(false));
27
28MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
29 : MipsTargetLowering(TM) {
30 // Set up the register classes
Reed Kotlera430cb62013-04-09 19:46:01 +000031
32 clearRegisterClasses();
33
Akira Hatanaka18587862013-08-06 23:08:38 +000034 addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000035
36 if (HasMips64)
Akira Hatanaka18587862013-08-06 23:08:38 +000037 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000038
39 if (Subtarget->hasDSP()) {
40 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
41
42 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
Akira Hatanaka7d635522013-08-14 00:53:38 +000043 addRegisterClass(VecTys[i], &Mips::DSPRRegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000044
45 // Expand all builtin opcodes.
46 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
47 setOperationAction(Opc, VecTys[i], Expand);
48
Akira Hatanaka3d602412013-04-13 00:55:41 +000049 setOperationAction(ISD::ADD, VecTys[i], Legal);
50 setOperationAction(ISD::SUB, VecTys[i], Legal);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000051 setOperationAction(ISD::LOAD, VecTys[i], Legal);
52 setOperationAction(ISD::STORE, VecTys[i], Legal);
53 setOperationAction(ISD::BITCAST, VecTys[i], Legal);
54 }
Akira Hatanaka97a62bf2013-04-19 23:21:32 +000055
Akira Hatanaka5e795092013-08-02 19:23:33 +000056 // Expand all truncating stores and extending loads.
57 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
58 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
59
60 for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
61 for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
62 setTruncStoreAction((MVT::SimpleValueType)VT0,
63 (MVT::SimpleValueType)VT1, Expand);
64
65 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
66 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
67 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
68 }
69
Akira Hatanaka97a62bf2013-04-19 23:21:32 +000070 setTargetDAGCombine(ISD::SHL);
71 setTargetDAGCombine(ISD::SRA);
72 setTargetDAGCombine(ISD::SRL);
Akira Hatanakacd6c5792013-04-30 22:37:26 +000073 setTargetDAGCombine(ISD::SETCC);
74 setTargetDAGCombine(ISD::VSELECT);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000075 }
76
Akira Hatanaka3d602412013-04-13 00:55:41 +000077 if (Subtarget->hasDSPR2())
78 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
79
Jack Carter3f70e902013-08-13 20:54:07 +000080 if (Subtarget->hasMSA()) {
Daniel Sandersc73488a2013-08-23 10:10:13 +000081 addMSAType(MVT::v16i8, &Mips::MSA128BRegClass);
82 addMSAType(MVT::v8i16, &Mips::MSA128HRegClass);
83 addMSAType(MVT::v4i32, &Mips::MSA128WRegClass);
84 addMSAType(MVT::v2i64, &Mips::MSA128DRegClass);
85 addMSAType(MVT::v8f16, &Mips::MSA128HRegClass);
86 addMSAType(MVT::v4f32, &Mips::MSA128WRegClass);
87 addMSAType(MVT::v2f64, &Mips::MSA128DRegClass);
Jack Carter3f70e902013-08-13 20:54:07 +000088 }
89
Reed Kotlerc673f9c2013-08-30 19:40:56 +000090 if (!Subtarget->mipsSEUsesSoftFloat()) {
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000091 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
92
93 // When dealing with single precision only, use libcalls
94 if (!Subtarget->isSingleFloat()) {
Akira Hatanakaad341d42013-08-20 23:38:40 +000095 if (Subtarget->isFP64bit())
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000096 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
97 else
98 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
99 }
100 }
101
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000102 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
103 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
104 setOperationAction(ISD::MULHS, MVT::i32, Custom);
105 setOperationAction(ISD::MULHU, MVT::i32, Custom);
106
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000107 if (HasMips64) {
108 setOperationAction(ISD::MULHS, MVT::i64, Custom);
109 setOperationAction(ISD::MULHU, MVT::i64, Custom);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000110 setOperationAction(ISD::MUL, MVT::i64, Custom);
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000111 }
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000112
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000113 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
114 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
115
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000116 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
117 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
118 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
119 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000120 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
121 setOperationAction(ISD::LOAD, MVT::i32, Custom);
122 setOperationAction(ISD::STORE, MVT::i32, Custom);
123
Akira Hatanakad593a772013-03-30 01:42:24 +0000124 setTargetDAGCombine(ISD::ADDE);
125 setTargetDAGCombine(ISD::SUBE);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000126 setTargetDAGCombine(ISD::MUL);
Akira Hatanakad593a772013-03-30 01:42:24 +0000127
Daniel Sanders3c380d52013-08-28 12:14:50 +0000128 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000129 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
130 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
131
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000132 computeRegisterProperties();
133}
134
135const MipsTargetLowering *
136llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
137 return new MipsSETargetLowering(TM);
138}
139
Daniel Sandersc73488a2013-08-23 10:10:13 +0000140void MipsSETargetLowering::
141addMSAType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
142 addRegisterClass(Ty, RC);
Jack Cartere2a93762013-08-15 12:24:57 +0000143
144 // Expand all builtin opcodes.
145 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
146 setOperationAction(Opc, Ty, Expand);
147
148 setOperationAction(ISD::LOAD, Ty, Legal);
149 setOperationAction(ISD::STORE, Ty, Legal);
150 setOperationAction(ISD::BITCAST, Ty, Legal);
151}
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000152
153bool
154MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
155 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
156
157 switch (SVT) {
158 case MVT::i64:
159 case MVT::i32:
160 if (Fast)
161 *Fast = true;
162 return true;
163 default:
164 return false;
165 }
166}
167
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000168SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
169 SelectionDAG &DAG) const {
170 switch(Op.getOpcode()) {
171 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
172 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
173 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
174 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
175 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
176 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
Akira Hatanakab109ea82013-04-22 20:13:37 +0000177 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
178 DAG);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000179 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
180 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000181 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000182 }
183
184 return MipsTargetLowering::LowerOperation(Op, DAG);
185}
186
Akira Hatanakad593a772013-03-30 01:42:24 +0000187// selectMADD -
188// Transforms a subgraph in CurDAG if the following pattern is found:
189// (addc multLo, Lo0), (adde multHi, Hi0),
190// where,
191// multHi/Lo: product of multiplication
192// Lo0: initial value of Lo register
193// Hi0: initial value of Hi register
194// Return true if pattern matching was successful.
195static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
196 // ADDENode's second operand must be a flag output of an ADDC node in order
197 // for the matching to be successful.
198 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
199
200 if (ADDCNode->getOpcode() != ISD::ADDC)
201 return false;
202
203 SDValue MultHi = ADDENode->getOperand(0);
204 SDValue MultLo = ADDCNode->getOperand(0);
205 SDNode *MultNode = MultHi.getNode();
206 unsigned MultOpc = MultHi.getOpcode();
207
208 // MultHi and MultLo must be generated by the same node,
209 if (MultLo.getNode() != MultNode)
210 return false;
211
212 // and it must be a multiplication.
213 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
214 return false;
215
216 // MultLo amd MultHi must be the first and second output of MultNode
217 // respectively.
218 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
219 return false;
220
221 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
222 // of the values of MultNode, in which case MultNode will be removed in later
223 // phases.
224 // If there exist users other than ADDENode or ADDCNode, this function returns
225 // here, which will result in MultNode being mapped to a single MULT
226 // instruction node rather than a pair of MULT and MADD instructions being
227 // produced.
228 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
229 return false;
230
Andrew Trickac6d9be2013-05-25 02:42:55 +0000231 SDLoc DL(ADDENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000232
233 // Initialize accumulator.
234 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
235 ADDCNode->getOperand(1),
236 ADDENode->getOperand(1));
237
238 // create MipsMAdd(u) node
239 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
240
241 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
242 MultNode->getOperand(0),// Factor 0
243 MultNode->getOperand(1),// Factor 1
244 ACCIn);
245
246 // replace uses of adde and addc here
247 if (!SDValue(ADDCNode, 0).use_empty()) {
248 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
249 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
250 LoIdx);
251 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
252 }
253 if (!SDValue(ADDENode, 0).use_empty()) {
254 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
255 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
256 HiIdx);
257 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
258 }
259
260 return true;
261}
262
263// selectMSUB -
264// Transforms a subgraph in CurDAG if the following pattern is found:
265// (addc Lo0, multLo), (sube Hi0, multHi),
266// where,
267// multHi/Lo: product of multiplication
268// Lo0: initial value of Lo register
269// Hi0: initial value of Hi register
270// Return true if pattern matching was successful.
271static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
272 // SUBENode's second operand must be a flag output of an SUBC node in order
273 // for the matching to be successful.
274 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
275
276 if (SUBCNode->getOpcode() != ISD::SUBC)
277 return false;
278
279 SDValue MultHi = SUBENode->getOperand(1);
280 SDValue MultLo = SUBCNode->getOperand(1);
281 SDNode *MultNode = MultHi.getNode();
282 unsigned MultOpc = MultHi.getOpcode();
283
284 // MultHi and MultLo must be generated by the same node,
285 if (MultLo.getNode() != MultNode)
286 return false;
287
288 // and it must be a multiplication.
289 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
290 return false;
291
292 // MultLo amd MultHi must be the first and second output of MultNode
293 // respectively.
294 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
295 return false;
296
297 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
298 // of the values of MultNode, in which case MultNode will be removed in later
299 // phases.
300 // If there exist users other than SUBENode or SUBCNode, this function returns
301 // here, which will result in MultNode being mapped to a single MULT
302 // instruction node rather than a pair of MULT and MSUB instructions being
303 // produced.
304 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
305 return false;
306
Andrew Trickac6d9be2013-05-25 02:42:55 +0000307 SDLoc DL(SUBENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000308
309 // Initialize accumulator.
310 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
311 SUBCNode->getOperand(0),
312 SUBENode->getOperand(0));
313
314 // create MipsSub(u) node
315 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
316
317 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
318 MultNode->getOperand(0),// Factor 0
319 MultNode->getOperand(1),// Factor 1
320 ACCIn);
321
322 // replace uses of sube and subc here
323 if (!SDValue(SUBCNode, 0).use_empty()) {
324 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
325 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
326 LoIdx);
327 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
328 }
329 if (!SDValue(SUBENode, 0).use_empty()) {
330 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
331 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
332 HiIdx);
333 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
334 }
335
336 return true;
337}
338
339static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
340 TargetLowering::DAGCombinerInfo &DCI,
341 const MipsSubtarget *Subtarget) {
342 if (DCI.isBeforeLegalize())
343 return SDValue();
344
345 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
346 selectMADD(N, &DAG))
347 return SDValue(N, 0);
348
349 return SDValue();
350}
351
352static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
353 TargetLowering::DAGCombinerInfo &DCI,
354 const MipsSubtarget *Subtarget) {
355 if (DCI.isBeforeLegalize())
356 return SDValue();
357
358 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
359 selectMSUB(N, &DAG))
360 return SDValue(N, 0);
361
362 return SDValue();
363}
364
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000365static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
366 EVT ShiftTy, SelectionDAG &DAG) {
367 // Clear the upper (64 - VT.sizeInBits) bits.
368 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
369
370 // Return 0.
371 if (C == 0)
372 return DAG.getConstant(0, VT);
373
374 // Return x.
375 if (C == 1)
376 return X;
377
378 // If c is power of 2, return (shl x, log2(c)).
379 if (isPowerOf2_64(C))
380 return DAG.getNode(ISD::SHL, DL, VT, X,
381 DAG.getConstant(Log2_64(C), ShiftTy));
382
383 unsigned Log2Ceil = Log2_64_Ceil(C);
384 uint64_t Floor = 1LL << Log2_64(C);
385 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
386
387 // If |c - floor_c| <= |c - ceil_c|,
388 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
389 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
390 if (C - Floor <= Ceil - C) {
391 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
392 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
393 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
394 }
395
396 // If |c - floor_c| > |c - ceil_c|,
397 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
398 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
399 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
400 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
401}
402
403static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
404 const TargetLowering::DAGCombinerInfo &DCI,
405 const MipsSETargetLowering *TL) {
406 EVT VT = N->getValueType(0);
407
408 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
409 if (!VT.isVector())
410 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
411 VT, TL->getScalarShiftAmountTy(VT), DAG);
412
413 return SDValue(N, 0);
414}
415
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000416static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
417 SelectionDAG &DAG,
418 const MipsSubtarget *Subtarget) {
419 // See if this is a vector splat immediate node.
420 APInt SplatValue, SplatUndef;
421 unsigned SplatBitSize;
422 bool HasAnyUndefs;
423 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
424 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
425
Akira Hatanakad5972632013-04-22 19:58:23 +0000426 if (!BV ||
Akira Hatanakab109ea82013-04-22 20:13:37 +0000427 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
Akira Hatanakae311b002013-04-23 18:09:42 +0000428 EltSize, !Subtarget->isLittle()) ||
Akira Hatanakad5972632013-04-22 19:58:23 +0000429 (SplatBitSize != EltSize) ||
Akira Hatanakae311b002013-04-23 18:09:42 +0000430 (SplatValue.getZExtValue() >= EltSize))
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000431 return SDValue();
432
Andrew Trickac6d9be2013-05-25 02:42:55 +0000433 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000434 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
435}
436
437static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
438 TargetLowering::DAGCombinerInfo &DCI,
439 const MipsSubtarget *Subtarget) {
440 EVT Ty = N->getValueType(0);
441
442 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
443 return SDValue();
444
445 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
446}
447
448static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
449 TargetLowering::DAGCombinerInfo &DCI,
450 const MipsSubtarget *Subtarget) {
451 EVT Ty = N->getValueType(0);
452
453 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
454 return SDValue();
455
456 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
457}
458
459
460static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
461 TargetLowering::DAGCombinerInfo &DCI,
462 const MipsSubtarget *Subtarget) {
463 EVT Ty = N->getValueType(0);
464
465 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
466 return SDValue();
467
468 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
469}
470
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000471static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
472 bool IsV216 = (Ty == MVT::v2i16);
473
474 switch (CC) {
475 case ISD::SETEQ:
476 case ISD::SETNE: return true;
477 case ISD::SETLT:
478 case ISD::SETLE:
479 case ISD::SETGT:
480 case ISD::SETGE: return IsV216;
481 case ISD::SETULT:
482 case ISD::SETULE:
483 case ISD::SETUGT:
484 case ISD::SETUGE: return !IsV216;
485 default: return false;
486 }
487}
488
489static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
490 EVT Ty = N->getValueType(0);
491
492 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
493 return SDValue();
494
495 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
496 return SDValue();
497
Andrew Trickac6d9be2013-05-25 02:42:55 +0000498 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000499 N->getOperand(1), N->getOperand(2));
500}
501
502static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
503 EVT Ty = N->getValueType(0);
504
505 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
506 return SDValue();
507
508 SDValue SetCC = N->getOperand(0);
509
510 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
511 return SDValue();
512
Andrew Trickac6d9be2013-05-25 02:42:55 +0000513 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000514 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
515 N->getOperand(2), SetCC.getOperand(2));
516}
517
Akira Hatanakad593a772013-03-30 01:42:24 +0000518SDValue
519MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
520 SelectionDAG &DAG = DCI.DAG;
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000521 SDValue Val;
Akira Hatanakad593a772013-03-30 01:42:24 +0000522
523 switch (N->getOpcode()) {
524 case ISD::ADDE:
525 return performADDECombine(N, DAG, DCI, Subtarget);
526 case ISD::SUBE:
527 return performSUBECombine(N, DAG, DCI, Subtarget);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000528 case ISD::MUL:
529 return performMULCombine(N, DAG, DCI, this);
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000530 case ISD::SHL:
531 return performSHLCombine(N, DAG, DCI, Subtarget);
532 case ISD::SRA:
533 return performSRACombine(N, DAG, DCI, Subtarget);
534 case ISD::SRL:
535 return performSRLCombine(N, DAG, DCI, Subtarget);
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000536 case ISD::VSELECT:
537 return performVSELECTCombine(N, DAG);
538 case ISD::SETCC: {
539 Val = performSETCCCombine(N, DAG);
540 break;
Akira Hatanakad593a772013-03-30 01:42:24 +0000541 }
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000542 }
543
544 if (Val.getNode())
545 return Val;
546
547 return MipsTargetLowering::PerformDAGCombine(N, DCI);
Akira Hatanakad593a772013-03-30 01:42:24 +0000548}
549
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000550MachineBasicBlock *
551MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
552 MachineBasicBlock *BB) const {
553 switch (MI->getOpcode()) {
554 default:
555 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
556 case Mips::BPOSGE32_PSEUDO:
557 return emitBPOSGE32(MI, BB);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000558 case Mips::SNZ_B_PSEUDO:
559 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
560 case Mips::SNZ_H_PSEUDO:
561 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
562 case Mips::SNZ_W_PSEUDO:
563 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
564 case Mips::SNZ_D_PSEUDO:
565 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
566 case Mips::SNZ_V_PSEUDO:
567 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
568 case Mips::SZ_B_PSEUDO:
569 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
570 case Mips::SZ_H_PSEUDO:
571 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
572 case Mips::SZ_W_PSEUDO:
573 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
574 case Mips::SZ_D_PSEUDO:
575 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
576 case Mips::SZ_V_PSEUDO:
577 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000578 }
579}
580
581bool MipsSETargetLowering::
582isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
583 unsigned NextStackOffset,
584 const MipsFunctionInfo& FI) const {
585 if (!EnableMipsTailCalls)
586 return false;
587
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000588 // Return false if either the callee or caller has a byval argument.
589 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
590 return false;
591
592 // Return true if the callee's argument area is no larger than the
593 // caller's.
594 return NextStackOffset <= FI.getIncomingArgSize();
595}
596
597void MipsSETargetLowering::
598getOpndList(SmallVectorImpl<SDValue> &Ops,
599 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
600 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
601 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
602 // T9 should contain the address of the callee function if
603 // -reloction-model=pic or it is an indirect call.
604 if (IsPICCall || !GlobalOrExternal) {
605 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
606 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
607 } else
608 Ops.push_back(Callee);
609
610 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
611 InternalLinkage, CLI, Callee, Chain);
612}
613
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000614SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
615 bool HasLo, bool HasHi,
616 SelectionDAG &DAG) const {
617 EVT Ty = Op.getOperand(0).getValueType();
Andrew Trickac6d9be2013-05-25 02:42:55 +0000618 SDLoc DL(Op);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000619 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
620 Op.getOperand(0), Op.getOperand(1));
621 SDValue Lo, Hi;
622
623 if (HasLo)
624 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
625 DAG.getConstant(Mips::sub_lo, MVT::i32));
626 if (HasHi)
627 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
628 DAG.getConstant(Mips::sub_hi, MVT::i32));
629
630 if (!HasLo || !HasHi)
631 return HasLo ? Lo : Hi;
632
633 SDValue Vals[] = { Lo, Hi };
634 return DAG.getMergeValues(Vals, 2, DL);
635}
636
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000637
Andrew Trickac6d9be2013-05-25 02:42:55 +0000638static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000639 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
640 DAG.getConstant(0, MVT::i32));
641 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
642 DAG.getConstant(1, MVT::i32));
643 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
644}
645
Andrew Trickac6d9be2013-05-25 02:42:55 +0000646static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000647 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
648 DAG.getConstant(Mips::sub_lo, MVT::i32));
649 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
650 DAG.getConstant(Mips::sub_hi, MVT::i32));
651 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
652}
653
654// This function expands mips intrinsic nodes which have 64-bit input operands
655// or output values.
656//
657// out64 = intrinsic-node in64
658// =>
659// lo = copy (extract-element (in64, 0))
660// hi = copy (extract-element (in64, 1))
661// mips-specific-node
662// v0 = copy lo
663// v1 = copy hi
664// out64 = merge-values (v0, v1)
665//
666static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
Andrew Trickac6d9be2013-05-25 02:42:55 +0000667 SDLoc DL(Op);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000668 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
669 SmallVector<SDValue, 3> Ops;
670 unsigned OpNo = 0;
671
672 // See if Op has a chain input.
673 if (HasChainIn)
674 Ops.push_back(Op->getOperand(OpNo++));
675
676 // The next operand is the intrinsic opcode.
677 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
678
679 // See if the next operand has type i64.
680 SDValue Opnd = Op->getOperand(++OpNo), In64;
681
682 if (Opnd.getValueType() == MVT::i64)
683 In64 = initAccumulator(Opnd, DL, DAG);
684 else
685 Ops.push_back(Opnd);
686
687 // Push the remaining operands.
688 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
689 Ops.push_back(Op->getOperand(OpNo));
690
691 // Add In64 to the end of the list.
692 if (In64.getNode())
693 Ops.push_back(In64);
694
695 // Scan output.
696 SmallVector<EVT, 2> ResTys;
697
698 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
699 I != E; ++I)
700 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
701
702 // Create node.
703 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
704 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
705
706 if (!HasChainIn)
707 return Out;
708
709 assert(Val->getValueType(1) == MVT::Other);
710 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
711 return DAG.getMergeValues(Vals, 2, DL);
712}
713
Daniel Sanders3c380d52013-08-28 12:14:50 +0000714static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
715 SDLoc DL(Op);
716 SDValue Value = Op->getOperand(1);
717 EVT ResTy = Op->getValueType(0);
718
719 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
720
721 return Result;
722}
723
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000724SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
725 SelectionDAG &DAG) const {
726 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
727 default:
728 return SDValue();
729 case Intrinsic::mips_shilo:
730 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
731 case Intrinsic::mips_dpau_h_qbl:
732 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
733 case Intrinsic::mips_dpau_h_qbr:
734 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
735 case Intrinsic::mips_dpsu_h_qbl:
736 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
737 case Intrinsic::mips_dpsu_h_qbr:
738 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
739 case Intrinsic::mips_dpa_w_ph:
740 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
741 case Intrinsic::mips_dps_w_ph:
742 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
743 case Intrinsic::mips_dpax_w_ph:
744 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
745 case Intrinsic::mips_dpsx_w_ph:
746 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
747 case Intrinsic::mips_mulsa_w_ph:
748 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
749 case Intrinsic::mips_mult:
750 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
751 case Intrinsic::mips_multu:
752 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
753 case Intrinsic::mips_madd:
754 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
755 case Intrinsic::mips_maddu:
756 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
757 case Intrinsic::mips_msub:
758 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
759 case Intrinsic::mips_msubu:
760 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000761 case Intrinsic::mips_bnz_b:
762 case Intrinsic::mips_bnz_h:
763 case Intrinsic::mips_bnz_w:
764 case Intrinsic::mips_bnz_d:
765 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
766 case Intrinsic::mips_bnz_v:
767 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
768 case Intrinsic::mips_bz_b:
769 case Intrinsic::mips_bz_h:
770 case Intrinsic::mips_bz_w:
771 case Intrinsic::mips_bz_d:
772 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
773 case Intrinsic::mips_bz_v:
774 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000775 }
776}
777
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000778static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
779 SDLoc DL(Op);
780 SDValue ChainIn = Op->getOperand(0);
781 SDValue Address = Op->getOperand(2);
782 SDValue Offset = Op->getOperand(3);
783 EVT ResTy = Op->getValueType(0);
784 EVT PtrTy = Address->getValueType(0);
785
786 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
787
788 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
789 false, false, 16);
790}
791
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000792SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
793 SelectionDAG &DAG) const {
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000794 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
795 switch (Intr) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000796 default:
797 return SDValue();
798 case Intrinsic::mips_extp:
799 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
800 case Intrinsic::mips_extpdp:
801 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
802 case Intrinsic::mips_extr_w:
803 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
804 case Intrinsic::mips_extr_r_w:
805 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
806 case Intrinsic::mips_extr_rs_w:
807 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
808 case Intrinsic::mips_extr_s_h:
809 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
810 case Intrinsic::mips_mthlip:
811 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
812 case Intrinsic::mips_mulsaq_s_w_ph:
813 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
814 case Intrinsic::mips_maq_s_w_phl:
815 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
816 case Intrinsic::mips_maq_s_w_phr:
817 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
818 case Intrinsic::mips_maq_sa_w_phl:
819 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
820 case Intrinsic::mips_maq_sa_w_phr:
821 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
822 case Intrinsic::mips_dpaq_s_w_ph:
823 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
824 case Intrinsic::mips_dpsq_s_w_ph:
825 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
826 case Intrinsic::mips_dpaq_sa_l_w:
827 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
828 case Intrinsic::mips_dpsq_sa_l_w:
829 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
830 case Intrinsic::mips_dpaqx_s_w_ph:
831 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
832 case Intrinsic::mips_dpaqx_sa_w_ph:
833 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
834 case Intrinsic::mips_dpsqx_s_w_ph:
835 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
836 case Intrinsic::mips_dpsqx_sa_w_ph:
837 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000838 case Intrinsic::mips_ld_b:
839 case Intrinsic::mips_ld_h:
840 case Intrinsic::mips_ld_w:
841 case Intrinsic::mips_ld_d:
842 case Intrinsic::mips_ldx_b:
843 case Intrinsic::mips_ldx_h:
844 case Intrinsic::mips_ldx_w:
845 case Intrinsic::mips_ldx_d:
846 return lowerMSALoadIntr(Op, DAG, Intr);
847 }
848}
849
850static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
851 SDLoc DL(Op);
852 SDValue ChainIn = Op->getOperand(0);
853 SDValue Value = Op->getOperand(2);
854 SDValue Address = Op->getOperand(3);
855 SDValue Offset = Op->getOperand(4);
856 EVT PtrTy = Address->getValueType(0);
857
858 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
859
860 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
861 false, 16);
862}
863
864SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
865 SelectionDAG &DAG) const {
866 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
867 switch (Intr) {
868 default:
869 return SDValue();
870 case Intrinsic::mips_st_b:
871 case Intrinsic::mips_st_h:
872 case Intrinsic::mips_st_w:
873 case Intrinsic::mips_st_d:
874 case Intrinsic::mips_stx_b:
875 case Intrinsic::mips_stx_h:
876 case Intrinsic::mips_stx_w:
877 case Intrinsic::mips_stx_d:
Daniel Sanders3c380d52013-08-28 12:14:50 +0000878 return lowerMSAStoreIntr(Op, DAG, Intr);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000879 }
880}
881
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000882MachineBasicBlock * MipsSETargetLowering::
883emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
884 // $bb:
885 // bposge32_pseudo $vr0
886 // =>
887 // $bb:
888 // bposge32 $tbb
889 // $fbb:
890 // li $vr2, 0
891 // b $sink
892 // $tbb:
893 // li $vr1, 1
894 // $sink:
895 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
896
897 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
898 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
Akira Hatanaka18587862013-08-06 23:08:38 +0000899 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000900 DebugLoc DL = MI->getDebugLoc();
901 const BasicBlock *LLVM_BB = BB->getBasicBlock();
902 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
903 MachineFunction *F = BB->getParent();
904 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
905 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
906 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
907 F->insert(It, FBB);
908 F->insert(It, TBB);
909 F->insert(It, Sink);
910
911 // Transfer the remainder of BB and its successor edges to Sink.
912 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
913 BB->end());
914 Sink->transferSuccessorsAndUpdatePHIs(BB);
915
916 // Add successors.
917 BB->addSuccessor(FBB);
918 BB->addSuccessor(TBB);
919 FBB->addSuccessor(Sink);
920 TBB->addSuccessor(Sink);
921
922 // Insert the real bposge32 instruction to $BB.
923 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
924
925 // Fill $FBB.
926 unsigned VR2 = RegInfo.createVirtualRegister(RC);
927 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
928 .addReg(Mips::ZERO).addImm(0);
929 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
930
931 // Fill $TBB.
932 unsigned VR1 = RegInfo.createVirtualRegister(RC);
933 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
934 .addReg(Mips::ZERO).addImm(1);
935
936 // Insert phi function to $Sink.
937 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
938 MI->getOperand(0).getReg())
939 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
940
941 MI->eraseFromParent(); // The pseudo instruction is gone now.
942 return Sink;
943}
Daniel Sanders3c380d52013-08-28 12:14:50 +0000944
945MachineBasicBlock * MipsSETargetLowering::
946emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
947 unsigned BranchOp) const{
948 // $bb:
949 // vany_nonzero $rd, $ws
950 // =>
951 // $bb:
952 // bnz.b $ws, $tbb
953 // b $fbb
954 // $fbb:
955 // li $rd1, 0
956 // b $sink
957 // $tbb:
958 // li $rd2, 1
959 // $sink:
960 // $rd = phi($rd1, $fbb, $rd2, $tbb)
961
962 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
963 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
964 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
965 DebugLoc DL = MI->getDebugLoc();
966 const BasicBlock *LLVM_BB = BB->getBasicBlock();
967 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
968 MachineFunction *F = BB->getParent();
969 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
970 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
971 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
972 F->insert(It, FBB);
973 F->insert(It, TBB);
974 F->insert(It, Sink);
975
976 // Transfer the remainder of BB and its successor edges to Sink.
977 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
978 BB->end());
979 Sink->transferSuccessorsAndUpdatePHIs(BB);
980
981 // Add successors.
982 BB->addSuccessor(FBB);
983 BB->addSuccessor(TBB);
984 FBB->addSuccessor(Sink);
985 TBB->addSuccessor(Sink);
986
987 // Insert the real bnz.b instruction to $BB.
988 BuildMI(BB, DL, TII->get(BranchOp))
989 .addReg(MI->getOperand(1).getReg())
990 .addMBB(TBB);
991
992 // Fill $FBB.
993 unsigned RD1 = RegInfo.createVirtualRegister(RC);
994 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
995 .addReg(Mips::ZERO).addImm(0);
996 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
997
998 // Fill $TBB.
999 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1000 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1001 .addReg(Mips::ZERO).addImm(1);
1002
1003 // Insert phi function to $Sink.
1004 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1005 MI->getOperand(0).getReg())
1006 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1007
1008 MI->eraseFromParent(); // The pseudo instruction is gone now.
1009 return Sink;
1010}