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::CTPOP, Ty, Legal);
170 setOperationAction(ISD::MUL, Ty, Legal);
171 setOperationAction(ISD::OR, Ty, Legal);
172 setOperationAction(ISD::SDIV, Ty, Legal);
173 setOperationAction(ISD::SHL, Ty, Legal);
174 setOperationAction(ISD::SRA, Ty, Legal);
175 setOperationAction(ISD::SRL, Ty, Legal);
176 setOperationAction(ISD::SUB, Ty, Legal);
177 setOperationAction(ISD::UDIV, Ty, Legal);
178 setOperationAction(ISD::XOR, Ty, Legal);
181 // Enable MSA support for the given floating-point type and Register class.
182 void MipsSETargetLowering::
183 addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) {
184 addRegisterClass(Ty, RC);
186 // Expand all builtin opcodes.
187 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
188 setOperationAction(Opc, Ty, Expand);
190 setOperationAction(ISD::LOAD, Ty, Legal);
191 setOperationAction(ISD::STORE, Ty, Legal);
192 setOperationAction(ISD::BITCAST, Ty, Legal);
194 if (Ty != MVT::v8f16) {
195 setOperationAction(ISD::FADD, Ty, Legal);
196 setOperationAction(ISD::FDIV, Ty, Legal);
197 setOperationAction(ISD::FLOG2, Ty, Legal);
198 setOperationAction(ISD::FMUL, Ty, Legal);
199 setOperationAction(ISD::FRINT, Ty, Legal);
200 setOperationAction(ISD::FSQRT, Ty, Legal);
201 setOperationAction(ISD::FSUB, Ty, Legal);
206 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
207 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
220 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
221 SelectionDAG &DAG) const {
222 switch(Op.getOpcode()) {
223 case ISD::LOAD: return lowerLOAD(Op, DAG);
224 case ISD::STORE: return lowerSTORE(Op, DAG);
225 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
226 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
227 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
228 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
229 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
230 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
231 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
233 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
234 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG);
235 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG);
236 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG);
239 return MipsTargetLowering::LowerOperation(Op, DAG);
243 // Transforms a subgraph in CurDAG if the following pattern is found:
244 // (addc multLo, Lo0), (adde multHi, Hi0),
246 // multHi/Lo: product of multiplication
247 // Lo0: initial value of Lo register
248 // Hi0: initial value of Hi register
249 // Return true if pattern matching was successful.
250 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
251 // ADDENode's second operand must be a flag output of an ADDC node in order
252 // for the matching to be successful.
253 SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
255 if (ADDCNode->getOpcode() != ISD::ADDC)
258 SDValue MultHi = ADDENode->getOperand(0);
259 SDValue MultLo = ADDCNode->getOperand(0);
260 SDNode *MultNode = MultHi.getNode();
261 unsigned MultOpc = MultHi.getOpcode();
263 // MultHi and MultLo must be generated by the same node,
264 if (MultLo.getNode() != MultNode)
267 // and it must be a multiplication.
268 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
271 // MultLo amd MultHi must be the first and second output of MultNode
273 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
276 // Transform this to a MADD only if ADDENode and ADDCNode are the only users
277 // of the values of MultNode, in which case MultNode will be removed in later
279 // If there exist users other than ADDENode or ADDCNode, this function returns
280 // here, which will result in MultNode being mapped to a single MULT
281 // instruction node rather than a pair of MULT and MADD instructions being
283 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
288 // Initialize accumulator.
289 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
290 ADDCNode->getOperand(1),
291 ADDENode->getOperand(1));
293 // create MipsMAdd(u) node
294 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
296 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
297 MultNode->getOperand(0),// Factor 0
298 MultNode->getOperand(1),// Factor 1
301 // replace uses of adde and addc here
302 if (!SDValue(ADDCNode, 0).use_empty()) {
303 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
304 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
306 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
308 if (!SDValue(ADDENode, 0).use_empty()) {
309 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
310 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
312 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
319 // Transforms a subgraph in CurDAG if the following pattern is found:
320 // (addc Lo0, multLo), (sube Hi0, multHi),
322 // multHi/Lo: product of multiplication
323 // Lo0: initial value of Lo register
324 // Hi0: initial value of Hi register
325 // Return true if pattern matching was successful.
326 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
327 // SUBENode's second operand must be a flag output of an SUBC node in order
328 // for the matching to be successful.
329 SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
331 if (SUBCNode->getOpcode() != ISD::SUBC)
334 SDValue MultHi = SUBENode->getOperand(1);
335 SDValue MultLo = SUBCNode->getOperand(1);
336 SDNode *MultNode = MultHi.getNode();
337 unsigned MultOpc = MultHi.getOpcode();
339 // MultHi and MultLo must be generated by the same node,
340 if (MultLo.getNode() != MultNode)
343 // and it must be a multiplication.
344 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
347 // MultLo amd MultHi must be the first and second output of MultNode
349 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
352 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
353 // of the values of MultNode, in which case MultNode will be removed in later
355 // If there exist users other than SUBENode or SUBCNode, this function returns
356 // here, which will result in MultNode being mapped to a single MULT
357 // instruction node rather than a pair of MULT and MSUB instructions being
359 if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
364 // Initialize accumulator.
365 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
366 SUBCNode->getOperand(0),
367 SUBENode->getOperand(0));
369 // create MipsSub(u) node
370 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
372 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
373 MultNode->getOperand(0),// Factor 0
374 MultNode->getOperand(1),// Factor 1
377 // replace uses of sube and subc here
378 if (!SDValue(SUBCNode, 0).use_empty()) {
379 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
380 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
382 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
384 if (!SDValue(SUBENode, 0).use_empty()) {
385 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
386 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
388 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
394 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
395 TargetLowering::DAGCombinerInfo &DCI,
396 const MipsSubtarget *Subtarget) {
397 if (DCI.isBeforeLegalize())
400 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
402 return SDValue(N, 0);
407 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
408 TargetLowering::DAGCombinerInfo &DCI,
409 const MipsSubtarget *Subtarget) {
410 if (DCI.isBeforeLegalize())
413 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
415 return SDValue(N, 0);
420 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
421 EVT ShiftTy, SelectionDAG &DAG) {
422 // Clear the upper (64 - VT.sizeInBits) bits.
423 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
427 return DAG.getConstant(0, VT);
433 // If c is power of 2, return (shl x, log2(c)).
434 if (isPowerOf2_64(C))
435 return DAG.getNode(ISD::SHL, DL, VT, X,
436 DAG.getConstant(Log2_64(C), ShiftTy));
438 unsigned Log2Ceil = Log2_64_Ceil(C);
439 uint64_t Floor = 1LL << Log2_64(C);
440 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
442 // If |c - floor_c| <= |c - ceil_c|,
443 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
444 // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
445 if (C - Floor <= Ceil - C) {
446 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
447 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
448 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
451 // If |c - floor_c| > |c - ceil_c|,
452 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
453 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
454 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
455 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
458 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
459 const TargetLowering::DAGCombinerInfo &DCI,
460 const MipsSETargetLowering *TL) {
461 EVT VT = N->getValueType(0);
463 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
465 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
466 VT, TL->getScalarShiftAmountTy(VT), DAG);
468 return SDValue(N, 0);
471 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
473 const MipsSubtarget *Subtarget) {
474 // See if this is a vector splat immediate node.
475 APInt SplatValue, SplatUndef;
476 unsigned SplatBitSize;
478 unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
479 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
482 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
483 EltSize, !Subtarget->isLittle()) ||
484 (SplatBitSize != EltSize) ||
485 (SplatValue.getZExtValue() >= EltSize))
488 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
489 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
492 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
493 TargetLowering::DAGCombinerInfo &DCI,
494 const MipsSubtarget *Subtarget) {
495 EVT Ty = N->getValueType(0);
497 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
500 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
503 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
504 TargetLowering::DAGCombinerInfo &DCI,
505 const MipsSubtarget *Subtarget) {
506 EVT Ty = N->getValueType(0);
508 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
511 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
515 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
516 TargetLowering::DAGCombinerInfo &DCI,
517 const MipsSubtarget *Subtarget) {
518 EVT Ty = N->getValueType(0);
520 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
523 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
526 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
527 bool IsV216 = (Ty == MVT::v2i16);
531 case ISD::SETNE: return true;
535 case ISD::SETGE: return IsV216;
539 case ISD::SETUGE: return !IsV216;
540 default: return false;
544 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
545 EVT Ty = N->getValueType(0);
547 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
550 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
553 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
554 N->getOperand(1), N->getOperand(2));
557 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
558 EVT Ty = N->getValueType(0);
560 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
563 SDValue SetCC = N->getOperand(0);
565 if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
568 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
569 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
570 N->getOperand(2), SetCC.getOperand(2));
573 static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
574 const MipsSubtarget *Subtarget) {
575 EVT Ty = N->getValueType(0);
577 if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) {
578 // Try the following combines:
579 // (xor (or $a, $b), (build_vector allones))
580 // (xor (or $a, $b), (bitcast (build_vector allones)))
581 SDValue Op0 = N->getOperand(0);
582 SDValue Op1 = N->getOperand(1);
584 ConstantSDNode *Const;
586 if (ISD::isBuildVectorAllOnes(Op0.getNode()))
588 else if (ISD::isBuildVectorAllOnes(Op1.getNode()))
590 else if ((Op0->getOpcode() == MipsISD::VSPLAT ||
591 Op0->getOpcode() == MipsISD::VSPLATD) &&
592 (Const = dyn_cast<ConstantSDNode>(Op0->getOperand(0))) &&
593 Const->isAllOnesValue())
595 else if ((Op1->getOpcode() == MipsISD::VSPLAT ||
596 Op1->getOpcode() == MipsISD::VSPLATD) &&
597 (Const = dyn_cast<ConstantSDNode>(Op1->getOperand(0))) &&
598 Const->isAllOnesValue())
603 if (NotOp->getOpcode() == ISD::OR)
604 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0),
605 NotOp->getOperand(1));
612 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
613 SelectionDAG &DAG = DCI.DAG;
616 switch (N->getOpcode()) {
618 return performADDECombine(N, DAG, DCI, Subtarget);
620 return performSUBECombine(N, DAG, DCI, Subtarget);
622 return performMULCombine(N, DAG, DCI, this);
624 return performSHLCombine(N, DAG, DCI, Subtarget);
626 return performSRACombine(N, DAG, DCI, Subtarget);
628 return performSRLCombine(N, DAG, DCI, Subtarget);
630 return performVSELECTCombine(N, DAG);
632 Val = performXORCombine(N, DAG, Subtarget);
635 Val = performSETCCCombine(N, DAG);
642 return MipsTargetLowering::PerformDAGCombine(N, DCI);
646 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
647 MachineBasicBlock *BB) const {
648 switch (MI->getOpcode()) {
650 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
651 case Mips::BPOSGE32_PSEUDO:
652 return emitBPOSGE32(MI, BB);
653 case Mips::SNZ_B_PSEUDO:
654 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B);
655 case Mips::SNZ_H_PSEUDO:
656 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H);
657 case Mips::SNZ_W_PSEUDO:
658 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W);
659 case Mips::SNZ_D_PSEUDO:
660 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D);
661 case Mips::SNZ_V_PSEUDO:
662 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V);
663 case Mips::SZ_B_PSEUDO:
664 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B);
665 case Mips::SZ_H_PSEUDO:
666 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H);
667 case Mips::SZ_W_PSEUDO:
668 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W);
669 case Mips::SZ_D_PSEUDO:
670 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D);
671 case Mips::SZ_V_PSEUDO:
672 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V);
676 bool MipsSETargetLowering::
677 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
678 unsigned NextStackOffset,
679 const MipsFunctionInfo& FI) const {
680 if (!EnableMipsTailCalls)
683 // Return false if either the callee or caller has a byval argument.
684 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
687 // Return true if the callee's argument area is no larger than the
689 return NextStackOffset <= FI.getIncomingArgSize();
692 void MipsSETargetLowering::
693 getOpndList(SmallVectorImpl<SDValue> &Ops,
694 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
695 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
696 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
697 // T9 should contain the address of the callee function if
698 // -reloction-model=pic or it is an indirect call.
699 if (IsPICCall || !GlobalOrExternal) {
700 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
701 RegsToPass.push_front(std::make_pair(T9Reg, Callee));
703 Ops.push_back(Callee);
705 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
706 InternalLinkage, CLI, Callee, Chain);
709 SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
710 LoadSDNode &Nd = *cast<LoadSDNode>(Op);
712 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
713 return MipsTargetLowering::lowerLOAD(Op, DAG);
715 // Replace a double precision load with two i32 loads and a buildpair64.
717 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
718 EVT PtrVT = Ptr.getValueType();
720 // i32 load from lower address.
721 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr,
722 MachinePointerInfo(), Nd.isVolatile(),
723 Nd.isNonTemporal(), Nd.isInvariant(),
726 // i32 load from higher address.
727 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
728 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr,
729 MachinePointerInfo(), Nd.isVolatile(),
730 Nd.isNonTemporal(), Nd.isInvariant(),
731 std::min(Nd.getAlignment(), 4U));
733 if (!Subtarget->isLittle())
736 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
737 SDValue Ops[2] = {BP, Hi.getValue(1)};
738 return DAG.getMergeValues(Ops, 2, DL);
741 SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
742 StoreSDNode &Nd = *cast<StoreSDNode>(Op);
744 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
745 return MipsTargetLowering::lowerSTORE(Op, DAG);
747 // Replace a double precision store with two extractelement64s and i32 stores.
749 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
750 EVT PtrVT = Ptr.getValueType();
751 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
752 Val, DAG.getConstant(0, MVT::i32));
753 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
754 Val, DAG.getConstant(1, MVT::i32));
756 if (!Subtarget->isLittle())
759 // i32 store to lower address.
760 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(),
761 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(),
764 // i32 store to higher address.
765 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT));
766 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(),
767 Nd.isVolatile(), Nd.isNonTemporal(),
768 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo());
771 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
772 bool HasLo, bool HasHi,
773 SelectionDAG &DAG) const {
774 EVT Ty = Op.getOperand(0).getValueType();
776 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
777 Op.getOperand(0), Op.getOperand(1));
781 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
782 DAG.getConstant(Mips::sub_lo, MVT::i32));
784 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
785 DAG.getConstant(Mips::sub_hi, MVT::i32));
787 if (!HasLo || !HasHi)
788 return HasLo ? Lo : Hi;
790 SDValue Vals[] = { Lo, Hi };
791 return DAG.getMergeValues(Vals, 2, DL);
795 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
796 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
797 DAG.getConstant(0, MVT::i32));
798 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
799 DAG.getConstant(1, MVT::i32));
800 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
803 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
804 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
805 DAG.getConstant(Mips::sub_lo, MVT::i32));
806 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
807 DAG.getConstant(Mips::sub_hi, MVT::i32));
808 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
811 // This function expands mips intrinsic nodes which have 64-bit input operands
814 // out64 = intrinsic-node in64
816 // lo = copy (extract-element (in64, 0))
817 // hi = copy (extract-element (in64, 1))
818 // mips-specific-node
821 // out64 = merge-values (v0, v1)
823 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
825 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
826 SmallVector<SDValue, 3> Ops;
829 // See if Op has a chain input.
831 Ops.push_back(Op->getOperand(OpNo++));
833 // The next operand is the intrinsic opcode.
834 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
836 // See if the next operand has type i64.
837 SDValue Opnd = Op->getOperand(++OpNo), In64;
839 if (Opnd.getValueType() == MVT::i64)
840 In64 = initAccumulator(Opnd, DL, DAG);
844 // Push the remaining operands.
845 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
846 Ops.push_back(Op->getOperand(OpNo));
848 // Add In64 to the end of the list.
853 SmallVector<EVT, 2> ResTys;
855 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
857 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
860 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
861 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
866 assert(Val->getValueType(1) == MVT::Other);
867 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
868 return DAG.getMergeValues(Vals, 2, DL);
871 static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
873 SDValue LHS = Op->getOperand(1);
874 SDValue RHS = Op->getOperand(2);
875 EVT ResTy = Op->getValueType(0);
877 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS);
882 static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
884 SDValue Value = Op->getOperand(1);
885 EVT ResTy = Op->getValueType(0);
887 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
892 static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
894 SDValue Value = Op->getOperand(1);
895 EVT ResTy = Op->getValueType(0);
897 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value);
902 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
903 SelectionDAG &DAG) const {
904 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
907 case Intrinsic::mips_shilo:
908 return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
909 case Intrinsic::mips_dpau_h_qbl:
910 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
911 case Intrinsic::mips_dpau_h_qbr:
912 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
913 case Intrinsic::mips_dpsu_h_qbl:
914 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
915 case Intrinsic::mips_dpsu_h_qbr:
916 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
917 case Intrinsic::mips_dpa_w_ph:
918 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
919 case Intrinsic::mips_dps_w_ph:
920 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
921 case Intrinsic::mips_dpax_w_ph:
922 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
923 case Intrinsic::mips_dpsx_w_ph:
924 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
925 case Intrinsic::mips_mulsa_w_ph:
926 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
927 case Intrinsic::mips_mult:
928 return lowerDSPIntr(Op, DAG, MipsISD::Mult);
929 case Intrinsic::mips_multu:
930 return lowerDSPIntr(Op, DAG, MipsISD::Multu);
931 case Intrinsic::mips_madd:
932 return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
933 case Intrinsic::mips_maddu:
934 return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
935 case Intrinsic::mips_msub:
936 return lowerDSPIntr(Op, DAG, MipsISD::MSub);
937 case Intrinsic::mips_msubu:
938 return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
939 case Intrinsic::mips_addv_b:
940 case Intrinsic::mips_addv_h:
941 case Intrinsic::mips_addv_w:
942 case Intrinsic::mips_addv_d:
943 return lowerMSABinaryIntr(Op, DAG, ISD::ADD);
944 case Intrinsic::mips_and_v:
945 return lowerMSABinaryIntr(Op, DAG, ISD::AND);
946 case Intrinsic::mips_bnz_b:
947 case Intrinsic::mips_bnz_h:
948 case Intrinsic::mips_bnz_w:
949 case Intrinsic::mips_bnz_d:
950 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO);
951 case Intrinsic::mips_bnz_v:
952 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO);
953 case Intrinsic::mips_bz_b:
954 case Intrinsic::mips_bz_h:
955 case Intrinsic::mips_bz_w:
956 case Intrinsic::mips_bz_d:
957 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO);
958 case Intrinsic::mips_bz_v:
959 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO);
960 case Intrinsic::mips_div_s_b:
961 case Intrinsic::mips_div_s_h:
962 case Intrinsic::mips_div_s_w:
963 case Intrinsic::mips_div_s_d:
964 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV);
965 case Intrinsic::mips_div_u_b:
966 case Intrinsic::mips_div_u_h:
967 case Intrinsic::mips_div_u_w:
968 case Intrinsic::mips_div_u_d:
969 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV);
970 case Intrinsic::mips_fadd_w:
971 case Intrinsic::mips_fadd_d:
972 return lowerMSABinaryIntr(Op, DAG, ISD::FADD);
973 case Intrinsic::mips_fdiv_w:
974 case Intrinsic::mips_fdiv_d:
975 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV);
976 case Intrinsic::mips_fill_b:
977 case Intrinsic::mips_fill_h:
978 case Intrinsic::mips_fill_w:
979 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
980 case Intrinsic::mips_flog2_w:
981 case Intrinsic::mips_flog2_d:
982 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2);
983 case Intrinsic::mips_fmul_w:
984 case Intrinsic::mips_fmul_d:
985 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL);
986 case Intrinsic::mips_frint_w:
987 case Intrinsic::mips_frint_d:
988 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT);
989 case Intrinsic::mips_fsqrt_w:
990 case Intrinsic::mips_fsqrt_d:
991 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT);
992 case Intrinsic::mips_fsub_w:
993 case Intrinsic::mips_fsub_d:
994 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB);
995 case Intrinsic::mips_ldi_b:
996 case Intrinsic::mips_ldi_h:
997 case Intrinsic::mips_ldi_w:
998 case Intrinsic::mips_ldi_d:
999 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT);
1000 case Intrinsic::mips_mulv_b:
1001 case Intrinsic::mips_mulv_h:
1002 case Intrinsic::mips_mulv_w:
1003 case Intrinsic::mips_mulv_d:
1004 return lowerMSABinaryIntr(Op, DAG, ISD::MUL);
1005 case Intrinsic::mips_nlzc_b:
1006 case Intrinsic::mips_nlzc_h:
1007 case Intrinsic::mips_nlzc_w:
1008 case Intrinsic::mips_nlzc_d:
1009 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ);
1010 case Intrinsic::mips_nor_v: {
1011 SDValue Res = lowerMSABinaryIntr(Op, DAG, ISD::OR);
1012 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0));
1014 case Intrinsic::mips_or_v:
1015 return lowerMSABinaryIntr(Op, DAG, ISD::OR);
1016 case Intrinsic::mips_pcnt_b:
1017 case Intrinsic::mips_pcnt_h:
1018 case Intrinsic::mips_pcnt_w:
1019 case Intrinsic::mips_pcnt_d:
1020 return lowerMSAUnaryIntr(Op, DAG, ISD::CTPOP);
1021 case Intrinsic::mips_sll_b:
1022 case Intrinsic::mips_sll_h:
1023 case Intrinsic::mips_sll_w:
1024 case Intrinsic::mips_sll_d:
1025 return lowerMSABinaryIntr(Op, DAG, ISD::SHL);
1026 case Intrinsic::mips_sra_b:
1027 case Intrinsic::mips_sra_h:
1028 case Intrinsic::mips_sra_w:
1029 case Intrinsic::mips_sra_d:
1030 return lowerMSABinaryIntr(Op, DAG, ISD::SRA);
1031 case Intrinsic::mips_srl_b:
1032 case Intrinsic::mips_srl_h:
1033 case Intrinsic::mips_srl_w:
1034 case Intrinsic::mips_srl_d:
1035 return lowerMSABinaryIntr(Op, DAG, ISD::SRL);
1036 case Intrinsic::mips_subv_b:
1037 case Intrinsic::mips_subv_h:
1038 case Intrinsic::mips_subv_w:
1039 case Intrinsic::mips_subv_d:
1040 return lowerMSABinaryIntr(Op, DAG, ISD::SUB);
1041 case Intrinsic::mips_xor_v:
1042 return lowerMSABinaryIntr(Op, DAG, ISD::XOR);
1046 static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1048 SDValue ChainIn = Op->getOperand(0);
1049 SDValue Address = Op->getOperand(2);
1050 SDValue Offset = Op->getOperand(3);
1051 EVT ResTy = Op->getValueType(0);
1052 EVT PtrTy = Address->getValueType(0);
1054 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1056 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false,
1060 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
1061 SelectionDAG &DAG) const {
1062 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1066 case Intrinsic::mips_extp:
1067 return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
1068 case Intrinsic::mips_extpdp:
1069 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
1070 case Intrinsic::mips_extr_w:
1071 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
1072 case Intrinsic::mips_extr_r_w:
1073 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
1074 case Intrinsic::mips_extr_rs_w:
1075 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
1076 case Intrinsic::mips_extr_s_h:
1077 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
1078 case Intrinsic::mips_mthlip:
1079 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
1080 case Intrinsic::mips_mulsaq_s_w_ph:
1081 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
1082 case Intrinsic::mips_maq_s_w_phl:
1083 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
1084 case Intrinsic::mips_maq_s_w_phr:
1085 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
1086 case Intrinsic::mips_maq_sa_w_phl:
1087 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
1088 case Intrinsic::mips_maq_sa_w_phr:
1089 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
1090 case Intrinsic::mips_dpaq_s_w_ph:
1091 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
1092 case Intrinsic::mips_dpsq_s_w_ph:
1093 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
1094 case Intrinsic::mips_dpaq_sa_l_w:
1095 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
1096 case Intrinsic::mips_dpsq_sa_l_w:
1097 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
1098 case Intrinsic::mips_dpaqx_s_w_ph:
1099 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
1100 case Intrinsic::mips_dpaqx_sa_w_ph:
1101 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
1102 case Intrinsic::mips_dpsqx_s_w_ph:
1103 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
1104 case Intrinsic::mips_dpsqx_sa_w_ph:
1105 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
1106 case Intrinsic::mips_ld_b:
1107 case Intrinsic::mips_ld_h:
1108 case Intrinsic::mips_ld_w:
1109 case Intrinsic::mips_ld_d:
1110 case Intrinsic::mips_ldx_b:
1111 case Intrinsic::mips_ldx_h:
1112 case Intrinsic::mips_ldx_w:
1113 case Intrinsic::mips_ldx_d:
1114 return lowerMSALoadIntr(Op, DAG, Intr);
1118 static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) {
1120 SDValue ChainIn = Op->getOperand(0);
1121 SDValue Value = Op->getOperand(2);
1122 SDValue Address = Op->getOperand(3);
1123 SDValue Offset = Op->getOperand(4);
1124 EVT PtrTy = Address->getValueType(0);
1126 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset);
1128 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false,
1132 SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op,
1133 SelectionDAG &DAG) const {
1134 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue();
1138 case Intrinsic::mips_st_b:
1139 case Intrinsic::mips_st_h:
1140 case Intrinsic::mips_st_w:
1141 case Intrinsic::mips_st_d:
1142 case Intrinsic::mips_stx_b:
1143 case Intrinsic::mips_stx_h:
1144 case Intrinsic::mips_stx_w:
1145 case Intrinsic::mips_stx_d:
1146 return lowerMSAStoreIntr(Op, DAG, Intr);
1150 /// \brief Check if the given BuildVectorSDNode is a splat.
1151 /// This method currently relies on DAG nodes being reused when equivalent,
1152 /// so it's possible for this to return false even when isConstantSplat returns
1154 static bool isSplatVector(const BuildVectorSDNode *N) {
1155 unsigned int nOps = N->getNumOperands();
1156 assert(nOps > 1 && "isSplat has 0 or 1 sized build vector");
1158 SDValue Operand0 = N->getOperand(0);
1160 for (unsigned int i = 1; i < nOps; ++i) {
1161 if (N->getOperand(i) != Operand0)
1168 // Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the
1171 // Lowers according to the following rules:
1172 // - Vectors of 128-bits may be legal subject to the other rules. Other sizes
1174 // - Non-constant splats are legal and are lowered to MipsISD::VSPLAT.
1175 // - Constant splats with an element size of 32-bits or less are legal and are
1176 // lowered to MipsISD::VSPLAT.
1177 // - Constant splats with an element size of 64-bits but whose value would fit
1178 // within a 10 bit immediate are legal and are lowered to MipsISD::VSPLATD.
1179 // - All other ISD::BUILD_VECTORS are not legal
1180 SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op,
1181 SelectionDAG &DAG) const {
1182 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op);
1183 EVT ResTy = Op->getValueType(0);
1185 APInt SplatValue, SplatUndef;
1186 unsigned SplatBitSize;
1189 if (!Subtarget->hasMSA() || !ResTy.is128BitVector())
1192 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,
1194 !Subtarget->isLittle())) {
1197 EVT ConstTy = MVT::i32;
1198 unsigned SplatOp = MipsISD::VSPLAT;
1200 switch (SplatBitSize) {
1204 TmpVecTy = MVT::v2i64;
1206 // i64 is an illegal type on Mips32, but if it the constant fits into a
1207 // signed 10-bit value then we can still handle it using VSPLATD and an
1211 else if (isInt<10>(SplatValue.getSExtValue())) {
1212 SplatValue = SplatValue.trunc(32);
1213 SplatOp = MipsISD::VSPLATD;
1218 TmpVecTy = MVT::v4i32;
1221 TmpVecTy = MVT::v8i16;
1222 SplatValue = SplatValue.sext(32);
1225 TmpVecTy = MVT::v16i8;
1226 SplatValue = SplatValue.sext(32);
1230 Result = DAG.getNode(SplatOp, DL, TmpVecTy,
1231 DAG.getConstant(SplatValue, ConstTy));
1232 if (ResTy != Result.getValueType())
1233 Result = DAG.getNode(ISD::BITCAST, DL, ResTy, Result);
1237 else if (isSplatVector(Node))
1238 return DAG.getNode(MipsISD::VSPLAT, DL, ResTy, Op->getOperand(0));
1243 MachineBasicBlock * MipsSETargetLowering::
1244 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
1246 // bposge32_pseudo $vr0
1256 // $vr0 = phi($vr2, $fbb, $vr1, $tbb)
1258 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1259 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1260 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1261 DebugLoc DL = MI->getDebugLoc();
1262 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1263 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1264 MachineFunction *F = BB->getParent();
1265 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1266 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1267 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1270 F->insert(It, Sink);
1272 // Transfer the remainder of BB and its successor edges to Sink.
1273 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1275 Sink->transferSuccessorsAndUpdatePHIs(BB);
1278 BB->addSuccessor(FBB);
1279 BB->addSuccessor(TBB);
1280 FBB->addSuccessor(Sink);
1281 TBB->addSuccessor(Sink);
1283 // Insert the real bposge32 instruction to $BB.
1284 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
1287 unsigned VR2 = RegInfo.createVirtualRegister(RC);
1288 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
1289 .addReg(Mips::ZERO).addImm(0);
1290 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1293 unsigned VR1 = RegInfo.createVirtualRegister(RC);
1294 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
1295 .addReg(Mips::ZERO).addImm(1);
1297 // Insert phi function to $Sink.
1298 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1299 MI->getOperand(0).getReg())
1300 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
1302 MI->eraseFromParent(); // The pseudo instruction is gone now.
1306 MachineBasicBlock * MipsSETargetLowering::
1307 emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB,
1308 unsigned BranchOp) const{
1310 // vany_nonzero $rd, $ws
1321 // $rd = phi($rd1, $fbb, $rd2, $tbb)
1323 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
1324 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
1325 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
1326 DebugLoc DL = MI->getDebugLoc();
1327 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1328 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
1329 MachineFunction *F = BB->getParent();
1330 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
1331 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
1332 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB);
1335 F->insert(It, Sink);
1337 // Transfer the remainder of BB and its successor edges to Sink.
1338 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
1340 Sink->transferSuccessorsAndUpdatePHIs(BB);
1343 BB->addSuccessor(FBB);
1344 BB->addSuccessor(TBB);
1345 FBB->addSuccessor(Sink);
1346 TBB->addSuccessor(Sink);
1348 // Insert the real bnz.b instruction to $BB.
1349 BuildMI(BB, DL, TII->get(BranchOp))
1350 .addReg(MI->getOperand(1).getReg())
1354 unsigned RD1 = RegInfo.createVirtualRegister(RC);
1355 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1)
1356 .addReg(Mips::ZERO).addImm(0);
1357 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
1360 unsigned RD2 = RegInfo.createVirtualRegister(RC);
1361 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2)
1362 .addReg(Mips::ZERO).addImm(1);
1364 // Insert phi function to $Sink.
1365 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
1366 MI->getOperand(0).getReg())
1367 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB);
1369 MI->eraseFromParent(); // The pseudo instruction is gone now.