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