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_WO_CHAIN, MVT::Other, Custom);
129 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
130 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
132 computeRegisterProperties();
135 const MipsTargetLowering *
136 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
137 return new MipsSETargetLowering(TM);
140 void MipsSETargetLowering::
141 addMSAType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
142 addRegisterClass(Ty, RC);
144 // Expand all builtin opcodes.
145 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
146 setOperationAction(Opc, Ty, Expand);
148 setOperationAction(ISD::LOAD, Ty, Legal);
149 setOperationAction(ISD::STORE, Ty, Legal);
150 setOperationAction(ISD::BITCAST, Ty, Legal);
154 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
155 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
168 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
169 SelectionDAG &DAG) const {
170 switch(Op.getOpcode()) {
171 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
172 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
173 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
174 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
175 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
176 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
177 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
179 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
180 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
181 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
184 return MipsTargetLowering::LowerOperation(Op, DAG);
188 // Transforms a subgraph in CurDAG if the following pattern is found:
189 // (addc multLo, Lo0), (adde multHi, Hi0),
191 // multHi/Lo: product of multiplication
192 // Lo0: initial value of Lo register
193 // Hi0: initial value of Hi register
194 // Return true if pattern matching was successful.
195 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
196 // ADDENode's second operand must be a flag output of an ADDC node in order
197 // for the matching to be successful.
198 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
200 if (ADDCNode->getOpcode() != ISD::ADDC)
203 SDValue MultHi = ADDENode->getOperand(0);
204 SDValue MultLo = ADDCNode->getOperand(0);
205 SDNode *MultNode = MultHi.getNode();
206 unsigned MultOpc = MultHi.getOpcode();
208 // MultHi and MultLo must be generated by the same node,
209 if (MultLo.getNode() != MultNode)
212 // and it must be a multiplication.
213 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
216 // MultLo amd MultHi must be the first and second output of MultNode
218 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
221 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
222 // of the values of MultNode, in which case MultNode will be removed in later
224 // If there exist users other than ADDENode or ADDCNode, this function returns
225 // here, which will result in MultNode being mapped to a single MULT
226 // instruction node rather than a pair of MULT and MADD instructions being
228 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
233 // Initialize accumulator.
234 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
235 ADDCNode->getOperand(1),
236 ADDENode->getOperand(1));
238 // create MipsMAdd(u) node
239 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
241 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
242 MultNode->getOperand(0),// Factor 0
243 MultNode->getOperand(1),// Factor 1
246 // replace uses of adde and addc here
247 if (!SDValue(ADDCNode, 0).use_empty()) {
248 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
249 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
251 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
253 if (!SDValue(ADDENode, 0).use_empty()) {
254 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
255 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
257 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
264 // Transforms a subgraph in CurDAG if the following pattern is found:
265 // (addc Lo0, multLo), (sube Hi0, multHi),
267 // multHi/Lo: product of multiplication
268 // Lo0: initial value of Lo register
269 // Hi0: initial value of Hi register
270 // Return true if pattern matching was successful.
271 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
272 // SUBENode's second operand must be a flag output of an SUBC node in order
273 // for the matching to be successful.
274 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
276 if (SUBCNode->getOpcode() != ISD::SUBC)
279 SDValue MultHi = SUBENode->getOperand(1);
280 SDValue MultLo = SUBCNode->getOperand(1);
281 SDNode *MultNode = MultHi.getNode();
282 unsigned MultOpc = MultHi.getOpcode();
284 // MultHi and MultLo must be generated by the same node,
285 if (MultLo.getNode() != MultNode)
288 // and it must be a multiplication.
289 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
292 // MultLo amd MultHi must be the first and second output of MultNode
294 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
297 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
298 // of the values of MultNode, in which case MultNode will be removed in later
300 // If there exist users other than SUBENode or SUBCNode, this function returns
301 // here, which will result in MultNode being mapped to a single MULT
302 // instruction node rather than a pair of MULT and MSUB instructions being
304 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
309 // Initialize accumulator.
310 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
311 SUBCNode->getOperand(0),
312 SUBENode->getOperand(0));
314 // create MipsSub(u) node
315 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
317 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
318 MultNode->getOperand(0),// Factor 0
319 MultNode->getOperand(1),// Factor 1
322 // replace uses of sube and subc here
323 if (!SDValue(SUBCNode, 0).use_empty()) {
324 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
325 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
327 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
329 if (!SDValue(SUBENode, 0).use_empty()) {
330 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
331 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
333 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
339 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
340 TargetLowering::DAGCombinerInfo &DCI,
341 const MipsSubtarget *Subtarget) {
342 if (DCI.isBeforeLegalize())
345 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
347 return SDValue(N, 0);
352 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
353 TargetLowering::DAGCombinerInfo &DCI,
354 const MipsSubtarget *Subtarget) {
355 if (DCI.isBeforeLegalize())
358 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
360 return SDValue(N, 0);
365 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
366 EVT ShiftTy, SelectionDAG &DAG) {
367 // Clear the upper (64 - VT.sizeInBits) bits.
368 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
372 return DAG.getConstant(0, VT);
378 // If c is power of 2, return (shl x, log2(c)).
379 if (isPowerOf2_64(C))
380 return DAG.getNode(ISD::SHL, DL, VT, X,
381 DAG.getConstant(Log2_64(C), ShiftTy));
383 unsigned Log2Ceil = Log2_64_Ceil(C);
384 uint64_t Floor = 1LL << Log2_64(C);
385 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
387 // If |c - floor_c| <= |c - ceil_c|,
388 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
389 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
390 if (C - Floor <= Ceil - C) {
391 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
392 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
393 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
396 // If |c - floor_c| > |c - ceil_c|,
397 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
398 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
399 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
400 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
403 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
404 const TargetLowering::DAGCombinerInfo &DCI,
405 const MipsSETargetLowering *TL) {
406 EVT VT = N->getValueType(0);
408 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
410 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
411 VT, TL->getScalarShiftAmountTy(VT), DAG);
413 return SDValue(N, 0);
416 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
418 const MipsSubtarget *Subtarget) {
419 // See if this is a vector splat immediate node.
420 APInt SplatValue, SplatUndef;
421 unsigned SplatBitSize;
423 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
424 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
427 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
428 EltSize, !Subtarget->isLittle()) ||
429 (SplatBitSize != EltSize) ||
430 (SplatValue.getZExtValue() >= EltSize))
433 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
434 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
437 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
438 TargetLowering::DAGCombinerInfo &DCI,
439 const MipsSubtarget *Subtarget) {
440 EVT Ty = N->getValueType(0);
442 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
445 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
448 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
449 TargetLowering::DAGCombinerInfo &DCI,
450 const MipsSubtarget *Subtarget) {
451 EVT Ty = N->getValueType(0);
453 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
456 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
460 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
461 TargetLowering::DAGCombinerInfo &DCI,
462 const MipsSubtarget *Subtarget) {
463 EVT Ty = N->getValueType(0);
465 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
468 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
471 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
472 bool IsV216 = (Ty == MVT::v2i16);
476 case ISD::SETNE: return true;
480 case ISD::SETGE: return IsV216;
484 case ISD::SETUGE: return !IsV216;
485 default: return false;
489 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
490 EVT Ty = N->getValueType(0);
492 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
495 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
498 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
499 N->getOperand(1), N->getOperand(2));
502 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
503 EVT Ty = N->getValueType(0);
505 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
508 SDValue SetCC = N->getOperand(0);
510 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
513 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
514 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
515 N->getOperand(2), SetCC.getOperand(2));
519 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
520 SelectionDAG &DAG = DCI.DAG;
523 switch (N->getOpcode()) {
525 return performADDECombine(N, DAG, DCI, Subtarget);
527 return performSUBECombine(N, DAG, DCI, Subtarget);
529 return performMULCombine(N, DAG, DCI, this);
531 return performSHLCombine(N, DAG, DCI, Subtarget);
533 return performSRACombine(N, DAG, DCI, Subtarget);
535 return performSRLCombine(N, DAG, DCI, Subtarget);
537 return performVSELECTCombine(N, DAG);
539 Val = performSETCCCombine(N, DAG);
547 return MipsTargetLowering::PerformDAGCombine(N, DCI);
551 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
552 MachineBasicBlock *BB) const {
553 switch (MI->getOpcode()) {
555 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
556 case Mips::BPOSGE32_PSEUDO:
557 return emitBPOSGE32(MI, BB);
558 case Mips::SNZ_B_PSEUDO:
559 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
560 case Mips::SNZ_H_PSEUDO:
561 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
562 case Mips::SNZ_W_PSEUDO:
563 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
564 case Mips::SNZ_D_PSEUDO:
565 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
566 case Mips::SNZ_V_PSEUDO:
567 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
568 case Mips::SZ_B_PSEUDO:
569 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
570 case Mips::SZ_H_PSEUDO:
571 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
572 case Mips::SZ_W_PSEUDO:
573 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
574 case Mips::SZ_D_PSEUDO:
575 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
576 case Mips::SZ_V_PSEUDO:
577 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
581 bool MipsSETargetLowering::
582 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
583 unsigned NextStackOffset,
584 const MipsFunctionInfo& FI) const {
585 if (!EnableMipsTailCalls)
588 // Return false if either the callee or caller has a byval argument.
589 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
592 // Return true if the callee's argument area is no larger than the
594 return NextStackOffset <= FI.getIncomingArgSize();
597 void MipsSETargetLowering::
598 getOpndList(SmallVectorImpl<SDValue> &Ops,
599 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
600 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
601 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
602 // T9 should contain the address of the callee function if
603 // -reloction-model=pic or it is an indirect call.
604 if (IsPICCall || !GlobalOrExternal) {
605 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
606 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
608 Ops.push_back(Callee);
610 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
611 InternalLinkage, CLI, Callee, Chain);
614 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
615 bool HasLo, bool HasHi,
616 SelectionDAG &DAG) const {
617 EVT Ty = Op.getOperand(0).getValueType();
619 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
620 Op.getOperand(0), Op.getOperand(1));
624 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
625 DAG.getConstant(Mips::sub_lo, MVT::i32));
627 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
628 DAG.getConstant(Mips::sub_hi, MVT::i32));
630 if (!HasLo || !HasHi)
631 return HasLo ? Lo : Hi;
633 SDValue Vals[] = { Lo, Hi };
634 return DAG.getMergeValues(Vals, 2, DL);
638 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
639 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
640 DAG.getConstant(0, MVT::i32));
641 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
642 DAG.getConstant(1, MVT::i32));
643 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
646 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
647 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
648 DAG.getConstant(Mips::sub_lo, MVT::i32));
649 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
650 DAG.getConstant(Mips::sub_hi, MVT::i32));
651 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
654 // This function expands mips intrinsic nodes which have 64-bit input operands
657 // out64 = intrinsic-node in64
659 // lo = copy (extract-element (in64, 0))
660 // hi = copy (extract-element (in64, 1))
661 // mips-specific-node
664 // out64 = merge-values (v0, v1)
666 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
668 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
669 SmallVector<SDValue, 3> Ops;
672 // See if Op has a chain input.
674 Ops.push_back(Op->getOperand(OpNo++));
676 // The next operand is the intrinsic opcode.
677 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
679 // See if the next operand has type i64.
680 SDValue Opnd = Op->getOperand(++OpNo), In64;
682 if (Opnd.getValueType() == MVT::i64)
683 In64 = initAccumulator(Opnd, DL, DAG);
687 // Push the remaining operands.
688 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
689 Ops.push_back(Op->getOperand(OpNo));
691 // Add In64 to the end of the list.
696 SmallVector<EVT, 2> ResTys;
698 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
700 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
703 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
704 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
709 assert(Val->getValueType(1) == MVT::Other);
710 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
711 return DAG.getMergeValues(Vals, 2, DL);
714 static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
716 SDValue Value = Op->getOperand(1);
717 EVT ResTy = Op->getValueType(0);
719 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
724 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
725 SelectionDAG &DAG) const {
726 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
729 case Intrinsic::mips_shilo:
730 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
731 case Intrinsic::mips_dpau_h_qbl:
732 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
733 case Intrinsic::mips_dpau_h_qbr:
734 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
735 case Intrinsic::mips_dpsu_h_qbl:
736 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
737 case Intrinsic::mips_dpsu_h_qbr:
738 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
739 case Intrinsic::mips_dpa_w_ph:
740 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
741 case Intrinsic::mips_dps_w_ph:
742 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
743 case Intrinsic::mips_dpax_w_ph:
744 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
745 case Intrinsic::mips_dpsx_w_ph:
746 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
747 case Intrinsic::mips_mulsa_w_ph:
748 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
749 case Intrinsic::mips_mult:
750 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
751 case Intrinsic::mips_multu:
752 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
753 case Intrinsic::mips_madd:
754 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
755 case Intrinsic::mips_maddu:
756 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
757 case Intrinsic::mips_msub:
758 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
759 case Intrinsic::mips_msubu:
760 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
761 case Intrinsic::mips_bnz_b:
762 case Intrinsic::mips_bnz_h:
763 case Intrinsic::mips_bnz_w:
764 case Intrinsic::mips_bnz_d:
765 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
766 case Intrinsic::mips_bnz_v:
767 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
768 case Intrinsic::mips_bz_b:
769 case Intrinsic::mips_bz_h:
770 case Intrinsic::mips_bz_w:
771 case Intrinsic::mips_bz_d:
772 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
773 case Intrinsic::mips_bz_v:
774 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
778 static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
780 SDValue ChainIn = Op->getOperand(0);
781 SDValue Address = Op->getOperand(2);
782 SDValue Offset = Op->getOperand(3);
783 EVT ResTy = Op->getValueType(0);
784 EVT PtrTy = Address->getValueType(0);
786 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
788 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
792 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
793 SelectionDAG &DAG) const {
794 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
798 case Intrinsic::mips_extp:
799 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
800 case Intrinsic::mips_extpdp:
801 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
802 case Intrinsic::mips_extr_w:
803 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
804 case Intrinsic::mips_extr_r_w:
805 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
806 case Intrinsic::mips_extr_rs_w:
807 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
808 case Intrinsic::mips_extr_s_h:
809 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
810 case Intrinsic::mips_mthlip:
811 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
812 case Intrinsic::mips_mulsaq_s_w_ph:
813 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
814 case Intrinsic::mips_maq_s_w_phl:
815 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
816 case Intrinsic::mips_maq_s_w_phr:
817 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
818 case Intrinsic::mips_maq_sa_w_phl:
819 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
820 case Intrinsic::mips_maq_sa_w_phr:
821 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
822 case Intrinsic::mips_dpaq_s_w_ph:
823 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
824 case Intrinsic::mips_dpsq_s_w_ph:
825 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
826 case Intrinsic::mips_dpaq_sa_l_w:
827 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
828 case Intrinsic::mips_dpsq_sa_l_w:
829 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
830 case Intrinsic::mips_dpaqx_s_w_ph:
831 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
832 case Intrinsic::mips_dpaqx_sa_w_ph:
833 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
834 case Intrinsic::mips_dpsqx_s_w_ph:
835 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
836 case Intrinsic::mips_dpsqx_sa_w_ph:
837 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
838 case Intrinsic::mips_ld_b:
839 case Intrinsic::mips_ld_h:
840 case Intrinsic::mips_ld_w:
841 case Intrinsic::mips_ld_d:
842 case Intrinsic::mips_ldx_b:
843 case Intrinsic::mips_ldx_h:
844 case Intrinsic::mips_ldx_w:
845 case Intrinsic::mips_ldx_d:
846 return lowerMSALoadIntr(Op, DAG, Intr);
850 static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
852 SDValue ChainIn = Op->getOperand(0);
853 SDValue Value = Op->getOperand(2);
854 SDValue Address = Op->getOperand(3);
855 SDValue Offset = Op->getOperand(4);
856 EVT PtrTy = Address->getValueType(0);
858 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
860 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
864 SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
865 SelectionDAG &DAG) const {
866 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
870 case Intrinsic::mips_st_b:
871 case Intrinsic::mips_st_h:
872 case Intrinsic::mips_st_w:
873 case Intrinsic::mips_st_d:
874 case Intrinsic::mips_stx_b:
875 case Intrinsic::mips_stx_h:
876 case Intrinsic::mips_stx_w:
877 case Intrinsic::mips_stx_d:
878 return lowerMSAStoreIntr(Op, DAG, Intr);
882 MachineBasicBlock * MipsSETargetLowering::
883 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
885 // bposge32_pseudo $vr0
895 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
897 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
898 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
899 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
900 DebugLoc DL = MI->getDebugLoc();
901 const BasicBlock *LLVM_BB = BB->getBasicBlock();
902 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
903 MachineFunction *F = BB->getParent();
904 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
905 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
906 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
911 // Transfer the remainder of BB and its successor edges to Sink.
912 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
914 Sink->transferSuccessorsAndUpdatePHIs(BB);
917 BB->addSuccessor(FBB);
918 BB->addSuccessor(TBB);
919 FBB->addSuccessor(Sink);
920 TBB->addSuccessor(Sink);
922 // Insert the real bposge32 instruction to $BB.
923 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
926 unsigned VR2 = RegInfo.createVirtualRegister(RC);
927 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
928 .addReg(Mips::ZERO).addImm(0);
929 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
932 unsigned VR1 = RegInfo.createVirtualRegister(RC);
933 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
934 .addReg(Mips::ZERO).addImm(1);
936 // Insert phi function to $Sink.
937 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
938 MI->getOperand(0).getReg())
939 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
941 MI->eraseFromParent(); // The pseudo instruction is gone now.
945 MachineBasicBlock * MipsSETargetLowering::
946 emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
947 unsigned BranchOp) const{
949 // vany_nonzero $rd, $ws
960 // $rd = phi($rd1, $fbb, $rd2, $tbb)
962 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
963 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
964 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
965 DebugLoc DL = MI->getDebugLoc();
966 const BasicBlock *LLVM_BB = BB->getBasicBlock();
967 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
968 MachineFunction *F = BB->getParent();
969 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
970 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
971 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
976 // Transfer the remainder of BB and its successor edges to Sink.
977 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
979 Sink->transferSuccessorsAndUpdatePHIs(BB);
982 BB->addSuccessor(FBB);
983 BB->addSuccessor(TBB);
984 FBB->addSuccessor(Sink);
985 TBB->addSuccessor(Sink);
987 // Insert the real bnz.b instruction to $BB.
988 BuildMI(BB, DL, TII->get(BranchOp))
989 .addReg(MI->getOperand(1).getReg())
993 unsigned RD1 = RegInfo.createVirtualRegister(RC);
994 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
995 .addReg(Mips::ZERO).addImm(0);
996 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
999 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1000 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1001 .addReg(Mips::ZERO).addImm(1);
1003 // Insert phi function to $Sink.
1004 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1005 MI->getOperand(0).getReg())
1006 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1008 MI->eraseFromParent(); // The pseudo instruction is gone now.