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 // Expand all truncating stores and extending loads.
57 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
58 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
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);
65 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
66 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
67 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
70 setTargetDAGCombine(ISD::SHL);
71 setTargetDAGCombine(ISD::SRA);
72 setTargetDAGCombine(ISD::SRL);
73 setTargetDAGCombine(ISD::SETCC);
74 setTargetDAGCombine(ISD::VSELECT);
77 if (Subtarget->hasDSPR2())
78 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
80 if (!TM.Options.UseSoftFloat) {
81 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
83 // When dealing with single precision only, use libcalls
84 if (!Subtarget->isSingleFloat()) {
86 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
88 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
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);
98 setOperationAction(ISD::MULHS, MVT::i64, Custom);
99 setOperationAction(ISD::MULHU, MVT::i64, Custom);
100 setOperationAction(ISD::MUL, MVT::i64, Custom);
103 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
104 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
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);
114 setTargetDAGCombine(ISD::ADDE);
115 setTargetDAGCombine(ISD::SUBE);
116 setTargetDAGCombine(ISD::MUL);
118 computeRegisterProperties();
121 const MipsTargetLowering *
122 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
123 return new MipsSETargetLowering(TM);
128 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
129 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
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,
153 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
154 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
157 return MipsTargetLowering::LowerOperation(Op, DAG);
161 // Transforms a subgraph in CurDAG if the following pattern is found:
162 // (addc multLo, Lo0), (adde multHi, Hi0),
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();
173 if (ADDCNode->getOpcode() != ISD::ADDC)
176 SDValue MultHi = ADDENode->getOperand(0);
177 SDValue MultLo = ADDCNode->getOperand(0);
178 SDNode *MultNode = MultHi.getNode();
179 unsigned MultOpc = MultHi.getOpcode();
181 // MultHi and MultLo must be generated by the same node,
182 if (MultLo.getNode() != MultNode)
185 // and it must be a multiplication.
186 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
189 // MultLo amd MultHi must be the first and second output of MultNode
191 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
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
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
201 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
206 // Initialize accumulator.
207 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
208 ADDCNode->getOperand(1),
209 ADDENode->getOperand(1));
211 // create MipsMAdd(u) node
212 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
214 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
215 MultNode->getOperand(0),// Factor 0
216 MultNode->getOperand(1),// Factor 1
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,
224 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
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,
230 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
237 // Transforms a subgraph in CurDAG if the following pattern is found:
238 // (addc Lo0, multLo), (sube Hi0, multHi),
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();
249 if (SUBCNode->getOpcode() != ISD::SUBC)
252 SDValue MultHi = SUBENode->getOperand(1);
253 SDValue MultLo = SUBCNode->getOperand(1);
254 SDNode *MultNode = MultHi.getNode();
255 unsigned MultOpc = MultHi.getOpcode();
257 // MultHi and MultLo must be generated by the same node,
258 if (MultLo.getNode() != MultNode)
261 // and it must be a multiplication.
262 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
265 // MultLo amd MultHi must be the first and second output of MultNode
267 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
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
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
277 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
282 // Initialize accumulator.
283 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
284 SUBCNode->getOperand(0),
285 SUBENode->getOperand(0));
287 // create MipsSub(u) node
288 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
290 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
291 MultNode->getOperand(0),// Factor 0
292 MultNode->getOperand(1),// Factor 1
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,
300 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
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,
306 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
312 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
313 TargetLowering::DAGCombinerInfo &DCI,
314 const MipsSubtarget *Subtarget) {
315 if (DCI.isBeforeLegalize())
318 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
320 return SDValue(N, 0);
325 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
326 TargetLowering::DAGCombinerInfo &DCI,
327 const MipsSubtarget *Subtarget) {
328 if (DCI.isBeforeLegalize())
331 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
333 return SDValue(N, 0);
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());
345 return DAG.getConstant(0, VT);
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));
356 unsigned Log2Ceil = Log2_64_Ceil(C);
357 uint64_t Floor = 1LL << Log2_64(C);
358 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
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);
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);
376 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
377 const TargetLowering::DAGCombinerInfo &DCI,
378 const MipsSETargetLowering *TL) {
379 EVT VT = N->getValueType(0);
381 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
383 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
384 VT, TL->getScalarShiftAmountTy(VT), DAG);
386 return SDValue(N, 0);
389 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
391 const MipsSubtarget *Subtarget) {
392 // See if this is a vector splat immediate node.
393 APInt SplatValue, SplatUndef;
394 unsigned SplatBitSize;
396 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
397 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
400 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
401 EltSize, !Subtarget->isLittle()) ||
402 (SplatBitSize != EltSize) ||
403 (SplatValue.getZExtValue() >= EltSize))
406 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
407 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
410 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
411 TargetLowering::DAGCombinerInfo &DCI,
412 const MipsSubtarget *Subtarget) {
413 EVT Ty = N->getValueType(0);
415 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
418 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
421 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
422 TargetLowering::DAGCombinerInfo &DCI,
423 const MipsSubtarget *Subtarget) {
424 EVT Ty = N->getValueType(0);
426 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
429 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
433 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
434 TargetLowering::DAGCombinerInfo &DCI,
435 const MipsSubtarget *Subtarget) {
436 EVT Ty = N->getValueType(0);
438 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
441 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
444 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
445 bool IsV216 = (Ty == MVT::v2i16);
449 case ISD::SETNE: return true;
453 case ISD::SETGE: return IsV216;
457 case ISD::SETUGE: return !IsV216;
458 default: return false;
462 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
463 EVT Ty = N->getValueType(0);
465 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
468 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
471 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
472 N->getOperand(1), N->getOperand(2));
475 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
476 EVT Ty = N->getValueType(0);
478 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
481 SDValue SetCC = N->getOperand(0);
483 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
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));
492 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
493 SelectionDAG &DAG = DCI.DAG;
496 switch (N->getOpcode()) {
498 return performADDECombine(N, DAG, DCI, Subtarget);
500 return performSUBECombine(N, DAG, DCI, Subtarget);
502 return performMULCombine(N, DAG, DCI, this);
504 return performSHLCombine(N, DAG, DCI, Subtarget);
506 return performSRACombine(N, DAG, DCI, Subtarget);
508 return performSRLCombine(N, DAG, DCI, Subtarget);
510 return performVSELECTCombine(N, DAG);
512 Val = performSETCCCombine(N, DAG);
520 return MipsTargetLowering::PerformDAGCombine(N, DCI);
524 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
525 MachineBasicBlock *BB) const {
526 switch (MI->getOpcode()) {
528 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
529 case Mips::BPOSGE32_PSEUDO:
530 return emitBPOSGE32(MI, BB);
534 bool MipsSETargetLowering::
535 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
536 unsigned NextStackOffset,
537 const MipsFunctionInfo& FI) const {
538 if (!EnableMipsTailCalls)
541 // Return false if either the callee or caller has a byval argument.
542 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
545 // Return true if the callee's argument area is no larger than the
547 return NextStackOffset <= FI.getIncomingArgSize();
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));
561 Ops.push_back(Callee);
563 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
564 InternalLinkage, CLI, Callee, Chain);
567 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
568 bool HasLo, bool HasHi,
569 SelectionDAG &DAG) const {
570 EVT Ty = Op.getOperand(0).getValueType();
572 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
573 Op.getOperand(0), Op.getOperand(1));
577 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
578 DAG.getConstant(Mips::sub_lo, MVT::i32));
580 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
581 DAG.getConstant(Mips::sub_hi, MVT::i32));
583 if (!HasLo || !HasHi)
584 return HasLo ? Lo : Hi;
586 SDValue Vals[] = { Lo, Hi };
587 return DAG.getMergeValues(Vals, 2, DL);
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);
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);
607 // This function expands mips intrinsic nodes which have 64-bit input operands
610 // out64 = intrinsic-node in64
612 // lo = copy (extract-element (in64, 0))
613 // hi = copy (extract-element (in64, 1))
614 // mips-specific-node
617 // out64 = merge-values (v0, v1)
619 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
621 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
622 SmallVector<SDValue, 3> Ops;
625 // See if Op has a chain input.
627 Ops.push_back(Op->getOperand(OpNo++));
629 // The next operand is the intrinsic opcode.
630 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
632 // See if the next operand has type i64.
633 SDValue Opnd = Op->getOperand(++OpNo), In64;
635 if (Opnd.getValueType() == MVT::i64)
636 In64 = initAccumulator(Opnd, DL, DAG);
640 // Push the remaining operands.
641 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
642 Ops.push_back(Op->getOperand(OpNo));
644 // Add In64 to the end of the list.
649 SmallVector<EVT, 2> ResTys;
651 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
653 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
656 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
657 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
662 assert(Val->getValueType(1) == MVT::Other);
663 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
664 return DAG.getMergeValues(Vals, 2, DL);
667 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
668 SelectionDAG &DAG) const {
669 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
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);
707 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
708 SelectionDAG &DAG) const {
709 switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) {
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);
755 MachineBasicBlock * MipsSETargetLowering::
756 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
758 // bposge32_pseudo $vr0
768 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
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);
784 // Transfer the remainder of BB and its successor edges to Sink.
785 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
787 Sink->transferSuccessorsAndUpdatePHIs(BB);
790 BB->addSuccessor(FBB);
791 BB->addSuccessor(TBB);
792 FBB->addSuccessor(Sink);
793 TBB->addSuccessor(Sink);
795 // Insert the real bposge32 instruction to $BB.
796 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
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);
805 unsigned VR1 = RegInfo.createVirtualRegister(RC);
806 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
807 .addReg(Mips::ZERO).addImm(1);
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);
814 MI->eraseFromParent(); // The pseudo instruction is gone now.