diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 118 |
1 files changed, 71 insertions, 47 deletions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 224569b2503..1d7a1c0ae8c 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -179,11 +179,11 @@ unsigned MipsTargetLowering::getFunctionAlignment(const Function *) const { // (addc multLo, Lo0), (adde multHi, Hi0), // where, // multHi/Lo: product of multiplication -// Lo0: initial value of Lo register -// Hi0: initial value of Hi register +// Lo0: initial value of Lo register +// Hi0: initial value of Hi register // Return true if mattern matching was successful. static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { - // ADDENode's second operand must be a flag output of an ADDC node in order + // ADDENode's second operand must be a flag output of an ADDC node in order // for the matching to be successful. SDNode* ADDCNode = ADDENode->getOperand(2).getNode(); @@ -192,7 +192,7 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { SDValue MultHi = ADDENode->getOperand(0); SDValue MultLo = ADDCNode->getOperand(0); - SDNode* MultNode = MultHi.getNode(); + SDNode* MultNode = MultHi.getNode(); unsigned MultOpc = MultHi.getOpcode(); // MultHi and MultLo must be generated by the same node, @@ -202,39 +202,39 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { // and it must be a multiplication. if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) return false; - - // MultLo amd MultHi must be the first and second output of MultNode - // respectively. + + // MultLo amd MultHi must be the first and second output of MultNode + // respectively. if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) return false; - // Transform this to a MADD only if ADDENode and ADDCNode are the only users + // Transform this to a MADD only if ADDENode and ADDCNode are the only users // of the values of MultNode, in which case MultNode will be removed in later // phases. // If there exist users other than ADDENode or ADDCNode, this function returns - // here, which will result in MultNode being mapped to a single MULT - // instruction node rather than a pair of MULT and MADD instructions being + // here, which will result in MultNode being mapped to a single MULT + // instruction node rather than a pair of MULT and MADD instructions being // produced. if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) return false; - SDValue Chain = CurDAG->getEntryNode(); + SDValue Chain = CurDAG->getEntryNode(); DebugLoc dl = ADDENode->getDebugLoc(); // create MipsMAdd(u) node MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; - + SDValue MAdd = CurDAG->getNode(MultOpc, dl, MVT::Glue, MultNode->getOperand(0),// Factor 0 MultNode->getOperand(1),// Factor 1 - ADDCNode->getOperand(1),// Lo0 + ADDCNode->getOperand(1),// Lo0 ADDENode->getOperand(1));// Hi0 // create CopyFromReg nodes SDValue CopyFromLo = CurDAG->getCopyFromReg(Chain, dl, Mips::LO, MVT::i32, MAdd); - SDValue CopyFromHi = CurDAG->getCopyFromReg(CopyFromLo.getValue(1), dl, + SDValue CopyFromHi = CurDAG->getCopyFromReg(CopyFromLo.getValue(1), dl, Mips::HI, MVT::i32, CopyFromLo.getValue(2)); @@ -245,7 +245,7 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { if (!SDValue(ADDENode, 0).use_empty()) CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), CopyFromHi); - return true; + return true; } // SelectMsub - @@ -253,11 +253,11 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { // (addc Lo0, multLo), (sube Hi0, multHi), // where, // multHi/Lo: product of multiplication -// Lo0: initial value of Lo register -// Hi0: initial value of Hi register +// Lo0: initial value of Lo register +// Hi0: initial value of Hi register // Return true if mattern matching was successful. static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) { - // SUBENode's second operand must be a flag output of an SUBC node in order + // SUBENode's second operand must be a flag output of an SUBC node in order // for the matching to be successful. SDNode* SUBCNode = SUBENode->getOperand(2).getNode(); @@ -266,7 +266,7 @@ static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) { SDValue MultHi = SUBENode->getOperand(1); SDValue MultLo = SUBCNode->getOperand(1); - SDNode* MultNode = MultHi.getNode(); + SDNode* MultNode = MultHi.getNode(); unsigned MultOpc = MultHi.getOpcode(); // MultHi and MultLo must be generated by the same node, @@ -330,9 +330,9 @@ static SDValue PerformADDECombine(SDNode *N, SelectionDAG& DAG, if (Subtarget->isMips32() && SelectMadd(N, &DAG)) return SDValue(N, 0); - + return SDValue(); -} +} static SDValue PerformSUBECombine(SDNode *N, SelectionDAG& DAG, TargetLowering::DAGCombinerInfo &DCI, @@ -342,11 +342,11 @@ static SDValue PerformSUBECombine(SDNode *N, SelectionDAG& DAG, if (Subtarget->isMips32() && SelectMsub(N, &DAG)) return SDValue(N, 0); - + return SDValue(); -} +} -SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) +SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; unsigned opc = N->getOpcode(); @@ -842,9 +842,15 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, Mips::D6, Mips::D7 }; - unsigned Reg=0; - unsigned UnallocIntReg = State.getFirstUnallocated(IntRegs, IntRegsSize); - bool IntRegUsed = (IntRegs[UnallocIntReg] != (unsigned (Mips::A0))); + unsigned Reg = 0; + static bool IntRegUsed = false; + + // This must be the first arg of the call if no regs have been allocated. + // Initialize IntRegUsed in that case. + if (IntRegs[State.getFirstUnallocated(IntRegs, IntRegsSize)] == Mips::A0 && + F32Regs[State.getFirstUnallocated(F32Regs, FloatRegsSize)] == Mips::F12 && + F64Regs[State.getFirstUnallocated(F64Regs, FloatRegsSize)] == Mips::D6) + IntRegUsed = false; // Promote i8 and i16 if (LocVT == MVT::i8 || LocVT == MVT::i16) { @@ -857,30 +863,48 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, LocInfo = CCValAssign::AExt; } - if (ValVT == MVT::i32 || (ValVT == MVT::f32 && IntRegUsed)) { + if (ValVT == MVT::i32) { Reg = State.AllocateReg(IntRegs, IntRegsSize); IntRegUsed = true; - LocVT = MVT::i32; - } - - if (ValVT.isFloatingPoint() && !IntRegUsed) { - if (ValVT == MVT::f32) - Reg = State.AllocateReg(F32Regs, FloatRegsSize); - else - Reg = State.AllocateReg(F64Regs, FloatRegsSize); - } + } else if (ValVT == MVT::f32) { + // An int reg has to be marked allocated regardless of whether or not + // IntRegUsed is true. + Reg = State.AllocateReg(IntRegs, IntRegsSize); - if (ValVT == MVT::f64 && IntRegUsed) { - if (UnallocIntReg != IntRegsSize) { - // If we hit register A3 as the first not allocated, we must - // mark it as allocated (shadow) and use the stack instead. - if (IntRegs[UnallocIntReg] != (unsigned (Mips::A3))) - Reg = Mips::A2; - for (;UnallocIntReg < IntRegsSize; ++UnallocIntReg) - State.AllocateReg(UnallocIntReg); + if (IntRegUsed) { + if (Reg) // Int reg is available + LocVT = MVT::i32; + } else { + unsigned FReg = State.AllocateReg(F32Regs, FloatRegsSize); + if (FReg) // F32 reg is available + Reg = FReg; + else if (Reg) // No F32 regs are available, but an int reg is available. + LocVT = MVT::i32; } - LocVT = MVT::i32; - } + } else if (ValVT == MVT::f64) { + // Int regs have to be marked allocated regardless of whether or not + // IntRegUsed is true. + Reg = State.AllocateReg(IntRegs, IntRegsSize); + if (Reg == Mips::A1) + Reg = State.AllocateReg(IntRegs, IntRegsSize); + else if (Reg == Mips::A3) + Reg = 0; + State.AllocateReg(IntRegs, IntRegsSize); + + // At this point, Reg is A0, A2 or 0, and all the unavailable integer regs + // are marked as allocated. + if (IntRegUsed) { + if (Reg)// if int reg is available + LocVT = MVT::i32; + } else { + unsigned FReg = State.AllocateReg(F64Regs, FloatRegsSize); + if (FReg) // F64 reg is available. + Reg = FReg; + else if (Reg) // No F64 regs are available, but an int reg is available. + LocVT = MVT::i32; + } + } else + assert(false && "cannot handle this ValVT"); if (!Reg) { unsigned SizeInBytes = ValVT.getSizeInBits() >> 3; |