blob: 610b8bf38530f5941b284f7bb5d1b4f33d387a6d [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
Akira Hatanaka3e675852013-09-07 00:52:30 +000028static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
29 cl::desc("Expand double precision loads and "
30 "stores to their single precision "
31 "counterparts"));
32
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000033MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
34 : MipsTargetLowering(TM) {
35 // Set up the register classes
Reed Kotlera430cb62013-04-09 19:46:01 +000036
37 clearRegisterClasses();
38
Akira Hatanaka18587862013-08-06 23:08:38 +000039 addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000040
41 if (HasMips64)
Akira Hatanaka18587862013-08-06 23:08:38 +000042 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000043
44 if (Subtarget->hasDSP()) {
45 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
46
47 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
Akira Hatanaka7d635522013-08-14 00:53:38 +000048 addRegisterClass(VecTys[i], &Mips::DSPRRegClass);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000049
50 // Expand all builtin opcodes.
51 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
52 setOperationAction(Opc, VecTys[i], Expand);
53
Akira Hatanaka3d602412013-04-13 00:55:41 +000054 setOperationAction(ISD::ADD, VecTys[i], Legal);
55 setOperationAction(ISD::SUB, VecTys[i], Legal);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000056 setOperationAction(ISD::LOAD, VecTys[i], Legal);
57 setOperationAction(ISD::STORE, VecTys[i], Legal);
58 setOperationAction(ISD::BITCAST, VecTys[i], Legal);
59 }
Akira Hatanaka97a62bf2013-04-19 23:21:32 +000060
Akira Hatanaka5e795092013-08-02 19:23:33 +000061 // Expand all truncating stores and extending loads.
62 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
63 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
64
65 for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
66 for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
67 setTruncStoreAction((MVT::SimpleValueType)VT0,
68 (MVT::SimpleValueType)VT1, Expand);
69
70 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
71 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
72 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
73 }
74
Akira Hatanaka97a62bf2013-04-19 23:21:32 +000075 setTargetDAGCombine(ISD::SHL);
76 setTargetDAGCombine(ISD::SRA);
77 setTargetDAGCombine(ISD::SRL);
Akira Hatanakacd6c5792013-04-30 22:37:26 +000078 setTargetDAGCombine(ISD::SETCC);
79 setTargetDAGCombine(ISD::VSELECT);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000080 }
81
Akira Hatanaka3d602412013-04-13 00:55:41 +000082 if (Subtarget->hasDSPR2())
83 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
84
Jack Carter3f70e902013-08-13 20:54:07 +000085 if (Subtarget->hasMSA()) {
Daniel Sandersddfbd582013-09-11 10:15:48 +000086 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
87 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
88 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
89 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
90 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
91 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
92 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
Daniel Sanders915432c2013-09-23 13:22:24 +000093
94 setTargetDAGCombine(ISD::XOR);
Jack Carter3f70e902013-08-13 20:54:07 +000095 }
96
Reed Kotlerc673f9c2013-08-30 19:40:56 +000097 if (!Subtarget->mipsSEUsesSoftFloat()) {
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000098 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
99
100 // When dealing with single precision only, use libcalls
101 if (!Subtarget->isSingleFloat()) {
Akira Hatanakaad341d42013-08-20 23:38:40 +0000102 if (Subtarget->isFP64bit())
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000103 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
104 else
105 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
106 }
107 }
108
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000109 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
110 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
111 setOperationAction(ISD::MULHS, MVT::i32, Custom);
112 setOperationAction(ISD::MULHU, MVT::i32, Custom);
113
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000114 if (HasMips64) {
115 setOperationAction(ISD::MULHS, MVT::i64, Custom);
116 setOperationAction(ISD::MULHU, MVT::i64, Custom);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000117 setOperationAction(ISD::MUL, MVT::i64, Custom);
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000118 }
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000119
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000120 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
121 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
122
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000123 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
124 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
125 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
126 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000127 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
128 setOperationAction(ISD::LOAD, MVT::i32, Custom);
129 setOperationAction(ISD::STORE, MVT::i32, Custom);
130
Akira Hatanakad593a772013-03-30 01:42:24 +0000131 setTargetDAGCombine(ISD::ADDE);
132 setTargetDAGCombine(ISD::SUBE);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000133 setTargetDAGCombine(ISD::MUL);
Akira Hatanakad593a772013-03-30 01:42:24 +0000134
Daniel Sanders3c380d52013-08-28 12:14:50 +0000135 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000136 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
137 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
138
Akira Hatanaka3e675852013-09-07 00:52:30 +0000139 if (NoDPLoadStore) {
140 setOperationAction(ISD::LOAD, MVT::f64, Custom);
141 setOperationAction(ISD::STORE, MVT::f64, Custom);
142 }
143
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000144 computeRegisterProperties();
145}
146
147const MipsTargetLowering *
148llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
149 return new MipsSETargetLowering(TM);
150}
151
Daniel Sandersda521cc2013-09-23 12:02:46 +0000152// Enable MSA support for the given integer type and Register class.
Daniel Sandersc73488a2013-08-23 10:10:13 +0000153void MipsSETargetLowering::
Daniel Sandersddfbd582013-09-11 10:15:48 +0000154addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
155 addRegisterClass(Ty, RC);
156
157 // Expand all builtin opcodes.
158 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
159 setOperationAction(Opc, Ty, Expand);
160
161 setOperationAction(ISD::BITCAST, Ty, Legal);
162 setOperationAction(ISD::LOAD, Ty, Legal);
163 setOperationAction(ISD::STORE, Ty, Legal);
Daniel Sandersda521cc2013-09-23 12:02:46 +0000164 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom);
Daniel Sandersddfbd582013-09-11 10:15:48 +0000165
Daniel Sanders68831cb2013-09-11 10:28:16 +0000166 setOperationAction(ISD::ADD, Ty, Legal);
Daniel Sanders4e812c12013-09-23 12:57:42 +0000167 setOperationAction(ISD::AND, Ty, Legal);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000168 setOperationAction(ISD::CTLZ, Ty, Legal);
Daniel Sandersa399d692013-09-23 13:40:21 +0000169 setOperationAction(ISD::CTPOP, Ty, Legal);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000170 setOperationAction(ISD::MUL, Ty, Legal);
Daniel Sanders4e812c12013-09-23 12:57:42 +0000171 setOperationAction(ISD::OR, Ty, Legal);
Daniel Sandersece929d2013-09-11 10:38:58 +0000172 setOperationAction(ISD::SDIV, Ty, Legal);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000173 setOperationAction(ISD::SHL, Ty, Legal);
174 setOperationAction(ISD::SRA, Ty, Legal);
175 setOperationAction(ISD::SRL, Ty, Legal);
176 setOperationAction(ISD::SUB, Ty, Legal);
Daniel Sandersece929d2013-09-11 10:38:58 +0000177 setOperationAction(ISD::UDIV, Ty, Legal);
Daniel Sanders4e812c12013-09-23 12:57:42 +0000178 setOperationAction(ISD::XOR, Ty, Legal);
Daniel Sandersddfbd582013-09-11 10:15:48 +0000179}
180
Daniel Sandersda521cc2013-09-23 12:02:46 +0000181// Enable MSA support for the given floating-point type and Register class.
Daniel Sandersddfbd582013-09-11 10:15:48 +0000182void MipsSETargetLowering::
183addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
Daniel Sandersc73488a2013-08-23 10:10:13 +0000184 addRegisterClass(Ty, RC);
Jack Cartere2a93762013-08-15 12:24:57 +0000185
186 // Expand all builtin opcodes.
187 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
188 setOperationAction(Opc, Ty, Expand);
189
190 setOperationAction(ISD::LOAD, Ty, Legal);
191 setOperationAction(ISD::STORE, Ty, Legal);
192 setOperationAction(ISD::BITCAST, Ty, Legal);
Daniel Sanders2ac12822013-09-11 10:51:30 +0000193
194 if (Ty != MVT::v8f16) {
195 setOperationAction(ISD::FADD, Ty, Legal);
196 setOperationAction(ISD::FDIV, Ty, Legal);
197 setOperationAction(ISD::FLOG2, Ty, Legal);
198 setOperationAction(ISD::FMUL, Ty, Legal);
199 setOperationAction(ISD::FRINT, Ty, Legal);
200 setOperationAction(ISD::FSQRT, Ty, Legal);
201 setOperationAction(ISD::FSUB, Ty, Legal);
202 }
Jack Cartere2a93762013-08-15 12:24:57 +0000203}
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000204
205bool
206MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
207 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
208
209 switch (SVT) {
210 case MVT::i64:
211 case MVT::i32:
212 if (Fast)
213 *Fast = true;
214 return true;
215 default:
216 return false;
217 }
218}
219
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000220SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
221 SelectionDAG &DAG) const {
222 switch(Op.getOpcode()) {
Akira Hatanaka3e675852013-09-07 00:52:30 +0000223 case ISD::LOAD: return lowerLOAD(Op, DAG);
224 case ISD::STORE: return lowerSTORE(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000225 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
226 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
227 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
228 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
229 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
230 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
Akira Hatanakab109ea82013-04-22 20:13:37 +0000231 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
232 DAG);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000233 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
234 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000235 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
Daniel Sandersda521cc2013-09-23 12:02:46 +0000236 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000237 }
238
239 return MipsTargetLowering::LowerOperation(Op, DAG);
240}
241
Akira Hatanakad593a772013-03-30 01:42:24 +0000242// selectMADD -
243// Transforms a subgraph in CurDAG if the following pattern is found:
244// (addc multLo, Lo0), (adde multHi, Hi0),
245// where,
246// multHi/Lo: product of multiplication
247// Lo0: initial value of Lo register
248// Hi0: initial value of Hi register
249// Return true if pattern matching was successful.
250static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
251 // ADDENode's second operand must be a flag output of an ADDC node in order
252 // for the matching to be successful.
253 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
254
255 if (ADDCNode->getOpcode() != ISD::ADDC)
256 return false;
257
258 SDValue MultHi = ADDENode->getOperand(0);
259 SDValue MultLo = ADDCNode->getOperand(0);
260 SDNode *MultNode = MultHi.getNode();
261 unsigned MultOpc = MultHi.getOpcode();
262
263 // MultHi and MultLo must be generated by the same node,
264 if (MultLo.getNode() != MultNode)
265 return false;
266
267 // and it must be a multiplication.
268 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
269 return false;
270
271 // MultLo amd MultHi must be the first and second output of MultNode
272 // respectively.
273 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
274 return false;
275
276 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
277 // of the values of MultNode, in which case MultNode will be removed in later
278 // phases.
279 // If there exist users other than ADDENode or ADDCNode, this function returns
280 // here, which will result in MultNode being mapped to a single MULT
281 // instruction node rather than a pair of MULT and MADD instructions being
282 // produced.
283 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
284 return false;
285
Andrew Trickac6d9be2013-05-25 02:42:55 +0000286 SDLoc DL(ADDENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000287
288 // Initialize accumulator.
289 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
290 ADDCNode->getOperand(1),
291 ADDENode->getOperand(1));
292
293 // create MipsMAdd(u) node
294 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
295
296 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
297 MultNode->getOperand(0),// Factor 0
298 MultNode->getOperand(1),// Factor 1
299 ACCIn);
300
301 // replace uses of adde and addc here
302 if (!SDValue(ADDCNode, 0).use_empty()) {
303 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
304 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
305 LoIdx);
306 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
307 }
308 if (!SDValue(ADDENode, 0).use_empty()) {
309 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
310 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
311 HiIdx);
312 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
313 }
314
315 return true;
316}
317
318// selectMSUB -
319// Transforms a subgraph in CurDAG if the following pattern is found:
320// (addc Lo0, multLo), (sube Hi0, multHi),
321// where,
322// multHi/Lo: product of multiplication
323// Lo0: initial value of Lo register
324// Hi0: initial value of Hi register
325// Return true if pattern matching was successful.
326static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
327 // SUBENode's second operand must be a flag output of an SUBC node in order
328 // for the matching to be successful.
329 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
330
331 if (SUBCNode->getOpcode() != ISD::SUBC)
332 return false;
333
334 SDValue MultHi = SUBENode->getOperand(1);
335 SDValue MultLo = SUBCNode->getOperand(1);
336 SDNode *MultNode = MultHi.getNode();
337 unsigned MultOpc = MultHi.getOpcode();
338
339 // MultHi and MultLo must be generated by the same node,
340 if (MultLo.getNode() != MultNode)
341 return false;
342
343 // and it must be a multiplication.
344 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
345 return false;
346
347 // MultLo amd MultHi must be the first and second output of MultNode
348 // respectively.
349 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
350 return false;
351
352 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
353 // of the values of MultNode, in which case MultNode will be removed in later
354 // phases.
355 // If there exist users other than SUBENode or SUBCNode, this function returns
356 // here, which will result in MultNode being mapped to a single MULT
357 // instruction node rather than a pair of MULT and MSUB instructions being
358 // produced.
359 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
360 return false;
361
Andrew Trickac6d9be2013-05-25 02:42:55 +0000362 SDLoc DL(SUBENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000363
364 // Initialize accumulator.
365 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
366 SUBCNode->getOperand(0),
367 SUBENode->getOperand(0));
368
369 // create MipsSub(u) node
370 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
371
372 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
373 MultNode->getOperand(0),// Factor 0
374 MultNode->getOperand(1),// Factor 1
375 ACCIn);
376
377 // replace uses of sube and subc here
378 if (!SDValue(SUBCNode, 0).use_empty()) {
379 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
380 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
381 LoIdx);
382 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
383 }
384 if (!SDValue(SUBENode, 0).use_empty()) {
385 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
386 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
387 HiIdx);
388 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
389 }
390
391 return true;
392}
393
394static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
395 TargetLowering::DAGCombinerInfo &DCI,
396 const MipsSubtarget *Subtarget) {
397 if (DCI.isBeforeLegalize())
398 return SDValue();
399
400 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
401 selectMADD(N, &DAG))
402 return SDValue(N, 0);
403
404 return SDValue();
405}
406
407static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
408 TargetLowering::DAGCombinerInfo &DCI,
409 const MipsSubtarget *Subtarget) {
410 if (DCI.isBeforeLegalize())
411 return SDValue();
412
413 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
414 selectMSUB(N, &DAG))
415 return SDValue(N, 0);
416
417 return SDValue();
418}
419
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000420static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
421 EVT ShiftTy, SelectionDAG &DAG) {
422 // Clear the upper (64 - VT.sizeInBits) bits.
423 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
424
425 // Return 0.
426 if (C == 0)
427 return DAG.getConstant(0, VT);
428
429 // Return x.
430 if (C == 1)
431 return X;
432
433 // If c is power of 2, return (shl x, log2(c)).
434 if (isPowerOf2_64(C))
435 return DAG.getNode(ISD::SHL, DL, VT, X,
436 DAG.getConstant(Log2_64(C), ShiftTy));
437
438 unsigned Log2Ceil = Log2_64_Ceil(C);
439 uint64_t Floor = 1LL << Log2_64(C);
440 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
441
442 // If |c - floor_c| <= |c - ceil_c|,
443 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
444 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
445 if (C - Floor <= Ceil - C) {
446 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
447 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
448 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
449 }
450
451 // If |c - floor_c| > |c - ceil_c|,
452 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
453 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
454 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
455 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
456}
457
458static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
459 const TargetLowering::DAGCombinerInfo &DCI,
460 const MipsSETargetLowering *TL) {
461 EVT VT = N->getValueType(0);
462
463 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
464 if (!VT.isVector())
465 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
466 VT, TL->getScalarShiftAmountTy(VT), DAG);
467
468 return SDValue(N, 0);
469}
470
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000471static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
472 SelectionDAG &DAG,
473 const MipsSubtarget *Subtarget) {
474 // See if this is a vector splat immediate node.
475 APInt SplatValue, SplatUndef;
476 unsigned SplatBitSize;
477 bool HasAnyUndefs;
478 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
479 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
480
Akira Hatanakad5972632013-04-22 19:58:23 +0000481 if (!BV ||
Akira Hatanakab109ea82013-04-22 20:13:37 +0000482 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
Akira Hatanakae311b002013-04-23 18:09:42 +0000483 EltSize, !Subtarget->isLittle()) ||
Akira Hatanakad5972632013-04-22 19:58:23 +0000484 (SplatBitSize != EltSize) ||
Akira Hatanakae311b002013-04-23 18:09:42 +0000485 (SplatValue.getZExtValue() >= EltSize))
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000486 return SDValue();
487
Andrew Trickac6d9be2013-05-25 02:42:55 +0000488 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000489 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
490}
491
492static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
493 TargetLowering::DAGCombinerInfo &DCI,
494 const MipsSubtarget *Subtarget) {
495 EVT Ty = N->getValueType(0);
496
497 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
498 return SDValue();
499
500 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
501}
502
503static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
504 TargetLowering::DAGCombinerInfo &DCI,
505 const MipsSubtarget *Subtarget) {
506 EVT Ty = N->getValueType(0);
507
508 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
509 return SDValue();
510
511 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
512}
513
514
515static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
516 TargetLowering::DAGCombinerInfo &DCI,
517 const MipsSubtarget *Subtarget) {
518 EVT Ty = N->getValueType(0);
519
520 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
521 return SDValue();
522
523 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
524}
525
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000526static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
527 bool IsV216 = (Ty == MVT::v2i16);
528
529 switch (CC) {
530 case ISD::SETEQ:
531 case ISD::SETNE: return true;
532 case ISD::SETLT:
533 case ISD::SETLE:
534 case ISD::SETGT:
535 case ISD::SETGE: return IsV216;
536 case ISD::SETULT:
537 case ISD::SETULE:
538 case ISD::SETUGT:
539 case ISD::SETUGE: return !IsV216;
540 default: return false;
541 }
542}
543
544static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
545 EVT Ty = N->getValueType(0);
546
547 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
548 return SDValue();
549
550 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
551 return SDValue();
552
Andrew Trickac6d9be2013-05-25 02:42:55 +0000553 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000554 N->getOperand(1), N->getOperand(2));
555}
556
557static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
558 EVT Ty = N->getValueType(0);
559
560 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
561 return SDValue();
562
563 SDValue SetCC = N->getOperand(0);
564
565 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
566 return SDValue();
567
Andrew Trickac6d9be2013-05-25 02:42:55 +0000568 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000569 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
570 N->getOperand(2), SetCC.getOperand(2));
571}
572
Daniel Sanders915432c2013-09-23 13:22:24 +0000573static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
574 const MipsSubtarget *Subtarget) {
575 EVT Ty = N->getValueType(0);
576
577 if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
578 // Try the following combines:
579 // (xor (or $a, $b), (build_vector allones))
580 // (xor (or $a, $b), (bitcast (build_vector allones)))
581 SDValue Op0 = N->getOperand(0);
582 SDValue Op1 = N->getOperand(1);
583 SDValue NotOp;
584 ConstantSDNode *Const;
585
586 if (ISD::isBuildVectorAllOnes(Op0.getNode()))
587 NotOp = Op1;
588 else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
589 NotOp = Op0;
590 else if ((Op0->getOpcode() == MipsISD::VSPLAT ||
591 Op0->getOpcode() == MipsISD::VSPLATD) &&
592 (Const = dyn_cast<ConstantSDNode>(Op0->getOperand(0))) &&
593 Const->isAllOnesValue())
594 NotOp = Op1;
595 else if ((Op1->getOpcode() == MipsISD::VSPLAT ||
596 Op1->getOpcode() == MipsISD::VSPLATD) &&
597 (Const = dyn_cast<ConstantSDNode>(Op1->getOperand(0))) &&
598 Const->isAllOnesValue())
599 NotOp = Op0;
600 else
601 return SDValue();
602
603 if (NotOp->getOpcode() == ISD::OR)
604 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
605 NotOp->getOperand(1));
606 }
607
608 return SDValue();
609}
610
Akira Hatanakad593a772013-03-30 01:42:24 +0000611SDValue
612MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
613 SelectionDAG &DAG = DCI.DAG;
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000614 SDValue Val;
Akira Hatanakad593a772013-03-30 01:42:24 +0000615
616 switch (N->getOpcode()) {
617 case ISD::ADDE:
618 return performADDECombine(N, DAG, DCI, Subtarget);
619 case ISD::SUBE:
620 return performSUBECombine(N, DAG, DCI, Subtarget);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000621 case ISD::MUL:
622 return performMULCombine(N, DAG, DCI, this);
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000623 case ISD::SHL:
624 return performSHLCombine(N, DAG, DCI, Subtarget);
625 case ISD::SRA:
626 return performSRACombine(N, DAG, DCI, Subtarget);
627 case ISD::SRL:
628 return performSRLCombine(N, DAG, DCI, Subtarget);
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000629 case ISD::VSELECT:
630 return performVSELECTCombine(N, DAG);
Daniel Sanders915432c2013-09-23 13:22:24 +0000631 case ISD::XOR:
632 Val = performXORCombine(N, DAG, Subtarget);
633 break;
634 case ISD::SETCC:
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000635 Val = performSETCCCombine(N, DAG);
636 break;
Akira Hatanakad593a772013-03-30 01:42:24 +0000637 }
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000638
639 if (Val.getNode())
640 return Val;
641
642 return MipsTargetLowering::PerformDAGCombine(N, DCI);
Akira Hatanakad593a772013-03-30 01:42:24 +0000643}
644
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000645MachineBasicBlock *
646MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
647 MachineBasicBlock *BB) const {
648 switch (MI->getOpcode()) {
649 default:
650 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
651 case Mips::BPOSGE32_PSEUDO:
652 return emitBPOSGE32(MI, BB);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000653 case Mips::SNZ_B_PSEUDO:
654 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
655 case Mips::SNZ_H_PSEUDO:
656 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
657 case Mips::SNZ_W_PSEUDO:
658 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
659 case Mips::SNZ_D_PSEUDO:
660 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
661 case Mips::SNZ_V_PSEUDO:
662 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
663 case Mips::SZ_B_PSEUDO:
664 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
665 case Mips::SZ_H_PSEUDO:
666 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
667 case Mips::SZ_W_PSEUDO:
668 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
669 case Mips::SZ_D_PSEUDO:
670 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
671 case Mips::SZ_V_PSEUDO:
672 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000673 }
674}
675
676bool MipsSETargetLowering::
677isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
678 unsigned NextStackOffset,
679 const MipsFunctionInfo& FI) const {
680 if (!EnableMipsTailCalls)
681 return false;
682
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000683 // Return false if either the callee or caller has a byval argument.
684 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
685 return false;
686
687 // Return true if the callee's argument area is no larger than the
688 // caller's.
689 return NextStackOffset <= FI.getIncomingArgSize();
690}
691
692void MipsSETargetLowering::
693getOpndList(SmallVectorImpl<SDValue> &Ops,
694 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
695 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
696 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
697 // T9 should contain the address of the callee function if
698 // -reloction-model=pic or it is an indirect call.
699 if (IsPICCall || !GlobalOrExternal) {
700 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
701 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
702 } else
703 Ops.push_back(Callee);
704
705 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
706 InternalLinkage, CLI, Callee, Chain);
707}
708
Akira Hatanaka3e675852013-09-07 00:52:30 +0000709SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
710 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
711
712 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
713 return MipsTargetLowering::lowerLOAD(Op, DAG);
714
715 // Replace a double precision load with two i32 loads and a buildpair64.
716 SDLoc DL(Op);
717 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
718 EVT PtrVT = Ptr.getValueType();
719
720 // i32 load from lower address.
721 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
722 MachinePointerInfo(), Nd.isVolatile(),
723 Nd.isNonTemporal(), Nd.isInvariant(),
724 Nd.getAlignment());
725
726 // i32 load from higher address.
727 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
728 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
729 MachinePointerInfo(), Nd.isVolatile(),
730 Nd.isNonTemporal(), Nd.isInvariant(),
Akira Hatanaka2dd3afc2013-09-09 17:59:32 +0000731 std::min(Nd.getAlignment(), 4U));
Akira Hatanaka3e675852013-09-07 00:52:30 +0000732
733 if (!Subtarget->isLittle())
734 std::swap(Lo, Hi);
735
736 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
737 SDValue Ops[2] = {BP, Hi.getValue(1)};
738 return DAG.getMergeValues(Ops, 2, DL);
739}
740
741SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
742 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
743
744 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
745 return MipsTargetLowering::lowerSTORE(Op, DAG);
746
747 // Replace a double precision store with two extractelement64s and i32 stores.
748 SDLoc DL(Op);
749 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
750 EVT PtrVT = Ptr.getValueType();
751 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
752 Val, DAG.getConstant(0, MVT::i32));
753 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
754 Val, DAG.getConstant(1, MVT::i32));
755
756 if (!Subtarget->isLittle())
757 std::swap(Lo, Hi);
758
759 // i32 store to lower address.
760 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
761 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
762 Nd.getTBAAInfo());
763
764 // i32 store to higher address.
765 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
766 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
Akira Hatanaka2dd3afc2013-09-09 17:59:32 +0000767 Nd.isVolatile(), Nd.isNonTemporal(),
768 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
Akira Hatanaka3e675852013-09-07 00:52:30 +0000769}
770
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000771SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
772 bool HasLo, bool HasHi,
773 SelectionDAG &DAG) const {
774 EVT Ty = Op.getOperand(0).getValueType();
Andrew Trickac6d9be2013-05-25 02:42:55 +0000775 SDLoc DL(Op);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000776 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
777 Op.getOperand(0), Op.getOperand(1));
778 SDValue Lo, Hi;
779
780 if (HasLo)
781 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
782 DAG.getConstant(Mips::sub_lo, MVT::i32));
783 if (HasHi)
784 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
785 DAG.getConstant(Mips::sub_hi, MVT::i32));
786
787 if (!HasLo || !HasHi)
788 return HasLo ? Lo : Hi;
789
790 SDValue Vals[] = { Lo, Hi };
791 return DAG.getMergeValues(Vals, 2, DL);
792}
793
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000794
Andrew Trickac6d9be2013-05-25 02:42:55 +0000795static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000796 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
797 DAG.getConstant(0, MVT::i32));
798 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
799 DAG.getConstant(1, MVT::i32));
800 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
801}
802
Andrew Trickac6d9be2013-05-25 02:42:55 +0000803static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000804 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
805 DAG.getConstant(Mips::sub_lo, MVT::i32));
806 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
807 DAG.getConstant(Mips::sub_hi, MVT::i32));
808 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
809}
810
811// This function expands mips intrinsic nodes which have 64-bit input operands
812// or output values.
813//
814// out64 = intrinsic-node in64
815// =>
816// lo = copy (extract-element (in64, 0))
817// hi = copy (extract-element (in64, 1))
818// mips-specific-node
819// v0 = copy lo
820// v1 = copy hi
821// out64 = merge-values (v0, v1)
822//
823static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
Andrew Trickac6d9be2013-05-25 02:42:55 +0000824 SDLoc DL(Op);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000825 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
826 SmallVector<SDValue, 3> Ops;
827 unsigned OpNo = 0;
828
829 // See if Op has a chain input.
830 if (HasChainIn)
831 Ops.push_back(Op->getOperand(OpNo++));
832
833 // The next operand is the intrinsic opcode.
834 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
835
836 // See if the next operand has type i64.
837 SDValue Opnd = Op->getOperand(++OpNo), In64;
838
839 if (Opnd.getValueType() == MVT::i64)
840 In64 = initAccumulator(Opnd, DL, DAG);
841 else
842 Ops.push_back(Opnd);
843
844 // Push the remaining operands.
845 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
846 Ops.push_back(Op->getOperand(OpNo));
847
848 // Add In64 to the end of the list.
849 if (In64.getNode())
850 Ops.push_back(In64);
851
852 // Scan output.
853 SmallVector<EVT, 2> ResTys;
854
855 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
856 I != E; ++I)
857 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
858
859 // Create node.
860 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
861 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
862
863 if (!HasChainIn)
864 return Out;
865
866 assert(Val->getValueType(1) == MVT::Other);
867 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
868 return DAG.getMergeValues(Vals, 2, DL);
869}
870
Daniel Sanders68831cb2013-09-11 10:28:16 +0000871static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
872 SDLoc DL(Op);
873 SDValue LHS = Op->getOperand(1);
874 SDValue RHS = Op->getOperand(2);
875 EVT ResTy = Op->getValueType(0);
876
877 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS);
878
879 return Result;
880}
881
Daniel Sanders3c380d52013-08-28 12:14:50 +0000882static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
883 SDLoc DL(Op);
884 SDValue Value = Op->getOperand(1);
885 EVT ResTy = Op->getValueType(0);
886
887 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
888
889 return Result;
890}
891
Daniel Sanders2ac12822013-09-11 10:51:30 +0000892static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
893 SDLoc DL(Op);
894 SDValue Value = Op->getOperand(1);
895 EVT ResTy = Op->getValueType(0);
896
897 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
898
899 return Result;
900}
901
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000902SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
903 SelectionDAG &DAG) const {
904 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
905 default:
906 return SDValue();
907 case Intrinsic::mips_shilo:
908 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
909 case Intrinsic::mips_dpau_h_qbl:
910 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
911 case Intrinsic::mips_dpau_h_qbr:
912 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
913 case Intrinsic::mips_dpsu_h_qbl:
914 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
915 case Intrinsic::mips_dpsu_h_qbr:
916 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
917 case Intrinsic::mips_dpa_w_ph:
918 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
919 case Intrinsic::mips_dps_w_ph:
920 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
921 case Intrinsic::mips_dpax_w_ph:
922 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
923 case Intrinsic::mips_dpsx_w_ph:
924 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
925 case Intrinsic::mips_mulsa_w_ph:
926 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
927 case Intrinsic::mips_mult:
928 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
929 case Intrinsic::mips_multu:
930 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
931 case Intrinsic::mips_madd:
932 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
933 case Intrinsic::mips_maddu:
934 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
935 case Intrinsic::mips_msub:
936 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
937 case Intrinsic::mips_msubu:
938 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
Daniel Sanders68831cb2013-09-11 10:28:16 +0000939 case Intrinsic::mips_addv_b:
940 case Intrinsic::mips_addv_h:
941 case Intrinsic::mips_addv_w:
942 case Intrinsic::mips_addv_d:
943 return lowerMSABinaryIntr(Op, DAG, ISD::ADD);
Daniel Sanders4e812c12013-09-23 12:57:42 +0000944 case Intrinsic::mips_and_v:
945 return lowerMSABinaryIntr(Op, DAG, ISD::AND);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000946 case Intrinsic::mips_bnz_b:
947 case Intrinsic::mips_bnz_h:
948 case Intrinsic::mips_bnz_w:
949 case Intrinsic::mips_bnz_d:
950 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
951 case Intrinsic::mips_bnz_v:
952 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
953 case Intrinsic::mips_bz_b:
954 case Intrinsic::mips_bz_h:
955 case Intrinsic::mips_bz_w:
956 case Intrinsic::mips_bz_d:
957 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
958 case Intrinsic::mips_bz_v:
959 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
Daniel Sandersece929d2013-09-11 10:38:58 +0000960 case Intrinsic::mips_div_s_b:
961 case Intrinsic::mips_div_s_h:
962 case Intrinsic::mips_div_s_w:
963 case Intrinsic::mips_div_s_d:
964 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV);
965 case Intrinsic::mips_div_u_b:
966 case Intrinsic::mips_div_u_h:
967 case Intrinsic::mips_div_u_w:
968 case Intrinsic::mips_div_u_d:
969 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV);
Daniel Sanders2ac12822013-09-11 10:51:30 +0000970 case Intrinsic::mips_fadd_w:
971 case Intrinsic::mips_fadd_d:
972 return lowerMSABinaryIntr(Op, DAG, ISD::FADD);
973 case Intrinsic::mips_fdiv_w:
974 case Intrinsic::mips_fdiv_d:
975 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV);
Daniel Sandersda521cc2013-09-23 12:02:46 +0000976 case Intrinsic::mips_fill_b:
977 case Intrinsic::mips_fill_h:
978 case Intrinsic::mips_fill_w:
979 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
Daniel Sanders2ac12822013-09-11 10:51:30 +0000980 case Intrinsic::mips_flog2_w:
981 case Intrinsic::mips_flog2_d:
982 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2);
983 case Intrinsic::mips_fmul_w:
984 case Intrinsic::mips_fmul_d:
985 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL);
986 case Intrinsic::mips_frint_w:
987 case Intrinsic::mips_frint_d:
988 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT);
989 case Intrinsic::mips_fsqrt_w:
990 case Intrinsic::mips_fsqrt_d:
991 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT);
992 case Intrinsic::mips_fsub_w:
993 case Intrinsic::mips_fsub_d:
994 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB);
Daniel Sandersda521cc2013-09-23 12:02:46 +0000995 case Intrinsic::mips_ldi_b:
996 case Intrinsic::mips_ldi_h:
997 case Intrinsic::mips_ldi_w:
998 case Intrinsic::mips_ldi_d:
999 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +00001000 case Intrinsic::mips_mulv_b:
1001 case Intrinsic::mips_mulv_h:
1002 case Intrinsic::mips_mulv_w:
1003 case Intrinsic::mips_mulv_d:
1004 return lowerMSABinaryIntr(Op, DAG, ISD::MUL);
1005 case Intrinsic::mips_nlzc_b:
1006 case Intrinsic::mips_nlzc_h:
1007 case Intrinsic::mips_nlzc_w:
1008 case Intrinsic::mips_nlzc_d:
1009 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ);
Daniel Sanders915432c2013-09-23 13:22:24 +00001010 case Intrinsic::mips_nor_v: {
1011 SDValue Res = lowerMSABinaryIntr(Op, DAG, ISD::OR);
1012 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0));
1013 }
Daniel Sanders4e812c12013-09-23 12:57:42 +00001014 case Intrinsic::mips_or_v:
1015 return lowerMSABinaryIntr(Op, DAG, ISD::OR);
Daniel Sandersa399d692013-09-23 13:40:21 +00001016 case Intrinsic::mips_pcnt_b:
1017 case Intrinsic::mips_pcnt_h:
1018 case Intrinsic::mips_pcnt_w:
1019 case Intrinsic::mips_pcnt_d:
1020 return lowerMSAUnaryIntr(Op, DAG, ISD::CTPOP);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +00001021 case Intrinsic::mips_sll_b:
1022 case Intrinsic::mips_sll_h:
1023 case Intrinsic::mips_sll_w:
1024 case Intrinsic::mips_sll_d:
1025 return lowerMSABinaryIntr(Op, DAG, ISD::SHL);
1026 case Intrinsic::mips_sra_b:
1027 case Intrinsic::mips_sra_h:
1028 case Intrinsic::mips_sra_w:
1029 case Intrinsic::mips_sra_d:
1030 return lowerMSABinaryIntr(Op, DAG, ISD::SRA);
1031 case Intrinsic::mips_srl_b:
1032 case Intrinsic::mips_srl_h:
1033 case Intrinsic::mips_srl_w:
1034 case Intrinsic::mips_srl_d:
1035 return lowerMSABinaryIntr(Op, DAG, ISD::SRL);
1036 case Intrinsic::mips_subv_b:
1037 case Intrinsic::mips_subv_h:
1038 case Intrinsic::mips_subv_w:
1039 case Intrinsic::mips_subv_d:
1040 return lowerMSABinaryIntr(Op, DAG, ISD::SUB);
Daniel Sanders4e812c12013-09-23 12:57:42 +00001041 case Intrinsic::mips_xor_v:
1042 return lowerMSABinaryIntr(Op, DAG, ISD::XOR);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +00001043 }
1044}
1045
Daniel Sanders2fd3e672013-08-28 12:04:29 +00001046static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1047 SDLoc DL(Op);
1048 SDValue ChainIn = Op->getOperand(0);
1049 SDValue Address = Op->getOperand(2);
1050 SDValue Offset = Op->getOperand(3);
1051 EVT ResTy = Op->getValueType(0);
1052 EVT PtrTy = Address->getValueType(0);
1053
1054 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1055
1056 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
1057 false, false, 16);
1058}
1059
Akira Hatanaka4e0980a2013-04-13 02:13:30 +00001060SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
1061 SelectionDAG &DAG) const {
Daniel Sanders2fd3e672013-08-28 12:04:29 +00001062 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1063 switch (Intr) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +00001064 default:
1065 return SDValue();
1066 case Intrinsic::mips_extp:
1067 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
1068 case Intrinsic::mips_extpdp:
1069 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
1070 case Intrinsic::mips_extr_w:
1071 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
1072 case Intrinsic::mips_extr_r_w:
1073 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
1074 case Intrinsic::mips_extr_rs_w:
1075 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
1076 case Intrinsic::mips_extr_s_h:
1077 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
1078 case Intrinsic::mips_mthlip:
1079 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
1080 case Intrinsic::mips_mulsaq_s_w_ph:
1081 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
1082 case Intrinsic::mips_maq_s_w_phl:
1083 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
1084 case Intrinsic::mips_maq_s_w_phr:
1085 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
1086 case Intrinsic::mips_maq_sa_w_phl:
1087 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
1088 case Intrinsic::mips_maq_sa_w_phr:
1089 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
1090 case Intrinsic::mips_dpaq_s_w_ph:
1091 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
1092 case Intrinsic::mips_dpsq_s_w_ph:
1093 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
1094 case Intrinsic::mips_dpaq_sa_l_w:
1095 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
1096 case Intrinsic::mips_dpsq_sa_l_w:
1097 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
1098 case Intrinsic::mips_dpaqx_s_w_ph:
1099 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
1100 case Intrinsic::mips_dpaqx_sa_w_ph:
1101 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
1102 case Intrinsic::mips_dpsqx_s_w_ph:
1103 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
1104 case Intrinsic::mips_dpsqx_sa_w_ph:
1105 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
Daniel Sanders2fd3e672013-08-28 12:04:29 +00001106 case Intrinsic::mips_ld_b:
1107 case Intrinsic::mips_ld_h:
1108 case Intrinsic::mips_ld_w:
1109 case Intrinsic::mips_ld_d:
1110 case Intrinsic::mips_ldx_b:
1111 case Intrinsic::mips_ldx_h:
1112 case Intrinsic::mips_ldx_w:
1113 case Intrinsic::mips_ldx_d:
1114 return lowerMSALoadIntr(Op, DAG, Intr);
1115 }
1116}
1117
1118static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1119 SDLoc DL(Op);
1120 SDValue ChainIn = Op->getOperand(0);
1121 SDValue Value = Op->getOperand(2);
1122 SDValue Address = Op->getOperand(3);
1123 SDValue Offset = Op->getOperand(4);
1124 EVT PtrTy = Address->getValueType(0);
1125
1126 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1127
1128 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
1129 false, 16);
1130}
1131
1132SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
1133 SelectionDAG &DAG) const {
1134 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1135 switch (Intr) {
1136 default:
1137 return SDValue();
1138 case Intrinsic::mips_st_b:
1139 case Intrinsic::mips_st_h:
1140 case Intrinsic::mips_st_w:
1141 case Intrinsic::mips_st_d:
1142 case Intrinsic::mips_stx_b:
1143 case Intrinsic::mips_stx_h:
1144 case Intrinsic::mips_stx_w:
1145 case Intrinsic::mips_stx_d:
Daniel Sanders3c380d52013-08-28 12:14:50 +00001146 return lowerMSAStoreIntr(Op, DAG, Intr);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +00001147 }
1148}
1149
Daniel Sandersda521cc2013-09-23 12:02:46 +00001150/// \brief Check if the given BuildVectorSDNode is a splat.
1151/// This method currently relies on DAG nodes being reused when equivalent,
1152/// so it's possible for this to return false even when isConstantSplat returns
1153/// true.
1154static bool isSplatVector(const BuildVectorSDNode *N) {
Daniel Sandersda521cc2013-09-23 12:02:46 +00001155 unsigned int nOps = N->getNumOperands();
1156 assert(nOps > 1 && "isSplat has 0 or 1 sized build vector");
1157
1158 SDValue Operand0 = N->getOperand(0);
1159
1160 for (unsigned int i = 1; i < nOps; ++i) {
1161 if (N->getOperand(i) != Operand0)
1162 return false;
1163 }
1164
1165 return true;
1166}
1167
1168// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
1169// backend.
1170//
1171// Lowers according to the following rules:
1172// - Vectors of 128-bits may be legal subject to the other rules. Other sizes
1173// are not legal.
1174// - Non-constant splats are legal and are lowered to MipsISD::VSPLAT.
1175// - Constant splats with an element size of 32-bits or less are legal and are
1176// lowered to MipsISD::VSPLAT.
1177// - Constant splats with an element size of 64-bits but whose value would fit
1178// within a 10 bit immediate are legal and are lowered to MipsISD::VSPLATD.
1179// - All other ISD::BUILD_VECTORS are not legal
1180SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
1181 SelectionDAG &DAG) const {
1182 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
1183 EVT ResTy = Op->getValueType(0);
1184 SDLoc DL(Op);
1185 APInt SplatValue, SplatUndef;
1186 unsigned SplatBitSize;
1187 bool HasAnyUndefs;
1188
1189 if (!Subtarget->hasMSA() || !ResTy.is128BitVector())
1190 return SDValue();
1191
1192 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1193 HasAnyUndefs, 8,
1194 !Subtarget->isLittle())) {
1195 SDValue Result;
1196 EVT TmpVecTy;
1197 EVT ConstTy = MVT::i32;
1198 unsigned SplatOp = MipsISD::VSPLAT;
1199
1200 switch (SplatBitSize) {
1201 default:
1202 return SDValue();
1203 case 64:
1204 TmpVecTy = MVT::v2i64;
1205
1206 // i64 is an illegal type on Mips32, but if it the constant fits into a
1207 // signed 10-bit value then we can still handle it using VSPLATD and an
1208 // i32 constant
1209 if (HasMips64)
1210 ConstTy = MVT::i64;
1211 else if (isInt<10>(SplatValue.getSExtValue())) {
1212 SplatValue = SplatValue.trunc(32);
1213 SplatOp = MipsISD::VSPLATD;
1214 } else
1215 return SDValue();
1216 break;
1217 case 32:
1218 TmpVecTy = MVT::v4i32;
1219 break;
1220 case 16:
1221 TmpVecTy = MVT::v8i16;
1222 SplatValue = SplatValue.sext(32);
1223 break;
1224 case 8:
1225 TmpVecTy = MVT::v16i8;
1226 SplatValue = SplatValue.sext(32);
1227 break;
1228 }
1229
1230 Result = DAG.getNode(SplatOp, DL, TmpVecTy,
1231 DAG.getConstant(SplatValue, ConstTy));
1232 if (ResTy != Result.getValueType())
1233 Result = DAG.getNode(ISD::BITCAST, DL, ResTy, Result);
1234
1235 return Result;
1236 }
1237 else if (isSplatVector(Node))
1238 return DAG.getNode(MipsISD::VSPLAT, DL, ResTy, Op->getOperand(0));
1239
1240 return SDValue();
1241}
1242
Akira Hatanaka5ac065a2013-03-13 00:54:29 +00001243MachineBasicBlock * MipsSETargetLowering::
1244emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
1245 // $bb:
1246 // bposge32_pseudo $vr0
1247 // =>
1248 // $bb:
1249 // bposge32 $tbb
1250 // $fbb:
1251 // li $vr2, 0
1252 // b $sink
1253 // $tbb:
1254 // li $vr1, 1
1255 // $sink:
1256 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
1257
1258 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1259 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
Akira Hatanaka18587862013-08-06 23:08:38 +00001260 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
Akira Hatanaka5ac065a2013-03-13 00:54:29 +00001261 DebugLoc DL = MI->getDebugLoc();
1262 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1263 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1264 MachineFunction *F = BB->getParent();
1265 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1266 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1267 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1268 F->insert(It, FBB);
1269 F->insert(It, TBB);
1270 F->insert(It, Sink);
1271
1272 // Transfer the remainder of BB and its successor edges to Sink.
1273 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1274 BB->end());
1275 Sink->transferSuccessorsAndUpdatePHIs(BB);
1276
1277 // Add successors.
1278 BB->addSuccessor(FBB);
1279 BB->addSuccessor(TBB);
1280 FBB->addSuccessor(Sink);
1281 TBB->addSuccessor(Sink);
1282
1283 // Insert the real bposge32 instruction to $BB.
1284 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
1285
1286 // Fill $FBB.
1287 unsigned VR2 = RegInfo.createVirtualRegister(RC);
1288 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
1289 .addReg(Mips::ZERO).addImm(0);
1290 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1291
1292 // Fill $TBB.
1293 unsigned VR1 = RegInfo.createVirtualRegister(RC);
1294 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
1295 .addReg(Mips::ZERO).addImm(1);
1296
1297 // Insert phi function to $Sink.
1298 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1299 MI->getOperand(0).getReg())
1300 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
1301
1302 MI->eraseFromParent(); // The pseudo instruction is gone now.
1303 return Sink;
1304}
Daniel Sanders3c380d52013-08-28 12:14:50 +00001305
1306MachineBasicBlock * MipsSETargetLowering::
1307emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
1308 unsigned BranchOp) const{
1309 // $bb:
1310 // vany_nonzero $rd, $ws
1311 // =>
1312 // $bb:
1313 // bnz.b $ws, $tbb
1314 // b $fbb
1315 // $fbb:
1316 // li $rd1, 0
1317 // b $sink
1318 // $tbb:
1319 // li $rd2, 1
1320 // $sink:
1321 // $rd = phi($rd1, $fbb, $rd2, $tbb)
1322
1323 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1324 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1325 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1326 DebugLoc DL = MI->getDebugLoc();
1327 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1328 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1329 MachineFunction *F = BB->getParent();
1330 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1331 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1332 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1333 F->insert(It, FBB);
1334 F->insert(It, TBB);
1335 F->insert(It, Sink);
1336
1337 // Transfer the remainder of BB and its successor edges to Sink.
1338 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1339 BB->end());
1340 Sink->transferSuccessorsAndUpdatePHIs(BB);
1341
1342 // Add successors.
1343 BB->addSuccessor(FBB);
1344 BB->addSuccessor(TBB);
1345 FBB->addSuccessor(Sink);
1346 TBB->addSuccessor(Sink);
1347
1348 // Insert the real bnz.b instruction to $BB.
1349 BuildMI(BB, DL, TII->get(BranchOp))
1350 .addReg(MI->getOperand(1).getReg())
1351 .addMBB(TBB);
1352
1353 // Fill $FBB.
1354 unsigned RD1 = RegInfo.createVirtualRegister(RC);
1355 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
1356 .addReg(Mips::ZERO).addImm(0);
1357 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1358
1359 // Fill $TBB.
1360 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1361 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1362 .addReg(Mips::ZERO).addImm(1);
1363
1364 // Insert phi function to $Sink.
1365 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1366 MI->getOperand(0).getReg())
1367 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1368
1369 MI->eraseFromParent(); // The pseudo instruction is gone now.
1370 return Sink;
1371}