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