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