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