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 static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
29 cl::desc("Expand double precision loads and "
30 "stores to their single precision "
33 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
34 : MipsTargetLowering(TM) {
35 // Set up the register classes
37 clearRegisterClasses();
39 addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
42 addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
44 if (Subtarget->hasDSP()) {
45 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
47 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
48 addRegisterClass(VecTys[i], &Mips::DSPRRegClass);
50 // Expand all builtin opcodes.
51 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
52 setOperationAction(Opc, VecTys[i], Expand);
54 setOperationAction(ISD::ADD, VecTys[i], Legal);
55 setOperationAction(ISD::SUB, VecTys[i], Legal);
56 setOperationAction(ISD::LOAD, VecTys[i], Legal);
57 setOperationAction(ISD::STORE, VecTys[i], Legal);
58 setOperationAction(ISD::BITCAST, VecTys[i], Legal);
61 // Expand all truncating stores and extending loads.
62 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
63 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
65 for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) {
66 for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1)
67 setTruncStoreAction((MVT::SimpleValueType)VT0,
68 (MVT::SimpleValueType)VT1, Expand);
70 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
71 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
72 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
75 setTargetDAGCombine(ISD::SHL);
76 setTargetDAGCombine(ISD::SRA);
77 setTargetDAGCombine(ISD::SRL);
78 setTargetDAGCombine(ISD::SETCC);
79 setTargetDAGCombine(ISD::VSELECT);
82 if (Subtarget->hasDSPR2())
83 setOperationAction(ISD::MUL, MVT::v2i16, Legal);
85 if (Subtarget->hasMSA()) {
86 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass);
87 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass);
88 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass);
89 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass);
90 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass);
91 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
92 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
94 setTargetDAGCombine(ISD::XOR);
97 if (!Subtarget->mipsSEUsesSoftFloat()) {
98 addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
100 // When dealing with single precision only, use libcalls
101 if (!Subtarget->isSingleFloat()) {
102 if (Subtarget->isFP64bit())
103 addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
105 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
109 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom);
110 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom);
111 setOperationAction(ISD::MULHS, MVT::i32, Custom);
112 setOperationAction(ISD::MULHU, MVT::i32, Custom);
115 setOperationAction(ISD::MULHS, MVT::i64, Custom);
116 setOperationAction(ISD::MULHU, MVT::i64, Custom);
117 setOperationAction(ISD::MUL, MVT::i64, Custom);
120 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
121 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
123 setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
124 setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
125 setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
126 setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
127 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
128 setOperationAction(ISD::LOAD, MVT::i32, Custom);
129 setOperationAction(ISD::STORE, MVT::i32, Custom);
131 setTargetDAGCombine(ISD::ADDE);
132 setTargetDAGCombine(ISD::SUBE);
133 setTargetDAGCombine(ISD::MUL);
135 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
136 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
137 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
140 setOperationAction(ISD::LOAD, MVT::f64, Custom);
141 setOperationAction(ISD::STORE, MVT::f64, Custom);
144 computeRegisterProperties();
147 const MipsTargetLowering *
148 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
149 return new MipsSETargetLowering(TM);
152 // Enable MSA support for the given integer type and Register class.
153 void MipsSETargetLowering::
154 addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
155 addRegisterClass(Ty, RC);
157 // Expand all builtin opcodes.
158 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
159 setOperationAction(Opc, Ty, Expand);
161 setOperationAction(ISD::BITCAST, Ty, Legal);
162 setOperationAction(ISD::LOAD, Ty, Legal);
163 setOperationAction(ISD::STORE, Ty, Legal);
164 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom);
166 setOperationAction(ISD::ADD, Ty, Legal);
167 setOperationAction(ISD::AND, Ty, Legal);
168 setOperationAction(ISD::CTLZ, Ty, Legal);
169 setOperationAction(ISD::MUL, Ty, Legal);
170 setOperationAction(ISD::OR, Ty, Legal);
171 setOperationAction(ISD::SDIV, Ty, Legal);
172 setOperationAction(ISD::SHL, Ty, Legal);
173 setOperationAction(ISD::SRA, Ty, Legal);
174 setOperationAction(ISD::SRL, Ty, Legal);
175 setOperationAction(ISD::SUB, Ty, Legal);
176 setOperationAction(ISD::UDIV, Ty, Legal);
177 setOperationAction(ISD::XOR, Ty, Legal);
180 // Enable MSA support for the given floating-point type and Register class.
181 void MipsSETargetLowering::
182 addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
183 addRegisterClass(Ty, RC);
185 // Expand all builtin opcodes.
186 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
187 setOperationAction(Opc, Ty, Expand);
189 setOperationAction(ISD::LOAD, Ty, Legal);
190 setOperationAction(ISD::STORE, Ty, Legal);
191 setOperationAction(ISD::BITCAST, Ty, Legal);
193 if (Ty != MVT::v8f16) {
194 setOperationAction(ISD::FADD, Ty, Legal);
195 setOperationAction(ISD::FDIV, Ty, Legal);
196 setOperationAction(ISD::FLOG2, Ty, Legal);
197 setOperationAction(ISD::FMUL, Ty, Legal);
198 setOperationAction(ISD::FRINT, Ty, Legal);
199 setOperationAction(ISD::FSQRT, Ty, Legal);
200 setOperationAction(ISD::FSUB, Ty, Legal);
205 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
206 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
219 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
220 SelectionDAG &DAG) const {
221 switch(Op.getOpcode()) {
222 case ISD::LOAD: return lowerLOAD(Op, DAG);
223 case ISD::STORE: return lowerSTORE(Op, DAG);
224 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
225 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
226 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
227 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
228 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
229 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
230 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
232 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
233 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
234 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
235 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
238 return MipsTargetLowering::LowerOperation(Op, DAG);
242 // Transforms a subgraph in CurDAG if the following pattern is found:
243 // (addc multLo, Lo0), (adde multHi, Hi0),
245 // multHi/Lo: product of multiplication
246 // Lo0: initial value of Lo register
247 // Hi0: initial value of Hi register
248 // Return true if pattern matching was successful.
249 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
250 // ADDENode's second operand must be a flag output of an ADDC node in order
251 // for the matching to be successful.
252 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
254 if (ADDCNode->getOpcode() != ISD::ADDC)
257 SDValue MultHi = ADDENode->getOperand(0);
258 SDValue MultLo = ADDCNode->getOperand(0);
259 SDNode *MultNode = MultHi.getNode();
260 unsigned MultOpc = MultHi.getOpcode();
262 // MultHi and MultLo must be generated by the same node,
263 if (MultLo.getNode() != MultNode)
266 // and it must be a multiplication.
267 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
270 // MultLo amd MultHi must be the first and second output of MultNode
272 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
275 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
276 // of the values of MultNode, in which case MultNode will be removed in later
278 // If there exist users other than ADDENode or ADDCNode, this function returns
279 // here, which will result in MultNode being mapped to a single MULT
280 // instruction node rather than a pair of MULT and MADD instructions being
282 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
287 // Initialize accumulator.
288 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
289 ADDCNode->getOperand(1),
290 ADDENode->getOperand(1));
292 // create MipsMAdd(u) node
293 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
295 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
296 MultNode->getOperand(0),// Factor 0
297 MultNode->getOperand(1),// Factor 1
300 // replace uses of adde and addc here
301 if (!SDValue(ADDCNode, 0).use_empty()) {
302 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
303 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
305 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
307 if (!SDValue(ADDENode, 0).use_empty()) {
308 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
309 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
311 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
318 // Transforms a subgraph in CurDAG if the following pattern is found:
319 // (addc Lo0, multLo), (sube Hi0, multHi),
321 // multHi/Lo: product of multiplication
322 // Lo0: initial value of Lo register
323 // Hi0: initial value of Hi register
324 // Return true if pattern matching was successful.
325 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
326 // SUBENode's second operand must be a flag output of an SUBC node in order
327 // for the matching to be successful.
328 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
330 if (SUBCNode->getOpcode() != ISD::SUBC)
333 SDValue MultHi = SUBENode->getOperand(1);
334 SDValue MultLo = SUBCNode->getOperand(1);
335 SDNode *MultNode = MultHi.getNode();
336 unsigned MultOpc = MultHi.getOpcode();
338 // MultHi and MultLo must be generated by the same node,
339 if (MultLo.getNode() != MultNode)
342 // and it must be a multiplication.
343 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
346 // MultLo amd MultHi must be the first and second output of MultNode
348 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
351 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
352 // of the values of MultNode, in which case MultNode will be removed in later
354 // If there exist users other than SUBENode or SUBCNode, this function returns
355 // here, which will result in MultNode being mapped to a single MULT
356 // instruction node rather than a pair of MULT and MSUB instructions being
358 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
363 // Initialize accumulator.
364 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
365 SUBCNode->getOperand(0),
366 SUBENode->getOperand(0));
368 // create MipsSub(u) node
369 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
371 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
372 MultNode->getOperand(0),// Factor 0
373 MultNode->getOperand(1),// Factor 1
376 // replace uses of sube and subc here
377 if (!SDValue(SUBCNode, 0).use_empty()) {
378 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
379 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
381 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
383 if (!SDValue(SUBENode, 0).use_empty()) {
384 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
385 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
387 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
393 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
394 TargetLowering::DAGCombinerInfo &DCI,
395 const MipsSubtarget *Subtarget) {
396 if (DCI.isBeforeLegalize())
399 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
401 return SDValue(N, 0);
406 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
407 TargetLowering::DAGCombinerInfo &DCI,
408 const MipsSubtarget *Subtarget) {
409 if (DCI.isBeforeLegalize())
412 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
414 return SDValue(N, 0);
419 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
420 EVT ShiftTy, SelectionDAG &DAG) {
421 // Clear the upper (64 - VT.sizeInBits) bits.
422 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
426 return DAG.getConstant(0, VT);
432 // If c is power of 2, return (shl x, log2(c)).
433 if (isPowerOf2_64(C))
434 return DAG.getNode(ISD::SHL, DL, VT, X,
435 DAG.getConstant(Log2_64(C), ShiftTy));
437 unsigned Log2Ceil = Log2_64_Ceil(C);
438 uint64_t Floor = 1LL << Log2_64(C);
439 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
441 // If |c - floor_c| <= |c - ceil_c|,
442 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
443 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
444 if (C - Floor <= Ceil - C) {
445 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
446 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
447 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
450 // If |c - floor_c| > |c - ceil_c|,
451 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
452 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
453 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
454 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
457 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
458 const TargetLowering::DAGCombinerInfo &DCI,
459 const MipsSETargetLowering *TL) {
460 EVT VT = N->getValueType(0);
462 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
464 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
465 VT, TL->getScalarShiftAmountTy(VT), DAG);
467 return SDValue(N, 0);
470 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
472 const MipsSubtarget *Subtarget) {
473 // See if this is a vector splat immediate node.
474 APInt SplatValue, SplatUndef;
475 unsigned SplatBitSize;
477 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
478 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
481 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
482 EltSize, !Subtarget->isLittle()) ||
483 (SplatBitSize != EltSize) ||
484 (SplatValue.getZExtValue() >= EltSize))
487 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
488 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
491 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
492 TargetLowering::DAGCombinerInfo &DCI,
493 const MipsSubtarget *Subtarget) {
494 EVT Ty = N->getValueType(0);
496 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
499 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
502 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
503 TargetLowering::DAGCombinerInfo &DCI,
504 const MipsSubtarget *Subtarget) {
505 EVT Ty = N->getValueType(0);
507 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
510 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
514 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
515 TargetLowering::DAGCombinerInfo &DCI,
516 const MipsSubtarget *Subtarget) {
517 EVT Ty = N->getValueType(0);
519 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
522 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
525 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
526 bool IsV216 = (Ty == MVT::v2i16);
530 case ISD::SETNE: return true;
534 case ISD::SETGE: return IsV216;
538 case ISD::SETUGE: return !IsV216;
539 default: return false;
543 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
544 EVT Ty = N->getValueType(0);
546 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
549 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
552 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
553 N->getOperand(1), N->getOperand(2));
556 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
557 EVT Ty = N->getValueType(0);
559 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
562 SDValue SetCC = N->getOperand(0);
564 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
567 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
568 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
569 N->getOperand(2), SetCC.getOperand(2));
572 static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
573 const MipsSubtarget *Subtarget) {
574 EVT Ty = N->getValueType(0);
576 if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
577 // Try the following combines:
578 // (xor (or $a, $b), (build_vector allones))
579 // (xor (or $a, $b), (bitcast (build_vector allones)))
580 SDValue Op0 = N->getOperand(0);
581 SDValue Op1 = N->getOperand(1);
583 ConstantSDNode *Const;
585 if (ISD::isBuildVectorAllOnes(Op0.getNode()))
587 else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
589 else if ((Op0->getOpcode() == MipsISD::VSPLAT ||
590 Op0->getOpcode() == MipsISD::VSPLATD) &&
591 (Const = dyn_cast<ConstantSDNode>(Op0->getOperand(0))) &&
592 Const->isAllOnesValue())
594 else if ((Op1->getOpcode() == MipsISD::VSPLAT ||
595 Op1->getOpcode() == MipsISD::VSPLATD) &&
596 (Const = dyn_cast<ConstantSDNode>(Op1->getOperand(0))) &&
597 Const->isAllOnesValue())
602 if (NotOp->getOpcode() == ISD::OR)
603 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
604 NotOp->getOperand(1));
611 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
612 SelectionDAG &DAG = DCI.DAG;
615 switch (N->getOpcode()) {
617 return performADDECombine(N, DAG, DCI, Subtarget);
619 return performSUBECombine(N, DAG, DCI, Subtarget);
621 return performMULCombine(N, DAG, DCI, this);
623 return performSHLCombine(N, DAG, DCI, Subtarget);
625 return performSRACombine(N, DAG, DCI, Subtarget);
627 return performSRLCombine(N, DAG, DCI, Subtarget);
629 return performVSELECTCombine(N, DAG);
631 Val = performXORCombine(N, DAG, Subtarget);
634 Val = performSETCCCombine(N, DAG);
641 return MipsTargetLowering::PerformDAGCombine(N, DCI);
645 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
646 MachineBasicBlock *BB) const {
647 switch (MI->getOpcode()) {
649 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
650 case Mips::BPOSGE32_PSEUDO:
651 return emitBPOSGE32(MI, BB);
652 case Mips::SNZ_B_PSEUDO:
653 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
654 case Mips::SNZ_H_PSEUDO:
655 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
656 case Mips::SNZ_W_PSEUDO:
657 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
658 case Mips::SNZ_D_PSEUDO:
659 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
660 case Mips::SNZ_V_PSEUDO:
661 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
662 case Mips::SZ_B_PSEUDO:
663 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
664 case Mips::SZ_H_PSEUDO:
665 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
666 case Mips::SZ_W_PSEUDO:
667 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
668 case Mips::SZ_D_PSEUDO:
669 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
670 case Mips::SZ_V_PSEUDO:
671 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
675 bool MipsSETargetLowering::
676 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
677 unsigned NextStackOffset,
678 const MipsFunctionInfo& FI) const {
679 if (!EnableMipsTailCalls)
682 // Return false if either the callee or caller has a byval argument.
683 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
686 // Return true if the callee's argument area is no larger than the
688 return NextStackOffset <= FI.getIncomingArgSize();
691 void MipsSETargetLowering::
692 getOpndList(SmallVectorImpl<SDValue> &Ops,
693 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
694 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
695 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
696 // T9 should contain the address of the callee function if
697 // -reloction-model=pic or it is an indirect call.
698 if (IsPICCall || !GlobalOrExternal) {
699 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
700 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
702 Ops.push_back(Callee);
704 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
705 InternalLinkage, CLI, Callee, Chain);
708 SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
709 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
711 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
712 return MipsTargetLowering::lowerLOAD(Op, DAG);
714 // Replace a double precision load with two i32 loads and a buildpair64.
716 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
717 EVT PtrVT = Ptr.getValueType();
719 // i32 load from lower address.
720 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
721 MachinePointerInfo(), Nd.isVolatile(),
722 Nd.isNonTemporal(), Nd.isInvariant(),
725 // i32 load from higher address.
726 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
727 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
728 MachinePointerInfo(), Nd.isVolatile(),
729 Nd.isNonTemporal(), Nd.isInvariant(),
730 std::min(Nd.getAlignment(), 4U));
732 if (!Subtarget->isLittle())
735 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
736 SDValue Ops[2] = {BP, Hi.getValue(1)};
737 return DAG.getMergeValues(Ops, 2, DL);
740 SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
741 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
743 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
744 return MipsTargetLowering::lowerSTORE(Op, DAG);
746 // Replace a double precision store with two extractelement64s and i32 stores.
748 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
749 EVT PtrVT = Ptr.getValueType();
750 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
751 Val, DAG.getConstant(0, MVT::i32));
752 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
753 Val, DAG.getConstant(1, MVT::i32));
755 if (!Subtarget->isLittle())
758 // i32 store to lower address.
759 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
760 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
763 // i32 store to higher address.
764 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
765 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
766 Nd.isVolatile(), Nd.isNonTemporal(),
767 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
770 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
771 bool HasLo, bool HasHi,
772 SelectionDAG &DAG) const {
773 EVT Ty = Op.getOperand(0).getValueType();
775 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
776 Op.getOperand(0), Op.getOperand(1));
780 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
781 DAG.getConstant(Mips::sub_lo, MVT::i32));
783 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
784 DAG.getConstant(Mips::sub_hi, MVT::i32));
786 if (!HasLo || !HasHi)
787 return HasLo ? Lo : Hi;
789 SDValue Vals[] = { Lo, Hi };
790 return DAG.getMergeValues(Vals, 2, DL);
794 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
795 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
796 DAG.getConstant(0, MVT::i32));
797 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
798 DAG.getConstant(1, MVT::i32));
799 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
802 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
803 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
804 DAG.getConstant(Mips::sub_lo, MVT::i32));
805 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
806 DAG.getConstant(Mips::sub_hi, MVT::i32));
807 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
810 // This function expands mips intrinsic nodes which have 64-bit input operands
813 // out64 = intrinsic-node in64
815 // lo = copy (extract-element (in64, 0))
816 // hi = copy (extract-element (in64, 1))
817 // mips-specific-node
820 // out64 = merge-values (v0, v1)
822 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
824 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
825 SmallVector<SDValue, 3> Ops;
828 // See if Op has a chain input.
830 Ops.push_back(Op->getOperand(OpNo++));
832 // The next operand is the intrinsic opcode.
833 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
835 // See if the next operand has type i64.
836 SDValue Opnd = Op->getOperand(++OpNo), In64;
838 if (Opnd.getValueType() == MVT::i64)
839 In64 = initAccumulator(Opnd, DL, DAG);
843 // Push the remaining operands.
844 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
845 Ops.push_back(Op->getOperand(OpNo));
847 // Add In64 to the end of the list.
852 SmallVector<EVT, 2> ResTys;
854 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
856 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
859 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
860 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
865 assert(Val->getValueType(1) == MVT::Other);
866 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
867 return DAG.getMergeValues(Vals, 2, DL);
870 static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
872 SDValue LHS = Op->getOperand(1);
873 SDValue RHS = Op->getOperand(2);
874 EVT ResTy = Op->getValueType(0);
876 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS);
881 static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
883 SDValue Value = Op->getOperand(1);
884 EVT ResTy = Op->getValueType(0);
886 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
891 static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
893 SDValue Value = Op->getOperand(1);
894 EVT ResTy = Op->getValueType(0);
896 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
901 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
902 SelectionDAG &DAG) const {
903 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
906 case Intrinsic::mips_shilo:
907 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
908 case Intrinsic::mips_dpau_h_qbl:
909 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
910 case Intrinsic::mips_dpau_h_qbr:
911 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
912 case Intrinsic::mips_dpsu_h_qbl:
913 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
914 case Intrinsic::mips_dpsu_h_qbr:
915 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
916 case Intrinsic::mips_dpa_w_ph:
917 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
918 case Intrinsic::mips_dps_w_ph:
919 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
920 case Intrinsic::mips_dpax_w_ph:
921 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
922 case Intrinsic::mips_dpsx_w_ph:
923 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
924 case Intrinsic::mips_mulsa_w_ph:
925 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
926 case Intrinsic::mips_mult:
927 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
928 case Intrinsic::mips_multu:
929 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
930 case Intrinsic::mips_madd:
931 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
932 case Intrinsic::mips_maddu:
933 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
934 case Intrinsic::mips_msub:
935 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
936 case Intrinsic::mips_msubu:
937 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
938 case Intrinsic::mips_addv_b:
939 case Intrinsic::mips_addv_h:
940 case Intrinsic::mips_addv_w:
941 case Intrinsic::mips_addv_d:
942 return lowerMSABinaryIntr(Op, DAG, ISD::ADD);
943 case Intrinsic::mips_and_v:
944 return lowerMSABinaryIntr(Op, DAG, ISD::AND);
945 case Intrinsic::mips_bnz_b:
946 case Intrinsic::mips_bnz_h:
947 case Intrinsic::mips_bnz_w:
948 case Intrinsic::mips_bnz_d:
949 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
950 case Intrinsic::mips_bnz_v:
951 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
952 case Intrinsic::mips_bz_b:
953 case Intrinsic::mips_bz_h:
954 case Intrinsic::mips_bz_w:
955 case Intrinsic::mips_bz_d:
956 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
957 case Intrinsic::mips_bz_v:
958 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
959 case Intrinsic::mips_div_s_b:
960 case Intrinsic::mips_div_s_h:
961 case Intrinsic::mips_div_s_w:
962 case Intrinsic::mips_div_s_d:
963 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV);
964 case Intrinsic::mips_div_u_b:
965 case Intrinsic::mips_div_u_h:
966 case Intrinsic::mips_div_u_w:
967 case Intrinsic::mips_div_u_d:
968 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV);
969 case Intrinsic::mips_fadd_w:
970 case Intrinsic::mips_fadd_d:
971 return lowerMSABinaryIntr(Op, DAG, ISD::FADD);
972 case Intrinsic::mips_fdiv_w:
973 case Intrinsic::mips_fdiv_d:
974 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV);
975 case Intrinsic::mips_fill_b:
976 case Intrinsic::mips_fill_h:
977 case Intrinsic::mips_fill_w:
978 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
979 case Intrinsic::mips_flog2_w:
980 case Intrinsic::mips_flog2_d:
981 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2);
982 case Intrinsic::mips_fmul_w:
983 case Intrinsic::mips_fmul_d:
984 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL);
985 case Intrinsic::mips_frint_w:
986 case Intrinsic::mips_frint_d:
987 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT);
988 case Intrinsic::mips_fsqrt_w:
989 case Intrinsic::mips_fsqrt_d:
990 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT);
991 case Intrinsic::mips_fsub_w:
992 case Intrinsic::mips_fsub_d:
993 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB);
994 case Intrinsic::mips_ldi_b:
995 case Intrinsic::mips_ldi_h:
996 case Intrinsic::mips_ldi_w:
997 case Intrinsic::mips_ldi_d:
998 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
999 case Intrinsic::mips_mulv_b:
1000 case Intrinsic::mips_mulv_h:
1001 case Intrinsic::mips_mulv_w:
1002 case Intrinsic::mips_mulv_d:
1003 return lowerMSABinaryIntr(Op, DAG, ISD::MUL);
1004 case Intrinsic::mips_nlzc_b:
1005 case Intrinsic::mips_nlzc_h:
1006 case Intrinsic::mips_nlzc_w:
1007 case Intrinsic::mips_nlzc_d:
1008 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ);
1009 case Intrinsic::mips_nor_v: {
1010 SDValue Res = lowerMSABinaryIntr(Op, DAG, ISD::OR);
1011 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0));
1013 case Intrinsic::mips_or_v:
1014 return lowerMSABinaryIntr(Op, DAG, ISD::OR);
1015 case Intrinsic::mips_sll_b:
1016 case Intrinsic::mips_sll_h:
1017 case Intrinsic::mips_sll_w:
1018 case Intrinsic::mips_sll_d:
1019 return lowerMSABinaryIntr(Op, DAG, ISD::SHL);
1020 case Intrinsic::mips_sra_b:
1021 case Intrinsic::mips_sra_h:
1022 case Intrinsic::mips_sra_w:
1023 case Intrinsic::mips_sra_d:
1024 return lowerMSABinaryIntr(Op, DAG, ISD::SRA);
1025 case Intrinsic::mips_srl_b:
1026 case Intrinsic::mips_srl_h:
1027 case Intrinsic::mips_srl_w:
1028 case Intrinsic::mips_srl_d:
1029 return lowerMSABinaryIntr(Op, DAG, ISD::SRL);
1030 case Intrinsic::mips_subv_b:
1031 case Intrinsic::mips_subv_h:
1032 case Intrinsic::mips_subv_w:
1033 case Intrinsic::mips_subv_d:
1034 return lowerMSABinaryIntr(Op, DAG, ISD::SUB);
1035 case Intrinsic::mips_xor_v:
1036 return lowerMSABinaryIntr(Op, DAG, ISD::XOR);
1040 static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1042 SDValue ChainIn = Op->getOperand(0);
1043 SDValue Address = Op->getOperand(2);
1044 SDValue Offset = Op->getOperand(3);
1045 EVT ResTy = Op->getValueType(0);
1046 EVT PtrTy = Address->getValueType(0);
1048 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1050 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
1054 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
1055 SelectionDAG &DAG) const {
1056 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1060 case Intrinsic::mips_extp:
1061 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
1062 case Intrinsic::mips_extpdp:
1063 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
1064 case Intrinsic::mips_extr_w:
1065 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
1066 case Intrinsic::mips_extr_r_w:
1067 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
1068 case Intrinsic::mips_extr_rs_w:
1069 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
1070 case Intrinsic::mips_extr_s_h:
1071 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
1072 case Intrinsic::mips_mthlip:
1073 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
1074 case Intrinsic::mips_mulsaq_s_w_ph:
1075 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
1076 case Intrinsic::mips_maq_s_w_phl:
1077 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
1078 case Intrinsic::mips_maq_s_w_phr:
1079 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
1080 case Intrinsic::mips_maq_sa_w_phl:
1081 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
1082 case Intrinsic::mips_maq_sa_w_phr:
1083 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
1084 case Intrinsic::mips_dpaq_s_w_ph:
1085 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
1086 case Intrinsic::mips_dpsq_s_w_ph:
1087 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
1088 case Intrinsic::mips_dpaq_sa_l_w:
1089 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
1090 case Intrinsic::mips_dpsq_sa_l_w:
1091 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
1092 case Intrinsic::mips_dpaqx_s_w_ph:
1093 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
1094 case Intrinsic::mips_dpaqx_sa_w_ph:
1095 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
1096 case Intrinsic::mips_dpsqx_s_w_ph:
1097 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
1098 case Intrinsic::mips_dpsqx_sa_w_ph:
1099 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
1100 case Intrinsic::mips_ld_b:
1101 case Intrinsic::mips_ld_h:
1102 case Intrinsic::mips_ld_w:
1103 case Intrinsic::mips_ld_d:
1104 case Intrinsic::mips_ldx_b:
1105 case Intrinsic::mips_ldx_h:
1106 case Intrinsic::mips_ldx_w:
1107 case Intrinsic::mips_ldx_d:
1108 return lowerMSALoadIntr(Op, DAG, Intr);
1112 static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1114 SDValue ChainIn = Op->getOperand(0);
1115 SDValue Value = Op->getOperand(2);
1116 SDValue Address = Op->getOperand(3);
1117 SDValue Offset = Op->getOperand(4);
1118 EVT PtrTy = Address->getValueType(0);
1120 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1122 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
1126 SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
1127 SelectionDAG &DAG) const {
1128 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1132 case Intrinsic::mips_st_b:
1133 case Intrinsic::mips_st_h:
1134 case Intrinsic::mips_st_w:
1135 case Intrinsic::mips_st_d:
1136 case Intrinsic::mips_stx_b:
1137 case Intrinsic::mips_stx_h:
1138 case Intrinsic::mips_stx_w:
1139 case Intrinsic::mips_stx_d:
1140 return lowerMSAStoreIntr(Op, DAG, Intr);
1144 /// \brief Check if the given BuildVectorSDNode is a splat.
1145 /// This method currently relies on DAG nodes being reused when equivalent,
1146 /// so it's possible for this to return false even when isConstantSplat returns
1148 static bool isSplatVector(const BuildVectorSDNode *N) {
1149 unsigned int nOps = N->getNumOperands();
1150 assert(nOps > 1 && "isSplat has 0 or 1 sized build vector");
1152 SDValue Operand0 = N->getOperand(0);
1154 for (unsigned int i = 1; i < nOps; ++i) {
1155 if (N->getOperand(i) != Operand0)
1162 // Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
1165 // Lowers according to the following rules:
1166 // - Vectors of 128-bits may be legal subject to the other rules. Other sizes
1168 // - Non-constant splats are legal and are lowered to MipsISD::VSPLAT.
1169 // - Constant splats with an element size of 32-bits or less are legal and are
1170 // lowered to MipsISD::VSPLAT.
1171 // - Constant splats with an element size of 64-bits but whose value would fit
1172 // within a 10 bit immediate are legal and are lowered to MipsISD::VSPLATD.
1173 // - All other ISD::BUILD_VECTORS are not legal
1174 SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
1175 SelectionDAG &DAG) const {
1176 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
1177 EVT ResTy = Op->getValueType(0);
1179 APInt SplatValue, SplatUndef;
1180 unsigned SplatBitSize;
1183 if (!Subtarget->hasMSA() || !ResTy.is128BitVector())
1186 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1188 !Subtarget->isLittle())) {
1191 EVT ConstTy = MVT::i32;
1192 unsigned SplatOp = MipsISD::VSPLAT;
1194 switch (SplatBitSize) {
1198 TmpVecTy = MVT::v2i64;
1200 // i64 is an illegal type on Mips32, but if it the constant fits into a
1201 // signed 10-bit value then we can still handle it using VSPLATD and an
1205 else if (isInt<10>(SplatValue.getSExtValue())) {
1206 SplatValue = SplatValue.trunc(32);
1207 SplatOp = MipsISD::VSPLATD;
1212 TmpVecTy = MVT::v4i32;
1215 TmpVecTy = MVT::v8i16;
1216 SplatValue = SplatValue.sext(32);
1219 TmpVecTy = MVT::v16i8;
1220 SplatValue = SplatValue.sext(32);
1224 Result = DAG.getNode(SplatOp, DL, TmpVecTy,
1225 DAG.getConstant(SplatValue, ConstTy));
1226 if (ResTy != Result.getValueType())
1227 Result = DAG.getNode(ISD::BITCAST, DL, ResTy, Result);
1231 else if (isSplatVector(Node))
1232 return DAG.getNode(MipsISD::VSPLAT, DL, ResTy, Op->getOperand(0));
1237 MachineBasicBlock * MipsSETargetLowering::
1238 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
1240 // bposge32_pseudo $vr0
1250 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
1252 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1253 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1254 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1255 DebugLoc DL = MI->getDebugLoc();
1256 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1257 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1258 MachineFunction *F = BB->getParent();
1259 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1260 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1261 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1264 F->insert(It, Sink);
1266 // Transfer the remainder of BB and its successor edges to Sink.
1267 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1269 Sink->transferSuccessorsAndUpdatePHIs(BB);
1272 BB->addSuccessor(FBB);
1273 BB->addSuccessor(TBB);
1274 FBB->addSuccessor(Sink);
1275 TBB->addSuccessor(Sink);
1277 // Insert the real bposge32 instruction to $BB.
1278 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
1281 unsigned VR2 = RegInfo.createVirtualRegister(RC);
1282 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
1283 .addReg(Mips::ZERO).addImm(0);
1284 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1287 unsigned VR1 = RegInfo.createVirtualRegister(RC);
1288 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
1289 .addReg(Mips::ZERO).addImm(1);
1291 // Insert phi function to $Sink.
1292 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1293 MI->getOperand(0).getReg())
1294 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
1296 MI->eraseFromParent(); // The pseudo instruction is gone now.
1300 MachineBasicBlock * MipsSETargetLowering::
1301 emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
1302 unsigned BranchOp) const{
1304 // vany_nonzero $rd, $ws
1315 // $rd = phi($rd1, $fbb, $rd2, $tbb)
1317 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1318 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1319 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1320 DebugLoc DL = MI->getDebugLoc();
1321 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1322 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1323 MachineFunction *F = BB->getParent();
1324 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1325 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1326 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1329 F->insert(It, Sink);
1331 // Transfer the remainder of BB and its successor edges to Sink.
1332 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1334 Sink->transferSuccessorsAndUpdatePHIs(BB);
1337 BB->addSuccessor(FBB);
1338 BB->addSuccessor(TBB);
1339 FBB->addSuccessor(Sink);
1340 TBB->addSuccessor(Sink);
1342 // Insert the real bnz.b instruction to $BB.
1343 BuildMI(BB, DL, TII->get(BranchOp))
1344 .addReg(MI->getOperand(1).getReg())
1348 unsigned RD1 = RegInfo.createVirtualRegister(RC);
1349 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
1350 .addReg(Mips::ZERO).addImm(0);
1351 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1354 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1355 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1356 .addReg(Mips::ZERO).addImm(1);
1358 // Insert phi function to $Sink.
1359 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1360 MI->getOperand(0).getReg())
1361 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1363 MI->eraseFromParent(); // The pseudo instruction is gone now.