Home | History | Annotate | Download | only in Mips
      1 //===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Subclass of MipsTargetLowering specialized for mips32/64.
     11 //
     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"
     21 
     22 using namespace llvm;
     23 
     24 static cl::opt<bool>
     25 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
     26                     cl::desc("MIPS: Enable tail calls."), cl::init(false));
     27 
     28 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
     29   : MipsTargetLowering(TM) {
     30   // Set up the register classes
     31 
     32   clearRegisterClasses();
     33 
     34   addRegisterClass(MVT::i32, &Mips::GPR32RegClass);
     35 
     36   if (HasMips64)
     37     addRegisterClass(MVT::i64, &Mips::GPR64RegClass);
     38 
     39   if (Subtarget->hasDSP()) {
     40     MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
     41 
     42     for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
     43       addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
     44 
     45       // Expand all builtin opcodes.
     46       for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
     47         setOperationAction(Opc, VecTys[i], Expand);
     48 
     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);
     54     }
     55 
     56     // Expand all truncating stores and extending loads.
     57     unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
     58     unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
     59 
     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);
     64 
     65       setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
     66       setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand);
     67       setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand);
     68     }
     69 
     70     setTargetDAGCombine(ISD::SHL);
     71     setTargetDAGCombine(ISD::SRA);
     72     setTargetDAGCombine(ISD::SRL);
     73     setTargetDAGCombine(ISD::SETCC);
     74     setTargetDAGCombine(ISD::VSELECT);
     75   }
     76 
     77   if (Subtarget->hasDSPR2())
     78     setOperationAction(ISD::MUL, MVT::v2i16, Legal);
     79 
     80   if (!TM.Options.UseSoftFloat) {
     81     addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
     82 
     83     // When dealing with single precision only, use libcalls
     84     if (!Subtarget->isSingleFloat()) {
     85       if (HasMips64)
     86         addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
     87       else
     88         addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
     89     }
     90   }
     91 
     92   setOperationAction(ISD::SMUL_LOHI,          MVT::i32, Custom);
     93   setOperationAction(ISD::UMUL_LOHI,          MVT::i32, Custom);
     94   setOperationAction(ISD::MULHS,              MVT::i32, Custom);
     95   setOperationAction(ISD::MULHU,              MVT::i32, Custom);
     96 
     97   if (HasMips64) {
     98     setOperationAction(ISD::MULHS,            MVT::i64, Custom);
     99     setOperationAction(ISD::MULHU,            MVT::i64, Custom);
    100     setOperationAction(ISD::MUL,              MVT::i64, Custom);
    101   }
    102 
    103   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom);
    104   setOperationAction(ISD::INTRINSIC_W_CHAIN,  MVT::i64, Custom);
    105 
    106   setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
    107   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
    108   setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
    109   setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
    110   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
    111   setOperationAction(ISD::LOAD,               MVT::i32, Custom);
    112   setOperationAction(ISD::STORE,              MVT::i32, Custom);
    113 
    114   setTargetDAGCombine(ISD::ADDE);
    115   setTargetDAGCombine(ISD::SUBE);
    116   setTargetDAGCombine(ISD::MUL);
    117 
    118   computeRegisterProperties();
    119 }
    120 
    121 const MipsTargetLowering *
    122 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
    123   return new MipsSETargetLowering(TM);
    124 }
    125 
    126 
    127 bool
    128 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
    129   MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
    130 
    131   switch (SVT) {
    132   case MVT::i64:
    133   case MVT::i32:
    134     if (Fast)
    135       *Fast = true;
    136     return true;
    137   default:
    138     return false;
    139   }
    140 }
    141 
    142 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
    143                                              SelectionDAG &DAG) const {
    144   switch(Op.getOpcode()) {
    145   case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
    146   case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
    147   case ISD::MULHS:     return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
    148   case ISD::MULHU:     return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
    149   case ISD::MUL:       return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
    150   case ISD::SDIVREM:   return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
    151   case ISD::UDIVREM:   return lowerMulDiv(Op, MipsISD::DivRemU, true, true,
    152                                           DAG);
    153   case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG);
    154   case ISD::INTRINSIC_W_CHAIN:  return lowerINTRINSIC_W_CHAIN(Op, DAG);
    155   }
    156 
    157   return MipsTargetLowering::LowerOperation(Op, DAG);
    158 }
    159 
    160 // selectMADD -
    161 // Transforms a subgraph in CurDAG if the following pattern is found:
    162 //  (addc multLo, Lo0), (adde multHi, Hi0),
    163 // where,
    164 //  multHi/Lo: product of multiplication
    165 //  Lo0: initial value of Lo register
    166 //  Hi0: initial value of Hi register
    167 // Return true if pattern matching was successful.
    168 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
    169   // ADDENode's second operand must be a flag output of an ADDC node in order
    170   // for the matching to be successful.
    171   SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
    172 
    173   if (ADDCNode->getOpcode() != ISD::ADDC)
    174     return false;
    175 
    176   SDValue MultHi = ADDENode->getOperand(0);
    177   SDValue MultLo = ADDCNode->getOperand(0);
    178   SDNode *MultNode = MultHi.getNode();
    179   unsigned MultOpc = MultHi.getOpcode();
    180 
    181   // MultHi and MultLo must be generated by the same node,
    182   if (MultLo.getNode() != MultNode)
    183     return false;
    184 
    185   // and it must be a multiplication.
    186   if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
    187     return false;
    188 
    189   // MultLo amd MultHi must be the first and second output of MultNode
    190   // respectively.
    191   if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
    192     return false;
    193 
    194   // Transform this to a MADD only if ADDENode and ADDCNode are the only users
    195   // of the values of MultNode, in which case MultNode will be removed in later
    196   // phases.
    197   // If there exist users other than ADDENode or ADDCNode, this function returns
    198   // here, which will result in MultNode being mapped to a single MULT
    199   // instruction node rather than a pair of MULT and MADD instructions being
    200   // produced.
    201   if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
    202     return false;
    203 
    204   SDLoc DL(ADDENode);
    205 
    206   // Initialize accumulator.
    207   SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
    208                                   ADDCNode->getOperand(1),
    209                                   ADDENode->getOperand(1));
    210 
    211   // create MipsMAdd(u) node
    212   MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
    213 
    214   SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
    215                                  MultNode->getOperand(0),// Factor 0
    216                                  MultNode->getOperand(1),// Factor 1
    217                                  ACCIn);
    218 
    219   // replace uses of adde and addc here
    220   if (!SDValue(ADDCNode, 0).use_empty()) {
    221     SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
    222     SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
    223                                     LoIdx);
    224     CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
    225   }
    226   if (!SDValue(ADDENode, 0).use_empty()) {
    227     SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
    228     SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
    229                                     HiIdx);
    230     CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
    231   }
    232 
    233   return true;
    234 }
    235 
    236 // selectMSUB -
    237 // Transforms a subgraph in CurDAG if the following pattern is found:
    238 //  (addc Lo0, multLo), (sube Hi0, multHi),
    239 // where,
    240 //  multHi/Lo: product of multiplication
    241 //  Lo0: initial value of Lo register
    242 //  Hi0: initial value of Hi register
    243 // Return true if pattern matching was successful.
    244 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
    245   // SUBENode's second operand must be a flag output of an SUBC node in order
    246   // for the matching to be successful.
    247   SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
    248 
    249   if (SUBCNode->getOpcode() != ISD::SUBC)
    250     return false;
    251 
    252   SDValue MultHi = SUBENode->getOperand(1);
    253   SDValue MultLo = SUBCNode->getOperand(1);
    254   SDNode *MultNode = MultHi.getNode();
    255   unsigned MultOpc = MultHi.getOpcode();
    256 
    257   // MultHi and MultLo must be generated by the same node,
    258   if (MultLo.getNode() != MultNode)
    259     return false;
    260 
    261   // and it must be a multiplication.
    262   if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
    263     return false;
    264 
    265   // MultLo amd MultHi must be the first and second output of MultNode
    266   // respectively.
    267   if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
    268     return false;
    269 
    270   // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
    271   // of the values of MultNode, in which case MultNode will be removed in later
    272   // phases.
    273   // If there exist users other than SUBENode or SUBCNode, this function returns
    274   // here, which will result in MultNode being mapped to a single MULT
    275   // instruction node rather than a pair of MULT and MSUB instructions being
    276   // produced.
    277   if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
    278     return false;
    279 
    280   SDLoc DL(SUBENode);
    281 
    282   // Initialize accumulator.
    283   SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
    284                                   SUBCNode->getOperand(0),
    285                                   SUBENode->getOperand(0));
    286 
    287   // create MipsSub(u) node
    288   MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
    289 
    290   SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
    291                                  MultNode->getOperand(0),// Factor 0
    292                                  MultNode->getOperand(1),// Factor 1
    293                                  ACCIn);
    294 
    295   // replace uses of sube and subc here
    296   if (!SDValue(SUBCNode, 0).use_empty()) {
    297     SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
    298     SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
    299                                     LoIdx);
    300     CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
    301   }
    302   if (!SDValue(SUBENode, 0).use_empty()) {
    303     SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
    304     SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
    305                                     HiIdx);
    306     CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
    307   }
    308 
    309   return true;
    310 }
    311 
    312 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
    313                                   TargetLowering::DAGCombinerInfo &DCI,
    314                                   const MipsSubtarget *Subtarget) {
    315   if (DCI.isBeforeLegalize())
    316     return SDValue();
    317 
    318   if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
    319       selectMADD(N, &DAG))
    320     return SDValue(N, 0);
    321 
    322   return SDValue();
    323 }
    324 
    325 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
    326                                   TargetLowering::DAGCombinerInfo &DCI,
    327                                   const MipsSubtarget *Subtarget) {
    328   if (DCI.isBeforeLegalize())
    329     return SDValue();
    330 
    331   if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
    332       selectMSUB(N, &DAG))
    333     return SDValue(N, 0);
    334 
    335   return SDValue();
    336 }
    337 
    338 static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT,
    339                             EVT ShiftTy, SelectionDAG &DAG) {
    340   // Clear the upper (64 - VT.sizeInBits) bits.
    341   C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits());
    342 
    343   // Return 0.
    344   if (C == 0)
    345     return DAG.getConstant(0, VT);
    346 
    347   // Return x.
    348   if (C == 1)
    349     return X;
    350 
    351   // If c is power of 2, return (shl x, log2(c)).
    352   if (isPowerOf2_64(C))
    353     return DAG.getNode(ISD::SHL, DL, VT, X,
    354                        DAG.getConstant(Log2_64(C), ShiftTy));
    355 
    356   unsigned Log2Ceil = Log2_64_Ceil(C);
    357   uint64_t Floor = 1LL << Log2_64(C);
    358   uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil;
    359 
    360   // If |c - floor_c| <= |c - ceil_c|,
    361   // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))),
    362   // return (add constMult(x, floor_c), constMult(x, c - floor_c)).
    363   if (C - Floor <= Ceil - C) {
    364     SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG);
    365     SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG);
    366     return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1);
    367   }
    368 
    369   // If |c - floor_c| > |c - ceil_c|,
    370   // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)).
    371   SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG);
    372   SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG);
    373   return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1);
    374 }
    375 
    376 static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG,
    377                                  const TargetLowering::DAGCombinerInfo &DCI,
    378                                  const MipsSETargetLowering *TL) {
    379   EVT VT = N->getValueType(0);
    380 
    381   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
    382     if (!VT.isVector())
    383       return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N),
    384                           VT, TL->getScalarShiftAmountTy(VT), DAG);
    385 
    386   return SDValue(N, 0);
    387 }
    388 
    389 static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty,
    390                                       SelectionDAG &DAG,
    391                                       const MipsSubtarget *Subtarget) {
    392   // See if this is a vector splat immediate node.
    393   APInt SplatValue, SplatUndef;
    394   unsigned SplatBitSize;
    395   bool HasAnyUndefs;
    396   unsigned EltSize = Ty.getVectorElementType().getSizeInBits();
    397   BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
    398 
    399   if (!BV ||
    400       !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
    401                            EltSize, !Subtarget->isLittle()) ||
    402       (SplatBitSize != EltSize) ||
    403       (SplatValue.getZExtValue() >= EltSize))
    404     return SDValue();
    405 
    406   return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0),
    407                      DAG.getConstant(SplatValue.getZExtValue(), MVT::i32));
    408 }
    409 
    410 static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,
    411                                  TargetLowering::DAGCombinerInfo &DCI,
    412                                  const MipsSubtarget *Subtarget) {
    413   EVT Ty = N->getValueType(0);
    414 
    415   if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
    416     return SDValue();
    417 
    418   return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget);
    419 }
    420 
    421 static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG,
    422                                  TargetLowering::DAGCombinerInfo &DCI,
    423                                  const MipsSubtarget *Subtarget) {
    424   EVT Ty = N->getValueType(0);
    425 
    426   if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2()))
    427     return SDValue();
    428 
    429   return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget);
    430 }
    431 
    432 
    433 static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
    434                                  TargetLowering::DAGCombinerInfo &DCI,
    435                                  const MipsSubtarget *Subtarget) {
    436   EVT Ty = N->getValueType(0);
    437 
    438   if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8))
    439     return SDValue();
    440 
    441   return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget);
    442 }
    443 
    444 static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) {
    445   bool IsV216 = (Ty == MVT::v2i16);
    446 
    447   switch (CC) {
    448   case ISD::SETEQ:
    449   case ISD::SETNE:  return true;
    450   case ISD::SETLT:
    451   case ISD::SETLE:
    452   case ISD::SETGT:
    453   case ISD::SETGE:  return IsV216;
    454   case ISD::SETULT:
    455   case ISD::SETULE:
    456   case ISD::SETUGT:
    457   case ISD::SETUGE: return !IsV216;
    458   default:          return false;
    459   }
    460 }
    461 
    462 static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) {
    463   EVT Ty = N->getValueType(0);
    464 
    465   if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
    466     return SDValue();
    467 
    468   if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get()))
    469     return SDValue();
    470 
    471   return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0),
    472                      N->getOperand(1), N->getOperand(2));
    473 }
    474 
    475 static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) {
    476   EVT Ty = N->getValueType(0);
    477 
    478   if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8))
    479     return SDValue();
    480 
    481   SDValue SetCC = N->getOperand(0);
    482 
    483   if (SetCC.getOpcode() != MipsISD::SETCC_DSP)
    484     return SDValue();
    485 
    486   return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty,
    487                      SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1),
    488                      N->getOperand(2), SetCC.getOperand(2));
    489 }
    490 
    491 SDValue
    492 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
    493   SelectionDAG &DAG = DCI.DAG;
    494   SDValue Val;
    495 
    496   switch (N->getOpcode()) {
    497   case ISD::ADDE:
    498     return performADDECombine(N, DAG, DCI, Subtarget);
    499   case ISD::SUBE:
    500     return performSUBECombine(N, DAG, DCI, Subtarget);
    501   case ISD::MUL:
    502     return performMULCombine(N, DAG, DCI, this);
    503   case ISD::SHL:
    504     return performSHLCombine(N, DAG, DCI, Subtarget);
    505   case ISD::SRA:
    506     return performSRACombine(N, DAG, DCI, Subtarget);
    507   case ISD::SRL:
    508     return performSRLCombine(N, DAG, DCI, Subtarget);
    509   case ISD::VSELECT:
    510     return performVSELECTCombine(N, DAG);
    511   case ISD::SETCC: {
    512     Val = performSETCCCombine(N, DAG);
    513     break;
    514   }
    515   }
    516 
    517   if (Val.getNode())
    518     return Val;
    519 
    520   return MipsTargetLowering::PerformDAGCombine(N, DCI);
    521 }
    522 
    523 MachineBasicBlock *
    524 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
    525                                                   MachineBasicBlock *BB) const {
    526   switch (MI->getOpcode()) {
    527   default:
    528     return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
    529   case Mips::BPOSGE32_PSEUDO:
    530     return emitBPOSGE32(MI, BB);
    531   }
    532 }
    533 
    534 bool MipsSETargetLowering::
    535 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
    536                                   unsigned NextStackOffset,
    537                                   const MipsFunctionInfo& FI) const {
    538   if (!EnableMipsTailCalls)
    539     return false;
    540 
    541   // Return false if either the callee or caller has a byval argument.
    542   if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
    543     return false;
    544 
    545   // Return true if the callee's argument area is no larger than the
    546   // caller's.
    547   return NextStackOffset <= FI.getIncomingArgSize();
    548 }
    549 
    550 void MipsSETargetLowering::
    551 getOpndList(SmallVectorImpl<SDValue> &Ops,
    552             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
    553             bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
    554             CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
    555   // T9 should contain the address of the callee function if
    556   // -reloction-model=pic or it is an indirect call.
    557   if (IsPICCall || !GlobalOrExternal) {
    558     unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
    559     RegsToPass.push_front(std::make_pair(T9Reg, Callee));
    560   } else
    561     Ops.push_back(Callee);
    562 
    563   MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
    564                                   InternalLinkage, CLI, Callee, Chain);
    565 }
    566 
    567 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
    568                                           bool HasLo, bool HasHi,
    569                                           SelectionDAG &DAG) const {
    570   EVT Ty = Op.getOperand(0).getValueType();
    571   SDLoc DL(Op);
    572   SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
    573                              Op.getOperand(0), Op.getOperand(1));
    574   SDValue Lo, Hi;
    575 
    576   if (HasLo)
    577     Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
    578                      DAG.getConstant(Mips::sub_lo, MVT::i32));
    579   if (HasHi)
    580     Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
    581                      DAG.getConstant(Mips::sub_hi, MVT::i32));
    582 
    583   if (!HasLo || !HasHi)
    584     return HasLo ? Lo : Hi;
    585 
    586   SDValue Vals[] = { Lo, Hi };
    587   return DAG.getMergeValues(Vals, 2, DL);
    588 }
    589 
    590 
    591 static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) {
    592   SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
    593                              DAG.getConstant(0, MVT::i32));
    594   SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In,
    595                              DAG.getConstant(1, MVT::i32));
    596   return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi);
    597 }
    598 
    599 static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) {
    600   SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
    601                            DAG.getConstant(Mips::sub_lo, MVT::i32));
    602   SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op,
    603                            DAG.getConstant(Mips::sub_hi, MVT::i32));
    604   return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
    605 }
    606 
    607 // This function expands mips intrinsic nodes which have 64-bit input operands
    608 // or output values.
    609 //
    610 // out64 = intrinsic-node in64
    611 // =>
    612 // lo = copy (extract-element (in64, 0))
    613 // hi = copy (extract-element (in64, 1))
    614 // mips-specific-node
    615 // v0 = copy lo
    616 // v1 = copy hi
    617 // out64 = merge-values (v0, v1)
    618 //
    619 static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) {
    620   SDLoc DL(Op);
    621   bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other;
    622   SmallVector<SDValue, 3> Ops;
    623   unsigned OpNo = 0;
    624 
    625   // See if Op has a chain input.
    626   if (HasChainIn)
    627     Ops.push_back(Op->getOperand(OpNo++));
    628 
    629   // The next operand is the intrinsic opcode.
    630   assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant);
    631 
    632   // See if the next operand has type i64.
    633   SDValue Opnd = Op->getOperand(++OpNo), In64;
    634 
    635   if (Opnd.getValueType() == MVT::i64)
    636     In64 = initAccumulator(Opnd, DL, DAG);
    637   else
    638     Ops.push_back(Opnd);
    639 
    640   // Push the remaining operands.
    641   for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo)
    642     Ops.push_back(Op->getOperand(OpNo));
    643 
    644   // Add In64 to the end of the list.
    645   if (In64.getNode())
    646     Ops.push_back(In64);
    647 
    648   // Scan output.
    649   SmallVector<EVT, 2> ResTys;
    650 
    651   for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end();
    652        I != E; ++I)
    653     ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I);
    654 
    655   // Create node.
    656   SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size());
    657   SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val;
    658 
    659   if (!HasChainIn)
    660     return Out;
    661 
    662   assert(Val->getValueType(1) == MVT::Other);
    663   SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) };
    664   return DAG.getMergeValues(Vals, 2, DL);
    665 }
    666 
    667 SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op,
    668                                                       SelectionDAG &DAG) const {
    669   switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) {
    670   default:
    671     return SDValue();
    672   case Intrinsic::mips_shilo:
    673     return lowerDSPIntr(Op, DAG, MipsISD::SHILO);
    674   case Intrinsic::mips_dpau_h_qbl:
    675     return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL);
    676   case Intrinsic::mips_dpau_h_qbr:
    677     return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR);
    678   case Intrinsic::mips_dpsu_h_qbl:
    679     return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL);
    680   case Intrinsic::mips_dpsu_h_qbr:
    681     return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR);
    682   case Intrinsic::mips_dpa_w_ph:
    683     return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH);
    684   case Intrinsic::mips_dps_w_ph:
    685     return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH);
    686   case Intrinsic::mips_dpax_w_ph:
    687     return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH);
    688   case Intrinsic::mips_dpsx_w_ph:
    689     return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH);
    690   case Intrinsic::mips_mulsa_w_ph:
    691     return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH);
    692   case Intrinsic::mips_mult:
    693     return lowerDSPIntr(Op, DAG, MipsISD::Mult);
    694   case Intrinsic::mips_multu:
    695     return lowerDSPIntr(Op, DAG, MipsISD::Multu);
    696   case Intrinsic::mips_madd:
    697     return lowerDSPIntr(Op, DAG, MipsISD::MAdd);
    698   case Intrinsic::mips_maddu:
    699     return lowerDSPIntr(Op, DAG, MipsISD::MAddu);
    700   case Intrinsic::mips_msub:
    701     return lowerDSPIntr(Op, DAG, MipsISD::MSub);
    702   case Intrinsic::mips_msubu:
    703     return lowerDSPIntr(Op, DAG, MipsISD::MSubu);
    704   }
    705 }
    706 
    707 SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
    708                                                      SelectionDAG &DAG) const {
    709   switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) {
    710   default:
    711     return SDValue();
    712   case Intrinsic::mips_extp:
    713     return lowerDSPIntr(Op, DAG, MipsISD::EXTP);
    714   case Intrinsic::mips_extpdp:
    715     return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP);
    716   case Intrinsic::mips_extr_w:
    717     return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W);
    718   case Intrinsic::mips_extr_r_w:
    719     return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W);
    720   case Intrinsic::mips_extr_rs_w:
    721     return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W);
    722   case Intrinsic::mips_extr_s_h:
    723     return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H);
    724   case Intrinsic::mips_mthlip:
    725     return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP);
    726   case Intrinsic::mips_mulsaq_s_w_ph:
    727     return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH);
    728   case Intrinsic::mips_maq_s_w_phl:
    729     return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL);
    730   case Intrinsic::mips_maq_s_w_phr:
    731     return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR);
    732   case Intrinsic::mips_maq_sa_w_phl:
    733     return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL);
    734   case Intrinsic::mips_maq_sa_w_phr:
    735     return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR);
    736   case Intrinsic::mips_dpaq_s_w_ph:
    737     return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH);
    738   case Intrinsic::mips_dpsq_s_w_ph:
    739     return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH);
    740   case Intrinsic::mips_dpaq_sa_l_w:
    741     return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W);
    742   case Intrinsic::mips_dpsq_sa_l_w:
    743     return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W);
    744   case Intrinsic::mips_dpaqx_s_w_ph:
    745     return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH);
    746   case Intrinsic::mips_dpaqx_sa_w_ph:
    747     return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH);
    748   case Intrinsic::mips_dpsqx_s_w_ph:
    749     return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH);
    750   case Intrinsic::mips_dpsqx_sa_w_ph:
    751     return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH);
    752   }
    753 }
    754 
    755 MachineBasicBlock * MipsSETargetLowering::
    756 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
    757   // $bb:
    758   //  bposge32_pseudo $vr0
    759   //  =>
    760   // $bb:
    761   //  bposge32 $tbb
    762   // $fbb:
    763   //  li $vr2, 0
    764   //  b $sink
    765   // $tbb:
    766   //  li $vr1, 1
    767   // $sink:
    768   //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
    769 
    770   MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
    771   const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
    772   const TargetRegisterClass *RC = &Mips::GPR32RegClass;
    773   DebugLoc DL = MI->getDebugLoc();
    774   const BasicBlock *LLVM_BB = BB->getBasicBlock();
    775   MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
    776   MachineFunction *F = BB->getParent();
    777   MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
    778   MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
    779   MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
    780   F->insert(It, FBB);
    781   F->insert(It, TBB);
    782   F->insert(It, Sink);
    783 
    784   // Transfer the remainder of BB and its successor edges to Sink.
    785   Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
    786                BB->end());
    787   Sink->transferSuccessorsAndUpdatePHIs(BB);
    788 
    789   // Add successors.
    790   BB->addSuccessor(FBB);
    791   BB->addSuccessor(TBB);
    792   FBB->addSuccessor(Sink);
    793   TBB->addSuccessor(Sink);
    794 
    795   // Insert the real bposge32 instruction to $BB.
    796   BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
    797 
    798   // Fill $FBB.
    799   unsigned VR2 = RegInfo.createVirtualRegister(RC);
    800   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
    801     .addReg(Mips::ZERO).addImm(0);
    802   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
    803 
    804   // Fill $TBB.
    805   unsigned VR1 = RegInfo.createVirtualRegister(RC);
    806   BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
    807     .addReg(Mips::ZERO).addImm(1);
    808 
    809   // Insert phi function to $Sink.
    810   BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
    811           MI->getOperand(0).getReg())
    812     .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
    813 
    814   MI->eraseFromParent();   // The pseudo instruction is gone now.
    815   return Sink;
    816 }
    817