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::GPR32RegClass);
37 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
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::DSPRRegClass);
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 (Subtarget->hasMSA()) {
81 addMSAType(MVT::v16i8, &Mips::MSA128BRegClass);
82 addMSAType(MVT::v8i16, &Mips::MSA128HRegClass);
83 addMSAType(MVT::v4i32, &Mips::MSA128WRegClass);
84 addMSAType(MVT::v2i64, &Mips::MSA128DRegClass);
85 addMSAType(MVT::v8f16, &Mips::MSA128HRegClass);
86 addMSAType(MVT::v4f32, &Mips::MSA128WRegClass);
87 addMSAType(MVT::v2f64, &Mips::MSA128DRegClass);
90 if (!TM.Options.UseSoftFloat) {
91 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
93 // When dealing with single precision only, use libcalls
94 if (!Subtarget->isSingleFloat()) {
95 if (Subtarget->isFP64bit())
96 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
98 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
102 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
103 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
104 setOperationAction(ISD::MULHS, MVT::i32, Custom);
105 setOperationAction(ISD::MULHU, MVT::i32, Custom);
108 setOperationAction(ISD::MULHS, MVT::i64, Custom);
109 setOperationAction(ISD::MULHU, MVT::i64, Custom);
110 setOperationAction(ISD::MUL, MVT::i64, Custom);
113 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
114 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
116 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
117 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
118 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
119 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
120 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
121 setOperationAction(ISD::LOAD, MVT::i32, Custom);
122 setOperationAction(ISD::STORE, MVT::i32, Custom);
124 setTargetDAGCombine(ISD::ADDE);
125 setTargetDAGCombine(ISD::SUBE);
126 setTargetDAGCombine(ISD::MUL);
128 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
129 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
131 computeRegisterProperties();
134 const MipsTargetLowering *
135 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
136 return new MipsSETargetLowering(TM);
139 void MipsSETargetLowering::
140 addMSAType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
141 addRegisterClass(Ty, RC);
143 // Expand all builtin opcodes.
144 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
145 setOperationAction(Opc, Ty, Expand);
147 setOperationAction(ISD::LOAD, Ty, Legal);
148 setOperationAction(ISD::STORE, Ty, Legal);
149 setOperationAction(ISD::BITCAST, Ty, Legal);
153 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
154 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
167 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
168 SelectionDAG &DAG) const {
169 switch(Op.getOpcode()) {
170 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
171 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
172 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
173 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
174 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
175 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
176 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
178 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
179 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
180 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
183 return MipsTargetLowering::LowerOperation(Op, DAG);
187 // Transforms a subgraph in CurDAG if the following pattern is found:
188 // (addc multLo, Lo0), (adde multHi, Hi0),
190 // multHi/Lo: product of multiplication
191 // Lo0: initial value of Lo register
192 // Hi0: initial value of Hi register
193 // Return true if pattern matching was successful.
194 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
195 // ADDENode's second operand must be a flag output of an ADDC node in order
196 // for the matching to be successful.
197 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
199 if (ADDCNode->getOpcode() != ISD::ADDC)
202 SDValue MultHi = ADDENode->getOperand(0);
203 SDValue MultLo = ADDCNode->getOperand(0);
204 SDNode *MultNode = MultHi.getNode();
205 unsigned MultOpc = MultHi.getOpcode();
207 // MultHi and MultLo must be generated by the same node,
208 if (MultLo.getNode() != MultNode)
211 // and it must be a multiplication.
212 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
215 // MultLo amd MultHi must be the first and second output of MultNode
217 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
220 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
221 // of the values of MultNode, in which case MultNode will be removed in later
223 // If there exist users other than ADDENode or ADDCNode, this function returns
224 // here, which will result in MultNode being mapped to a single MULT
225 // instruction node rather than a pair of MULT and MADD instructions being
227 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
232 // Initialize accumulator.
233 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
234 ADDCNode->getOperand(1),
235 ADDENode->getOperand(1));
237 // create MipsMAdd(u) node
238 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
240 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
241 MultNode->getOperand(0),// Factor 0
242 MultNode->getOperand(1),// Factor 1
245 // replace uses of adde and addc here
246 if (!SDValue(ADDCNode, 0).use_empty()) {
247 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
248 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
250 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
252 if (!SDValue(ADDENode, 0).use_empty()) {
253 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
254 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
256 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
263 // Transforms a subgraph in CurDAG if the following pattern is found:
264 // (addc Lo0, multLo), (sube Hi0, multHi),
266 // multHi/Lo: product of multiplication
267 // Lo0: initial value of Lo register
268 // Hi0: initial value of Hi register
269 // Return true if pattern matching was successful.
270 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
271 // SUBENode's second operand must be a flag output of an SUBC node in order
272 // for the matching to be successful.
273 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
275 if (SUBCNode->getOpcode() != ISD::SUBC)
278 SDValue MultHi = SUBENode->getOperand(1);
279 SDValue MultLo = SUBCNode->getOperand(1);
280 SDNode *MultNode = MultHi.getNode();
281 unsigned MultOpc = MultHi.getOpcode();
283 // MultHi and MultLo must be generated by the same node,
284 if (MultLo.getNode() != MultNode)
287 // and it must be a multiplication.
288 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
291 // MultLo amd MultHi must be the first and second output of MultNode
293 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
296 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
297 // of the values of MultNode, in which case MultNode will be removed in later
299 // If there exist users other than SUBENode or SUBCNode, this function returns
300 // here, which will result in MultNode being mapped to a single MULT
301 // instruction node rather than a pair of MULT and MSUB instructions being
303 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
308 // Initialize accumulator.
309 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
310 SUBCNode->getOperand(0),
311 SUBENode->getOperand(0));
313 // create MipsSub(u) node
314 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
316 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
317 MultNode->getOperand(0),// Factor 0
318 MultNode->getOperand(1),// Factor 1
321 // replace uses of sube and subc here
322 if (!SDValue(SUBCNode, 0).use_empty()) {
323 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
324 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
326 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
328 if (!SDValue(SUBENode, 0).use_empty()) {
329 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
330 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
332 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
338 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
339 TargetLowering::DAGCombinerInfo &DCI,
340 const MipsSubtarget *Subtarget) {
341 if (DCI.isBeforeLegalize())
344 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
346 return SDValue(N, 0);
351 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
352 TargetLowering::DAGCombinerInfo &DCI,
353 const MipsSubtarget *Subtarget) {
354 if (DCI.isBeforeLegalize())
357 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
359 return SDValue(N, 0);
364 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
365 EVT ShiftTy, SelectionDAG &DAG) {
366 // Clear the upper (64 - VT.sizeInBits) bits.
367 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
371 return DAG.getConstant(0, VT);
377 // If c is power of 2, return (shl x, log2(c)).
378 if (isPowerOf2_64(C))
379 return DAG.getNode(ISD::SHL, DL, VT, X,
380 DAG.getConstant(Log2_64(C), ShiftTy));
382 unsigned Log2Ceil = Log2_64_Ceil(C);
383 uint64_t Floor = 1LL << Log2_64(C);
384 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
386 // If |c - floor_c| <= |c - ceil_c|,
387 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
388 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
389 if (C - Floor <= Ceil - C) {
390 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
391 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
392 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
395 // If |c - floor_c| > |c - ceil_c|,
396 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
397 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
398 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
399 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
402 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
403 const TargetLowering::DAGCombinerInfo &DCI,
404 const MipsSETargetLowering *TL) {
405 EVT VT = N->getValueType(0);
407 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
409 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
410 VT, TL->getScalarShiftAmountTy(VT), DAG);
412 return SDValue(N, 0);
415 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
417 const MipsSubtarget *Subtarget) {
418 // See if this is a vector splat immediate node.
419 APInt SplatValue, SplatUndef;
420 unsigned SplatBitSize;
422 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
423 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
426 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
427 EltSize, !Subtarget->isLittle()) ||
428 (SplatBitSize != EltSize) ||
429 (SplatValue.getZExtValue() >= EltSize))
432 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
433 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
436 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
437 TargetLowering::DAGCombinerInfo &DCI,
438 const MipsSubtarget *Subtarget) {
439 EVT Ty = N->getValueType(0);
441 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
444 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
447 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
448 TargetLowering::DAGCombinerInfo &DCI,
449 const MipsSubtarget *Subtarget) {
450 EVT Ty = N->getValueType(0);
452 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
455 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
459 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
460 TargetLowering::DAGCombinerInfo &DCI,
461 const MipsSubtarget *Subtarget) {
462 EVT Ty = N->getValueType(0);
464 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
467 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
470 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
471 bool IsV216 = (Ty == MVT::v2i16);
475 case ISD::SETNE: return true;
479 case ISD::SETGE: return IsV216;
483 case ISD::SETUGE: return !IsV216;
484 default: return false;
488 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
489 EVT Ty = N->getValueType(0);
491 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
494 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
497 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
498 N->getOperand(1), N->getOperand(2));
501 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
502 EVT Ty = N->getValueType(0);
504 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
507 SDValue SetCC = N->getOperand(0);
509 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
512 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
513 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
514 N->getOperand(2), SetCC.getOperand(2));
518 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
519 SelectionDAG &DAG = DCI.DAG;
522 switch (N->getOpcode()) {
524 return performADDECombine(N, DAG, DCI, Subtarget);
526 return performSUBECombine(N, DAG, DCI, Subtarget);
528 return performMULCombine(N, DAG, DCI, this);
530 return performSHLCombine(N, DAG, DCI, Subtarget);
532 return performSRACombine(N, DAG, DCI, Subtarget);
534 return performSRLCombine(N, DAG, DCI, Subtarget);
536 return performVSELECTCombine(N, DAG);
538 Val = performSETCCCombine(N, DAG);
546 return MipsTargetLowering::PerformDAGCombine(N, DCI);
550 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
551 MachineBasicBlock *BB) const {
552 switch (MI->getOpcode()) {
554 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
555 case Mips::BPOSGE32_PSEUDO:
556 return emitBPOSGE32(MI, BB);
560 bool MipsSETargetLowering::
561 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
562 unsigned NextStackOffset,
563 const MipsFunctionInfo& FI) const {
564 if (!EnableMipsTailCalls)
567 // Return false if either the callee or caller has a byval argument.
568 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
571 // Return true if the callee's argument area is no larger than the
573 return NextStackOffset <= FI.getIncomingArgSize();
576 void MipsSETargetLowering::
577 getOpndList(SmallVectorImpl<SDValue> &Ops,
578 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
579 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
580 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
581 // T9 should contain the address of the callee function if
582 // -reloction-model=pic or it is an indirect call.
583 if (IsPICCall || !GlobalOrExternal) {
584 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
585 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
587 Ops.push_back(Callee);
589 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
590 InternalLinkage, CLI, Callee, Chain);
593 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
594 bool HasLo, bool HasHi,
595 SelectionDAG &DAG) const {
596 EVT Ty = Op.getOperand(0).getValueType();
598 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
599 Op.getOperand(0), Op.getOperand(1));
603 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
604 DAG.getConstant(Mips::sub_lo, MVT::i32));
606 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
607 DAG.getConstant(Mips::sub_hi, MVT::i32));
609 if (!HasLo || !HasHi)
610 return HasLo ? Lo : Hi;
612 SDValue Vals[] = { Lo, Hi };
613 return DAG.getMergeValues(Vals, 2, DL);
617 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
618 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
619 DAG.getConstant(0, MVT::i32));
620 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
621 DAG.getConstant(1, MVT::i32));
622 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
625 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
626 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
627 DAG.getConstant(Mips::sub_lo, MVT::i32));
628 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
629 DAG.getConstant(Mips::sub_hi, MVT::i32));
630 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
633 // This function expands mips intrinsic nodes which have 64-bit input operands
636 // out64 = intrinsic-node in64
638 // lo = copy (extract-element (in64, 0))
639 // hi = copy (extract-element (in64, 1))
640 // mips-specific-node
643 // out64 = merge-values (v0, v1)
645 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
647 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
648 SmallVector<SDValue, 3> Ops;
651 // See if Op has a chain input.
653 Ops.push_back(Op->getOperand(OpNo++));
655 // The next operand is the intrinsic opcode.
656 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
658 // See if the next operand has type i64.
659 SDValue Opnd = Op->getOperand(++OpNo), In64;
661 if (Opnd.getValueType() == MVT::i64)
662 In64 = initAccumulator(Opnd, DL, DAG);
666 // Push the remaining operands.
667 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
668 Ops.push_back(Op->getOperand(OpNo));
670 // Add In64 to the end of the list.
675 SmallVector<EVT, 2> ResTys;
677 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
679 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
682 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
683 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
688 assert(Val->getValueType(1) == MVT::Other);
689 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
690 return DAG.getMergeValues(Vals, 2, DL);
693 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
694 SelectionDAG &DAG) const {
695 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
698 case Intrinsic::mips_shilo:
699 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
700 case Intrinsic::mips_dpau_h_qbl:
701 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
702 case Intrinsic::mips_dpau_h_qbr:
703 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
704 case Intrinsic::mips_dpsu_h_qbl:
705 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
706 case Intrinsic::mips_dpsu_h_qbr:
707 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
708 case Intrinsic::mips_dpa_w_ph:
709 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
710 case Intrinsic::mips_dps_w_ph:
711 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
712 case Intrinsic::mips_dpax_w_ph:
713 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
714 case Intrinsic::mips_dpsx_w_ph:
715 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
716 case Intrinsic::mips_mulsa_w_ph:
717 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
718 case Intrinsic::mips_mult:
719 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
720 case Intrinsic::mips_multu:
721 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
722 case Intrinsic::mips_madd:
723 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
724 case Intrinsic::mips_maddu:
725 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
726 case Intrinsic::mips_msub:
727 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
728 case Intrinsic::mips_msubu:
729 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
733 static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
735 SDValue ChainIn = Op->getOperand(0);
736 SDValue Address = Op->getOperand(2);
737 SDValue Offset = Op->getOperand(3);
738 EVT ResTy = Op->getValueType(0);
739 EVT PtrTy = Address->getValueType(0);
741 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
743 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
747 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
748 SelectionDAG &DAG) const {
749 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
753 case Intrinsic::mips_extp:
754 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
755 case Intrinsic::mips_extpdp:
756 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
757 case Intrinsic::mips_extr_w:
758 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
759 case Intrinsic::mips_extr_r_w:
760 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
761 case Intrinsic::mips_extr_rs_w:
762 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
763 case Intrinsic::mips_extr_s_h:
764 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
765 case Intrinsic::mips_mthlip:
766 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
767 case Intrinsic::mips_mulsaq_s_w_ph:
768 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
769 case Intrinsic::mips_maq_s_w_phl:
770 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
771 case Intrinsic::mips_maq_s_w_phr:
772 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
773 case Intrinsic::mips_maq_sa_w_phl:
774 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
775 case Intrinsic::mips_maq_sa_w_phr:
776 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
777 case Intrinsic::mips_dpaq_s_w_ph:
778 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
779 case Intrinsic::mips_dpsq_s_w_ph:
780 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
781 case Intrinsic::mips_dpaq_sa_l_w:
782 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
783 case Intrinsic::mips_dpsq_sa_l_w:
784 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
785 case Intrinsic::mips_dpaqx_s_w_ph:
786 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
787 case Intrinsic::mips_dpaqx_sa_w_ph:
788 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
789 case Intrinsic::mips_dpsqx_s_w_ph:
790 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
791 case Intrinsic::mips_dpsqx_sa_w_ph:
792 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
793 case Intrinsic::mips_ld_b:
794 case Intrinsic::mips_ld_h:
795 case Intrinsic::mips_ld_w:
796 case Intrinsic::mips_ld_d:
797 case Intrinsic::mips_ldx_b:
798 case Intrinsic::mips_ldx_h:
799 case Intrinsic::mips_ldx_w:
800 case Intrinsic::mips_ldx_d:
801 return lowerMSALoadIntr(Op, DAG, Intr);
805 static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
807 SDValue ChainIn = Op->getOperand(0);
808 SDValue Value = Op->getOperand(2);
809 SDValue Address = Op->getOperand(3);
810 SDValue Offset = Op->getOperand(4);
811 EVT PtrTy = Address->getValueType(0);
813 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
815 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
819 SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
820 SelectionDAG &DAG) const {
821 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
825 case Intrinsic::mips_st_b:
826 case Intrinsic::mips_st_h:
827 case Intrinsic::mips_st_w:
828 case Intrinsic::mips_st_d:
829 case Intrinsic::mips_stx_b:
830 case Intrinsic::mips_stx_h:
831 case Intrinsic::mips_stx_w:
832 case Intrinsic::mips_stx_d:
833 return lowerMSAStoreIntr(Op, DAG, Intr);
837 MachineBasicBlock * MipsSETargetLowering::
838 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
840 // bposge32_pseudo $vr0
850 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
852 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
853 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
854 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
855 DebugLoc DL = MI->getDebugLoc();
856 const BasicBlock *LLVM_BB = BB->getBasicBlock();
857 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
858 MachineFunction *F = BB->getParent();
859 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
860 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
861 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
866 // Transfer the remainder of BB and its successor edges to Sink.
867 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
869 Sink->transferSuccessorsAndUpdatePHIs(BB);
872 BB->addSuccessor(FBB);
873 BB->addSuccessor(TBB);
874 FBB->addSuccessor(Sink);
875 TBB->addSuccessor(Sink);
877 // Insert the real bposge32 instruction to $BB.
878 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
881 unsigned VR2 = RegInfo.createVirtualRegister(RC);
882 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
883 .addReg(Mips::ZERO).addImm(0);
884 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
887 unsigned VR1 = RegInfo.createVirtualRegister(RC);
888 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
889 .addReg(Mips::ZERO).addImm(1);
891 // Insert phi function to $Sink.
892 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
893 MI->getOperand(0).getReg())
894 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
896 MI->eraseFromParent(); // The pseudo instruction is gone now.