blob: 879df6d12990de93737d32777200d0eebb0b3920 [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);
Jack Carter3f70e902013-08-13 20:54:07 +000093 }
94
Reed Kotlerc673f9c2013-08-30 19:40:56 +000095 if (!Subtarget->mipsSEUsesSoftFloat()) {
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000096 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
97
98 // When dealing with single precision only, use libcalls
99 if (!Subtarget->isSingleFloat()) {
Akira Hatanakaad341d42013-08-20 23:38:40 +0000100 if (Subtarget->isFP64bit())
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000101 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
102 else
103 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
104 }
105 }
106
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000107 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
108 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
109 setOperationAction(ISD::MULHS, MVT::i32, Custom);
110 setOperationAction(ISD::MULHU, MVT::i32, Custom);
111
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000112 if (HasMips64) {
113 setOperationAction(ISD::MULHS, MVT::i64, Custom);
114 setOperationAction(ISD::MULHU, MVT::i64, Custom);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000115 setOperationAction(ISD::MUL, MVT::i64, Custom);
Akira Hatanakafc82e4d2013-04-11 19:29:26 +0000116 }
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000117
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000118 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
119 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
120
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000121 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
122 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
123 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
124 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000125 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
126 setOperationAction(ISD::LOAD, MVT::i32, Custom);
127 setOperationAction(ISD::STORE, MVT::i32, Custom);
128
Akira Hatanakad593a772013-03-30 01:42:24 +0000129 setTargetDAGCombine(ISD::ADDE);
130 setTargetDAGCombine(ISD::SUBE);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000131 setTargetDAGCombine(ISD::MUL);
Akira Hatanakad593a772013-03-30 01:42:24 +0000132
Daniel Sanders3c380d52013-08-28 12:14:50 +0000133 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000134 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
135 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
136
Akira Hatanaka3e675852013-09-07 00:52:30 +0000137 if (NoDPLoadStore) {
138 setOperationAction(ISD::LOAD, MVT::f64, Custom);
139 setOperationAction(ISD::STORE, MVT::f64, Custom);
140 }
141
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000142 computeRegisterProperties();
143}
144
145const MipsTargetLowering *
146llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
147 return new MipsSETargetLowering(TM);
148}
149
Daniel Sandersc73488a2013-08-23 10:10:13 +0000150void MipsSETargetLowering::
Daniel Sandersddfbd582013-09-11 10:15:48 +0000151addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
152 addRegisterClass(Ty, RC);
153
154 // Expand all builtin opcodes.
155 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
156 setOperationAction(Opc, Ty, Expand);
157
158 setOperationAction(ISD::BITCAST, Ty, Legal);
159 setOperationAction(ISD::LOAD, Ty, Legal);
160 setOperationAction(ISD::STORE, Ty, Legal);
161
Daniel Sanders68831cb2013-09-11 10:28:16 +0000162 setOperationAction(ISD::ADD, Ty, Legal);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000163 setOperationAction(ISD::CTLZ, Ty, Legal);
164 setOperationAction(ISD::MUL, Ty, Legal);
Daniel Sandersece929d2013-09-11 10:38:58 +0000165 setOperationAction(ISD::SDIV, Ty, Legal);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000166 setOperationAction(ISD::SHL, Ty, Legal);
167 setOperationAction(ISD::SRA, Ty, Legal);
168 setOperationAction(ISD::SRL, Ty, Legal);
169 setOperationAction(ISD::SUB, Ty, Legal);
Daniel Sandersece929d2013-09-11 10:38:58 +0000170 setOperationAction(ISD::UDIV, Ty, Legal);
Daniel Sandersddfbd582013-09-11 10:15:48 +0000171}
172
173void MipsSETargetLowering::
174addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
Daniel Sandersc73488a2013-08-23 10:10:13 +0000175 addRegisterClass(Ty, RC);
Jack Cartere2a93762013-08-15 12:24:57 +0000176
177 // Expand all builtin opcodes.
178 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
179 setOperationAction(Opc, Ty, Expand);
180
181 setOperationAction(ISD::LOAD, Ty, Legal);
182 setOperationAction(ISD::STORE, Ty, Legal);
183 setOperationAction(ISD::BITCAST, Ty, Legal);
Daniel Sanders2ac12822013-09-11 10:51:30 +0000184
185 if (Ty != MVT::v8f16) {
186 setOperationAction(ISD::FADD, Ty, Legal);
187 setOperationAction(ISD::FDIV, Ty, Legal);
188 setOperationAction(ISD::FLOG2, Ty, Legal);
189 setOperationAction(ISD::FMUL, Ty, Legal);
190 setOperationAction(ISD::FRINT, Ty, Legal);
191 setOperationAction(ISD::FSQRT, Ty, Legal);
192 setOperationAction(ISD::FSUB, Ty, Legal);
193 }
Jack Cartere2a93762013-08-15 12:24:57 +0000194}
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000195
196bool
197MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
198 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
199
200 switch (SVT) {
201 case MVT::i64:
202 case MVT::i32:
203 if (Fast)
204 *Fast = true;
205 return true;
206 default:
207 return false;
208 }
209}
210
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000211SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
212 SelectionDAG &DAG) const {
213 switch(Op.getOpcode()) {
Akira Hatanaka3e675852013-09-07 00:52:30 +0000214 case ISD::LOAD: return lowerLOAD(Op, DAG);
215 case ISD::STORE: return lowerSTORE(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000216 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
217 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
218 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
219 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
220 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
221 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
Akira Hatanakab109ea82013-04-22 20:13:37 +0000222 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
223 DAG);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000224 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
225 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000226 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000227 }
228
229 return MipsTargetLowering::LowerOperation(Op, DAG);
230}
231
Akira Hatanakad593a772013-03-30 01:42:24 +0000232// selectMADD -
233// Transforms a subgraph in CurDAG if the following pattern is found:
234// (addc multLo, Lo0), (adde multHi, Hi0),
235// where,
236// multHi/Lo: product of multiplication
237// Lo0: initial value of Lo register
238// Hi0: initial value of Hi register
239// Return true if pattern matching was successful.
240static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
241 // ADDENode's second operand must be a flag output of an ADDC node in order
242 // for the matching to be successful.
243 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
244
245 if (ADDCNode->getOpcode() != ISD::ADDC)
246 return false;
247
248 SDValue MultHi = ADDENode->getOperand(0);
249 SDValue MultLo = ADDCNode->getOperand(0);
250 SDNode *MultNode = MultHi.getNode();
251 unsigned MultOpc = MultHi.getOpcode();
252
253 // MultHi and MultLo must be generated by the same node,
254 if (MultLo.getNode() != MultNode)
255 return false;
256
257 // and it must be a multiplication.
258 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
259 return false;
260
261 // MultLo amd MultHi must be the first and second output of MultNode
262 // respectively.
263 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
264 return false;
265
266 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
267 // of the values of MultNode, in which case MultNode will be removed in later
268 // phases.
269 // If there exist users other than ADDENode or ADDCNode, this function returns
270 // here, which will result in MultNode being mapped to a single MULT
271 // instruction node rather than a pair of MULT and MADD instructions being
272 // produced.
273 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
274 return false;
275
Andrew Trickac6d9be2013-05-25 02:42:55 +0000276 SDLoc DL(ADDENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000277
278 // Initialize accumulator.
279 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
280 ADDCNode->getOperand(1),
281 ADDENode->getOperand(1));
282
283 // create MipsMAdd(u) node
284 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
285
286 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
287 MultNode->getOperand(0),// Factor 0
288 MultNode->getOperand(1),// Factor 1
289 ACCIn);
290
291 // replace uses of adde and addc here
292 if (!SDValue(ADDCNode, 0).use_empty()) {
293 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
294 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
295 LoIdx);
296 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
297 }
298 if (!SDValue(ADDENode, 0).use_empty()) {
299 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
300 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
301 HiIdx);
302 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
303 }
304
305 return true;
306}
307
308// selectMSUB -
309// Transforms a subgraph in CurDAG if the following pattern is found:
310// (addc Lo0, multLo), (sube Hi0, multHi),
311// where,
312// multHi/Lo: product of multiplication
313// Lo0: initial value of Lo register
314// Hi0: initial value of Hi register
315// Return true if pattern matching was successful.
316static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
317 // SUBENode's second operand must be a flag output of an SUBC node in order
318 // for the matching to be successful.
319 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
320
321 if (SUBCNode->getOpcode() != ISD::SUBC)
322 return false;
323
324 SDValue MultHi = SUBENode->getOperand(1);
325 SDValue MultLo = SUBCNode->getOperand(1);
326 SDNode *MultNode = MultHi.getNode();
327 unsigned MultOpc = MultHi.getOpcode();
328
329 // MultHi and MultLo must be generated by the same node,
330 if (MultLo.getNode() != MultNode)
331 return false;
332
333 // and it must be a multiplication.
334 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
335 return false;
336
337 // MultLo amd MultHi must be the first and second output of MultNode
338 // respectively.
339 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
340 return false;
341
342 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
343 // of the values of MultNode, in which case MultNode will be removed in later
344 // phases.
345 // If there exist users other than SUBENode or SUBCNode, this function returns
346 // here, which will result in MultNode being mapped to a single MULT
347 // instruction node rather than a pair of MULT and MSUB instructions being
348 // produced.
349 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
350 return false;
351
Andrew Trickac6d9be2013-05-25 02:42:55 +0000352 SDLoc DL(SUBENode);
Akira Hatanakad593a772013-03-30 01:42:24 +0000353
354 // Initialize accumulator.
355 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
356 SUBCNode->getOperand(0),
357 SUBENode->getOperand(0));
358
359 // create MipsSub(u) node
360 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
361
362 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
363 MultNode->getOperand(0),// Factor 0
364 MultNode->getOperand(1),// Factor 1
365 ACCIn);
366
367 // replace uses of sube and subc here
368 if (!SDValue(SUBCNode, 0).use_empty()) {
369 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
370 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
371 LoIdx);
372 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
373 }
374 if (!SDValue(SUBENode, 0).use_empty()) {
375 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
376 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
377 HiIdx);
378 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
379 }
380
381 return true;
382}
383
384static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
385 TargetLowering::DAGCombinerInfo &DCI,
386 const MipsSubtarget *Subtarget) {
387 if (DCI.isBeforeLegalize())
388 return SDValue();
389
390 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
391 selectMADD(N, &DAG))
392 return SDValue(N, 0);
393
394 return SDValue();
395}
396
397static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
398 TargetLowering::DAGCombinerInfo &DCI,
399 const MipsSubtarget *Subtarget) {
400 if (DCI.isBeforeLegalize())
401 return SDValue();
402
403 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
404 selectMSUB(N, &DAG))
405 return SDValue(N, 0);
406
407 return SDValue();
408}
409
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000410static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
411 EVT ShiftTy, SelectionDAG &DAG) {
412 // Clear the upper (64 - VT.sizeInBits) bits.
413 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
414
415 // Return 0.
416 if (C == 0)
417 return DAG.getConstant(0, VT);
418
419 // Return x.
420 if (C == 1)
421 return X;
422
423 // If c is power of 2, return (shl x, log2(c)).
424 if (isPowerOf2_64(C))
425 return DAG.getNode(ISD::SHL, DL, VT, X,
426 DAG.getConstant(Log2_64(C), ShiftTy));
427
428 unsigned Log2Ceil = Log2_64_Ceil(C);
429 uint64_t Floor = 1LL << Log2_64(C);
430 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
431
432 // If |c - floor_c| <= |c - ceil_c|,
433 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
434 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
435 if (C - Floor <= Ceil - C) {
436 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
437 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
438 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
439 }
440
441 // If |c - floor_c| > |c - ceil_c|,
442 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
443 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
444 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
445 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
446}
447
448static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
449 const TargetLowering::DAGCombinerInfo &DCI,
450 const MipsSETargetLowering *TL) {
451 EVT VT = N->getValueType(0);
452
453 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
454 if (!VT.isVector())
455 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
456 VT, TL->getScalarShiftAmountTy(VT), DAG);
457
458 return SDValue(N, 0);
459}
460
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000461static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
462 SelectionDAG &DAG,
463 const MipsSubtarget *Subtarget) {
464 // See if this is a vector splat immediate node.
465 APInt SplatValue, SplatUndef;
466 unsigned SplatBitSize;
467 bool HasAnyUndefs;
468 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
469 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
470
Akira Hatanakad5972632013-04-22 19:58:23 +0000471 if (!BV ||
Akira Hatanakab109ea82013-04-22 20:13:37 +0000472 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
Akira Hatanakae311b002013-04-23 18:09:42 +0000473 EltSize, !Subtarget->isLittle()) ||
Akira Hatanakad5972632013-04-22 19:58:23 +0000474 (SplatBitSize != EltSize) ||
Akira Hatanakae311b002013-04-23 18:09:42 +0000475 (SplatValue.getZExtValue() >= EltSize))
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000476 return SDValue();
477
Andrew Trickac6d9be2013-05-25 02:42:55 +0000478 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000479 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
480}
481
482static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
483 TargetLowering::DAGCombinerInfo &DCI,
484 const MipsSubtarget *Subtarget) {
485 EVT Ty = N->getValueType(0);
486
487 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
488 return SDValue();
489
490 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
491}
492
493static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
494 TargetLowering::DAGCombinerInfo &DCI,
495 const MipsSubtarget *Subtarget) {
496 EVT Ty = N->getValueType(0);
497
498 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
499 return SDValue();
500
501 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
502}
503
504
505static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
506 TargetLowering::DAGCombinerInfo &DCI,
507 const MipsSubtarget *Subtarget) {
508 EVT Ty = N->getValueType(0);
509
510 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
511 return SDValue();
512
513 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
514}
515
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000516static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
517 bool IsV216 = (Ty == MVT::v2i16);
518
519 switch (CC) {
520 case ISD::SETEQ:
521 case ISD::SETNE: return true;
522 case ISD::SETLT:
523 case ISD::SETLE:
524 case ISD::SETGT:
525 case ISD::SETGE: return IsV216;
526 case ISD::SETULT:
527 case ISD::SETULE:
528 case ISD::SETUGT:
529 case ISD::SETUGE: return !IsV216;
530 default: return false;
531 }
532}
533
534static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
535 EVT Ty = N->getValueType(0);
536
537 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
538 return SDValue();
539
540 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
541 return SDValue();
542
Andrew Trickac6d9be2013-05-25 02:42:55 +0000543 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000544 N->getOperand(1), N->getOperand(2));
545}
546
547static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
548 EVT Ty = N->getValueType(0);
549
550 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
551 return SDValue();
552
553 SDValue SetCC = N->getOperand(0);
554
555 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
556 return SDValue();
557
Andrew Trickac6d9be2013-05-25 02:42:55 +0000558 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000559 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
560 N->getOperand(2), SetCC.getOperand(2));
561}
562
Akira Hatanakad593a772013-03-30 01:42:24 +0000563SDValue
564MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
565 SelectionDAG &DAG = DCI.DAG;
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000566 SDValue Val;
Akira Hatanakad593a772013-03-30 01:42:24 +0000567
568 switch (N->getOpcode()) {
569 case ISD::ADDE:
570 return performADDECombine(N, DAG, DCI, Subtarget);
571 case ISD::SUBE:
572 return performSUBECombine(N, DAG, DCI, Subtarget);
Akira Hatanaka9a308df2013-06-26 18:48:17 +0000573 case ISD::MUL:
574 return performMULCombine(N, DAG, DCI, this);
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000575 case ISD::SHL:
576 return performSHLCombine(N, DAG, DCI, Subtarget);
577 case ISD::SRA:
578 return performSRACombine(N, DAG, DCI, Subtarget);
579 case ISD::SRL:
580 return performSRLCombine(N, DAG, DCI, Subtarget);
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000581 case ISD::VSELECT:
582 return performVSELECTCombine(N, DAG);
583 case ISD::SETCC: {
584 Val = performSETCCCombine(N, DAG);
585 break;
Akira Hatanakad593a772013-03-30 01:42:24 +0000586 }
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000587 }
588
589 if (Val.getNode())
590 return Val;
591
592 return MipsTargetLowering::PerformDAGCombine(N, DCI);
Akira Hatanakad593a772013-03-30 01:42:24 +0000593}
594
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000595MachineBasicBlock *
596MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
597 MachineBasicBlock *BB) const {
598 switch (MI->getOpcode()) {
599 default:
600 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
601 case Mips::BPOSGE32_PSEUDO:
602 return emitBPOSGE32(MI, BB);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000603 case Mips::SNZ_B_PSEUDO:
604 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
605 case Mips::SNZ_H_PSEUDO:
606 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
607 case Mips::SNZ_W_PSEUDO:
608 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
609 case Mips::SNZ_D_PSEUDO:
610 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
611 case Mips::SNZ_V_PSEUDO:
612 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
613 case Mips::SZ_B_PSEUDO:
614 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
615 case Mips::SZ_H_PSEUDO:
616 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
617 case Mips::SZ_W_PSEUDO:
618 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
619 case Mips::SZ_D_PSEUDO:
620 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
621 case Mips::SZ_V_PSEUDO:
622 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000623 }
624}
625
626bool MipsSETargetLowering::
627isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
628 unsigned NextStackOffset,
629 const MipsFunctionInfo& FI) const {
630 if (!EnableMipsTailCalls)
631 return false;
632
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000633 // Return false if either the callee or caller has a byval argument.
634 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
635 return false;
636
637 // Return true if the callee's argument area is no larger than the
638 // caller's.
639 return NextStackOffset <= FI.getIncomingArgSize();
640}
641
642void MipsSETargetLowering::
643getOpndList(SmallVectorImpl<SDValue> &Ops,
644 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
645 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
646 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
647 // T9 should contain the address of the callee function if
648 // -reloction-model=pic or it is an indirect call.
649 if (IsPICCall || !GlobalOrExternal) {
650 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
651 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
652 } else
653 Ops.push_back(Callee);
654
655 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
656 InternalLinkage, CLI, Callee, Chain);
657}
658
Akira Hatanaka3e675852013-09-07 00:52:30 +0000659SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
660 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
661
662 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
663 return MipsTargetLowering::lowerLOAD(Op, DAG);
664
665 // Replace a double precision load with two i32 loads and a buildpair64.
666 SDLoc DL(Op);
667 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
668 EVT PtrVT = Ptr.getValueType();
669
670 // i32 load from lower address.
671 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
672 MachinePointerInfo(), Nd.isVolatile(),
673 Nd.isNonTemporal(), Nd.isInvariant(),
674 Nd.getAlignment());
675
676 // i32 load from higher address.
677 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
678 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
679 MachinePointerInfo(), Nd.isVolatile(),
680 Nd.isNonTemporal(), Nd.isInvariant(),
Akira Hatanaka2dd3afc2013-09-09 17:59:32 +0000681 std::min(Nd.getAlignment(), 4U));
Akira Hatanaka3e675852013-09-07 00:52:30 +0000682
683 if (!Subtarget->isLittle())
684 std::swap(Lo, Hi);
685
686 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
687 SDValue Ops[2] = {BP, Hi.getValue(1)};
688 return DAG.getMergeValues(Ops, 2, DL);
689}
690
691SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
692 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
693
694 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
695 return MipsTargetLowering::lowerSTORE(Op, DAG);
696
697 // Replace a double precision store with two extractelement64s and i32 stores.
698 SDLoc DL(Op);
699 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
700 EVT PtrVT = Ptr.getValueType();
701 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
702 Val, DAG.getConstant(0, MVT::i32));
703 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
704 Val, DAG.getConstant(1, MVT::i32));
705
706 if (!Subtarget->isLittle())
707 std::swap(Lo, Hi);
708
709 // i32 store to lower address.
710 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
711 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
712 Nd.getTBAAInfo());
713
714 // i32 store to higher address.
715 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
716 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
Akira Hatanaka2dd3afc2013-09-09 17:59:32 +0000717 Nd.isVolatile(), Nd.isNonTemporal(),
718 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
Akira Hatanaka3e675852013-09-07 00:52:30 +0000719}
720
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000721SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
722 bool HasLo, bool HasHi,
723 SelectionDAG &DAG) const {
724 EVT Ty = Op.getOperand(0).getValueType();
Andrew Trickac6d9be2013-05-25 02:42:55 +0000725 SDLoc DL(Op);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000726 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
727 Op.getOperand(0), Op.getOperand(1));
728 SDValue Lo, Hi;
729
730 if (HasLo)
731 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
732 DAG.getConstant(Mips::sub_lo, MVT::i32));
733 if (HasHi)
734 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
735 DAG.getConstant(Mips::sub_hi, MVT::i32));
736
737 if (!HasLo || !HasHi)
738 return HasLo ? Lo : Hi;
739
740 SDValue Vals[] = { Lo, Hi };
741 return DAG.getMergeValues(Vals, 2, DL);
742}
743
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000744
Andrew Trickac6d9be2013-05-25 02:42:55 +0000745static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000746 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
747 DAG.getConstant(0, MVT::i32));
748 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
749 DAG.getConstant(1, MVT::i32));
750 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
751}
752
Andrew Trickac6d9be2013-05-25 02:42:55 +0000753static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000754 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
755 DAG.getConstant(Mips::sub_lo, MVT::i32));
756 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
757 DAG.getConstant(Mips::sub_hi, MVT::i32));
758 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
759}
760
761// This function expands mips intrinsic nodes which have 64-bit input operands
762// or output values.
763//
764// out64 = intrinsic-node in64
765// =>
766// lo = copy (extract-element (in64, 0))
767// hi = copy (extract-element (in64, 1))
768// mips-specific-node
769// v0 = copy lo
770// v1 = copy hi
771// out64 = merge-values (v0, v1)
772//
773static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
Andrew Trickac6d9be2013-05-25 02:42:55 +0000774 SDLoc DL(Op);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000775 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
776 SmallVector<SDValue, 3> Ops;
777 unsigned OpNo = 0;
778
779 // See if Op has a chain input.
780 if (HasChainIn)
781 Ops.push_back(Op->getOperand(OpNo++));
782
783 // The next operand is the intrinsic opcode.
784 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
785
786 // See if the next operand has type i64.
787 SDValue Opnd = Op->getOperand(++OpNo), In64;
788
789 if (Opnd.getValueType() == MVT::i64)
790 In64 = initAccumulator(Opnd, DL, DAG);
791 else
792 Ops.push_back(Opnd);
793
794 // Push the remaining operands.
795 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
796 Ops.push_back(Op->getOperand(OpNo));
797
798 // Add In64 to the end of the list.
799 if (In64.getNode())
800 Ops.push_back(In64);
801
802 // Scan output.
803 SmallVector<EVT, 2> ResTys;
804
805 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
806 I != E; ++I)
807 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
808
809 // Create node.
810 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
811 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
812
813 if (!HasChainIn)
814 return Out;
815
816 assert(Val->getValueType(1) == MVT::Other);
817 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
818 return DAG.getMergeValues(Vals, 2, DL);
819}
820
Daniel Sanders68831cb2013-09-11 10:28:16 +0000821static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
822 SDLoc DL(Op);
823 SDValue LHS = Op->getOperand(1);
824 SDValue RHS = Op->getOperand(2);
825 EVT ResTy = Op->getValueType(0);
826
827 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS);
828
829 return Result;
830}
831
Daniel Sanders3c380d52013-08-28 12:14:50 +0000832static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
833 SDLoc DL(Op);
834 SDValue Value = Op->getOperand(1);
835 EVT ResTy = Op->getValueType(0);
836
837 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
838
839 return Result;
840}
841
Daniel Sanders2ac12822013-09-11 10:51:30 +0000842static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
843 SDLoc DL(Op);
844 SDValue Value = Op->getOperand(1);
845 EVT ResTy = Op->getValueType(0);
846
847 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
848
849 return Result;
850}
851
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000852SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
853 SelectionDAG &DAG) const {
854 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
855 default:
856 return SDValue();
857 case Intrinsic::mips_shilo:
858 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
859 case Intrinsic::mips_dpau_h_qbl:
860 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
861 case Intrinsic::mips_dpau_h_qbr:
862 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
863 case Intrinsic::mips_dpsu_h_qbl:
864 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
865 case Intrinsic::mips_dpsu_h_qbr:
866 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
867 case Intrinsic::mips_dpa_w_ph:
868 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
869 case Intrinsic::mips_dps_w_ph:
870 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
871 case Intrinsic::mips_dpax_w_ph:
872 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
873 case Intrinsic::mips_dpsx_w_ph:
874 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
875 case Intrinsic::mips_mulsa_w_ph:
876 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
877 case Intrinsic::mips_mult:
878 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
879 case Intrinsic::mips_multu:
880 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
881 case Intrinsic::mips_madd:
882 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
883 case Intrinsic::mips_maddu:
884 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
885 case Intrinsic::mips_msub:
886 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
887 case Intrinsic::mips_msubu:
888 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
Daniel Sanders68831cb2013-09-11 10:28:16 +0000889 case Intrinsic::mips_addv_b:
890 case Intrinsic::mips_addv_h:
891 case Intrinsic::mips_addv_w:
892 case Intrinsic::mips_addv_d:
893 return lowerMSABinaryIntr(Op, DAG, ISD::ADD);
Daniel Sanders3c380d52013-08-28 12:14:50 +0000894 case Intrinsic::mips_bnz_b:
895 case Intrinsic::mips_bnz_h:
896 case Intrinsic::mips_bnz_w:
897 case Intrinsic::mips_bnz_d:
898 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
899 case Intrinsic::mips_bnz_v:
900 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
901 case Intrinsic::mips_bz_b:
902 case Intrinsic::mips_bz_h:
903 case Intrinsic::mips_bz_w:
904 case Intrinsic::mips_bz_d:
905 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
906 case Intrinsic::mips_bz_v:
907 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
Daniel Sandersece929d2013-09-11 10:38:58 +0000908 case Intrinsic::mips_div_s_b:
909 case Intrinsic::mips_div_s_h:
910 case Intrinsic::mips_div_s_w:
911 case Intrinsic::mips_div_s_d:
912 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV);
913 case Intrinsic::mips_div_u_b:
914 case Intrinsic::mips_div_u_h:
915 case Intrinsic::mips_div_u_w:
916 case Intrinsic::mips_div_u_d:
917 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV);
Daniel Sanders2ac12822013-09-11 10:51:30 +0000918 case Intrinsic::mips_fadd_w:
919 case Intrinsic::mips_fadd_d:
920 return lowerMSABinaryIntr(Op, DAG, ISD::FADD);
921 case Intrinsic::mips_fdiv_w:
922 case Intrinsic::mips_fdiv_d:
923 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV);
924 case Intrinsic::mips_flog2_w:
925 case Intrinsic::mips_flog2_d:
926 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2);
927 case Intrinsic::mips_fmul_w:
928 case Intrinsic::mips_fmul_d:
929 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL);
930 case Intrinsic::mips_frint_w:
931 case Intrinsic::mips_frint_d:
932 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT);
933 case Intrinsic::mips_fsqrt_w:
934 case Intrinsic::mips_fsqrt_d:
935 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT);
936 case Intrinsic::mips_fsub_w:
937 case Intrinsic::mips_fsub_d:
938 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB);
Daniel Sandersf2eb1e42013-09-11 11:58:30 +0000939 case Intrinsic::mips_mulv_b:
940 case Intrinsic::mips_mulv_h:
941 case Intrinsic::mips_mulv_w:
942 case Intrinsic::mips_mulv_d:
943 return lowerMSABinaryIntr(Op, DAG, ISD::MUL);
944 case Intrinsic::mips_nlzc_b:
945 case Intrinsic::mips_nlzc_h:
946 case Intrinsic::mips_nlzc_w:
947 case Intrinsic::mips_nlzc_d:
948 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ);
949 case Intrinsic::mips_sll_b:
950 case Intrinsic::mips_sll_h:
951 case Intrinsic::mips_sll_w:
952 case Intrinsic::mips_sll_d:
953 return lowerMSABinaryIntr(Op, DAG, ISD::SHL);
954 case Intrinsic::mips_sra_b:
955 case Intrinsic::mips_sra_h:
956 case Intrinsic::mips_sra_w:
957 case Intrinsic::mips_sra_d:
958 return lowerMSABinaryIntr(Op, DAG, ISD::SRA);
959 case Intrinsic::mips_srl_b:
960 case Intrinsic::mips_srl_h:
961 case Intrinsic::mips_srl_w:
962 case Intrinsic::mips_srl_d:
963 return lowerMSABinaryIntr(Op, DAG, ISD::SRL);
964 case Intrinsic::mips_subv_b:
965 case Intrinsic::mips_subv_h:
966 case Intrinsic::mips_subv_w:
967 case Intrinsic::mips_subv_d:
968 return lowerMSABinaryIntr(Op, DAG, ISD::SUB);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000969 }
970}
971
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000972static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
973 SDLoc DL(Op);
974 SDValue ChainIn = Op->getOperand(0);
975 SDValue Address = Op->getOperand(2);
976 SDValue Offset = Op->getOperand(3);
977 EVT ResTy = Op->getValueType(0);
978 EVT PtrTy = Address->getValueType(0);
979
980 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
981
982 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
983 false, false, 16);
984}
985
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000986SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
987 SelectionDAG &DAG) const {
Daniel Sanders2fd3e672013-08-28 12:04:29 +0000988 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
989 switch (Intr) {
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000990 default:
991 return SDValue();
992 case Intrinsic::mips_extp:
993 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
994 case Intrinsic::mips_extpdp:
995 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
996 case Intrinsic::mips_extr_w:
997 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
998 case Intrinsic::mips_extr_r_w:
999 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
1000 case Intrinsic::mips_extr_rs_w:
1001 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
1002 case Intrinsic::mips_extr_s_h:
1003 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
1004 case Intrinsic::mips_mthlip:
1005 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
1006 case Intrinsic::mips_mulsaq_s_w_ph:
1007 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
1008 case Intrinsic::mips_maq_s_w_phl:
1009 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
1010 case Intrinsic::mips_maq_s_w_phr:
1011 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
1012 case Intrinsic::mips_maq_sa_w_phl:
1013 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
1014 case Intrinsic::mips_maq_sa_w_phr:
1015 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
1016 case Intrinsic::mips_dpaq_s_w_ph:
1017 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
1018 case Intrinsic::mips_dpsq_s_w_ph:
1019 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
1020 case Intrinsic::mips_dpaq_sa_l_w:
1021 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
1022 case Intrinsic::mips_dpsq_sa_l_w:
1023 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
1024 case Intrinsic::mips_dpaqx_s_w_ph:
1025 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
1026 case Intrinsic::mips_dpaqx_sa_w_ph:
1027 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
1028 case Intrinsic::mips_dpsqx_s_w_ph:
1029 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
1030 case Intrinsic::mips_dpsqx_sa_w_ph:
1031 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
Daniel Sanders2fd3e672013-08-28 12:04:29 +00001032 case Intrinsic::mips_ld_b:
1033 case Intrinsic::mips_ld_h:
1034 case Intrinsic::mips_ld_w:
1035 case Intrinsic::mips_ld_d:
1036 case Intrinsic::mips_ldx_b:
1037 case Intrinsic::mips_ldx_h:
1038 case Intrinsic::mips_ldx_w:
1039 case Intrinsic::mips_ldx_d:
1040 return lowerMSALoadIntr(Op, DAG, Intr);
1041 }
1042}
1043
1044static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1045 SDLoc DL(Op);
1046 SDValue ChainIn = Op->getOperand(0);
1047 SDValue Value = Op->getOperand(2);
1048 SDValue Address = Op->getOperand(3);
1049 SDValue Offset = Op->getOperand(4);
1050 EVT PtrTy = Address->getValueType(0);
1051
1052 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1053
1054 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
1055 false, 16);
1056}
1057
1058SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
1059 SelectionDAG &DAG) const {
1060 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1061 switch (Intr) {
1062 default:
1063 return SDValue();
1064 case Intrinsic::mips_st_b:
1065 case Intrinsic::mips_st_h:
1066 case Intrinsic::mips_st_w:
1067 case Intrinsic::mips_st_d:
1068 case Intrinsic::mips_stx_b:
1069 case Intrinsic::mips_stx_h:
1070 case Intrinsic::mips_stx_w:
1071 case Intrinsic::mips_stx_d:
Daniel Sanders3c380d52013-08-28 12:14:50 +00001072 return lowerMSAStoreIntr(Op, DAG, Intr);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +00001073 }
1074}
1075
Akira Hatanaka5ac065a2013-03-13 00:54:29 +00001076MachineBasicBlock * MipsSETargetLowering::
1077emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
1078 // $bb:
1079 // bposge32_pseudo $vr0
1080 // =>
1081 // $bb:
1082 // bposge32 $tbb
1083 // $fbb:
1084 // li $vr2, 0
1085 // b $sink
1086 // $tbb:
1087 // li $vr1, 1
1088 // $sink:
1089 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
1090
1091 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1092 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
Akira Hatanaka18587862013-08-06 23:08:38 +00001093 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
Akira Hatanaka5ac065a2013-03-13 00:54:29 +00001094 DebugLoc DL = MI->getDebugLoc();
1095 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1096 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1097 MachineFunction *F = BB->getParent();
1098 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1099 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1100 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1101 F->insert(It, FBB);
1102 F->insert(It, TBB);
1103 F->insert(It, Sink);
1104
1105 // Transfer the remainder of BB and its successor edges to Sink.
1106 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1107 BB->end());
1108 Sink->transferSuccessorsAndUpdatePHIs(BB);
1109
1110 // Add successors.
1111 BB->addSuccessor(FBB);
1112 BB->addSuccessor(TBB);
1113 FBB->addSuccessor(Sink);
1114 TBB->addSuccessor(Sink);
1115
1116 // Insert the real bposge32 instruction to $BB.
1117 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
1118
1119 // Fill $FBB.
1120 unsigned VR2 = RegInfo.createVirtualRegister(RC);
1121 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
1122 .addReg(Mips::ZERO).addImm(0);
1123 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1124
1125 // Fill $TBB.
1126 unsigned VR1 = RegInfo.createVirtualRegister(RC);
1127 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
1128 .addReg(Mips::ZERO).addImm(1);
1129
1130 // Insert phi function to $Sink.
1131 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1132 MI->getOperand(0).getReg())
1133 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
1134
1135 MI->eraseFromParent(); // The pseudo instruction is gone now.
1136 return Sink;
1137}
Daniel Sanders3c380d52013-08-28 12:14:50 +00001138
1139MachineBasicBlock * MipsSETargetLowering::
1140emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
1141 unsigned BranchOp) const{
1142 // $bb:
1143 // vany_nonzero $rd, $ws
1144 // =>
1145 // $bb:
1146 // bnz.b $ws, $tbb
1147 // b $fbb
1148 // $fbb:
1149 // li $rd1, 0
1150 // b $sink
1151 // $tbb:
1152 // li $rd2, 1
1153 // $sink:
1154 // $rd = phi($rd1, $fbb, $rd2, $tbb)
1155
1156 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1157 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1158 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1159 DebugLoc DL = MI->getDebugLoc();
1160 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1161 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1162 MachineFunction *F = BB->getParent();
1163 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1164 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1165 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1166 F->insert(It, FBB);
1167 F->insert(It, TBB);
1168 F->insert(It, Sink);
1169
1170 // Transfer the remainder of BB and its successor edges to Sink.
1171 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1172 BB->end());
1173 Sink->transferSuccessorsAndUpdatePHIs(BB);
1174
1175 // Add successors.
1176 BB->addSuccessor(FBB);
1177 BB->addSuccessor(TBB);
1178 FBB->addSuccessor(Sink);
1179 TBB->addSuccessor(Sink);
1180
1181 // Insert the real bnz.b instruction to $BB.
1182 BuildMI(BB, DL, TII->get(BranchOp))
1183 .addReg(MI->getOperand(1).getReg())
1184 .addMBB(TBB);
1185
1186 // Fill $FBB.
1187 unsigned RD1 = RegInfo.createVirtualRegister(RC);
1188 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
1189 .addReg(Mips::ZERO).addImm(0);
1190 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1191
1192 // Fill $TBB.
1193 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1194 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1195 .addReg(Mips::ZERO).addImm(1);
1196
1197 // Insert phi function to $Sink.
1198 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1199 MI->getOperand(0).getReg())
1200 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1201
1202 MI->eraseFromParent(); // The pseudo instruction is gone now.
1203 return Sink;
1204}