1 //===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Subclass of MipsTargetLowering specialized for mips32/64.
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"
25 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
26 cl::desc("MIPS: Enable tail calls."), cl::init(false));
28 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
29 : MipsTargetLowering(TM) {
30 // Set up the register classes
32 clearRegisterClasses();
34 addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
37 addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
39 if (Subtarget->hasDSP()) {
40 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
42 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
43 addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
45 // Expand all builtin opcodes.
46 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
47 setOperationAction(Opc, VecTys[i], Expand);
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);
56 setTargetDAGCombine(ISD::SHL);
57 setTargetDAGCombine(ISD::SRA);
58 setTargetDAGCombine(ISD::SRL);
59 setTargetDAGCombine(ISD::SETCC);
60 setTargetDAGCombine(ISD::VSELECT);
63 if (Subtarget->hasDSPR2())
64 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
66 if (!TM.Options.UseSoftFloat) {
67 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
69 // When dealing with single precision only, use libcalls
70 if (!Subtarget->isSingleFloat()) {
72 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
74 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
78 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);
84 setOperationAction(ISD::MULHS, MVT::i64, Custom);
85 setOperationAction(ISD::MULHU, MVT::i64, Custom);
86 setOperationAction(ISD::MUL, MVT::i64, Custom);
89 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
90 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
92 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);
96 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
97 setOperationAction(ISD::LOAD, MVT::i32, Custom);
98 setOperationAction(ISD::STORE, MVT::i32, Custom);
100 setTargetDAGCombine(ISD::ADDE);
101 setTargetDAGCombine(ISD::SUBE);
103 computeRegisterProperties();
106 const MipsTargetLowering *
107 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
108 return new MipsSETargetLowering(TM);
113 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
114 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
127 SDValue 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);
136 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
138 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
139 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
142 return MipsTargetLowering::LowerOperation(Op, DAG);
146 // Transforms a subgraph in CurDAG if the following pattern is found:
147 // (addc multLo, Lo0), (adde multHi, Hi0),
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.
153 static 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();
158 if (ADDCNode->getOpcode() != ISD::ADDC)
161 SDValue MultHi = ADDENode->getOperand(0);
162 SDValue MultLo = ADDCNode->getOperand(0);
163 SDNode *MultNode = MultHi.getNode();
164 unsigned MultOpc = MultHi.getOpcode();
166 // MultHi and MultLo must be generated by the same node,
167 if (MultLo.getNode() != MultNode)
170 // and it must be a multiplication.
171 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
174 // MultLo amd MultHi must be the first and second output of MultNode
176 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
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
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
186 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
189 DebugLoc DL = ADDENode->getDebugLoc();
191 // Initialize accumulator.
192 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
193 ADDCNode->getOperand(1),
194 ADDENode->getOperand(1));
196 // create MipsMAdd(u) node
197 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
199 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
200 MultNode->getOperand(0),// Factor 0
201 MultNode->getOperand(1),// Factor 1
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,
209 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
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,
215 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
222 // Transforms a subgraph in CurDAG if the following pattern is found:
223 // (addc Lo0, multLo), (sube Hi0, multHi),
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.
229 static 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();
234 if (SUBCNode->getOpcode() != ISD::SUBC)
237 SDValue MultHi = SUBENode->getOperand(1);
238 SDValue MultLo = SUBCNode->getOperand(1);
239 SDNode *MultNode = MultHi.getNode();
240 unsigned MultOpc = MultHi.getOpcode();
242 // MultHi and MultLo must be generated by the same node,
243 if (MultLo.getNode() != MultNode)
246 // and it must be a multiplication.
247 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
250 // MultLo amd MultHi must be the first and second output of MultNode
252 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
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
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
262 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
265 DebugLoc DL = SUBENode->getDebugLoc();
267 // Initialize accumulator.
268 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
269 SUBCNode->getOperand(0),
270 SUBENode->getOperand(0));
272 // create MipsSub(u) node
273 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
275 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
276 MultNode->getOperand(0),// Factor 0
277 MultNode->getOperand(1),// Factor 1
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,
285 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
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,
291 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
297 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
298 TargetLowering::DAGCombinerInfo &DCI,
299 const MipsSubtarget *Subtarget) {
300 if (DCI.isBeforeLegalize())
303 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
305 return SDValue(N, 0);
310 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
311 TargetLowering::DAGCombinerInfo &DCI,
312 const MipsSubtarget *Subtarget) {
313 if (DCI.isBeforeLegalize())
316 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
318 return SDValue(N, 0);
323 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
325 const MipsSubtarget *Subtarget) {
326 // See if this is a vector splat immediate node.
327 APInt SplatValue, SplatUndef;
328 unsigned SplatBitSize;
330 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
331 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
334 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
335 EltSize, !Subtarget->isLittle()) ||
336 (SplatBitSize != EltSize) ||
337 (SplatValue.getZExtValue() >= EltSize))
340 return DAG.getNode(Opc, N->getDebugLoc(), Ty, N->getOperand(0),
341 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
344 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
345 TargetLowering::DAGCombinerInfo &DCI,
346 const MipsSubtarget *Subtarget) {
347 EVT Ty = N->getValueType(0);
349 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
352 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
355 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
356 TargetLowering::DAGCombinerInfo &DCI,
357 const MipsSubtarget *Subtarget) {
358 EVT Ty = N->getValueType(0);
360 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
363 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
367 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
368 TargetLowering::DAGCombinerInfo &DCI,
369 const MipsSubtarget *Subtarget) {
370 EVT Ty = N->getValueType(0);
372 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
375 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
378 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
379 bool IsV216 = (Ty == MVT::v2i16);
383 case ISD::SETNE: return true;
387 case ISD::SETGE: return IsV216;
391 case ISD::SETUGE: return !IsV216;
392 default: return false;
396 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
397 EVT Ty = N->getValueType(0);
399 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
402 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
405 return DAG.getNode(MipsISD::SETCC_DSP, N->getDebugLoc(), Ty, N->getOperand(0),
406 N->getOperand(1), N->getOperand(2));
409 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
410 EVT Ty = N->getValueType(0);
412 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
415 SDValue SetCC = N->getOperand(0);
417 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
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));
426 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
427 SelectionDAG &DAG = DCI.DAG;
430 switch (N->getOpcode()) {
432 return performADDECombine(N, DAG, DCI, Subtarget);
434 return performSUBECombine(N, DAG, DCI, Subtarget);
436 return performSHLCombine(N, DAG, DCI, Subtarget);
438 return performSRACombine(N, DAG, DCI, Subtarget);
440 return performSRLCombine(N, DAG, DCI, Subtarget);
442 return performVSELECTCombine(N, DAG);
444 Val = performSETCCCombine(N, DAG);
452 return MipsTargetLowering::PerformDAGCombine(N, DCI);
456 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
457 MachineBasicBlock *BB) const {
458 switch (MI->getOpcode()) {
460 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
461 case Mips::BPOSGE32_PSEUDO:
462 return emitBPOSGE32(MI, BB);
466 bool MipsSETargetLowering::
467 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
468 unsigned NextStackOffset,
469 const MipsFunctionInfo& FI) const {
470 if (!EnableMipsTailCalls)
473 // Return false if either the callee or caller has a byval argument.
474 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
477 // Return true if the callee's argument area is no larger than the
479 return NextStackOffset <= FI.getIncomingArgSize();
482 void MipsSETargetLowering::
483 getOpndList(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));
493 Ops.push_back(Callee);
495 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
496 InternalLinkage, CLI, Callee, Chain);
499 SDValue 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));
509 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
510 DAG.getConstant(Mips::sub_lo, MVT::i32));
512 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
513 DAG.getConstant(Mips::sub_hi, MVT::i32));
515 if (!HasLo || !HasHi)
516 return HasLo ? Lo : Hi;
518 SDValue Vals[] = { Lo, Hi };
519 return DAG.getMergeValues(Vals, 2, DL);
523 static 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);
531 static 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);
539 // This function expands mips intrinsic nodes which have 64-bit input operands
542 // out64 = intrinsic-node in64
544 // lo = copy (extract-element (in64, 0))
545 // hi = copy (extract-element (in64, 1))
546 // mips-specific-node
549 // out64 = merge-values (v0, v1)
551 static 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;
557 // See if Op has a chain input.
559 Ops.push_back(Op->getOperand(OpNo++));
561 // The next operand is the intrinsic opcode.
562 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
564 // See if the next operand has type i64.
565 SDValue Opnd = Op->getOperand(++OpNo), In64;
567 if (Opnd.getValueType() == MVT::i64)
568 In64 = initAccumulator(Opnd, DL, DAG);
572 // Push the remaining operands.
573 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
574 Ops.push_back(Op->getOperand(OpNo));
576 // Add In64 to the end of the list.
581 SmallVector<EVT, 2> ResTys;
583 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
585 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
588 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
589 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
594 assert(Val->getValueType(1) == MVT::Other);
595 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
596 return DAG.getMergeValues(Vals, 2, DL);
599 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
600 SelectionDAG &DAG) const {
601 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
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);
639 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
640 SelectionDAG &DAG) const {
641 switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) {
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);
687 MachineBasicBlock * MipsSETargetLowering::
688 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
690 // bposge32_pseudo $vr0
700 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
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);
716 // Transfer the remainder of BB and its successor edges to Sink.
717 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
719 Sink->transferSuccessorsAndUpdatePHIs(BB);
722 BB->addSuccessor(FBB);
723 BB->addSuccessor(TBB);
724 FBB->addSuccessor(Sink);
725 TBB->addSuccessor(Sink);
727 // Insert the real bposge32 instruction to $BB.
728 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
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);
737 unsigned VR1 = RegInfo.createVirtualRegister(RC);
738 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
739 .addReg(Mips::ZERO).addImm(1);
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);
746 MI->eraseFromParent(); // The pseudo instruction is gone now.