blob: 8544bb89107390d96de447e52bb0eb25f6afcf56 [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 Hatanaka5ac065a2013-03-13 00:54:29 +000034 addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
35
36 if (HasMips64)
37 addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
38
39 if (Subtarget->hasDSP()) {
40 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
41
42 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
43 addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
44
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
56 setTargetDAGCombine(ISD::SHL);
57 setTargetDAGCombine(ISD::SRA);
58 setTargetDAGCombine(ISD::SRL);
Akira Hatanakacd6c5792013-04-30 22:37:26 +000059 setTargetDAGCombine(ISD::SETCC);
60 setTargetDAGCombine(ISD::VSELECT);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000061 }
62
Akira Hatanaka3d602412013-04-13 00:55:41 +000063 if (Subtarget->hasDSPR2())
64 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
65
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000066 if (!TM.Options.UseSoftFloat) {
67 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
68
69 // When dealing with single precision only, use libcalls
70 if (!Subtarget->isSingleFloat()) {
71 if (HasMips64)
72 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
73 else
74 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
75 }
76 }
77
Akira Hatanakaf5926fd2013-03-30 01:36:35 +000078 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
79 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
80 setOperationAction(ISD::MULHS, MVT::i32, Custom);
81 setOperationAction(ISD::MULHU, MVT::i32, Custom);
82
Akira Hatanakafc82e4d2013-04-11 19:29:26 +000083 if (HasMips64) {
84 setOperationAction(ISD::MULHS, MVT::i64, Custom);
85 setOperationAction(ISD::MULHU, MVT::i64, Custom);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +000086 setOperationAction(ISD::MUL, MVT::i64, Custom);
Akira Hatanakafc82e4d2013-04-11 19:29:26 +000087 }
Akira Hatanakaf5926fd2013-03-30 01:36:35 +000088
Akira Hatanaka4e0980a2013-04-13 02:13:30 +000089 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
90 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
91
Akira Hatanakaf5926fd2013-03-30 01:36:35 +000092 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
93 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
94 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
95 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
Akira Hatanaka5ac065a2013-03-13 00:54:29 +000096 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
97 setOperationAction(ISD::LOAD, MVT::i32, Custom);
98 setOperationAction(ISD::STORE, MVT::i32, Custom);
99
Akira Hatanakad593a772013-03-30 01:42:24 +0000100 setTargetDAGCombine(ISD::ADDE);
101 setTargetDAGCombine(ISD::SUBE);
102
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000103 computeRegisterProperties();
104}
105
106const MipsTargetLowering *
107llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
108 return new MipsSETargetLowering(TM);
109}
110
111
112bool
113MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
114 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
115
116 switch (SVT) {
117 case MVT::i64:
118 case MVT::i32:
119 if (Fast)
120 *Fast = true;
121 return true;
122 default:
123 return false;
124 }
125}
126
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000127SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
128 SelectionDAG &DAG) const {
129 switch(Op.getOpcode()) {
130 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
131 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
132 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
133 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
134 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
135 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
Akira Hatanakab109ea82013-04-22 20:13:37 +0000136 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
137 DAG);
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000138 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
139 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000140 }
141
142 return MipsTargetLowering::LowerOperation(Op, DAG);
143}
144
Akira Hatanakad593a772013-03-30 01:42:24 +0000145// selectMADD -
146// Transforms a subgraph in CurDAG if the following pattern is found:
147// (addc multLo, Lo0), (adde multHi, Hi0),
148// where,
149// multHi/Lo: product of multiplication
150// Lo0: initial value of Lo register
151// Hi0: initial value of Hi register
152// Return true if pattern matching was successful.
153static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
154 // ADDENode's second operand must be a flag output of an ADDC node in order
155 // for the matching to be successful.
156 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
157
158 if (ADDCNode->getOpcode() != ISD::ADDC)
159 return false;
160
161 SDValue MultHi = ADDENode->getOperand(0);
162 SDValue MultLo = ADDCNode->getOperand(0);
163 SDNode *MultNode = MultHi.getNode();
164 unsigned MultOpc = MultHi.getOpcode();
165
166 // MultHi and MultLo must be generated by the same node,
167 if (MultLo.getNode() != MultNode)
168 return false;
169
170 // and it must be a multiplication.
171 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
172 return false;
173
174 // MultLo amd MultHi must be the first and second output of MultNode
175 // respectively.
176 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
177 return false;
178
179 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
180 // of the values of MultNode, in which case MultNode will be removed in later
181 // phases.
182 // If there exist users other than ADDENode or ADDCNode, this function returns
183 // here, which will result in MultNode being mapped to a single MULT
184 // instruction node rather than a pair of MULT and MADD instructions being
185 // produced.
186 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
187 return false;
188
Akira Hatanakad593a772013-03-30 01:42:24 +0000189 DebugLoc DL = ADDENode->getDebugLoc();
190
191 // Initialize accumulator.
192 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
193 ADDCNode->getOperand(1),
194 ADDENode->getOperand(1));
195
196 // create MipsMAdd(u) node
197 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
198
199 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
200 MultNode->getOperand(0),// Factor 0
201 MultNode->getOperand(1),// Factor 1
202 ACCIn);
203
204 // replace uses of adde and addc here
205 if (!SDValue(ADDCNode, 0).use_empty()) {
206 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
207 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
208 LoIdx);
209 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
210 }
211 if (!SDValue(ADDENode, 0).use_empty()) {
212 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
213 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
214 HiIdx);
215 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
216 }
217
218 return true;
219}
220
221// selectMSUB -
222// Transforms a subgraph in CurDAG if the following pattern is found:
223// (addc Lo0, multLo), (sube Hi0, multHi),
224// where,
225// multHi/Lo: product of multiplication
226// Lo0: initial value of Lo register
227// Hi0: initial value of Hi register
228// Return true if pattern matching was successful.
229static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
230 // SUBENode's second operand must be a flag output of an SUBC node in order
231 // for the matching to be successful.
232 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
233
234 if (SUBCNode->getOpcode() != ISD::SUBC)
235 return false;
236
237 SDValue MultHi = SUBENode->getOperand(1);
238 SDValue MultLo = SUBCNode->getOperand(1);
239 SDNode *MultNode = MultHi.getNode();
240 unsigned MultOpc = MultHi.getOpcode();
241
242 // MultHi and MultLo must be generated by the same node,
243 if (MultLo.getNode() != MultNode)
244 return false;
245
246 // and it must be a multiplication.
247 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
248 return false;
249
250 // MultLo amd MultHi must be the first and second output of MultNode
251 // respectively.
252 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
253 return false;
254
255 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
256 // of the values of MultNode, in which case MultNode will be removed in later
257 // phases.
258 // If there exist users other than SUBENode or SUBCNode, this function returns
259 // here, which will result in MultNode being mapped to a single MULT
260 // instruction node rather than a pair of MULT and MSUB instructions being
261 // produced.
262 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
263 return false;
264
Akira Hatanakad593a772013-03-30 01:42:24 +0000265 DebugLoc DL = SUBENode->getDebugLoc();
266
267 // Initialize accumulator.
268 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
269 SUBCNode->getOperand(0),
270 SUBENode->getOperand(0));
271
272 // create MipsSub(u) node
273 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
274
275 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
276 MultNode->getOperand(0),// Factor 0
277 MultNode->getOperand(1),// Factor 1
278 ACCIn);
279
280 // replace uses of sube and subc here
281 if (!SDValue(SUBCNode, 0).use_empty()) {
282 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
283 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
284 LoIdx);
285 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
286 }
287 if (!SDValue(SUBENode, 0).use_empty()) {
288 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
289 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
290 HiIdx);
291 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
292 }
293
294 return true;
295}
296
297static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
298 TargetLowering::DAGCombinerInfo &DCI,
299 const MipsSubtarget *Subtarget) {
300 if (DCI.isBeforeLegalize())
301 return SDValue();
302
303 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
304 selectMADD(N, &DAG))
305 return SDValue(N, 0);
306
307 return SDValue();
308}
309
310static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
311 TargetLowering::DAGCombinerInfo &DCI,
312 const MipsSubtarget *Subtarget) {
313 if (DCI.isBeforeLegalize())
314 return SDValue();
315
316 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
317 selectMSUB(N, &DAG))
318 return SDValue(N, 0);
319
320 return SDValue();
321}
322
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000323static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
324 SelectionDAG &DAG,
325 const MipsSubtarget *Subtarget) {
326 // See if this is a vector splat immediate node.
327 APInt SplatValue, SplatUndef;
328 unsigned SplatBitSize;
329 bool HasAnyUndefs;
330 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
331 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
332
Akira Hatanakad5972632013-04-22 19:58:23 +0000333 if (!BV ||
Akira Hatanakab109ea82013-04-22 20:13:37 +0000334 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
Akira Hatanakae311b002013-04-23 18:09:42 +0000335 EltSize, !Subtarget->isLittle()) ||
Akira Hatanakad5972632013-04-22 19:58:23 +0000336 (SplatBitSize != EltSize) ||
Akira Hatanakae311b002013-04-23 18:09:42 +0000337 (SplatValue.getZExtValue() >= EltSize))
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000338 return SDValue();
339
340 return DAG.getNode(Opc, N->getDebugLoc(), Ty, N->getOperand(0),
341 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
342}
343
344static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
345 TargetLowering::DAGCombinerInfo &DCI,
346 const MipsSubtarget *Subtarget) {
347 EVT Ty = N->getValueType(0);
348
349 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
350 return SDValue();
351
352 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
353}
354
355static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
356 TargetLowering::DAGCombinerInfo &DCI,
357 const MipsSubtarget *Subtarget) {
358 EVT Ty = N->getValueType(0);
359
360 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
361 return SDValue();
362
363 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
364}
365
366
367static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
368 TargetLowering::DAGCombinerInfo &DCI,
369 const MipsSubtarget *Subtarget) {
370 EVT Ty = N->getValueType(0);
371
372 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
373 return SDValue();
374
375 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
376}
377
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000378static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
379 bool IsV216 = (Ty == MVT::v2i16);
380
381 switch (CC) {
382 case ISD::SETEQ:
383 case ISD::SETNE: return true;
384 case ISD::SETLT:
385 case ISD::SETLE:
386 case ISD::SETGT:
387 case ISD::SETGE: return IsV216;
388 case ISD::SETULT:
389 case ISD::SETULE:
390 case ISD::SETUGT:
391 case ISD::SETUGE: return !IsV216;
392 default: return false;
393 }
394}
395
396static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
397 EVT Ty = N->getValueType(0);
398
399 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
400 return SDValue();
401
402 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
403 return SDValue();
404
405 return DAG.getNode(MipsISD::SETCC_DSP, N->getDebugLoc(), Ty, N->getOperand(0),
406 N->getOperand(1), N->getOperand(2));
407}
408
409static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
410 EVT Ty = N->getValueType(0);
411
412 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
413 return SDValue();
414
415 SDValue SetCC = N->getOperand(0);
416
417 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
418 return SDValue();
419
420 return DAG.getNode(MipsISD::SELECT_CC_DSP, N->getDebugLoc(), Ty,
421 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
422 N->getOperand(2), SetCC.getOperand(2));
423}
424
Akira Hatanakad593a772013-03-30 01:42:24 +0000425SDValue
426MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
427 SelectionDAG &DAG = DCI.DAG;
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000428 SDValue Val;
Akira Hatanakad593a772013-03-30 01:42:24 +0000429
430 switch (N->getOpcode()) {
431 case ISD::ADDE:
432 return performADDECombine(N, DAG, DCI, Subtarget);
433 case ISD::SUBE:
434 return performSUBECombine(N, DAG, DCI, Subtarget);
Akira Hatanaka97a62bf2013-04-19 23:21:32 +0000435 case ISD::SHL:
436 return performSHLCombine(N, DAG, DCI, Subtarget);
437 case ISD::SRA:
438 return performSRACombine(N, DAG, DCI, Subtarget);
439 case ISD::SRL:
440 return performSRLCombine(N, DAG, DCI, Subtarget);
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000441 case ISD::VSELECT:
442 return performVSELECTCombine(N, DAG);
443 case ISD::SETCC: {
444 Val = performSETCCCombine(N, DAG);
445 break;
Akira Hatanakad593a772013-03-30 01:42:24 +0000446 }
Akira Hatanakacd6c5792013-04-30 22:37:26 +0000447 }
448
449 if (Val.getNode())
450 return Val;
451
452 return MipsTargetLowering::PerformDAGCombine(N, DCI);
Akira Hatanakad593a772013-03-30 01:42:24 +0000453}
454
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000455MachineBasicBlock *
456MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
457 MachineBasicBlock *BB) const {
458 switch (MI->getOpcode()) {
459 default:
460 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
461 case Mips::BPOSGE32_PSEUDO:
462 return emitBPOSGE32(MI, BB);
463 }
464}
465
466bool MipsSETargetLowering::
467isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
468 unsigned NextStackOffset,
469 const MipsFunctionInfo& FI) const {
470 if (!EnableMipsTailCalls)
471 return false;
472
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000473 // Return false if either the callee or caller has a byval argument.
474 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
475 return false;
476
477 // Return true if the callee's argument area is no larger than the
478 // caller's.
479 return NextStackOffset <= FI.getIncomingArgSize();
480}
481
482void MipsSETargetLowering::
483getOpndList(SmallVectorImpl<SDValue> &Ops,
484 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
485 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
486 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
487 // T9 should contain the address of the callee function if
488 // -reloction-model=pic or it is an indirect call.
489 if (IsPICCall || !GlobalOrExternal) {
490 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
491 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
492 } else
493 Ops.push_back(Callee);
494
495 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
496 InternalLinkage, CLI, Callee, Chain);
497}
498
Akira Hatanakaf5926fd2013-03-30 01:36:35 +0000499SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
500 bool HasLo, bool HasHi,
501 SelectionDAG &DAG) const {
502 EVT Ty = Op.getOperand(0).getValueType();
503 DebugLoc DL = Op.getDebugLoc();
504 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
505 Op.getOperand(0), Op.getOperand(1));
506 SDValue Lo, Hi;
507
508 if (HasLo)
509 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
510 DAG.getConstant(Mips::sub_lo, MVT::i32));
511 if (HasHi)
512 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
513 DAG.getConstant(Mips::sub_hi, MVT::i32));
514
515 if (!HasLo || !HasHi)
516 return HasLo ? Lo : Hi;
517
518 SDValue Vals[] = { Lo, Hi };
519 return DAG.getMergeValues(Vals, 2, DL);
520}
521
Akira Hatanaka4e0980a2013-04-13 02:13:30 +0000522
523static SDValue initAccumulator(SDValue In, DebugLoc DL, SelectionDAG &DAG) {
524 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
525 DAG.getConstant(0, MVT::i32));
526 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
527 DAG.getConstant(1, MVT::i32));
528 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
529}
530
531static SDValue extractLOHI(SDValue Op, DebugLoc DL, SelectionDAG &DAG) {
532 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
533 DAG.getConstant(Mips::sub_lo, MVT::i32));
534 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
535 DAG.getConstant(Mips::sub_hi, MVT::i32));
536 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
537}
538
539// This function expands mips intrinsic nodes which have 64-bit input operands
540// or output values.
541//
542// out64 = intrinsic-node in64
543// =>
544// lo = copy (extract-element (in64, 0))
545// hi = copy (extract-element (in64, 1))
546// mips-specific-node
547// v0 = copy lo
548// v1 = copy hi
549// out64 = merge-values (v0, v1)
550//
551static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
552 DebugLoc DL = Op.getDebugLoc();
553 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
554 SmallVector<SDValue, 3> Ops;
555 unsigned OpNo = 0;
556
557 // See if Op has a chain input.
558 if (HasChainIn)
559 Ops.push_back(Op->getOperand(OpNo++));
560
561 // The next operand is the intrinsic opcode.
562 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
563
564 // See if the next operand has type i64.
565 SDValue Opnd = Op->getOperand(++OpNo), In64;
566
567 if (Opnd.getValueType() == MVT::i64)
568 In64 = initAccumulator(Opnd, DL, DAG);
569 else
570 Ops.push_back(Opnd);
571
572 // Push the remaining operands.
573 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
574 Ops.push_back(Op->getOperand(OpNo));
575
576 // Add In64 to the end of the list.
577 if (In64.getNode())
578 Ops.push_back(In64);
579
580 // Scan output.
581 SmallVector<EVT, 2> ResTys;
582
583 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
584 I != E; ++I)
585 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
586
587 // Create node.
588 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
589 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
590
591 if (!HasChainIn)
592 return Out;
593
594 assert(Val->getValueType(1) == MVT::Other);
595 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
596 return DAG.getMergeValues(Vals, 2, DL);
597}
598
599SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
600 SelectionDAG &DAG) const {
601 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
602 default:
603 return SDValue();
604 case Intrinsic::mips_shilo:
605 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
606 case Intrinsic::mips_dpau_h_qbl:
607 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
608 case Intrinsic::mips_dpau_h_qbr:
609 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
610 case Intrinsic::mips_dpsu_h_qbl:
611 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
612 case Intrinsic::mips_dpsu_h_qbr:
613 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
614 case Intrinsic::mips_dpa_w_ph:
615 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
616 case Intrinsic::mips_dps_w_ph:
617 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
618 case Intrinsic::mips_dpax_w_ph:
619 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
620 case Intrinsic::mips_dpsx_w_ph:
621 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
622 case Intrinsic::mips_mulsa_w_ph:
623 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
624 case Intrinsic::mips_mult:
625 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
626 case Intrinsic::mips_multu:
627 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
628 case Intrinsic::mips_madd:
629 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
630 case Intrinsic::mips_maddu:
631 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
632 case Intrinsic::mips_msub:
633 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
634 case Intrinsic::mips_msubu:
635 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
636 }
637}
638
639SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
640 SelectionDAG &DAG) const {
641 switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) {
642 default:
643 return SDValue();
644 case Intrinsic::mips_extp:
645 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
646 case Intrinsic::mips_extpdp:
647 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
648 case Intrinsic::mips_extr_w:
649 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
650 case Intrinsic::mips_extr_r_w:
651 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
652 case Intrinsic::mips_extr_rs_w:
653 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
654 case Intrinsic::mips_extr_s_h:
655 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
656 case Intrinsic::mips_mthlip:
657 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
658 case Intrinsic::mips_mulsaq_s_w_ph:
659 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
660 case Intrinsic::mips_maq_s_w_phl:
661 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
662 case Intrinsic::mips_maq_s_w_phr:
663 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
664 case Intrinsic::mips_maq_sa_w_phl:
665 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
666 case Intrinsic::mips_maq_sa_w_phr:
667 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
668 case Intrinsic::mips_dpaq_s_w_ph:
669 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
670 case Intrinsic::mips_dpsq_s_w_ph:
671 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
672 case Intrinsic::mips_dpaq_sa_l_w:
673 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
674 case Intrinsic::mips_dpsq_sa_l_w:
675 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
676 case Intrinsic::mips_dpaqx_s_w_ph:
677 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
678 case Intrinsic::mips_dpaqx_sa_w_ph:
679 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
680 case Intrinsic::mips_dpsqx_s_w_ph:
681 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
682 case Intrinsic::mips_dpsqx_sa_w_ph:
683 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
684 }
685}
686
Akira Hatanaka5ac065a2013-03-13 00:54:29 +0000687MachineBasicBlock * MipsSETargetLowering::
688emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
689 // $bb:
690 // bposge32_pseudo $vr0
691 // =>
692 // $bb:
693 // bposge32 $tbb
694 // $fbb:
695 // li $vr2, 0
696 // b $sink
697 // $tbb:
698 // li $vr1, 1
699 // $sink:
700 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
701
702 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
703 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
704 const TargetRegisterClass *RC = &Mips::CPURegsRegClass;
705 DebugLoc DL = MI->getDebugLoc();
706 const BasicBlock *LLVM_BB = BB->getBasicBlock();
707 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
708 MachineFunction *F = BB->getParent();
709 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
710 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
711 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
712 F->insert(It, FBB);
713 F->insert(It, TBB);
714 F->insert(It, Sink);
715
716 // Transfer the remainder of BB and its successor edges to Sink.
717 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
718 BB->end());
719 Sink->transferSuccessorsAndUpdatePHIs(BB);
720
721 // Add successors.
722 BB->addSuccessor(FBB);
723 BB->addSuccessor(TBB);
724 FBB->addSuccessor(Sink);
725 TBB->addSuccessor(Sink);
726
727 // Insert the real bposge32 instruction to $BB.
728 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
729
730 // Fill $FBB.
731 unsigned VR2 = RegInfo.createVirtualRegister(RC);
732 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
733 .addReg(Mips::ZERO).addImm(0);
734 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
735
736 // Fill $TBB.
737 unsigned VR1 = RegInfo.createVirtualRegister(RC);
738 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
739 .addReg(Mips::ZERO).addImm(1);
740
741 // Insert phi function to $Sink.
742 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
743 MI->getOperand(0).getReg())
744 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
745
746 MI->eraseFromParent(); // The pseudo instruction is gone now.
747 return Sink;
748}