MipsSEISelLowering.cpp revision 9367b8d4f254d9e5cccb15334cc1a969c5be0d31
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//                     The LLVM Compiler Infrastructure
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// This file is distributed under the University of Illinois Open Source
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// License. See LICENSE.TXT for details.
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===----------------------------------------------------------------------===//
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Subclass of MipsTargetLowering specialized for mips32/64.
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//===----------------------------------------------------------------------===//
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "MipsSEISelLowering.h"
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "MipsRegisterInfo.h"
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "MipsTargetMachine.h"
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "llvm/CodeGen/MachineInstrBuilder.h"
1727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "llvm/CodeGen/MachineRegisterInfo.h"
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "llvm/Support/CommandLine.h"
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi#include "llvm/Target/TargetInstrInfo.h"
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiusing namespace llvm;
2227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic cl::opt<bool>
2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiEnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
2527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                    cl::desc("MIPS: Enable tail calls."), cl::init(false));
2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiMipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
2827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  : MipsTargetLowering(TM) {
2927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // Set up the register classes
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  clearRegisterClasses();
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
3427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (HasMips64)
3627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (Subtarget->hasDSP()) {
3927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
4027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
4327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      // Expand all builtin opcodes.
4527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
4627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        setOperationAction(Opc, VecTys[i], Expand);
4727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
4827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      setOperationAction(ISD::ADD, VecTys[i], Legal);
4927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      setOperationAction(ISD::SUB, VecTys[i], Legal);
5027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      setOperationAction(ISD::LOAD, VecTys[i], Legal);
5127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      setOperationAction(ISD::STORE, VecTys[i], Legal);
5227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      setOperationAction(ISD::BITCAST, VecTys[i], Legal);
5327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
5427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
5527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (Subtarget->hasDSPR2())
5727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    setOperationAction(ISD::MUL, MVT::v2i16, Legal);
5827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
5927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!TM.Options.UseSoftFloat) {
6027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
6127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
6227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    // When dealing with single precision only, use libcalls
6327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (!Subtarget->isSingleFloat()) {
6427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      if (HasMips64)
6527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
6627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      else
6727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
6827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
6927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
7027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
7127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::SMUL_LOHI,          MVT::i32, Custom);
7227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::UMUL_LOHI,          MVT::i32, Custom);
7327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::MULHS,              MVT::i32, Custom);
7427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::MULHU,              MVT::i32, Custom);
7527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
7627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (HasMips64) {
77e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    setOperationAction(ISD::MULHS,            MVT::i64, Custom);
78e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi    setOperationAction(ISD::MULHU,            MVT::i64, Custom);
7927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    setOperationAction(ISD::MUL,              MVT::i64, Custom);
8027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
8127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
8227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
83e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
84e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
8527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
8627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::MEMBARRIER,         MVT::Other, Custom);
8727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
8827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::LOAD,               MVT::i32, Custom);
8927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setOperationAction(ISD::STORE,              MVT::i32, Custom);
9027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
9127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setTargetDAGCombine(ISD::ADDE);
9227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  setTargetDAGCombine(ISD::SUBE);
9327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
94e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  computeRegisterProperties();
95e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi}
9627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
9727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiconst MipsTargetLowering *
9827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshillvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
9927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  return new MipsSETargetLowering(TM);
10027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
10127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshibool
10427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiMipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
10527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
10627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
10727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  switch (SVT) {
10827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case MVT::i64:
10927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case MVT::i32:
11027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    if (Fast)
11127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      *Fast = true;
11227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return true;
11327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  default:
11427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
11527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
11627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
11727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
11827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiSDValue MipsSETargetLowering::LowerOperation(SDValue Op,
11927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                             SelectionDAG &DAG) const {
12027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  switch(Op.getOpcode()) {
12127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
12227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
12327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::MULHS:     return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
12427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::MULHU:     return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
12527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::MUL:       return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
12627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::SDIVREM:   return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
12727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  case ISD::UDIVREM:   return lowerMulDiv(Op, MipsISD::DivRemU, true, true, DAG);
12827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
12927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
13027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  return MipsTargetLowering::LowerOperation(Op, DAG);
13127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
1322272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
13327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// selectMADD -
13427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Transforms a subgraph in CurDAG if the following pattern is found:
1352272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi//  (addc multLo, Lo0), (adde multHi, Hi0),
13627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// where,
13727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  multHi/Lo: product of multiplication
13827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  Lo0: initial value of Lo register
13927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  Hi0: initial value of Hi register
14027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Return true if pattern matching was successful.
14127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
14227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // ADDENode's second operand must be a flag output of an ADDC node in order
14327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // for the matching to be successful.
14427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
14527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (ADDCNode->getOpcode() != ISD::ADDC)
14727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
14827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
14927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue MultHi = ADDENode->getOperand(0);
15027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue MultLo = ADDCNode->getOperand(0);
15127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDNode *MultNode = MultHi.getNode();
15227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  unsigned MultOpc = MultHi.getOpcode();
15327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
15427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // MultHi and MultLo must be generated by the same node,
15527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultLo.getNode() != MultNode)
15627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
15727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
15827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // and it must be a multiplication.
15927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
16027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
16127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // MultLo amd MultHi must be the first and second output of MultNode
16327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // respectively.
16427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
16527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
16627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
16727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // Transform this to a MADD only if ADDENode and ADDCNode are the only users
16827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // of the values of MultNode, in which case MultNode will be removed in later
16927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // phases.
17027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // If there exist users other than ADDENode or ADDCNode, this function returns
17127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // here, which will result in MultNode being mapped to a single MULT
17227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // instruction node rather than a pair of MULT and MADD instructions being
17327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // produced.
17427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
17527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
17627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
17727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  DebugLoc DL = ADDENode->getDebugLoc();
1782272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
17927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // Initialize accumulator.
18027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
1812272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                                  ADDCNode->getOperand(1),
18227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                  ADDENode->getOperand(1));
18327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1842272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  // create MipsMAdd(u) node
18527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
18627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1872272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
18827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                 MultNode->getOperand(0),// Factor 0
18927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                 MultNode->getOperand(1),// Factor 1
19027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                 ACCIn);
19127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
19227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // replace uses of adde and addc here
19327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!SDValue(ADDCNode, 0).use_empty()) {
19427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
19527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
1962272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                                    LoIdx);
19727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
1982272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  }
19927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!SDValue(ADDENode, 0).use_empty()) {
20027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
2012272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
20227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                    HiIdx);
2032272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
20427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
20527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
2062272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  return true;
20727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi}
2082272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
20927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// selectMSUB -
21027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Transforms a subgraph in CurDAG if the following pattern is found:
21127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  (addc Lo0, multLo), (sube Hi0, multHi),
21227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// where,
21327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  multHi/Lo: product of multiplication
21427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  Lo0: initial value of Lo register
21527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi//  Hi0: initial value of Hi register
21627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi// Return true if pattern matching was successful.
21727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
21827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // SUBENode's second operand must be a flag output of an SUBC node in order
21927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // for the matching to be successful.
22027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
22127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (SUBCNode->getOpcode() != ISD::SUBC)
22327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
22427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
22527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue MultHi = SUBENode->getOperand(1);
22627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue MultLo = SUBCNode->getOperand(1);
22727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDNode *MultNode = MultHi.getNode();
22827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  unsigned MultOpc = MultHi.getOpcode();
22927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
23027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // MultHi and MultLo must be generated by the same node,
23127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultLo.getNode() != MultNode)
23227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
23327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
23427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // and it must be a multiplication.
23527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
23627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
23727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
23827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // MultLo amd MultHi must be the first and second output of MultNode
23927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // respectively.
24027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
24127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return false;
24227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
24327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
24427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // of the values of MultNode, in which case MultNode will be removed in later
24527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // phases.
246e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  // If there exist users other than SUBENode or SUBCNode, this function returns
247e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  // here, which will result in MultNode being mapped to a single MULT
248e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  // instruction node rather than a pair of MULT and MSUB instructions being
249e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  // produced.
250e943f84129326ab885cc7a69dcfa17f766b72b89Takeshi Aimi  if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
2512272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi    return false;
25227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
25327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  DebugLoc DL = SUBENode->getDebugLoc();
25427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
25527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // Initialize accumulator.
25627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
25727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                  SUBCNode->getOperand(0),
25827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                  SUBENode->getOperand(0));
2592272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
26027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // create MipsSub(u) node
26127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
2622272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi
26327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
26427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                 MultNode->getOperand(0),// Factor 0
2652272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                                 MultNode->getOperand(1),// Factor 1
26627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                 ACCIn);
26727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
26827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  // replace uses of sube and subc here
2692272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi  if (!SDValue(SUBCNode, 0).use_empty()) {
27027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
27127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
27227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                    LoIdx);
27327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
27427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
27527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (!SDValue(SUBENode, 0).use_empty()) {
27627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
27727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
27827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                    HiIdx);
27927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
28027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  }
28127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
28227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  return true;
2832272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi}
28427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
28527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshistatic SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
2862272ee27d9022d173b6eab45c409b3c3f57f30ecTakeshi Aimi                                  TargetLowering::DAGCombinerInfo &DCI,
28727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi                                  const MipsSubtarget *Subtarget) {
28827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (DCI.isBeforeLegalize())
28927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return SDValue();
29027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
29127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
29227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi      selectMADD(N, &DAG))
29327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    return SDValue(N, 0);
29427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
295  return SDValue();
296}
297
298static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
299                                  TargetLowering::DAGCombinerInfo &DCI,
300                                  const MipsSubtarget *Subtarget) {
301  if (DCI.isBeforeLegalize())
302    return SDValue();
303
304  if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
305      selectMSUB(N, &DAG))
306    return SDValue(N, 0);
307
308  return SDValue();
309}
310
311SDValue
312MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
313  SelectionDAG &DAG = DCI.DAG;
314
315  switch (N->getOpcode()) {
316  case ISD::ADDE:
317    return performADDECombine(N, DAG, DCI, Subtarget);
318  case ISD::SUBE:
319    return performSUBECombine(N, DAG, DCI, Subtarget);
320  default:
321    return MipsTargetLowering::PerformDAGCombine(N, DCI);
322  }
323}
324
325MachineBasicBlock *
326MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
327                                                  MachineBasicBlock *BB) const {
328  switch (MI->getOpcode()) {
329  default:
330    return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
331  case Mips::BPOSGE32_PSEUDO:
332    return emitBPOSGE32(MI, BB);
333  }
334}
335
336bool MipsSETargetLowering::
337isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
338                                  unsigned NextStackOffset,
339                                  const MipsFunctionInfo& FI) const {
340  if (!EnableMipsTailCalls)
341    return false;
342
343  // Return false if either the callee or caller has a byval argument.
344  if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
345    return false;
346
347  // Return true if the callee's argument area is no larger than the
348  // caller's.
349  return NextStackOffset <= FI.getIncomingArgSize();
350}
351
352void MipsSETargetLowering::
353getOpndList(SmallVectorImpl<SDValue> &Ops,
354            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
355            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
356            CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
357  // T9 should contain the address of the callee function if
358  // -reloction-model=pic or it is an indirect call.
359  if (IsPICCall || !GlobalOrExternal) {
360    unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
361    RegsToPass.push_front(std::make_pair(T9Reg, Callee));
362  } else
363    Ops.push_back(Callee);
364
365  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
366                                  InternalLinkage, CLI, Callee, Chain);
367}
368
369SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
370                                          bool HasLo, bool HasHi,
371                                          SelectionDAG &DAG) const {
372  EVT Ty = Op.getOperand(0).getValueType();
373  DebugLoc DL = Op.getDebugLoc();
374  SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
375                             Op.getOperand(0), Op.getOperand(1));
376  SDValue Lo, Hi;
377
378  if (HasLo)
379    Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
380                     DAG.getConstant(Mips::sub_lo, MVT::i32));
381  if (HasHi)
382    Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
383                     DAG.getConstant(Mips::sub_hi, MVT::i32));
384
385  if (!HasLo || !HasHi)
386    return HasLo ? Lo : Hi;
387
388  SDValue Vals[] = { Lo, Hi };
389  return DAG.getMergeValues(Vals, 2, DL);
390}
391
392MachineBasicBlock * MipsSETargetLowering::
393emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
394  // $bb:
395  //  bposge32_pseudo $vr0
396  //  =>
397  // $bb:
398  //  bposge32 $tbb
399  // $fbb:
400  //  li $vr2, 0
401  //  b $sink
402  // $tbb:
403  //  li $vr1, 1
404  // $sink:
405  //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
406
407  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
408  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
409  const TargetRegisterClass *RC = &Mips::CPURegsRegClass;
410  DebugLoc DL = MI->getDebugLoc();
411  const BasicBlock *LLVM_BB = BB->getBasicBlock();
412  MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
413  MachineFunction *F = BB->getParent();
414  MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
415  MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
416  MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
417  F->insert(It, FBB);
418  F->insert(It, TBB);
419  F->insert(It, Sink);
420
421  // Transfer the remainder of BB and its successor edges to Sink.
422  Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
423               BB->end());
424  Sink->transferSuccessorsAndUpdatePHIs(BB);
425
426  // Add successors.
427  BB->addSuccessor(FBB);
428  BB->addSuccessor(TBB);
429  FBB->addSuccessor(Sink);
430  TBB->addSuccessor(Sink);
431
432  // Insert the real bposge32 instruction to $BB.
433  BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
434
435  // Fill $FBB.
436  unsigned VR2 = RegInfo.createVirtualRegister(RC);
437  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
438    .addReg(Mips::ZERO).addImm(0);
439  BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
440
441  // Fill $TBB.
442  unsigned VR1 = RegInfo.createVirtualRegister(RC);
443  BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
444    .addReg(Mips::ZERO).addImm(1);
445
446  // Insert phi function to $Sink.
447  BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
448          MI->getOperand(0).getReg())
449    .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
450
451  MI->eraseFromParent();   // The pseudo instruction is gone now.
452  return Sink;
453}
454