From 7a2bdde0a0eebcd2125055e0eacaca040f0b766c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 15 Apr 2011 05:18:47 +0000 Subject: Fix a ton of comment typos found by codespell. Patch by Luis Felipe Strano Moraes! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129558 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 0e193f2..7baaa0f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -723,7 +723,7 @@ LowerBRCOND(SDValue Op, SelectionDAG &DAG) const SDValue CondRes = CreateFPCmp(DAG, Op.getOperand(1)); - // Return if flag is not set by a floating point comparision. + // Return if flag is not set by a floating point comparison. if (CondRes.getOpcode() != MipsISD::FPCmp) return Op; @@ -741,7 +741,7 @@ LowerSELECT(SDValue Op, SelectionDAG &DAG) const { SDValue Cond = CreateFPCmp(DAG, Op.getOperand(0)); - // Return if flag is not set by a floating point comparision. + // Return if flag is not set by a floating point comparison. if (Cond.getOpcode() != MipsISD::FPCmp) return Op; @@ -867,7 +867,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const // gp_rel relocation // FIXME: we should reference the constant pool using small data sections, - // but the asm printer currently doens't support this feature without + // but the asm printer currently doesn't support this feature without // hacking it. This feature should come soon so we can uncomment the // stuff below. //if (IsInSmallSection(C->getType())) { @@ -1189,7 +1189,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Build a sequence of copy-to-reg nodes chained together with token // chain and flag operands which copy the outgoing args into registers. - // The InFlag in necessary since all emited instructions must be + // The InFlag in necessary since all emitted instructions must be // stuck together. SDValue InFlag; for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { @@ -1272,7 +1272,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Create a stack location to hold GP when PIC is used. This stack // location is used on function prologue to save GP and also after all - // emited CALL's to restore GP. + // emitted CALL's to restore GP. if (IsPIC) { // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. -- cgit v1.1 From 99a2e98eddf00c4afd3817564cb8c914a6f66ae9 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 15 Apr 2011 19:52:08 +0000 Subject: Add pass that expands pseudo instructions into target instructions after register allocation. Define pseudos that get expanded into mtc1 or mfc1 instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129594 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 7baaa0f..a4fc859 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -52,6 +52,8 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::MSubu : return "MipsISD::MSubu"; case MipsISD::DivRem : return "MipsISD::DivRem"; case MipsISD::DivRemU : return "MipsISD::DivRemU"; + case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; + case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; default : return NULL; } } @@ -1132,11 +1134,12 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (VA.getValVT() == MVT::f32 && VA.getLocVT() == MVT::i32) Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg); if (VA.getValVT() == MVT::f64 && VA.getLocVT() == MVT::i32) { - Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i64, Arg); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Arg, - DAG.getConstant(0, getPointerTy())); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Arg, - DAG.getConstant(1, getPointerTy())); + SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, Arg, + DAG.getConstant(0, MVT::i32)); + SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, Arg, + DAG.getConstant(1, MVT::i32)); + if (!Subtarget->isLittle()) + std::swap(Lo, Hi); RegsToPass.push_back(std::make_pair(VA.getLocReg(), Lo)); RegsToPass.push_back(std::make_pair(VA.getLocReg()+1, Hi)); continue; @@ -1429,9 +1432,10 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, unsigned Reg2 = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg()+1, RC); SDValue ArgValue2 = DAG.getCopyFromReg(Chain, dl, Reg2, RegVT); - SDValue Pair = DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, ArgValue, - ArgValue2); - ArgValue = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Pair); + if (!Subtarget->isLittle()) + std::swap(ArgValue, ArgValue2); + ArgValue = DAG.getNode(MipsISD::BuildPairF64, dl, MVT::f64, + ArgValue, ArgValue2); } } -- cgit v1.1 From 0bf3dfbef60e36827df9c7e12b62503f1e345cd0 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 15 Apr 2011 21:00:26 +0000 Subject: Fix lines that have incorrect indentation or exceed 80 columns. There is no change in functionality. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129606 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 91 ++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 41 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a4fc859..fef720c 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1,16 +1,16 @@ -//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===// +//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation ----------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // // This file defines the interfaces that Mips uses to lower LLVM code into a // selection DAG. // -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// #define DEBUG_TYPE "mips-lower" #include "MipsISelLowering.h" @@ -221,8 +221,8 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { // 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 + // 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 // produced. if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) @@ -295,8 +295,8 @@ static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) { // Transform this to a MSUB only if SUBENode and SUBCNode 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 SUBENode or SUBCNode, this function returns - // here, which will result in MultNode being mapped to a single MULT + // If there exist users other than SUBENode or SUBCNode, this function + // returns here, which will result in MultNode being mapped to a single MULT // instruction node rather than a pair of MULT and MSUB instructions being // produced. if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) @@ -444,8 +444,8 @@ static SDValue CreateFPCmp(SelectionDAG& DAG, const SDValue& Op) { SDValue RHS = Op.getOperand(1); DebugLoc dl = Op.getDebugLoc(); - // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of node - // if necessary. + // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of + // node if necessary. ISD::CondCode CC = cast(Op.getOperand(2))->get(); return DAG.getNode(MipsISD::FPCmp, dl, MVT::Glue, LHS, RHS, @@ -520,9 +520,9 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const return SDValue(); } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Lower helper functions -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // AddLiveIn - This helper function adds the specified physical register to the // MachineFunction as a live in value. It also creates a corresponding @@ -653,9 +653,9 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Misc Lower Operation implementation -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// SDValue MipsTargetLowering:: LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const @@ -851,7 +851,8 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const MachinePointerInfo(), false, false, 0); - SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO); + SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, + MipsII::MO_ABS_LO); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, JTILo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); @@ -879,9 +880,11 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_ABS_HI); + N->getOffset(), + MipsII::MO_ABS_HI); SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_ABS_LO); + N->getOffset(), + MipsII::MO_ABS_LO); SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); @@ -892,7 +895,8 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const CP, MachinePointerInfo::getConstantPool(), false, false, 0); SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MipsII::MO_ABS_LO); + N->getOffset(), + MipsII::MO_ABS_LO); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); } @@ -916,13 +920,13 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { false, false, 0); } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Calling Convention Implementation -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// #include "MipsGenCallingConv.inc" -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // TODO: Implement a generic logic using tblgen that can support this. // Mips O32 ABI rules: // --- @@ -933,7 +937,7 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { // yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is // not used, it must be shadowed. If only A3 is avaiable, shadow it and // go to stack. -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, @@ -957,7 +961,8 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, // 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 && + F32Regs[State.getFirstUnallocated(F32Regs, FloatRegsSize)] == + Mips::F12 && F64Regs[State.getFirstUnallocated(F64Regs, FloatRegsSize)] == Mips::D6) IntRegUsed = false; @@ -1070,9 +1075,9 @@ static bool CC_MipsO32_VarArgs(unsigned ValNo, MVT ValVT, return false; // CC must always match } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Call Calling Convention Implementation -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// /// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. @@ -1134,10 +1139,11 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (VA.getValVT() == MVT::f32 && VA.getLocVT() == MVT::i32) Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg); if (VA.getValVT() == MVT::f64 && VA.getLocVT() == MVT::i32) { - SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, Arg, + SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, + MVT::i32, Arg, DAG.getConstant(0, MVT::i32)); - SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, Arg, - DAG.getConstant(1, MVT::i32)); + SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, + Arg, DAG.getConstant(1, MVT::i32)); if (!Subtarget->isLittle()) std::swap(Lo, Hi); RegsToPass.push_back(std::make_pair(VA.getLocReg(), Lo)); @@ -1342,20 +1348,21 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, return Chain; } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Formal Arguments Calling Convention Implementation -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// /// LowerFormalArguments - transform physical registers into virtual registers /// and generate load operations for arguments places on the stack. SDValue MipsTargetLowering::LowerFormalArguments(SDValue Chain, - CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl - &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) - const { + CallingConv::ID CallConv, + bool isVarArg, + const SmallVectorImpl + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl &InVals) + const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -1456,7 +1463,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // be used on emitPrologue) to avoid mis-calc of the first stack // offset on PEI::calculateFrameObjectOffsets. unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - LastStackArgEndOffset = FirstStackArgLoc + VA.getLocMemOffset() + ArgSize; + LastStackArgEndOffset = FirstStackArgLoc + VA.getLocMemOffset() + + ArgSize; int FI = MFI->CreateFixedObject(ArgSize, 0, true); MipsFI->recordLoadArgsFI(FI, -(4 + (FirstStackArgLoc + VA.getLocMemOffset()))); @@ -1545,9 +1553,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, return Chain; } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Return Value Calling Convention Implementation -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// SDValue MipsTargetLowering::LowerReturn(SDValue Chain, @@ -1572,7 +1580,8 @@ MipsTargetLowering::LowerReturn(SDValue Chain, if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) - DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); + DAG.getMachineFunction().getRegInfo() + .addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; @@ -1616,9 +1625,9 @@ MipsTargetLowering::LowerReturn(SDValue Chain, Chain, DAG.getRegister(Mips::RA, MVT::i32)); } -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// // Mips Inline Assembly Support -//===----------------------------------------------------------------------===// +//===---------------------------------------------------------------------===// /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. -- cgit v1.1 From 4552c9a3b34ad9b2085635266348d0d9b95514a6 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 15 Apr 2011 21:51:11 +0000 Subject: Reverse unnecessary changes made in r129606 and r129608. There is no change in functionality. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129612 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 71 ++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 39 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index fef720c..cde9fb3 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1,16 +1,16 @@ -//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation ----------===// +//===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // This file defines the interfaces that Mips uses to lower LLVM code into a // selection DAG. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "mips-lower" #include "MipsISelLowering.h" @@ -221,8 +221,8 @@ static bool SelectMadd(SDNode* ADDENode, SelectionDAG* CurDAG) { // 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 + // 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 // produced. if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) @@ -295,8 +295,8 @@ static bool SelectMsub(SDNode* SUBENode, SelectionDAG* CurDAG) { // Transform this to a MSUB only if SUBENode and SUBCNode 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 SUBENode or SUBCNode, this function - // returns here, which will result in MultNode being mapped to a single MULT + // If there exist users other than SUBENode or SUBCNode, this function returns + // here, which will result in MultNode being mapped to a single MULT // instruction node rather than a pair of MULT and MSUB instructions being // produced. if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) @@ -520,9 +520,9 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const return SDValue(); } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Lower helper functions -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // AddLiveIn - This helper function adds the specified physical register to the // MachineFunction as a live in value. It also creates a corresponding @@ -653,9 +653,9 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Misc Lower Operation implementation -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// SDValue MipsTargetLowering:: LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const @@ -880,11 +880,9 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { SDValue CPHi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), - MipsII::MO_ABS_HI); + N->getOffset(), MipsII::MO_ABS_HI); SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), - MipsII::MO_ABS_LO); + N->getOffset(), MipsII::MO_ABS_LO); SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, MVT::i32, CPHi); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); @@ -895,8 +893,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const CP, MachinePointerInfo::getConstantPool(), false, false, 0); SDValue CPLo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), - MipsII::MO_ABS_LO); + N->getOffset(), MipsII::MO_ABS_LO); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, CPLo); ResNode = DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); } @@ -920,13 +917,13 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { false, false, 0); } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Calling Convention Implementation -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "MipsGenCallingConv.inc" -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // TODO: Implement a generic logic using tblgen that can support this. // Mips O32 ABI rules: // --- @@ -937,7 +934,7 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { // yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is // not used, it must be shadowed. If only A3 is avaiable, shadow it and // go to stack. -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, @@ -961,8 +958,7 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, // 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 && + F32Regs[State.getFirstUnallocated(F32Regs, FloatRegsSize)] == Mips::F12 && F64Regs[State.getFirstUnallocated(F64Regs, FloatRegsSize)] == Mips::D6) IntRegUsed = false; @@ -1075,9 +1071,9 @@ static bool CC_MipsO32_VarArgs(unsigned ValNo, MVT ValVT, return false; // CC must always match } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Call Calling Convention Implementation -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. @@ -1139,9 +1135,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (VA.getValVT() == MVT::f32 && VA.getLocVT() == MVT::i32) Arg = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Arg); if (VA.getValVT() == MVT::f64 && VA.getLocVT() == MVT::i32) { - SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, - MVT::i32, Arg, - DAG.getConstant(0, MVT::i32)); + SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, + Arg, DAG.getConstant(0, MVT::i32)); SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, Arg, DAG.getConstant(1, MVT::i32)); if (!Subtarget->isLittle()) @@ -1348,9 +1343,9 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, return Chain; } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Formal Arguments Calling Convention Implementation -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// LowerFormalArguments - transform physical registers into virtual registers /// and generate load operations for arguments places on the stack. @@ -1362,7 +1357,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl &InVals) - const { + const { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -1463,8 +1458,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // be used on emitPrologue) to avoid mis-calc of the first stack // offset on PEI::calculateFrameObjectOffsets. unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - LastStackArgEndOffset = FirstStackArgLoc + VA.getLocMemOffset() + - ArgSize; + LastStackArgEndOffset = FirstStackArgLoc + VA.getLocMemOffset() + ArgSize; int FI = MFI->CreateFixedObject(ArgSize, 0, true); MipsFI->recordLoadArgsFI(FI, -(4 + (FirstStackArgLoc + VA.getLocMemOffset()))); @@ -1553,9 +1547,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, return Chain; } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Return Value Calling Convention Implementation -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// SDValue MipsTargetLowering::LowerReturn(SDValue Chain, @@ -1580,8 +1574,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { for (unsigned i = 0; i != RVLocs.size(); ++i) if (RVLocs[i].isRegLoc()) - DAG.getMachineFunction().getRegInfo() - .addLiveOut(RVLocs[i].getLocReg()); + DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } SDValue Flag; @@ -1625,9 +1618,9 @@ MipsTargetLowering::LowerReturn(SDValue Chain, Chain, DAG.getRegister(Mips::RA, MVT::i32)); } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Mips Inline Assembly Support -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. -- cgit v1.1 From f48eb533d56ee57afdfdf62fec6a74aa0b3bbf27 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 25 Apr 2011 17:10:45 +0000 Subject: Lower BlockAddress node when relocation-model is static. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130131 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 38 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index cde9fb3..1f1220f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -801,24 +801,30 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { + const BlockAddress *BA = cast(Op)->getBlockAddress(); + // FIXME there isn't actually debug info here + DebugLoc dl = Op.getDebugLoc(); + if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { - assert(false && "implement LowerBlockAddress for -static"); - return SDValue(0, 0); - } - else { - // FIXME there isn't actually debug info here - DebugLoc dl = Op.getDebugLoc(); - const BlockAddress *BA = cast(Op)->getBlockAddress(); - SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, - MipsII::MO_GOT); - SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, - MipsII::MO_ABS_LO); - SDValue Load = DAG.getLoad(MVT::i32, dl, - DAG.getEntryNode(), BAGOTOffset, - MachinePointerInfo(), false, false, 0); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALOOffset); - return DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); + // %hi/%lo relocation + SDValue BAHi = DAG.getBlockAddress(BA, MVT::i32, true, + MipsII::MO_ABS_HI); + SDValue BALo = DAG.getBlockAddress(BA, MVT::i32, true, + MipsII::MO_ABS_LO); + SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo); + return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo); } + + SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, + MipsII::MO_GOT); + SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, + MipsII::MO_ABS_LO); + SDValue Load = DAG.getLoad(MVT::i32, dl, + DAG.getEntryNode(), BAGOTOffset, + MachinePointerInfo(), false, false, 0); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALOOffset); + return DAG.getNode(ISD::ADD, dl, MVT::i32, Load, Lo); } SDValue MipsTargetLowering:: -- cgit v1.1 From 6b7588e6c4f6f1a9ab2b5182fafaa95eeb56ca8d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 4 May 2011 17:54:27 +0000 Subject: Prevent instructions using $gp from being placed between a jalr and the instruction that restores the clobbered $gp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130847 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 1f1220f..9592244 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1298,17 +1298,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } MipsFI->setGPStackOffset(LastArgStackLoc); } - - // Reload GP value. - FI = MipsFI->getGPFI(); - SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); - SDValue GPLoad = DAG.getLoad(MVT::i32, dl, Chain, FIN, - MachinePointerInfo::getFixedStack(FI), - false, false, 0); - Chain = GPLoad.getValue(1); - Chain = DAG.getCopyToReg(Chain, dl, DAG.getRegister(Mips::GP, MVT::i32), - GPLoad, SDValue(0,0)); - InFlag = Chain.getValue(1); } // Create the CALLSEQ_END node. -- cgit v1.1 From fc5d305597ea6336d75bd7f3b741e8d57d6a5105 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 6 May 2011 20:34:06 +0000 Subject: Make the logic for determining function alignment more explicit. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131012 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 9592244..456efc5 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -171,6 +171,8 @@ MipsTargetLowering(MipsTargetMachine &TM) setTargetDAGCombine(ISD::UDIVREM); setTargetDAGCombine(ISD::SETCC); + setMinFunctionAlignment(2); + setStackPointerRegisterToSaveRestore(Mips::SP); computeRegisterProperties(); } @@ -179,11 +181,6 @@ MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const { return MVT::i32; } -/// getFunctionAlignment - Return the Log2 alignment of this function. -unsigned MipsTargetLowering::getFunctionAlignment(const Function *) const { - return 2; -} - // SelectMadd - // Transforms a subgraph in CurDAG if the following pattern is found: // (addc multLo, Lo0), (adde multHi, Hi0), -- cgit v1.1 From 95b8ae190ef8ee00d0d5aa7e26cdda9cc9ed6717 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 19 May 2011 18:06:05 +0000 Subject: Simplify CC_MipsO32 and merge it with CC_MipsO32_VarArgs. Patch by Sasa Stankovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131657 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 118 +++++++++-------------------------- 1 file changed, 28 insertions(+), 90 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 456efc5..3503c87 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -937,6 +937,8 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { // yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is // not used, it must be shadowed. If only A3 is avaiable, shadow it and // go to stack. +// +// For vararg functions, all arguments are passed in A0, A1, A2, A3 and stack. //===----------------------------------------------------------------------===// static bool CC_MipsO32(unsigned ValNo, MVT ValVT, @@ -955,90 +957,6 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, Mips::D6, Mips::D7 }; - 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) { - LocVT = MVT::i32; - if (ArgFlags.isSExt()) - LocInfo = CCValAssign::SExt; - else if (ArgFlags.isZExt()) - LocInfo = CCValAssign::ZExt; - else - LocInfo = CCValAssign::AExt; - } - - if (ValVT == MVT::i32) { - Reg = State.AllocateReg(IntRegs, IntRegsSize); - IntRegUsed = true; - } 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 (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; - } - } 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; - unsigned Offset = State.AllocateStack(SizeInBytes, SizeInBytes); - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - } else - State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); - - return false; // CC must always match -} - -static bool CC_MipsO32_VarArgs(unsigned ValNo, MVT ValVT, - MVT LocVT, CCValAssign::LocInfo LocInfo, - ISD::ArgFlagsTy ArgFlags, CCState &State) { - - static const unsigned IntRegsSize=4; - - static const unsigned IntRegs[] = { - Mips::A0, Mips::A1, Mips::A2, Mips::A3 - }; - // Promote i8 and i16 if (LocVT == MVT::i8 || LocVT == MVT::i16) { LocVT = MVT::i32; @@ -1052,15 +970,37 @@ static bool CC_MipsO32_VarArgs(unsigned ValNo, MVT ValVT, unsigned Reg; - if (ValVT == MVT::i32 || ValVT == MVT::f32) { + // f32 and f64 are allocated in A0, A1, A2, A3 when either of the following + // is true: function is vararg, argument is 3rd or higher, there is previous + // argument which is not f32 or f64. + bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 + || State.getFirstUnallocated(F32Regs, FloatRegsSize) != ValNo; + + if (ValVT == MVT::i32 || (ValVT == MVT::f32 && AllocateFloatsInIntReg)) { Reg = State.AllocateReg(IntRegs, IntRegsSize); LocVT = MVT::i32; - } else if (ValVT == MVT::f64) { + } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) { + // Allocate int register and shadow next int register. If first + // available register is Mips::A1 or Mips::A3, shadow it too. Reg = State.AllocateReg(IntRegs, IntRegsSize); if (Reg == Mips::A1 || Reg == Mips::A3) Reg = State.AllocateReg(IntRegs, IntRegsSize); State.AllocateReg(IntRegs, IntRegsSize); LocVT = MVT::i32; + } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) { + // we are guaranteed to find an available float register + if (ValVT == MVT::f32) { + Reg = State.AllocateReg(F32Regs, FloatRegsSize); + // Shadow int register + State.AllocateReg(IntRegs, IntRegsSize); + } else { + Reg = State.AllocateReg(F64Regs, FloatRegsSize); + // Shadow int registers + unsigned Reg2 = State.AllocateReg(IntRegs, IntRegsSize); + if (Reg2 == Mips::A1 || Reg2 == Mips::A3) + State.AllocateReg(IntRegs, IntRegsSize); + State.AllocateReg(IntRegs, IntRegsSize); + } } else llvm_unreachable("Cannot handle this ValVT."); @@ -1107,8 +1047,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (Subtarget->isABI_O32()) { int VTsize = MVT(MVT::i32).getSizeInBits()/8; MFI->CreateFixedObject(VTsize, (VTsize*3), true); - CCInfo.AnalyzeCallOperands(Outs, - isVarArg ? CC_MipsO32_VarArgs : CC_MipsO32); + CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32); } else CCInfo.AnalyzeCallOperands(Outs, CC_Mips); @@ -1369,8 +1308,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, ArgLocs, *DAG.getContext()); if (Subtarget->isABI_O32()) - CCInfo.AnalyzeFormalArguments(Ins, - isVarArg ? CC_MipsO32_VarArgs : CC_MipsO32); + CCInfo.AnalyzeFormalArguments(Ins, CC_MipsO32); else CCInfo.AnalyzeFormalArguments(Ins, CC_Mips); -- cgit v1.1 From a1a7ba838230b4b77604cc9a9fbd22f40f354ba2 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 19 May 2011 20:29:48 +0000 Subject: Align i64 arguments to 64 bit boundaries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131668 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 3503c87..496d00f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -975,9 +975,15 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, // argument which is not f32 or f64. bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 || State.getFirstUnallocated(F32Regs, FloatRegsSize) != ValNo; + unsigned OrigAlign = ArgFlags.getOrigAlign(); + bool isI64 = (ValVT == MVT::i32 && OrigAlign == 8); if (ValVT == MVT::i32 || (ValVT == MVT::f32 && AllocateFloatsInIntReg)) { Reg = State.AllocateReg(IntRegs, IntRegsSize); + // If this is the first part of an i64 arg, + // the allocated register must be either A0 or A2. + if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3)) + Reg = State.AllocateReg(IntRegs, IntRegsSize); LocVT = MVT::i32; } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) { // Allocate int register and shadow next int register. If first @@ -1006,7 +1012,7 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, if (!Reg) { unsigned SizeInBytes = ValVT.getSizeInBits() >> 3; - unsigned Offset = State.AllocateStack(SizeInBytes, SizeInBytes); + unsigned Offset = State.AllocateStack(SizeInBytes, OrigAlign); State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); } else State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); -- cgit v1.1 From d992f6c6661e35b1a186a415667cbd3a91d37711 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 20 May 2011 01:45:06 +0000 Subject: Remove code that creates unnecessary frame objects. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131711 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 496d00f..f940185 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1048,11 +1048,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - // To meet O32 ABI, Mips must always allocate 16 bytes on - // the stack (even if less than 4 are used as arguments) if (Subtarget->isABI_O32()) { - int VTsize = MVT(MVT::i32).getSizeInBits()/8; - MFI->CreateFixedObject(VTsize, (VTsize*3), true); CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32); } else CCInfo.AnalyzeCallOperands(Outs, CC_Mips); -- cgit v1.1 From cd0f90f8317c8b59ed11256f8b0eeb54b3cc22e2 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 20 May 2011 02:30:51 +0000 Subject: Fix bug in which nodes that write to argument registers do not get glued with the JALR node. Patch by Sasa Stankovic git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131714 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index f940185..ea26d57 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1135,17 +1135,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOpChains[0], MemOpChains.size()); - // Build a sequence of copy-to-reg nodes chained together with token - // chain and flag operands which copy the outgoing args into registers. - // The InFlag in necessary since all emitted instructions must be - // stuck together. - SDValue InFlag; - for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { - Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, - RegsToPass[i].second, InFlag); - InFlag = Chain.getValue(1); - } - // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. @@ -1172,6 +1161,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, LoadSymAddr = true; } + SDValue InFlag; + // Create nodes that load address of callee and copy it to T9 if (IsPIC) { if (LoadSymAddr) { @@ -1197,6 +1188,16 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, Callee = DAG.getRegister(Mips::T9, MVT::i32); } + // Build a sequence of copy-to-reg nodes chained together with token + // chain and flag operands which copy the outgoing args into registers. + // The InFlag in necessary since all emitted instructions must be + // stuck together. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, + RegsToPass[i].second, InFlag); + InFlag = Chain.getValue(1); + } + // MipsJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... // -- cgit v1.1 From 17a1e8775119db75ece41e041eeb6480793696ff Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 20 May 2011 18:39:33 +0000 Subject: Make $fp and $ra callee-saved registers and let PrologEpilogInserter handle saving and restoring them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131745 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ea26d57..08da34b 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1042,6 +1042,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; + MipsFunctionInfo *MipsFI = MF.getInfo(); // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; @@ -1066,6 +1067,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, int LastArgStackLoc = 0; unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16); + MipsFI->setHasCall(); + // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { SDValue Arg = OutVals[i]; @@ -1226,7 +1229,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. int FI; - MipsFunctionInfo *MipsFI = MF.getInfo(); if (LastArgStackLoc >= MipsFI->getGPStackOffset()) { LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4); // Create the frame index only once. SPOffset here can be anything -- cgit v1.1 From d37776d1c15977d9d86cab08250b6cfd847b7cae Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 20 May 2011 21:39:54 +0000 Subject: In CC_MipsO32, allocate a stack space regardless of whether the argument is passed in register or on the stack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131758 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 47 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 08da34b..77a9855 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1010,11 +1010,12 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, } else llvm_unreachable("Cannot handle this ValVT."); - if (!Reg) { - unsigned SizeInBytes = ValVT.getSizeInBits() >> 3; - unsigned Offset = State.AllocateStack(SizeInBytes, OrigAlign); + unsigned SizeInBytes = ValVT.getSizeInBits() >> 3; + unsigned Offset = State.AllocateStack(SizeInBytes, OrigAlign); + + if (!Reg) State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - } else + else State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; // CC must always match @@ -1041,6 +1042,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetFrameLowering *TFL = MF.getTarget().getFrameLowering(); bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; MipsFunctionInfo *MipsFI = MF.getInfo(); @@ -1061,11 +1063,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // With EABI is it possible to have 16 args on registers. SmallVector, 16> RegsToPass; SmallVector MemOpChains; - - // First/LastArgStackLoc contains the first/last - // "at stack" argument location. - int LastArgStackLoc = 0; - unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16); + unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16); MipsFI->setHasCall(); @@ -1119,9 +1117,10 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // This guarantees that when allocating Local Area the firsts // 16 bytes which are alwayes reserved won't be overwritten // if O32 ABI is used. For EABI the first address is zero. - LastArgStackLoc = (FirstStackArgLoc + VA.getLocMemOffset()); + NextStackOffset = VA.getLocMemOffset(); int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, - LastArgStackLoc, true); + NextStackOffset, true); + NextStackOffset += VA.getValVT().getSizeInBits()/8; SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy()); @@ -1229,15 +1228,21 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. int FI; - if (LastArgStackLoc >= MipsFI->getGPStackOffset()) { - LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4); - // Create the frame index only once. SPOffset here can be anything - // (this will be fixed on processFunctionBeforeFrameFinalized) + int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + + if (MaxCallFrameSize < (int)NextStackOffset) { + MipsFI->setMaxCallFrameSize(NextStackOffset); + if (MipsFI->getGPStackOffset() == -1) { FI = MFI->CreateFixedObject(4, 0, true); MipsFI->setGPFI(FI); } - MipsFI->setGPStackOffset(LastArgStackLoc); + + // $gp restore slot must be aligned. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + MipsFI->setGPStackOffset(NextStackOffset); } } @@ -1317,8 +1322,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, else CCInfo.AnalyzeFormalArguments(Ins, CC_Mips); - unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16); - unsigned LastStackArgEndOffset = 0; + unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16); EVT LastRegArgValVT; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -1393,10 +1397,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // be used on emitPrologue) to avoid mis-calc of the first stack // offset on PEI::calculateFrameObjectOffsets. unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - LastStackArgEndOffset = FirstStackArgLoc + VA.getLocMemOffset() + ArgSize; + NextStackOffset = VA.getLocMemOffset() + ArgSize; int FI = MFI->CreateFixedObject(ArgSize, 0, true); - MipsFI->recordLoadArgsFI(FI, -(4 + - (FirstStackArgLoc + VA.getLocMemOffset()))); + MipsFI->recordLoadArgsFI(FI, -(4 + VA.getLocMemOffset())); // Create load nodes to retrieve arguments from the stack SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); @@ -1466,7 +1469,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // on stack. Record the frame index of the first variable argument. int FI = MFI->CreateFixedObject(4, 0, true); MFI->setObjectAlignment(FI, 4); - MipsFI->recordStoreVarArgsFI(FI, -(4+LastStackArgEndOffset)); + MipsFI->recordStoreVarArgsFI(FI, -(4+NextStackOffset)); MipsFI->setVarArgsFrameIndex(FI); } } -- cgit v1.1 From 43299776d7cae9843b354b9fcc08186437516d68 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 20 May 2011 23:22:14 +0000 Subject: Change the order fixed objects are created in MipsTargetLowering::LowerCall in preparation for reversing StackDirection. Fixed objects are created in the following order: 1. Incoming arguments passed on stack. 2. va_arg objects (include both arguments that are passed in registers and pointer to the location of the first va_arg argument). 3. $gp restore slot. 4. Outgoing arguments passed on stack. 5. Pointer to alloca'd space. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131767 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 60 +++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 25 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 77a9855..0ffceeb 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1067,6 +1067,13 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MipsFI->setHasCall(); + // Create GP frame object if this is the first call. + // SPOffset will be updated after call frame size is known. + if (IsPIC && MipsFI->getGPStackOffset() == -1) + MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); + + int FirstFI = -MFI->getNumFixedObjects() - 1, LastFI = 0; + // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { SDValue Arg = OutVals[i]; @@ -1118,11 +1125,11 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // 16 bytes which are alwayes reserved won't be overwritten // if O32 ABI is used. For EABI the first address is zero. NextStackOffset = VA.getLocMemOffset(); - int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, + LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, NextStackOffset, true); NextStackOffset += VA.getValVT().getSizeInBits()/8; - SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy()); + SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); // emit ISD::STORE whichs stores the // parameter value to a stack Location @@ -1227,17 +1234,11 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC) { // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. - int FI; int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); if (MaxCallFrameSize < (int)NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); - if (MipsFI->getGPStackOffset() == -1) { - FI = MFI->CreateFixedObject(4, 0, true); - MipsFI->setGPFI(FI); - } - // $gp restore slot must be aligned. unsigned StackAlignment = TFL->getStackAlignment(); NextStackOffset = (NextStackOffset + StackAlignment - 1) / @@ -1246,6 +1247,12 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } } + // Extend range of indices of frame objects for outgoing arguments that were + // created during this function call. Skip this step if no such objects were + // created. + if (LastFI) + MipsFI->extendOutArgFIRange(FirstFI, LastFI); + // Create the CALLSEQ_END node. Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(0, true), InFlag); @@ -1324,6 +1331,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16); EVT LastRegArgValVT; + int LastFI = 0;// MipsFI->LastInArgFI is 0 at the entry of this function. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; @@ -1398,13 +1406,13 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // offset on PEI::calculateFrameObjectOffsets. unsigned ArgSize = VA.getValVT().getSizeInBits()/8; NextStackOffset = VA.getLocMemOffset() + ArgSize; - int FI = MFI->CreateFixedObject(ArgSize, 0, true); - MipsFI->recordLoadArgsFI(FI, -(4 + VA.getLocMemOffset())); + LastFI = MFI->CreateFixedObject(ArgSize, 0, true); + MipsFI->recordLoadArgsFI(LastFI, -(4 + VA.getLocMemOffset())); // Create load nodes to retrieve arguments from the stack - SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); + SDValue FIN = DAG.getFrameIndex(LastFI, getPointerTy()); InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, - MachinePointerInfo::getFixedStack(FI), + MachinePointerInfo::getFixedStack(LastFI), false, false, 0)); } } @@ -1441,9 +1449,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32); - int FI = MFI->CreateFixedObject(4, 0, true); - MipsFI->recordStoreVarArgsFI(FI, -(4+(ArgRegEnd-Mips::A0)*4)); - SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy()); + LastFI = MFI->CreateFixedObject(4, 0, true); + MipsFI->recordStoreVarArgsFI(LastFI, -(4+(ArgRegEnd-Mips::A0)*4)); + SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, MachinePointerInfo(), false, false, 0)); @@ -1451,29 +1459,31 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Record the frame index of the first variable argument // which is a value necessary to VASTART. if (!MipsFI->getVarArgsFrameIndex()) { - MFI->setObjectAlignment(FI, 4); - MipsFI->setVarArgsFrameIndex(FI); + MFI->setObjectAlignment(LastFI, 4); + MipsFI->setVarArgsFrameIndex(LastFI); } } } else { // Last named formal argument is in register Mips::A3, and the first // variable argument is on stack. Record the frame index of the first // variable argument. - int FI = MFI->CreateFixedObject(4, 0, true); - MFI->setObjectAlignment(FI, 4); - MipsFI->recordStoreVarArgsFI(FI, -20); - MipsFI->setVarArgsFrameIndex(FI); + LastFI = MFI->CreateFixedObject(4, 0, true); + MFI->setObjectAlignment(LastFI, 4); + MipsFI->recordStoreVarArgsFI(LastFI, -20); + MipsFI->setVarArgsFrameIndex(LastFI); } } else { // Last named formal argument and all the variable arguments are passed // on stack. Record the frame index of the first variable argument. - int FI = MFI->CreateFixedObject(4, 0, true); - MFI->setObjectAlignment(FI, 4); - MipsFI->recordStoreVarArgsFI(FI, -(4+NextStackOffset)); - MipsFI->setVarArgsFrameIndex(FI); + LastFI = MFI->CreateFixedObject(4, 0, true); + MFI->setObjectAlignment(LastFI, 4); + MipsFI->recordStoreVarArgsFI(LastFI, -(4+NextStackOffset)); + MipsFI->setVarArgsFrameIndex(LastFI); } } + MipsFI->setLastInArgFI(LastFI); + // All stores are grouped in one node to allow the matching between // the size of Ins and InVals. This only happens when on varg functions if (!OutChains.empty()) { -- cgit v1.1 From 69c19f7316ed8e545c7339421b910543eb8e9eef Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 23 May 2011 20:16:59 +0000 Subject: Change StackDirection from StackGrowsUp to StackGrowsDown. The following improvements are accomplished as a result of applying this patch: - Fixed frame objects' offsets (relative to either the virtual frame pointer or the stack pointer) are set before instruction selection is completed. There is no need to wait until Prologue/Epilogue Insertion is run to set them. - Calculation of final offsets of fixed frame objects is straightforward. It is no longer necessary to assign negative offsets to fixed objects for incoming arguments in order to distinguish them from the others. - Since a fixed object has its relative offset set during instruction selection, there is no need to conservatively set its alignment to 4. - It is no longer necessary to reorder non-fixed frame objects in MipsFrameLowering::adjustMipsStackFrame. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131915 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 0ffceeb..dda7e8d 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1069,7 +1069,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Create GP frame object if this is the first call. // SPOffset will be updated after call frame size is known. - if (IsPIC && MipsFI->getGPStackOffset() == -1) + if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); int FirstFI = -MFI->getNumFixedObjects() - 1, LastFI = 0; @@ -1124,10 +1124,10 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // This guarantees that when allocating Local Area the firsts // 16 bytes which are alwayes reserved won't be overwritten // if O32 ABI is used. For EABI the first address is zero. + unsigned ArgSize = VA.getValVT().getSizeInBits()/8; NextStackOffset = VA.getLocMemOffset(); - LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, - NextStackOffset, true); - NextStackOffset += VA.getValVT().getSizeInBits()/8; + LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true); + NextStackOffset += ArgSize; SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); @@ -1243,7 +1243,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, unsigned StackAlignment = TFL->getStackAlignment(); NextStackOffset = (NextStackOffset + StackAlignment - 1) / StackAlignment * StackAlignment; - MipsFI->setGPStackOffset(NextStackOffset); + int GPFI = MipsFI->getGPFI(); + MFI->setObjectOffset(GPFI, NextStackOffset); } } @@ -1405,9 +1406,9 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // be used on emitPrologue) to avoid mis-calc of the first stack // offset on PEI::calculateFrameObjectOffsets. unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - NextStackOffset = VA.getLocMemOffset() + ArgSize; - LastFI = MFI->CreateFixedObject(ArgSize, 0, true); - MipsFI->recordLoadArgsFI(LastFI, -(4 + VA.getLocMemOffset())); + NextStackOffset = VA.getLocMemOffset(); + LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true); + NextStackOffset += ArgSize; // Create load nodes to retrieve arguments from the stack SDValue FIN = DAG.getFrameIndex(LastFI, getPointerTy()); @@ -1449,8 +1450,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32); - LastFI = MFI->CreateFixedObject(4, 0, true); - MipsFI->recordStoreVarArgsFI(LastFI, -(4+(ArgRegEnd-Mips::A0)*4)); + LastFI = MFI->CreateFixedObject(4, (ArgRegEnd-Mips::A0)*4, true); SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, MachinePointerInfo(), @@ -1458,26 +1458,20 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Record the frame index of the first variable argument // which is a value necessary to VASTART. - if (!MipsFI->getVarArgsFrameIndex()) { - MFI->setObjectAlignment(LastFI, 4); + if (!MipsFI->getVarArgsFrameIndex()) MipsFI->setVarArgsFrameIndex(LastFI); - } } } else { // Last named formal argument is in register Mips::A3, and the first // variable argument is on stack. Record the frame index of the first // variable argument. - LastFI = MFI->CreateFixedObject(4, 0, true); - MFI->setObjectAlignment(LastFI, 4); - MipsFI->recordStoreVarArgsFI(LastFI, -20); + LastFI = MFI->CreateFixedObject(4, 16, true); MipsFI->setVarArgsFrameIndex(LastFI); } } else { // Last named formal argument and all the variable arguments are passed // on stack. Record the frame index of the first variable argument. - LastFI = MFI->CreateFixedObject(4, 0, true); - MFI->setObjectAlignment(LastFI, 4); - MipsFI->recordStoreVarArgsFI(LastFI, -(4+NextStackOffset)); + LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); MipsFI->setVarArgsFrameIndex(LastFI); } } -- cgit v1.1 From bdd2ce9741643bab00ba2869852f6babbe072cf0 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 23 May 2011 21:13:59 +0000 Subject: Fixes related to coding style. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131922 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 72 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index dda7e8d..15ab172 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -36,25 +36,25 @@ using namespace llvm; const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { - case MipsISD::JmpLink : return "MipsISD::JmpLink"; - case MipsISD::Hi : return "MipsISD::Hi"; - case MipsISD::Lo : return "MipsISD::Lo"; - case MipsISD::GPRel : return "MipsISD::GPRel"; - case MipsISD::Ret : return "MipsISD::Ret"; - case MipsISD::FPBrcond : return "MipsISD::FPBrcond"; - case MipsISD::FPCmp : return "MipsISD::FPCmp"; - case MipsISD::CMovFP_T : return "MipsISD::CMovFP_T"; - case MipsISD::CMovFP_F : return "MipsISD::CMovFP_F"; - case MipsISD::FPRound : return "MipsISD::FPRound"; - case MipsISD::MAdd : return "MipsISD::MAdd"; - case MipsISD::MAddu : return "MipsISD::MAddu"; - case MipsISD::MSub : return "MipsISD::MSub"; - case MipsISD::MSubu : return "MipsISD::MSubu"; - case MipsISD::DivRem : return "MipsISD::DivRem"; - case MipsISD::DivRemU : return "MipsISD::DivRemU"; - case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; - case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; - default : return NULL; + case MipsISD::JmpLink: return "MipsISD::JmpLink"; + case MipsISD::Hi: return "MipsISD::Hi"; + case MipsISD::Lo: return "MipsISD::Lo"; + case MipsISD::GPRel: return "MipsISD::GPRel"; + case MipsISD::Ret: return "MipsISD::Ret"; + case MipsISD::FPBrcond: return "MipsISD::FPBrcond"; + case MipsISD::FPCmp: return "MipsISD::FPCmp"; + case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; + case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; + case MipsISD::FPRound: return "MipsISD::FPRound"; + case MipsISD::MAdd: return "MipsISD::MAdd"; + case MipsISD::MAddu: return "MipsISD::MAddu"; + case MipsISD::MSub: return "MipsISD::MSub"; + case MipsISD::MSubu: return "MipsISD::MSubu"; + case MipsISD::DivRem: return "MipsISD::DivRem"; + case MipsISD::DivRemU: return "MipsISD::DivRemU"; + case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; + case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; + default: return NULL; } } @@ -380,7 +380,7 @@ static SDValue PerformDivRemCombine(SDNode *N, SelectionDAG& DAG, // insert MFHI if (N->hasAnyUseOfValue(1)) { SDValue CopyFromHi = DAG.getCopyFromReg(InChain, dl, - Mips::HI, MVT::i32, InGlue); + Mips::HI, MVT::i32, InGlue); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi); } @@ -1051,9 +1051,9 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, *DAG.getContext()); - if (Subtarget->isABI_O32()) { + if (Subtarget->isABI_O32()) CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32); - } else + else CCInfo.AnalyzeCallOperands(Outs, CC_Mips); // Get a count of how many bytes are to be pushed on the stack. @@ -1232,20 +1232,20 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // location is used on function prologue to save GP and also after all // emitted CALL's to restore GP. if (IsPIC) { - // Function can have an arbitrary number of calls, so - // hold the LastArgStackLoc with the biggest offset. - int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); - - if (MaxCallFrameSize < (int)NextStackOffset) { - MipsFI->setMaxCallFrameSize(NextStackOffset); - - // $gp restore slot must be aligned. - unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / - StackAlignment * StackAlignment; - int GPFI = MipsFI->getGPFI(); - MFI->setObjectOffset(GPFI, NextStackOffset); - } + // Function can have an arbitrary number of calls, so + // hold the LastArgStackLoc with the biggest offset. + int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + + if (MaxCallFrameSize < (int)NextStackOffset) { + MipsFI->setMaxCallFrameSize(NextStackOffset); + + // $gp restore slot must be aligned. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + int GPFI = MipsFI->getGPFI(); + MFI->setObjectOffset(GPFI, NextStackOffset); + } } // Extend range of indices of frame objects for outgoing arguments that were -- cgit v1.1 From 46da136ec79f484decce7c6cfeef42fb25888996 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 23 May 2011 22:23:58 +0000 Subject: Expand f64 FPOW. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131928 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 15ab172..63bafa1 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -135,6 +135,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::FCOS, MVT::f64, Expand); setOperationAction(ISD::FPOWI, MVT::f32, Expand); setOperationAction(ISD::FPOW, MVT::f32, Expand); + setOperationAction(ISD::FPOW, MVT::f64, Expand); setOperationAction(ISD::FLOG, MVT::f32, Expand); setOperationAction(ISD::FLOG2, MVT::f32, Expand); setOperationAction(ISD::FLOG10, MVT::f32, Expand); -- cgit v1.1 From b4d8d31e59b11e7a4d560c01377ce02f1245f056 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 24 May 2011 00:23:52 +0000 Subject: Simplify offset calculation of stack frame objects for $gp restore location and variable arguments in LowerCall and LowerFormalArguments. This should also fix the bug in which handling of variable arguments is incorrect when the front-end optimizes away unused fixed arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131942 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 87 +++++++++++++----------------------- 1 file changed, 31 insertions(+), 56 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 63bafa1..075f66f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "mips-lower" +//#include #include "MipsISelLowering.h" #include "MipsMachineFunction.h" #include "MipsTargetMachine.h" @@ -1064,7 +1065,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // With EABI is it possible to have 16 args on registers. SmallVector, 16> RegsToPass; SmallVector MemOpChains; - unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16); MipsFI->setHasCall(); @@ -1125,11 +1125,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // This guarantees that when allocating Local Area the firsts // 16 bytes which are alwayes reserved won't be overwritten // if O32 ABI is used. For EABI the first address is zero. - unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - NextStackOffset = VA.getLocMemOffset(); - LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true); - NextStackOffset += ArgSize; - + LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, + VA.getLocMemOffset(), true); SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); // emit ISD::STORE whichs stores the @@ -1236,6 +1233,12 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + unsigned NextStackOffset = CCInfo.getNextStackOffset(); + + // For O32, a minimum of four words (16 bytes) of argument space is + // allocated. + if (Subtarget->isABI_O32()) + NextStackOffset = std::max(NextStackOffset, (unsigned)16); if (MaxCallFrameSize < (int)NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); @@ -1318,9 +1321,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Used with vargs to acumulate store chains. std::vector OutChains; - // Keep track of the last register used for arguments - unsigned ArgRegEnd = 0; - // Assign locations to all of the incoming arguments. SmallVector ArgLocs; CCState CCInfo(CallConv, isVarArg, getTargetMachine(), @@ -1331,8 +1331,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, else CCInfo.AnalyzeFormalArguments(Ins, CC_Mips); - unsigned NextStackOffset = (Subtarget->isABI_EABI() ? 0 : 16); - EVT LastRegArgValVT; int LastFI = 0;// MipsFI->LastInArgFI is 0 at the entry of this function. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -1341,8 +1339,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Arguments stored on registers if (VA.isRegLoc()) { EVT RegVT = VA.getLocVT(); - ArgRegEnd = VA.getLocReg(); - LastRegArgValVT = VA.getValVT(); + unsigned ArgReg = VA.getLocReg(); TargetRegisterClass *RC = 0; if (RegVT == MVT::i32) @@ -1357,7 +1354,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Transform the arguments stored on // physical registers into virtual ones - unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC); + unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgReg, RC); SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); // If this is an 8 or 16-bit value, it has been passed promoted @@ -1396,9 +1393,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // sanity check assert(VA.isMemLoc()); - // The last argument is not a register anymore - ArgRegEnd = 0; - // The stack pointer offset is relative to the caller stack frame. // Since the real stack size is unknown here, a negative SPOffset // is used so there's a way to adjust these offsets when the stack @@ -1406,10 +1400,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // used instead of a direct negative address (which is recorded to // be used on emitPrologue) to avoid mis-calc of the first stack // offset on PEI::calculateFrameObjectOffsets. - unsigned ArgSize = VA.getValVT().getSizeInBits()/8; - NextStackOffset = VA.getLocMemOffset(); - LastFI = MFI->CreateFixedObject(ArgSize, NextStackOffset, true); - NextStackOffset += ArgSize; + LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, + VA.getLocMemOffset(), true); // Create load nodes to retrieve arguments from the stack SDValue FIN = DAG.getFrameIndex(LastFI, getPointerTy()); @@ -1436,44 +1428,27 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // must have their values written to the caller stack frame. If the last // argument was placed in the stack, there's no need to save any register. if (isVarArg && Subtarget->isABI_O32()) { - if (ArgRegEnd) { - // Last named formal argument is passed in register. + // Record the frame index of the first variable argument + // which is a value necessary to VASTART. + unsigned NextStackOffset = CCInfo.getNextStackOffset(); + LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); + MipsFI->setVarArgsFrameIndex(LastFI); + + const unsigned O32IntRegs[] = { + Mips::A0, Mips::A1, Mips::A2, Mips::A3 + }; - // The last register argument that must be saved is Mips::A3 + // Copy variable arguments passed in registers to stack. + for (; NextStackOffset < 16; NextStackOffset += 4) { TargetRegisterClass *RC = Mips::CPURegsRegisterClass; - if (LastRegArgValVT == MVT::f64) - ArgRegEnd++; - - if (ArgRegEnd < Mips::A3) { - // Both the last named formal argument and the first variable - // argument are passed in registers. - for (++ArgRegEnd; ArgRegEnd <= Mips::A3; ++ArgRegEnd) { - unsigned Reg = AddLiveIn(DAG.getMachineFunction(), ArgRegEnd, RC); - SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32); - - LastFI = MFI->CreateFixedObject(4, (ArgRegEnd-Mips::A0)*4, true); - SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); - OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, - MachinePointerInfo(), - false, false, 0)); - - // Record the frame index of the first variable argument - // which is a value necessary to VASTART. - if (!MipsFI->getVarArgsFrameIndex()) - MipsFI->setVarArgsFrameIndex(LastFI); - } - } else { - // Last named formal argument is in register Mips::A3, and the first - // variable argument is on stack. Record the frame index of the first - // variable argument. - LastFI = MFI->CreateFixedObject(4, 16, true); - MipsFI->setVarArgsFrameIndex(LastFI); - } - } else { - // Last named formal argument and all the variable arguments are passed - // on stack. Record the frame index of the first variable argument. + unsigned Idx = NextStackOffset / 4; + unsigned Reg = AddLiveIn(DAG.getMachineFunction(), O32IntRegs[Idx], RC); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, MVT::i32); LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); - MipsFI->setVarArgsFrameIndex(LastFI); + SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); + OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, + MachinePointerInfo(), + false, false, 0)); } } -- cgit v1.1 From 4231c7ea6d278b6a07ce51c28d7e00e1d300d210 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 24 May 2011 19:18:33 +0000 Subject: Implement byval structure argument passing. The following limitations or deficiencies exist: - Works only if ABI is o32. - Zero-sized structures cannot be passed. - There is a lot of redundancy in generated code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131986 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 120 +++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 5 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 075f66f..cec1917 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -959,6 +959,17 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, Mips::D6, Mips::D7 }; + // ByVal Args + if (ArgFlags.isByVal()) { + State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, + 1 /*MinSize*/, 4 /*MinAlign*/, ArgFlags); + unsigned NextReg = (State.getNextStackOffset() + 3) / 4; + for (unsigned r = State.getFirstUnallocated(IntRegs, IntRegsSize); + r < std::min(IntRegsSize, NextReg); ++r) + State.AllocateReg(IntRegs[r]); + return false; + } + // Promote i8 and i16 if (LocVT == MVT::i8 || LocVT == MVT::i16) { LocVT = MVT::i32; @@ -1027,6 +1038,55 @@ static bool CC_MipsO32(unsigned ValNo, MVT ValVT, // Call Calling Convention Implementation //===----------------------------------------------------------------------===// +static const unsigned O32IntRegsSize = 4; + +static const unsigned O32IntRegs[] = { + Mips::A0, Mips::A1, Mips::A2, Mips::A3 +}; + +// Write ByVal Arg to arg registers and stack. +static void +WriteByValArg(SDValue& Chain, DebugLoc dl, + SmallVector, 16>& RegsToPass, + SmallVector& MemOpChains, int& LastFI, + MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, + const CCValAssign &VA, const ISD::ArgFlagsTy& Flags, MVT PtrType) { + unsigned FirstWord = VA.getLocMemOffset() / 4; + unsigned NumWords = (Flags.getByValSize() + 3) / 4; + unsigned LastWord = FirstWord + NumWords; + unsigned CurWord; + + // copy the first 4 words of byval arg to registers A0 - A3 + for (CurWord = FirstWord; CurWord < std::min(LastWord, O32IntRegsSize); + ++CurWord) { + SDValue LoadPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, Arg, + DAG.getConstant((CurWord - FirstWord) * 4, + MVT::i32)); + SDValue LoadVal = DAG.getLoad(MVT::i32, dl, Chain, LoadPtr, + MachinePointerInfo(), + false, false, 0); + MemOpChains.push_back(LoadVal.getValue(1)); + unsigned DstReg = O32IntRegs[CurWord]; + RegsToPass.push_back(std::make_pair(DstReg, LoadVal)); + } + + // copy remaining part of byval arg to stack. + if (CurWord < LastWord) { + unsigned SizeInBytes = (LastWord - CurWord) * 4; + SDValue Src = DAG.getNode(ISD::ADD, dl, MVT::i32, Arg, + DAG.getConstant((CurWord - FirstWord) * 4, + MVT::i32)); + LastFI = MFI->CreateFixedObject(SizeInBytes, CurWord * 4, true); + SDValue Dst = DAG.getFrameIndex(LastFI, PtrType); + Chain = DAG.getMemcpy(Chain, dl, Dst, Src, + DAG.getConstant(SizeInBytes, MVT::i32), + /*Align*/4, + /*isVolatile=*/false, /*AlwaysInline=*/false, + MachinePointerInfo(0), MachinePointerInfo(0)); + MemOpChains.push_back(Chain); + } +} + /// LowerCall - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: isTailCall. @@ -1121,6 +1181,18 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Register can't get to this point... assert(VA.isMemLoc()); + // ByVal Arg. + ISD::ArgFlagsTy Flags = Outs[i].Flags; + if (Flags.isByVal()) { + assert(Subtarget->isABI_O32() && + "No support for ByVal args by ABIs other than O32 yet."); + assert(Flags.getByValSize() && + "ByVal args of size 0 should have been ignored by front-end."); + WriteByValArg(Chain, dl, RegsToPass, MemOpChains, LastFI, MFI, DAG, Arg, + VA, Flags, getPointerTy()); + continue; + } + // Create the frame index object for this incoming parameter // This guarantees that when allocating Local Area the firsts // 16 bytes which are alwayes reserved won't be overwritten @@ -1299,6 +1371,29 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, //===----------------------------------------------------------------------===// // Formal Arguments Calling Convention Implementation //===----------------------------------------------------------------------===// +static void ReadByValArg(MachineFunction &MF, SDValue Chain, DebugLoc dl, + std::vector& OutChains, + SelectionDAG &DAG, unsigned NumWords, SDValue FIN, + const CCValAssign &VA, const ISD::ArgFlagsTy& Flags) { + unsigned LocMem = VA.getLocMemOffset(); + unsigned FirstWord = LocMem / 4; + + // copy register A0 - A3 to frame object + for (unsigned i = 0; i < NumWords; ++i) { + unsigned CurWord = FirstWord + i; + if (CurWord >= O32IntRegsSize) + break; + + unsigned SrcReg = O32IntRegs[CurWord]; + unsigned Reg = AddLiveIn(MF, SrcReg, Mips::CPURegsRegisterClass); + SDValue StorePtr = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN, + DAG.getConstant(i * 4, MVT::i32)); + SDValue Store = DAG.getStore(Chain, dl, DAG.getRegister(Reg, MVT::i32), + StorePtr, MachinePointerInfo(), false, + false, 0); + OutChains.push_back(Store); + } +} /// LowerFormalArguments - transform physical registers into virtual registers /// and generate load operations for arguments places on the stack. @@ -1393,6 +1488,23 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // sanity check assert(VA.isMemLoc()); + ISD::ArgFlagsTy Flags = Ins[i].Flags; + + if (Flags.isByVal()) { + assert(Subtarget->isABI_O32() && + "No support for ByVal args by ABIs other than O32 yet."); + assert(Flags.getByValSize() && + "ByVal args of size 0 should have been ignored by front-end."); + unsigned NumWords = (Flags.getByValSize() + 3) / 4; + LastFI = MFI->CreateFixedObject(NumWords * 4, VA.getLocMemOffset(), + true); + SDValue FIN = DAG.getFrameIndex(LastFI, getPointerTy()); + InVals.push_back(FIN); + ReadByValArg(MF, Chain, dl, OutChains, DAG, NumWords, FIN, VA, Flags); + + continue; + } + // The stack pointer offset is relative to the caller stack frame. // Since the real stack size is unknown here, a negative SPOffset // is used so there's a way to adjust these offsets when the stack @@ -1431,14 +1543,12 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Record the frame index of the first variable argument // which is a value necessary to VASTART. unsigned NextStackOffset = CCInfo.getNextStackOffset(); + assert(NextStackOffset % 4 == 0 && + "NextStackOffset must be aligned to 4-byte boundaries."); LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); MipsFI->setVarArgsFrameIndex(LastFI); - const unsigned O32IntRegs[] = { - Mips::A0, Mips::A1, Mips::A2, Mips::A3 - }; - - // Copy variable arguments passed in registers to stack. + // Copy variable arguments passed in registers to stack. for (; NextStackOffset < 16; NextStackOffset += 4) { TargetRegisterClass *RC = Mips::CPURegsRegisterClass; unsigned Idx = NextStackOffset / 4; -- cgit v1.1 From 053546c31e4752e3d76e1f0915ddd6c8a3280351 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 02:20:00 +0000 Subject: Fix lowering of DYNAMIC_STACKALLOC nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132030 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index cec1917..93e7a23 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -692,6 +692,13 @@ LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { + unsigned StackAlignment = + getTargetMachine().getFrameLowering()->getStackAlignment(); + assert(StackAlignment >= + cast(Op.getOperand(2).getNode())->getZExtValue() && + "Cannot lower if the alignment of the allocated space is larger than \ + that of the stack."); + SDValue Chain = Op.getOperand(0); SDValue Size = Op.getOperand(1); DebugLoc dl = Op.getDebugLoc(); @@ -705,11 +712,22 @@ LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const // The Sub result contains the new stack start address, so it // must be placed in the stack pointer register. - Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub); + Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, + SDValue()); + SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, + Chain.getValue(1)); + + // Align the allocated space. + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / + StackAlignment * StackAlignment; + SDValue AllocPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, + DAG.getConstant(SPOffset, MVT::i32)); // This node always has two return values: a new stack pointer // value and a chain - SDValue Ops[2] = { Sub, Chain }; + SDValue Ops[2] = { AllocPtr, NewSP.getValue(1) }; return DAG.getMergeValues(Ops, 2, dl); } -- cgit v1.1 From edacba83dc6b34676fe2be60e0bac487a6d1152d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 17:32:06 +0000 Subject: Coding style fixes. Added comments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132063 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 93e7a23..9efd0f7 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -714,10 +714,13 @@ LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const // must be placed in the stack pointer register. Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, SDValue()); + // Retrieve updated $sp. There is a glue input to prevent instructions that + // clobber $sp from being inserted between copytoreg and copyfromreg. SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, Chain.getValue(1)); - // Align the allocated space. + // The stack space reserved by alloca is located right above the argument + // area. It is aligned on a boundary that is a multiple of StackAlignment. MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *MipsFI = MF.getInfo(); unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / @@ -1068,7 +1071,8 @@ WriteByValArg(SDValue& Chain, DebugLoc dl, SmallVector, 16>& RegsToPass, SmallVector& MemOpChains, int& LastFI, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, - const CCValAssign &VA, const ISD::ArgFlagsTy& Flags, MVT PtrType) { + const CCValAssign &VA, const ISD::ArgFlagsTy& Flags, + MVT PtrType) { unsigned FirstWord = VA.getLocMemOffset() / 4; unsigned NumWords = (Flags.getByValSize() + 3) / 4; unsigned LastWord = FirstWord + NumWords; @@ -1146,8 +1150,10 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MipsFI->setHasCall(); - // Create GP frame object if this is the first call. - // SPOffset will be updated after call frame size is known. + // If this is the first call, create a stack frame object that points to + // a location to which .cprestore saves $gp. The offset of this frame object + // is set to 0, since we know nothing about the size of the argument area at + // this point. if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); @@ -1212,9 +1218,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } // Create the frame index object for this incoming parameter - // This guarantees that when allocating Local Area the firsts - // 16 bytes which are alwayes reserved won't be overwritten - // if O32 ABI is used. For EABI the first address is zero. LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, VA.getLocMemOffset(), true); SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); @@ -1316,9 +1319,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, Chain = DAG.getNode(MipsISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); - // Create a stack location to hold GP when PIC is used. This stack - // location is used on function prologue to save GP and also after all - // emitted CALL's to restore GP. if (IsPIC) { // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. @@ -1424,7 +1424,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl &InVals) const { - MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo(); @@ -1524,12 +1523,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, } // The stack pointer offset is relative to the caller stack frame. - // Since the real stack size is unknown here, a negative SPOffset - // is used so there's a way to adjust these offsets when the stack - // size get known (on EliminateFrameIndex). A dummy SPOffset is - // used instead of a direct negative address (which is recorded to - // be used on emitPrologue) to avoid mis-calc of the first stack - // offset on PEI::calculateFrameObjectOffsets. LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, VA.getLocMemOffset(), true); @@ -1554,9 +1547,6 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain); } - // To meet ABI, when VARARGS are passed on registers, the registers - // must have their values written to the caller stack frame. If the last - // argument was placed in the stack, there's no need to save any register. if (isVarArg && Subtarget->isABI_O32()) { // Record the frame index of the first variable argument // which is a value necessary to VASTART. @@ -1565,8 +1555,10 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, "NextStackOffset must be aligned to 4-byte boundaries."); LastFI = MFI->CreateFixedObject(4, NextStackOffset, true); MipsFI->setVarArgsFrameIndex(LastFI); - - // Copy variable arguments passed in registers to stack. + + // If NextStackOffset is smaller than o32's 16-byte reserved argument area, + // copy the integer registers that have not been used for argument passing + // to the caller's stack frame. for (; NextStackOffset < 16; NextStackOffset += 4) { TargetRegisterClass *RC = Mips::CPURegsRegisterClass; unsigned Idx = NextStackOffset / 4; -- cgit v1.1 From f15f49850768f5889c2e12aeb273e158597a1223 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 17:52:48 +0000 Subject: Change initial value of MaxCallFrameSize. MipsFI::getMaxCallFrameSize() should return 0 if there are no function calls made. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132065 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 9efd0f7..624736f 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1322,7 +1322,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC) { // Function can have an arbitrary number of calls, so // hold the LastArgStackLoc with the biggest offset. - int MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + unsigned MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); unsigned NextStackOffset = CCInfo.getNextStackOffset(); // For O32, a minimum of four words (16 bytes) of argument space is @@ -1330,7 +1330,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (Subtarget->isABI_O32()) NextStackOffset = std::max(NextStackOffset, (unsigned)16); - if (MaxCallFrameSize < (int)NextStackOffset) { + if (MaxCallFrameSize < NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); // $gp restore slot must be aligned. -- cgit v1.1 From 4c62f765a308543577d7e0094020d8d9362a8bcb Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 18:08:32 +0000 Subject: Update MaxCallFrameSize regardless of the relocation model selected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132070 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 624736f..e71bc78 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1319,20 +1319,20 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, Chain = DAG.getNode(MipsISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); - if (IsPIC) { - // Function can have an arbitrary number of calls, so - // hold the LastArgStackLoc with the biggest offset. - unsigned MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); - unsigned NextStackOffset = CCInfo.getNextStackOffset(); + // Function can have an arbitrary number of calls, so + // hold the LastArgStackLoc with the biggest offset. + unsigned MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + unsigned NextStackOffset = CCInfo.getNextStackOffset(); - // For O32, a minimum of four words (16 bytes) of argument space is - // allocated. - if (Subtarget->isABI_O32()) - NextStackOffset = std::max(NextStackOffset, (unsigned)16); + // For O32, a minimum of four words (16 bytes) of argument space is + // allocated. + if (Subtarget->isABI_O32()) + NextStackOffset = std::max(NextStackOffset, (unsigned)16); - if (MaxCallFrameSize < NextStackOffset) { - MipsFI->setMaxCallFrameSize(NextStackOffset); + if (MaxCallFrameSize < NextStackOffset) { + MipsFI->setMaxCallFrameSize(NextStackOffset); + if (IsPIC) { // $gp restore slot must be aligned. unsigned StackAlignment = TFL->getStackAlignment(); NextStackOffset = (NextStackOffset + StackAlignment - 1) / -- cgit v1.1 From 9c3d57c45e0ea788d9c6351345b91d2b8dea0a82 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 19:32:07 +0000 Subject: Custom-lower FCOPYSIGN nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132074 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index e71bc78..42a35ad 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -128,8 +128,8 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); + setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); + setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); setOperationAction(ISD::FSIN, MVT::f32, Expand); setOperationAction(ISD::FSIN, MVT::f64, Expand); setOperationAction(ISD::FCOS, MVT::f32, Expand); @@ -515,6 +515,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); + case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); } return SDValue(); } @@ -943,6 +944,60 @@ SDValue MipsTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { false, false, 0); } +static SDValue LowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG) { + // FIXME: Use ext/ins instructions if target architecture is Mips32r2. + DebugLoc dl = Op.getDebugLoc(); + SDValue Op0 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op.getOperand(0)); + SDValue Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op.getOperand(1)); + SDValue And0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op0, + DAG.getConstant(0x7fffffff, MVT::i32)); + SDValue And1 = DAG.getNode(ISD::AND, dl, MVT::i32, Op1, + DAG.getConstant(0x80000000, MVT::i32)); + SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, And0, And1); + return DAG.getNode(ISD::BITCAST, dl, MVT::f32, Result); +} + +static SDValue LowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool isLittle) { + // FIXME: + // Use ext/ins instructions if target architecture is Mips32r2. + // Eliminate redundant mfc1 and mtc1 instructions. + unsigned LoIdx = 0, HiIdx = 1; + + if (!isLittle) + std::swap(LoIdx, HiIdx); + + DebugLoc dl = Op.getDebugLoc(); + SDValue Word0 = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, + Op.getOperand(0), + DAG.getConstant(LoIdx, MVT::i32)); + SDValue Hi0 = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, + Op.getOperand(0), DAG.getConstant(HiIdx, MVT::i32)); + SDValue Hi1 = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32, + Op.getOperand(1), DAG.getConstant(HiIdx, MVT::i32)); + SDValue And0 = DAG.getNode(ISD::AND, dl, MVT::i32, Hi0, + DAG.getConstant(0x7fffffff, MVT::i32)); + SDValue And1 = DAG.getNode(ISD::AND, dl, MVT::i32, Hi1, + DAG.getConstant(0x80000000, MVT::i32)); + SDValue Word1 = DAG.getNode(ISD::OR, dl, MVT::i32, And0, And1); + + if (!isLittle) + std::swap(Word0, Word1); + + return DAG.getNode(MipsISD::BuildPairF64, dl, MVT::f64, Word0, Word1); +} + +SDValue MipsTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) + const { + EVT Ty = Op.getValueType(); + + assert(Ty == MVT::f32 || Ty == MVT::f64); + + if (Ty == MVT::f32) + return LowerFCOPYSIGN32(Op, DAG); + else + return LowerFCOPYSIGN64(Op, DAG, Subtarget->isLittle()); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// -- cgit v1.1 From d85b3ecbb36b6ab6cce3c41ef1606108bd8d809d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 20:08:05 +0000 Subject: Remove MipsTargetLowering::LowerFP_TO_SINT. Patterns for fp_to_sint have already been defined in MipsInstrFPU.td. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132076 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 42a35ad..834b1bf 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -103,7 +103,6 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SELECT, MVT::i32, Custom); setOperationAction(ISD::BRCOND, MVT::Other, Custom); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); - setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::SDIV, MVT::i32, Expand); @@ -508,7 +507,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); - case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); @@ -656,40 +654,6 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// - -SDValue MipsTargetLowering:: -LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const -{ - if (!Subtarget->isMips1()) - return Op; - - MachineFunction &MF = DAG.getMachineFunction(); - unsigned CCReg = AddLiveIn(MF, Mips::FCR31, Mips::CCRRegisterClass); - - SDValue Chain = DAG.getEntryNode(); - DebugLoc dl = Op.getDebugLoc(); - SDValue Src = Op.getOperand(0); - - // Set the condition register - SDValue CondReg = DAG.getCopyFromReg(Chain, dl, CCReg, MVT::i32); - CondReg = DAG.getCopyToReg(Chain, dl, Mips::AT, CondReg); - CondReg = DAG.getCopyFromReg(CondReg, dl, Mips::AT, MVT::i32); - - SDValue Cst = DAG.getConstant(3, MVT::i32); - SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, CondReg, Cst); - Cst = DAG.getConstant(2, MVT::i32); - SDValue Xor = DAG.getNode(ISD::XOR, dl, MVT::i32, Or, Cst); - - SDValue InFlag(0, 0); - CondReg = DAG.getCopyToReg(Chain, dl, Mips::FCR31, Xor, InFlag); - - // Emit the round instruction and bit convert to integer - SDValue Trunc = DAG.getNode(MipsISD::FPRound, dl, MVT::f32, - Src, CondReg.getValue(1)); - SDValue BitCvt = DAG.getNode(ISD::BITCAST, dl, MVT::i32, Trunc); - return BitCvt; -} - SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { -- cgit v1.1 From cf0cd8005c81853ddea3ce26b71491c48dc4984e Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 26 May 2011 18:59:03 +0000 Subject: Add support for C++ exception handling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132131 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 834b1bf..4c42561 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -141,8 +141,9 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::FLOG10, MVT::f32, Expand); setOperationAction(ISD::FEXP, MVT::f32, Expand); - setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); - + setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); + setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); + setOperationAction(ISD::VAARG, MVT::Other, Expand); setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAEND, MVT::Other, Expand); @@ -176,6 +177,9 @@ MipsTargetLowering(MipsTargetMachine &TM) setStackPointerRegisterToSaveRestore(Mips::SP); computeRegisterProperties(); + + setExceptionPointerRegister(Mips::A0); + setExceptionSelectorRegister(Mips::A1); } MVT::SimpleValueType MipsTargetLowering::getSetCCResultType(EVT VT) const { -- cgit v1.1 From 33458fedb607e64c46af6797057fbf0b4973a6f6 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 26 May 2011 20:30:31 +0000 Subject: Use MachineFrameInfo::hasCalls instead of MipsFunctionInfo::hasCall to check if a function has any function calls. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132140 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 4c42561..7aaf13c 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1171,8 +1171,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, SmallVector, 16> RegsToPass; SmallVector MemOpChains; - MipsFI->setHasCall(); - // If this is the first call, create a stack frame object that points to // a location to which .cprestore saves $gp. The offset of this frame object // is set to 0, since we know nothing about the size of the argument area at -- cgit v1.1 From 342837d0dcf4c47765bbd3f9c031418824b12747 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Sat, 28 May 2011 01:07:07 +0000 Subject: Define a wrapper node for target constant nodes (tglobaladdr, etc.). Need this to prevent emitting illegal conditional move instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132240 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 7aaf13c..e5dfb25 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -55,6 +55,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::DivRemU: return "MipsISD::DivRemU"; case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; + case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; default: return NULL; } } @@ -770,6 +771,7 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, } else { SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, MipsII::MO_GOT); + GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA); SDValue ResNode = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), GA, MachinePointerInfo(), false, false, 0); @@ -807,6 +809,7 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op, SDValue BAGOTOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_GOT); + BAGOTOffset = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, BAGOTOffset); SDValue BALOOffset = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_LO); SDValue Load = DAG.getLoad(MVT::i32, dl, @@ -841,10 +844,12 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const if (!IsPIC) { SDValue Ops[] = { JTI }; HiPart = DAG.getNode(MipsISD::Hi, dl, DAG.getVTList(MVT::i32), Ops, 1); - } else // Emit Load from Global Pointer + } else {// Emit Load from Global Pointer + JTI = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, JTI); HiPart = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), JTI, MachinePointerInfo(), false, false, 0); + } SDValue JTILo = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MipsII::MO_ABS_LO); @@ -884,6 +889,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const } else { SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), N->getOffset(), MipsII::MO_GOT); + CP = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, CP); SDValue Load = DAG.getLoad(MVT::i32, dl, DAG.getEntryNode(), CP, MachinePointerInfo::getConstantPool(), false, false, 0); @@ -1288,6 +1294,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC) { if (LoadSymAddr) { // Load callee address + Callee = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, Callee); SDValue LoadValue = DAG.getLoad(MVT::i32, dl, Chain, Callee, MachinePointerInfo::getGOT(), false, false, 0); -- cgit v1.1 From d979686bb47f2dcdca60f0a088f59d1964346453 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 31 May 2011 02:53:58 +0000 Subject: This patch implements the thread local storage. Implemented are General Dynamic, Initial Exec and Local Exec TLS models. Patch by Sasa Stankovic git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132322 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 60 ++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index e5dfb25..1ee5172 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -41,6 +41,10 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::Hi: return "MipsISD::Hi"; case MipsISD::Lo: return "MipsISD::Lo"; case MipsISD::GPRel: return "MipsISD::GPRel"; + case MipsISD::TlsGd: return "MipsISD::TlsGd"; + case MipsISD::TprelHi: return "MipsISD::TprelHi"; + case MipsISD::TprelLo: return "MipsISD::TprelLo"; + case MipsISD::ThreadPointer: return "MipsISD::ThreadPointer"; case MipsISD::Ret: return "MipsISD::Ret"; case MipsISD::FPBrcond: return "MipsISD::FPBrcond"; case MipsISD::FPCmp: return "MipsISD::FPCmp"; @@ -822,8 +826,60 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op, SDValue MipsTargetLowering:: LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { - llvm_unreachable("TLS not implemented for MIPS."); - return SDValue(); // Not reached + // If the relocation model is PIC, use the General Dynamic TLS Model, + // otherwise use the Initial Exec or Local Exec TLS Model. + // TODO: implement Local Dynamic TLS model + + GlobalAddressSDNode *GA = cast(Op); + DebugLoc dl = GA->getDebugLoc(); + const GlobalValue *GV = GA->getGlobal(); + EVT PtrVT = getPointerTy(); + + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { + // General Dynamic TLS Model + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, + 0, MipsII::MO_TLSGD); + SDValue Tlsgd = DAG.getNode(MipsISD::TlsGd, dl, MVT::i32, TGA); + SDValue GP = DAG.getRegister(Mips::GP, MVT::i32); + SDValue Argument = DAG.getNode(ISD::ADD, dl, MVT::i32, GP, Tlsgd); + + ArgListTy Args; + ArgListEntry Entry; + Entry.Node = Argument; + Entry.Ty = (const Type *) Type::getInt32Ty(*DAG.getContext()); + Args.push_back(Entry); + std::pair CallResult = + LowerCallTo(DAG.getEntryNode(), + (const Type *) Type::getInt32Ty(*DAG.getContext()), + false, false, false, false, + 0, CallingConv::C, false, true, + DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); + + return CallResult.first; + } else { + SDValue Offset; + if (GV->isDeclaration()) { + // Initial Exec TLS Model + SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_GOTTPREL); + Offset = DAG.getLoad(MVT::i32, dl, + DAG.getEntryNode(), TGA, MachinePointerInfo(), + false, false, 0); + } else { + // Local Exec TLS Model + SDVTList VTs = DAG.getVTList(MVT::i32); + SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_TPREL_HI); + SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_TPREL_LO); + SDValue Hi = DAG.getNode(MipsISD::TprelHi, dl, VTs, &TGAHi, 1); + SDValue Lo = DAG.getNode(MipsISD::TprelLo, dl, MVT::i32, TGALo); + Offset = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo); + } + + SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, dl, PtrVT); + return DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, Offset); + } } SDValue MipsTargetLowering:: -- cgit v1.1 From 4e694c96f1c0c2d09a287ff69bab5896e04dd3fd Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 31 May 2011 02:54:07 +0000 Subject: This patch implements atomic intrinsics atomic.load.add (sub,and,or,xor, nand), atomic.swap and atomic.cmp.swap, all in i8, i16 and i32 versions. The intrinsics are implemented by creating pseudo-instructions, which are then expanded in the method MipsTargetLowering::EmitInstrWithCustomInserter. Patch by Sasa Stankovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132323 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 532 ++++++++++++++++++++++++++++++++++- 1 file changed, 527 insertions(+), 5 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 1ee5172..a94e6d0 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -557,11 +557,6 @@ static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) { MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { - // There is no need to expand CMov instructions if target has - // conditional moves. - if (Subtarget->hasCondMov()) - return BB; - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); bool isFPCmp = false; DebugLoc dl = MI->getDebugLoc(); @@ -569,6 +564,63 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, switch (MI->getOpcode()) { default: assert(false && "Unexpected instr type to insert"); + + case Mips::ATOMIC_LOAD_ADD_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu); + case Mips::ATOMIC_LOAD_ADD_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::ADDu); + case Mips::ATOMIC_LOAD_ADD_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::ADDu); + + case Mips::ATOMIC_LOAD_AND_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::AND); + case Mips::ATOMIC_LOAD_AND_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::AND); + case Mips::ATOMIC_LOAD_AND_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::AND); + + case Mips::ATOMIC_LOAD_OR_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::OR); + case Mips::ATOMIC_LOAD_OR_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::OR); + case Mips::ATOMIC_LOAD_OR_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::OR); + + case Mips::ATOMIC_LOAD_XOR_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::XOR); + case Mips::ATOMIC_LOAD_XOR_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::XOR); + case Mips::ATOMIC_LOAD_XOR_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::XOR); + + case Mips::ATOMIC_LOAD_NAND_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, 0, true); + case Mips::ATOMIC_LOAD_NAND_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, 0, true); + case Mips::ATOMIC_LOAD_NAND_I32: + return EmitAtomicBinary(MI, BB, 4, 0, true); + + case Mips::ATOMIC_LOAD_SUB_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::SUBu); + case Mips::ATOMIC_LOAD_SUB_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::SUBu); + case Mips::ATOMIC_LOAD_SUB_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::SUBu); + + case Mips::ATOMIC_SWAP_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, 0); + case Mips::ATOMIC_SWAP_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, 0); + case Mips::ATOMIC_SWAP_I32: + return EmitAtomicBinary(MI, BB, 4, 0); + + case Mips::ATOMIC_CMP_SWAP_I8: + return EmitAtomicCmpSwapPartword(MI, BB, 1); + case Mips::ATOMIC_CMP_SWAP_I16: + return EmitAtomicCmpSwapPartword(MI, BB, 2); + case Mips::ATOMIC_CMP_SWAP_I32: + return EmitAtomicCmpSwap(MI, BB, 4); + case Mips::MOVT: case Mips::MOVT_S: case Mips::MOVT_D: @@ -593,6 +645,11 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, break; } + // There is no need to expand CMov instructions if target has + // conditional moves. + if (Subtarget->hasCondMov()) + return BB; + // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the // destination vreg to set, the condition code register to branch on, the @@ -660,6 +717,471 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } +// This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and +// Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true) +MachineBasicBlock * +MipsTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, + unsigned Size, unsigned BinOpcode, bool Nand) const { + assert(Size == 4 && "Unsupported size for EmitAtomicBinary."); + + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + const TargetRegisterClass *RC = getRegClassFor(MVT::i32); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + unsigned Dest = MI->getOperand(0).getReg(); + unsigned Ptr = MI->getOperand(1).getReg(); + unsigned Incr = MI->getOperand(2).getReg(); + + unsigned Oldval = RegInfo.createVirtualRegister(RC); + unsigned Tmp1 = RegInfo.createVirtualRegister(RC); + unsigned Tmp2 = RegInfo.createVirtualRegister(RC); + + // insert new blocks after the current block + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineFunction::iterator It = BB; + ++It; + MF->insert(It, loopMBB); + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + // thisMBB: + // ... + // sw incr, fi(sp) // store incr to stack (when BinOpcode == 0) + // fallthrough --> loopMBB + + // Note: for atomic.swap (when BinOpcode == 0), storing incr to stack before + // the loop and then loading it from stack in block loopMBB is necessary to + // prevent MachineLICM pass to hoist "or" instruction out of the block + // loopMBB. + + int fi; + if (BinOpcode == 0 && !Nand) { + // Get or create a temporary stack location. + MipsFunctionInfo *MipsFI = MF->getInfo(); + fi = MipsFI->getAtomicFrameIndex(); + if (fi == -1) { + fi = MF->getFrameInfo()->CreateStackObject(Size, Size, false); + MipsFI->setAtomicFrameIndex(fi); + } + + BuildMI(BB, dl, TII->get(Mips::SW)) + .addReg(Incr).addImm(0).addFrameIndex(fi); + } + BB->addSuccessor(loopMBB); + + // loopMBB: + // ll oldval, 0(ptr) + // or dest, $0, oldval + // tmp1, oldval, incr + // sc tmp1, 0(ptr) + // beq tmp1, $0, loopMBB + BB = loopMBB; + BuildMI(BB, dl, TII->get(Mips::LL), Oldval).addImm(0).addReg(Ptr); + BuildMI(BB, dl, TII->get(Mips::OR), Dest).addReg(Mips::ZERO).addReg(Oldval); + if (Nand) { + // and tmp2, oldval, incr + // nor tmp1, $0, tmp2 + BuildMI(BB, dl, TII->get(Mips::AND), Tmp2).addReg(Oldval).addReg(Incr); + BuildMI(BB, dl, TII->get(Mips::NOR), Tmp1).addReg(Mips::ZERO).addReg(Tmp2); + } else if (BinOpcode) { + // tmp1, oldval, incr + BuildMI(BB, dl, TII->get(BinOpcode), Tmp1).addReg(Oldval).addReg(Incr); + } else { + // lw tmp2, fi(sp) // load incr from stack + // or tmp1, $zero, tmp2 + BuildMI(BB, dl, TII->get(Mips::LW), Tmp2).addImm(0).addFrameIndex(fi);; + BuildMI(BB, dl, TII->get(Mips::OR), Tmp1).addReg(Mips::ZERO).addReg(Tmp2); + } + BuildMI(BB, dl, TII->get(Mips::SC), Tmp1).addReg(Tmp1).addImm(0).addReg(Ptr); + BuildMI(BB, dl, TII->get(Mips::BEQ)) + .addReg(Tmp1).addReg(Mips::ZERO).addMBB(loopMBB); + BB->addSuccessor(loopMBB); + BB->addSuccessor(exitMBB); + + MI->eraseFromParent(); // The instruction is gone now. + + return BB; +} + +MachineBasicBlock * +MipsTargetLowering::EmitAtomicBinaryPartword(MachineInstr *MI, + MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, + bool Nand) const { + assert((Size == 1 || Size == 2) && + "Unsupported size for EmitAtomicBinaryPartial."); + + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + const TargetRegisterClass *RC = getRegClassFor(MVT::i32); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + unsigned Dest = MI->getOperand(0).getReg(); + unsigned Ptr = MI->getOperand(1).getReg(); + unsigned Incr = MI->getOperand(2).getReg(); + + unsigned Addr = RegInfo.createVirtualRegister(RC); + unsigned Shift = RegInfo.createVirtualRegister(RC); + unsigned Mask = RegInfo.createVirtualRegister(RC); + unsigned Mask2 = RegInfo.createVirtualRegister(RC); + unsigned Newval = RegInfo.createVirtualRegister(RC); + unsigned Oldval = RegInfo.createVirtualRegister(RC); + unsigned Incr2 = RegInfo.createVirtualRegister(RC); + unsigned Tmp1 = RegInfo.createVirtualRegister(RC); + unsigned Tmp2 = RegInfo.createVirtualRegister(RC); + unsigned Tmp3 = RegInfo.createVirtualRegister(RC); + unsigned Tmp4 = RegInfo.createVirtualRegister(RC); + unsigned Tmp5 = RegInfo.createVirtualRegister(RC); + unsigned Tmp6 = RegInfo.createVirtualRegister(RC); + unsigned Tmp7 = RegInfo.createVirtualRegister(RC); + unsigned Tmp8 = RegInfo.createVirtualRegister(RC); + unsigned Tmp9 = RegInfo.createVirtualRegister(RC); + unsigned Tmp10 = RegInfo.createVirtualRegister(RC); + unsigned Tmp11 = RegInfo.createVirtualRegister(RC); + unsigned Tmp12 = RegInfo.createVirtualRegister(RC); + + // insert new blocks after the current block + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineFunction::iterator It = BB; + ++It; + MF->insert(It, loopMBB); + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + // thisMBB: + // addiu tmp1,$0,-4 # 0xfffffffc + // and addr,ptr,tmp1 + // andi tmp2,ptr,3 + // sll shift,tmp2,3 + // ori tmp3,$0,255 # 0xff + // sll mask,tmp3,shift + // nor mask2,$0,mask + // andi tmp4,incr,255 + // sll incr2,tmp4,shift + // sw incr2, fi(sp) // store incr2 to stack (when BinOpcode == 0) + + // Note: for atomic.swap (when BinOpcode == 0), storing incr2 to stack before + // the loop and then loading it from stack in block loopMBB is necessary to + // prevent MachineLICM pass to hoist "or" instruction out of the block + // loopMBB. + + int64_t MaskImm = (Size == 1) ? 255 : 65535; + BuildMI(BB, dl, TII->get(Mips::ADDiu), Tmp1).addReg(Mips::ZERO).addImm(-4); + BuildMI(BB, dl, TII->get(Mips::AND), Addr).addReg(Ptr).addReg(Tmp1); + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp2).addReg(Ptr).addImm(3); + BuildMI(BB, dl, TII->get(Mips::SLL), Shift).addReg(Tmp2).addImm(3); + BuildMI(BB, dl, TII->get(Mips::ORi), Tmp3).addReg(Mips::ZERO).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Mask).addReg(Tmp3).addReg(Shift); + BuildMI(BB, dl, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); + if (BinOpcode != Mips::SUBu) { + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp4).addReg(Incr).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Incr2).addReg(Tmp4).addReg(Shift); + } else { + BuildMI(BB, dl, TII->get(Mips::SUBu), Tmp4).addReg(Mips::ZERO).addReg(Incr); + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp5).addReg(Tmp4).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Incr2).addReg(Tmp5).addReg(Shift); + } + int fi; + if (BinOpcode == 0 && !Nand) { + // Get or create a temporary stack location. + MipsFunctionInfo *MipsFI = MF->getInfo(); + fi = MipsFI->getAtomicFrameIndex(); + if (fi == -1) { + fi = MF->getFrameInfo()->CreateStackObject(Size, Size, false); + MipsFI->setAtomicFrameIndex(fi); + } + + BuildMI(BB, dl, TII->get(Mips::SW)) + .addReg(Incr2).addImm(0).addFrameIndex(fi); + } + BB->addSuccessor(loopMBB); + + // loopMBB: + // ll oldval,0(addr) + // binop tmp7,oldval,incr2 + // and newval,tmp7,mask + // and tmp8,oldval,mask2 + // or tmp9,tmp8,newval + // sc tmp9,0(addr) + // beq tmp9,$0,loopMBB + BB = loopMBB; + BuildMI(BB, dl, TII->get(Mips::LL), Oldval).addImm(0).addReg(Addr); + if (Nand) { + // and tmp6, oldval, incr2 + // nor tmp7, $0, tmp6 + BuildMI(BB, dl, TII->get(Mips::AND), Tmp6).addReg(Oldval).addReg(Incr2); + BuildMI(BB, dl, TII->get(Mips::NOR), Tmp7).addReg(Mips::ZERO).addReg(Tmp6); + } else if (BinOpcode == Mips::SUBu) { + // addu tmp7, oldval, incr2 + BuildMI(BB, dl, TII->get(Mips::ADDu), Tmp7).addReg(Oldval).addReg(Incr2); + } else if (BinOpcode) { + // tmp7, oldval, incr2 + BuildMI(BB, dl, TII->get(BinOpcode), Tmp7).addReg(Oldval).addReg(Incr2); + } else { + // lw tmp6, fi(sp) // load incr2 from stack + // or tmp7, $zero, tmp6 + BuildMI(BB, dl, TII->get(Mips::LW), Tmp6).addImm(0).addFrameIndex(fi);; + BuildMI(BB, dl, TII->get(Mips::OR), Tmp7).addReg(Mips::ZERO).addReg(Tmp6); + } + BuildMI(BB, dl, TII->get(Mips::AND), Newval).addReg(Tmp7).addReg(Mask); + BuildMI(BB, dl, TII->get(Mips::AND), Tmp8).addReg(Oldval).addReg(Mask2); + BuildMI(BB, dl, TII->get(Mips::OR), Tmp9).addReg(Tmp8).addReg(Newval); + BuildMI(BB, dl, TII->get(Mips::SC), Tmp9).addReg(Tmp9).addImm(0).addReg(Addr); + BuildMI(BB, dl, TII->get(Mips::BEQ)) + .addReg(Tmp9).addReg(Mips::ZERO).addMBB(loopMBB); + BB->addSuccessor(loopMBB); + BB->addSuccessor(exitMBB); + + // exitMBB: + // and tmp10,oldval,mask + // srl tmp11,tmp10,shift + // sll tmp12,tmp11,24 + // sra dest,tmp12,24 + BB = exitMBB; + int64_t ShiftImm = (Size == 1) ? 24 : 16; + // reverse order + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SRA), Dest) + .addReg(Tmp12).addImm(ShiftImm); + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SLL), Tmp12) + .addReg(Tmp11).addImm(ShiftImm); + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SRL), Tmp11) + .addReg(Tmp10).addReg(Shift); + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::AND), Tmp10) + .addReg(Oldval).addReg(Mask); + + MI->eraseFromParent(); // The instruction is gone now. + + return BB; +} + +MachineBasicBlock * +MipsTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Size) const { + assert(Size == 4 && "Unsupported size for EmitAtomicCmpSwap."); + + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + const TargetRegisterClass *RC = getRegClassFor(MVT::i32); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + unsigned Dest = MI->getOperand(0).getReg(); + unsigned Ptr = MI->getOperand(1).getReg(); + unsigned Oldval = MI->getOperand(2).getReg(); + unsigned Newval = MI->getOperand(3).getReg(); + + unsigned Tmp1 = RegInfo.createVirtualRegister(RC); + unsigned Tmp2 = RegInfo.createVirtualRegister(RC); + + // insert new blocks after the current block + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineFunction::iterator It = BB; + ++It; + MF->insert(It, loop1MBB); + MF->insert(It, loop2MBB); + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + // Get or create a temporary stack location. + MipsFunctionInfo *MipsFI = MF->getInfo(); + int fi = MipsFI->getAtomicFrameIndex(); + if (fi == -1) { + fi = MF->getFrameInfo()->CreateStackObject(Size, Size, false); + MipsFI->setAtomicFrameIndex(fi); + } + + // thisMBB: + // ... + // sw newval, fi(sp) // store newval to stack + // fallthrough --> loop1MBB + + // Note: storing newval to stack before the loop and then loading it from + // stack in block loop2MBB is necessary to prevent MachineLICM pass to + // hoist "or" instruction out of the block loop2MBB. + + BuildMI(BB, dl, TII->get(Mips::SW)) + .addReg(Newval).addImm(0).addFrameIndex(fi); + BB->addSuccessor(loop1MBB); + + // loop1MBB: + // ll dest, 0(ptr) + // bne dest, oldval, exitMBB + BB = loop1MBB; + BuildMI(BB, dl, TII->get(Mips::LL), Dest).addImm(0).addReg(Ptr); + BuildMI(BB, dl, TII->get(Mips::BNE)) + .addReg(Dest).addReg(Oldval).addMBB(exitMBB); + BB->addSuccessor(exitMBB); + BB->addSuccessor(loop2MBB); + + // loop2MBB: + // lw tmp2, fi(sp) // load newval from stack + // or tmp1, $0, tmp2 + // sc tmp1, 0(ptr) + // beq tmp1, $0, loop1MBB + BB = loop2MBB; + BuildMI(BB, dl, TII->get(Mips::LW), Tmp2).addImm(0).addFrameIndex(fi);; + BuildMI(BB, dl, TII->get(Mips::OR), Tmp1).addReg(Mips::ZERO).addReg(Tmp2); + BuildMI(BB, dl, TII->get(Mips::SC), Tmp1).addReg(Tmp1).addImm(0).addReg(Ptr); + BuildMI(BB, dl, TII->get(Mips::BEQ)) + .addReg(Tmp1).addReg(Mips::ZERO).addMBB(loop1MBB); + BB->addSuccessor(loop1MBB); + BB->addSuccessor(exitMBB); + + MI->eraseFromParent(); // The instruction is gone now. + + return BB; +} + +MachineBasicBlock * +MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Size) const { + assert((Size == 1 || Size == 2) && + "Unsupported size for EmitAtomicCmpSwapPartial."); + + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &RegInfo = MF->getRegInfo(); + const TargetRegisterClass *RC = getRegClassFor(MVT::i32); + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + unsigned Dest = MI->getOperand(0).getReg(); + unsigned Ptr = MI->getOperand(1).getReg(); + unsigned Oldval = MI->getOperand(2).getReg(); + unsigned Newval = MI->getOperand(3).getReg(); + + unsigned Addr = RegInfo.createVirtualRegister(RC); + unsigned Shift = RegInfo.createVirtualRegister(RC); + unsigned Mask = RegInfo.createVirtualRegister(RC); + unsigned Mask2 = RegInfo.createVirtualRegister(RC); + unsigned Oldval2 = RegInfo.createVirtualRegister(RC); + unsigned Oldval3 = RegInfo.createVirtualRegister(RC); + unsigned Oldval4 = RegInfo.createVirtualRegister(RC); + unsigned Newval2 = RegInfo.createVirtualRegister(RC); + unsigned Tmp1 = RegInfo.createVirtualRegister(RC); + unsigned Tmp2 = RegInfo.createVirtualRegister(RC); + unsigned Tmp3 = RegInfo.createVirtualRegister(RC); + unsigned Tmp4 = RegInfo.createVirtualRegister(RC); + unsigned Tmp5 = RegInfo.createVirtualRegister(RC); + unsigned Tmp6 = RegInfo.createVirtualRegister(RC); + unsigned Tmp7 = RegInfo.createVirtualRegister(RC); + unsigned Tmp8 = RegInfo.createVirtualRegister(RC); + unsigned Tmp9 = RegInfo.createVirtualRegister(RC); + + // insert new blocks after the current block + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineFunction::iterator It = BB; + ++It; + MF->insert(It, loop1MBB); + MF->insert(It, loop2MBB); + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + // thisMBB: + // addiu tmp1,$0,-4 # 0xfffffffc + // and addr,ptr,tmp1 + // andi tmp2,ptr,3 + // sll shift,tmp2,3 + // ori tmp3,$0,255 # 0xff + // sll mask,tmp3,shift + // nor mask2,$0,mask + // andi tmp4,oldval,255 + // sll oldval2,tmp4,shift + // andi tmp5,newval,255 + // sll newval2,tmp5,shift + int64_t MaskImm = (Size == 1) ? 255 : 65535; + BuildMI(BB, dl, TII->get(Mips::ADDiu), Tmp1).addReg(Mips::ZERO).addImm(-4); + BuildMI(BB, dl, TII->get(Mips::AND), Addr).addReg(Ptr).addReg(Tmp1); + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp2).addReg(Ptr).addImm(3); + BuildMI(BB, dl, TII->get(Mips::SLL), Shift).addReg(Tmp2).addImm(3); + BuildMI(BB, dl, TII->get(Mips::ORi), Tmp3).addReg(Mips::ZERO).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Mask).addReg(Tmp3).addReg(Shift); + BuildMI(BB, dl, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask); + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp4).addReg(Oldval).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Oldval2).addReg(Tmp4).addReg(Shift); + BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp5).addReg(Newval).addImm(MaskImm); + BuildMI(BB, dl, TII->get(Mips::SLL), Newval2).addReg(Tmp5).addReg(Shift); + BB->addSuccessor(loop1MBB); + + // loop1MBB: + // ll oldval3,0(addr) + // and oldval4,oldval3,mask + // bne oldval4,oldval2,exitMBB + BB = loop1MBB; + BuildMI(BB, dl, TII->get(Mips::LL), Oldval3).addImm(0).addReg(Addr); + BuildMI(BB, dl, TII->get(Mips::AND), Oldval4).addReg(Oldval3).addReg(Mask); + BuildMI(BB, dl, TII->get(Mips::BNE)) + .addReg(Oldval4).addReg(Oldval2).addMBB(exitMBB); + BB->addSuccessor(exitMBB); + BB->addSuccessor(loop2MBB); + + // loop2MBB: + // and tmp6,oldval3,mask2 + // or tmp7,tmp6,newval2 + // sc tmp7,0(addr) + // beq tmp7,$0,loop1MBB + BB = loop2MBB; + BuildMI(BB, dl, TII->get(Mips::AND), Tmp6).addReg(Oldval3).addReg(Mask2); + BuildMI(BB, dl, TII->get(Mips::OR), Tmp7).addReg(Tmp6).addReg(Newval2); + BuildMI(BB, dl, TII->get(Mips::SC), Tmp7) + .addReg(Tmp7).addImm(0).addReg(Addr); + BuildMI(BB, dl, TII->get(Mips::BEQ)) + .addReg(Tmp7).addReg(Mips::ZERO).addMBB(loop1MBB); + BB->addSuccessor(loop1MBB); + BB->addSuccessor(exitMBB); + + // exitMBB: + // srl tmp8,oldval4,shift + // sll tmp9,tmp8,24 + // sra dest,tmp9,24 + BB = exitMBB; + int64_t ShiftImm = (Size == 1) ? 24 : 16; + // reverse order + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SRA), Dest) + .addReg(Tmp9).addImm(ShiftImm); + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SLL), Tmp9) + .addReg(Tmp8).addImm(ShiftImm); + BuildMI(*BB, BB->begin(), dl, TII->get(Mips::SRL), Tmp8) + .addReg(Oldval4).addReg(Shift); + + MI->eraseFromParent(); // The instruction is gone now. + + return BB; +} + //===----------------------------------------------------------------------===// // Misc Lower Operation implementation //===----------------------------------------------------------------------===// -- cgit v1.1 From cada2d0966b649b8f04a78f35b9d6d9b4330ce74 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 31 May 2011 20:25:26 +0000 Subject: Fix uninitialized variables and silence warnings git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132355 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a94e6d0..f737fd3 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -763,7 +763,7 @@ MipsTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, // prevent MachineLICM pass to hoist "or" instruction out of the block // loopMBB. - int fi; + int fi = 0; if (BinOpcode == 0 && !Nand) { // Get or create a temporary stack location. MipsFunctionInfo *MipsFI = MF->getInfo(); @@ -897,7 +897,8 @@ MipsTargetLowering::EmitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, dl, TII->get(Mips::ANDi), Tmp5).addReg(Tmp4).addImm(MaskImm); BuildMI(BB, dl, TII->get(Mips::SLL), Incr2).addReg(Tmp5).addReg(Shift); } - int fi; + + int fi = 0; if (BinOpcode == 0 && !Nand) { // Get or create a temporary stack location. MipsFunctionInfo *MipsFI = MF->getInfo(); -- cgit v1.1 From 2e591477af1ef8e3c5ba6d51e8aeee8c99c7fa8e Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Thu, 2 Jun 2011 00:24:44 +0000 Subject: Custom-lower FRAMEADDR. Patch by Sasa Stankovic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132444 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index f737fd3..d6ac5ef 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -523,6 +523,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::SELECT: return LowerSELECT(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); + case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); } return SDValue(); } @@ -1551,6 +1552,19 @@ SDValue MipsTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) return LowerFCOPYSIGN64(Op, DAG, Subtarget->isLittle()); } +SDValue MipsTargetLowering:: +LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { + unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); + assert((Depth == 0) && "Frame address can only be determined for current frame."); + + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MFI->setFrameAddressIsTaken(true); + EVT VT = Op.getValueType(); + DebugLoc dl = Op.getDebugLoc(); + SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, Mips::FP, VT); + return FrameAddr; +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// -- cgit v1.1 From 0f843821385213b33116eaecf0c13e987139f6a5 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 7 Jun 2011 18:58:42 +0000 Subject: Coding style fixes. - Fix indentation. - Move comments. - Fit lines in 80 columns. - Remove dead code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132724 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 56 +++++++++++++++++------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index d6ac5ef..ccdcb34 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "mips-lower" -//#include #include "MipsISelLowering.h" #include "MipsMachineFunction.h" #include "MipsTargetMachine.h" @@ -60,7 +59,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; - default: return NULL; + default: return NULL; } } @@ -722,7 +721,8 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, // Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true) MachineBasicBlock * MipsTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, - unsigned Size, unsigned BinOpcode, bool Nand) const { + unsigned Size, unsigned BinOpcode, + bool Nand) const { assert(Size == 4 && "Unsupported size for EmitAtomicBinary."); MachineFunction *MF = BB->getParent(); @@ -815,8 +815,9 @@ MipsTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, MachineBasicBlock * MipsTargetLowering::EmitAtomicBinaryPartword(MachineInstr *MI, - MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, - bool Nand) const { + MachineBasicBlock *BB, + unsigned Size, unsigned BinOpcode, + bool Nand) const { assert((Size == 1 || Size == 2) && "Unsupported size for EmitAtomicBinaryPartial."); @@ -974,8 +975,8 @@ MipsTargetLowering::EmitAtomicBinaryPartword(MachineInstr *MI, MachineBasicBlock * MipsTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, - MachineBasicBlock *BB, - unsigned Size) const { + MachineBasicBlock *BB, + unsigned Size) const { assert(Size == 4 && "Unsupported size for EmitAtomicCmpSwap."); MachineFunction *MF = BB->getParent(); @@ -1061,8 +1062,8 @@ MipsTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, MachineBasicBlock * MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI, - MachineBasicBlock *BB, - unsigned Size) const { + MachineBasicBlock *BB, + unsigned Size) const { assert((Size == 1 || Size == 2) && "Unsupported size for EmitAtomicCmpSwapPartial."); @@ -1296,26 +1297,23 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SDValue HiPart = DAG.getNode(MipsISD::Hi, dl, VTs, &GAHi, 1); SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); return DAG.getNode(ISD::ADD, dl, MVT::i32, HiPart, Lo); - } else { - SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_GOT); - GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA); - SDValue ResNode = DAG.getLoad(MVT::i32, dl, - DAG.getEntryNode(), GA, MachinePointerInfo(), - false, false, 0); - // On functions and global targets not internal linked only - // a load from got/GP is necessary for PIC to work. - if (!GV->hasInternalLinkage() && - (!GV->hasLocalLinkage() || isa(GV))) - return ResNode; - SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, - MipsII::MO_ABS_LO); - SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); - return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); } - llvm_unreachable("Dont know how to handle GlobalAddress"); - return SDValue(0,0); + SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_GOT); + GA = DAG.getNode(MipsISD::WrapperPIC, dl, MVT::i32, GA); + SDValue ResNode = DAG.getLoad(MVT::i32, dl, + DAG.getEntryNode(), GA, MachinePointerInfo(), + false, false, 0); + // On functions and global targets not internal linked only + // a load from got/GP is necessary for PIC to work. + if (!GV->hasInternalLinkage() && + (!GV->hasLocalLinkage() || isa(GV))) + return ResNode; + SDValue GALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, + MipsII::MO_ABS_LO); + SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, GALo); + return DAG.getNode(ISD::ADD, dl, MVT::i32, ResNode, Lo); } SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op, @@ -1555,7 +1553,8 @@ SDValue MipsTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) SDValue MipsTargetLowering:: LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); - assert((Depth == 0) && "Frame address can only be determined for current frame."); + assert((Depth == 0) && + "Frame address can only be determined for current frame."); MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setFrameAddressIsTaken(true); @@ -1988,7 +1987,6 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, const SmallVectorImpl &Ins, DebugLoc dl, SelectionDAG &DAG, SmallVectorImpl &InVals) const { - // Assign locations to each value returned by this call. SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, getTargetMachine(), -- cgit v1.1 From 14487d4f66c3127b29408aae46c1a948d348ec59 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 7 Jun 2011 19:28:39 +0000 Subject: Refactor MipsTargetLowering::EmitInstrWithCustomInserter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132726 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 182 +++++++++++++++++------------------ 1 file changed, 90 insertions(+), 92 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index ccdcb34..92ab00b 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -554,97 +554,11 @@ static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) { return Mips::BRANCH_INVALID; } -MachineBasicBlock * -MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - bool isFPCmp = false; - DebugLoc dl = MI->getDebugLoc(); - unsigned Opc; - - switch (MI->getOpcode()) { - default: assert(false && "Unexpected instr type to insert"); - - case Mips::ATOMIC_LOAD_ADD_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu); - case Mips::ATOMIC_LOAD_ADD_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, Mips::ADDu); - case Mips::ATOMIC_LOAD_ADD_I32: - return EmitAtomicBinary(MI, BB, 4, Mips::ADDu); - - case Mips::ATOMIC_LOAD_AND_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, Mips::AND); - case Mips::ATOMIC_LOAD_AND_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, Mips::AND); - case Mips::ATOMIC_LOAD_AND_I32: - return EmitAtomicBinary(MI, BB, 4, Mips::AND); - - case Mips::ATOMIC_LOAD_OR_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, Mips::OR); - case Mips::ATOMIC_LOAD_OR_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, Mips::OR); - case Mips::ATOMIC_LOAD_OR_I32: - return EmitAtomicBinary(MI, BB, 4, Mips::OR); - - case Mips::ATOMIC_LOAD_XOR_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, Mips::XOR); - case Mips::ATOMIC_LOAD_XOR_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, Mips::XOR); - case Mips::ATOMIC_LOAD_XOR_I32: - return EmitAtomicBinary(MI, BB, 4, Mips::XOR); - - case Mips::ATOMIC_LOAD_NAND_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, 0, true); - case Mips::ATOMIC_LOAD_NAND_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, 0, true); - case Mips::ATOMIC_LOAD_NAND_I32: - return EmitAtomicBinary(MI, BB, 4, 0, true); - - case Mips::ATOMIC_LOAD_SUB_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, Mips::SUBu); - case Mips::ATOMIC_LOAD_SUB_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, Mips::SUBu); - case Mips::ATOMIC_LOAD_SUB_I32: - return EmitAtomicBinary(MI, BB, 4, Mips::SUBu); - - case Mips::ATOMIC_SWAP_I8: - return EmitAtomicBinaryPartword(MI, BB, 1, 0); - case Mips::ATOMIC_SWAP_I16: - return EmitAtomicBinaryPartword(MI, BB, 2, 0); - case Mips::ATOMIC_SWAP_I32: - return EmitAtomicBinary(MI, BB, 4, 0); - - case Mips::ATOMIC_CMP_SWAP_I8: - return EmitAtomicCmpSwapPartword(MI, BB, 1); - case Mips::ATOMIC_CMP_SWAP_I16: - return EmitAtomicCmpSwapPartword(MI, BB, 2); - case Mips::ATOMIC_CMP_SWAP_I32: - return EmitAtomicCmpSwap(MI, BB, 4); - - case Mips::MOVT: - case Mips::MOVT_S: - case Mips::MOVT_D: - isFPCmp = true; - Opc = Mips::BC1F; - break; - case Mips::MOVF: - case Mips::MOVF_S: - case Mips::MOVF_D: - isFPCmp = true; - Opc = Mips::BC1T; - break; - case Mips::MOVZ_I: - case Mips::MOVZ_S: - case Mips::MOVZ_D: - Opc = Mips::BNE; - break; - case Mips::MOVN_I: - case Mips::MOVN_S: - case Mips::MOVN_D: - Opc = Mips::BEQ; - break; - } - +static MachineBasicBlock* ExpandCondMov(MachineInstr *MI, MachineBasicBlock *BB, + DebugLoc dl, + const MipsSubtarget* Subtarget, + const TargetInstrInfo *TII, + bool isFPCmp, unsigned Opc) { // There is no need to expand CMov instructions if target has // conditional moves. if (Subtarget->hasCondMov()) @@ -688,7 +602,6 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, BuildMI(BB, dl, TII->get(Opc)).addReg(MI->getOperand(2).getReg()) .addReg(Mips::ZERO).addMBB(sinkMBB); - // copy0MBB: // %FalseValue = ... // # fallthrough to sinkMBB @@ -717,6 +630,91 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return BB; } +MachineBasicBlock * +MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, + MachineBasicBlock *BB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + + switch (MI->getOpcode()) { + default: + assert(false && "Unexpected instr type to insert"); + return NULL; + case Mips::MOVT: + case Mips::MOVT_S: + case Mips::MOVT_D: + return ExpandCondMov(MI, BB, dl, Subtarget, TII, true, Mips::BC1F); + case Mips::MOVF: + case Mips::MOVF_S: + case Mips::MOVF_D: + return ExpandCondMov(MI, BB, dl, Subtarget, TII, true, Mips::BC1T); + case Mips::MOVZ_I: + case Mips::MOVZ_S: + case Mips::MOVZ_D: + return ExpandCondMov(MI, BB, dl, Subtarget, TII, false, Mips::BNE); + case Mips::MOVN_I: + case Mips::MOVN_S: + case Mips::MOVN_D: + return ExpandCondMov(MI, BB, dl, Subtarget, TII, false, Mips::BEQ); + + case Mips::ATOMIC_LOAD_ADD_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu); + case Mips::ATOMIC_LOAD_ADD_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::ADDu); + case Mips::ATOMIC_LOAD_ADD_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::ADDu); + + case Mips::ATOMIC_LOAD_AND_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::AND); + case Mips::ATOMIC_LOAD_AND_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::AND); + case Mips::ATOMIC_LOAD_AND_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::AND); + + case Mips::ATOMIC_LOAD_OR_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::OR); + case Mips::ATOMIC_LOAD_OR_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::OR); + case Mips::ATOMIC_LOAD_OR_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::OR); + + case Mips::ATOMIC_LOAD_XOR_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::XOR); + case Mips::ATOMIC_LOAD_XOR_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::XOR); + case Mips::ATOMIC_LOAD_XOR_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::XOR); + + case Mips::ATOMIC_LOAD_NAND_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, 0, true); + case Mips::ATOMIC_LOAD_NAND_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, 0, true); + case Mips::ATOMIC_LOAD_NAND_I32: + return EmitAtomicBinary(MI, BB, 4, 0, true); + + case Mips::ATOMIC_LOAD_SUB_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, Mips::SUBu); + case Mips::ATOMIC_LOAD_SUB_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, Mips::SUBu); + case Mips::ATOMIC_LOAD_SUB_I32: + return EmitAtomicBinary(MI, BB, 4, Mips::SUBu); + + case Mips::ATOMIC_SWAP_I8: + return EmitAtomicBinaryPartword(MI, BB, 1, 0); + case Mips::ATOMIC_SWAP_I16: + return EmitAtomicBinaryPartword(MI, BB, 2, 0); + case Mips::ATOMIC_SWAP_I32: + return EmitAtomicBinary(MI, BB, 4, 0); + + case Mips::ATOMIC_CMP_SWAP_I8: + return EmitAtomicCmpSwapPartword(MI, BB, 1); + case Mips::ATOMIC_CMP_SWAP_I16: + return EmitAtomicCmpSwapPartword(MI, BB, 2); + case Mips::ATOMIC_CMP_SWAP_I32: + return EmitAtomicCmpSwap(MI, BB, 4); + } +} + // This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and // Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true) MachineBasicBlock * -- cgit v1.1 From 3d21c2495d481f42bab9f8313b46e7bcf0e2d7ac Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 8 Jun 2011 17:39:33 +0000 Subject: Reorganize code in MipsTargetLowering::LowerCall to improve readability. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132756 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 74 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 38 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 92ab00b..2e9e2a1 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1760,20 +1760,41 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, CCInfo.AnalyzeCallOperands(Outs, CC_Mips); // Get a count of how many bytes are to be pushed on the stack. - unsigned NumBytes = CCInfo.getNextStackOffset(); - Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); + unsigned NextStackOffset = CCInfo.getNextStackOffset(); - // With EABI is it possible to have 16 args on registers. - SmallVector, 16> RegsToPass; - SmallVector MemOpChains; + Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NextStackOffset, + true)); // If this is the first call, create a stack frame object that points to - // a location to which .cprestore saves $gp. The offset of this frame object - // is set to 0, since we know nothing about the size of the argument area at - // this point. + // a location to which .cprestore saves $gp. if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); + // Update size of the maximum argument space. + // For O32, a minimum of four words (16 bytes) of argument space is + // allocated. + if (Subtarget->isABI_O32()) + NextStackOffset = std::max(NextStackOffset, (unsigned)16); + + unsigned MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); + + if (MaxCallFrameSize < NextStackOffset) { + MipsFI->setMaxCallFrameSize(NextStackOffset); + + if (IsPIC) { + // $gp restore slot must be aligned. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + int GPFI = MipsFI->getGPFI(); + MFI->setObjectOffset(GPFI, NextStackOffset); + } + } + + // With EABI is it possible to have 16 args on registers. + SmallVector, 16> RegsToPass; + SmallVector MemOpChains; + int FirstFI = -MFI->getNumFixedObjects() - 1, LastFI = 0; // Walk the register/memloc assignments, inserting copies/loads. @@ -1846,6 +1867,12 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, false, false, 0)); } + // Extend range of indices of frame objects for outgoing arguments that were + // created during this function call. Skip this step if no such objects were + // created. + if (LastFI) + MipsFI->extendOutArgFIRange(FirstFI, LastFI); + // Transform all store nodes into one single node because all store // nodes are independent of each other. if (!MemOpChains.empty()) @@ -1937,37 +1964,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, Chain = DAG.getNode(MipsISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); - // Function can have an arbitrary number of calls, so - // hold the LastArgStackLoc with the biggest offset. - unsigned MaxCallFrameSize = MipsFI->getMaxCallFrameSize(); - unsigned NextStackOffset = CCInfo.getNextStackOffset(); - - // For O32, a minimum of four words (16 bytes) of argument space is - // allocated. - if (Subtarget->isABI_O32()) - NextStackOffset = std::max(NextStackOffset, (unsigned)16); - - if (MaxCallFrameSize < NextStackOffset) { - MipsFI->setMaxCallFrameSize(NextStackOffset); - - if (IsPIC) { - // $gp restore slot must be aligned. - unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / - StackAlignment * StackAlignment; - int GPFI = MipsFI->getGPFI(); - MFI->setObjectOffset(GPFI, NextStackOffset); - } - } - - // Extend range of indices of frame objects for outgoing arguments that were - // created during this function call. Skip this step if no such objects were - // created. - if (LastFI) - MipsFI->extendOutArgFIRange(FirstFI, LastFI); - // Create the CALLSEQ_END node. - Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), + Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NextStackOffset, true), DAG.getIntPtrConstant(0, true), InFlag); InFlag = Chain.getValue(1); -- cgit v1.1 From 69b9044c668dfb92038385a96c030778de64edfd Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 8 Jun 2011 21:28:09 +0000 Subject: Fix bug in lowering of DYNAMIC_STACKALLOC nodes. The correct offset of the dynamically allocated stack area was not set. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132758 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 47 ++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 2e9e2a1..77ef829 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -59,6 +59,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; + case MipsISD::DynAlloc: return "MipsISD::DynAlloc"; default: return NULL; } } @@ -1189,6 +1190,9 @@ MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI, SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + unsigned StackAlignment = getTargetMachine().getFrameLowering()->getStackAlignment(); assert(StackAlignment >= @@ -1211,24 +1215,14 @@ LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const // must be placed in the stack pointer register. Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, SDValue()); - // Retrieve updated $sp. There is a glue input to prevent instructions that - // clobber $sp from being inserted between copytoreg and copyfromreg. - SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, - Chain.getValue(1)); - - // The stack space reserved by alloca is located right above the argument - // area. It is aligned on a boundary that is a multiple of StackAlignment. - MachineFunction &MF = DAG.getMachineFunction(); - MipsFunctionInfo *MipsFI = MF.getInfo(); - unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / - StackAlignment * StackAlignment; - SDValue AllocPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, - DAG.getConstant(SPOffset, MVT::i32)); // This node always has two return values: a new stack pointer // value and a chain - SDValue Ops[2] = { AllocPtr, NewSP.getValue(1) }; - return DAG.getMergeValues(Ops, 2, dl); + SDVTList VTLs = DAG.getVTList(MVT::i32, MVT::Other); + SDValue Ptr = DAG.getFrameIndex(MipsFI->getDynAllocFI(), getPointerTy()); + SDValue Ops[] = { Chain, Ptr, Chain.getValue(1) }; + + return DAG.getNode(MipsISD::DynAlloc, dl, VTLs, Ops, 3); } SDValue MipsTargetLowering:: @@ -1770,6 +1764,10 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); + // Get the frame index of the stack frame object that points to the location + // of dynamically allocated area on the stack. + int DynAllocFI = MipsFI->getDynAllocFI(); + // Update size of the maximum argument space. // For O32, a minimum of four words (16 bytes) of argument space is // allocated. @@ -1781,14 +1779,17 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (MaxCallFrameSize < NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); - if (IsPIC) { - // $gp restore slot must be aligned. - unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / - StackAlignment * StackAlignment; - int GPFI = MipsFI->getGPFI(); - MFI->setObjectOffset(GPFI, NextStackOffset); - } + // Set the offsets relative to $sp of the $gp restore slot and dynamically + // allocated stack space. These offsets must be aligned to a boundary + // determined by the stack alignment of the ABI. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + + if (IsPIC) + MFI->setObjectOffset(MipsFI->getGPFI(), NextStackOffset); + + MFI->setObjectOffset(DynAllocFI, NextStackOffset); } // With EABI is it possible to have 16 args on registers. -- cgit v1.1 From 471e4224809f51652c71f319532697a879a75a0d Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 8 Jun 2011 23:55:35 +0000 Subject: Add a parameter to CCState so that it can access the MachineFunction. No functional change. Part of PR6965 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132763 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 77ef829..6a429e3 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -148,7 +148,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); - + setOperationAction(ISD::VAARG, MVT::Other, Expand); setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAEND, MVT::Other, Expand); @@ -720,7 +720,7 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, // Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true) MachineBasicBlock * MipsTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, - unsigned Size, unsigned BinOpcode, + unsigned Size, unsigned BinOpcode, bool Nand) const { assert(Size == 4 && "Unsupported size for EmitAtomicBinary."); @@ -1502,11 +1502,11 @@ static SDValue LowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG) { } static SDValue LowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool isLittle) { - // FIXME: + // FIXME: // Use ext/ins instructions if target architecture is Mips32r2. // Eliminate redundant mfc1 and mtc1 instructions. unsigned LoIdx = 0, HiIdx = 1; - + if (!isLittle) std::swap(LoIdx, HiIdx); @@ -1707,7 +1707,7 @@ WriteByValArg(SDValue& Chain, DebugLoc dl, // copy remaining part of byval arg to stack. if (CurWord < LastWord) { - unsigned SizeInBytes = (LastWord - CurWord) * 4; + unsigned SizeInBytes = (LastWord - CurWord) * 4; SDValue Src = DAG.getNode(ISD::ADD, dl, MVT::i32, Arg, DAG.getConstant((CurWord - FirstWord) * 4, MVT::i32)); @@ -1745,8 +1745,8 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, - *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), ArgLocs, *DAG.getContext()); if (Subtarget->isABI_O32()) CCInfo.AnalyzeCallOperands(Outs, CC_MipsO32); @@ -1767,7 +1767,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Get the frame index of the stack frame object that points to the location // of dynamically allocated area on the stack. int DynAllocFI = MipsFI->getDynAllocFI(); - + // Update size of the maximum argument space. // For O32, a minimum of four words (16 bytes) of argument space is // allocated. @@ -1781,14 +1781,14 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Set the offsets relative to $sp of the $gp restore slot and dynamically // allocated stack space. These offsets must be aligned to a boundary - // determined by the stack alignment of the ABI. + // determined by the stack alignment of the ABI. unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / + NextStackOffset = (NextStackOffset + StackAlignment - 1) / StackAlignment * StackAlignment; if (IsPIC) MFI->setObjectOffset(MipsFI->getGPFI(), NextStackOffset); - + MFI->setObjectOffset(DynAllocFI, NextStackOffset); } @@ -1796,7 +1796,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, SmallVector, 16> RegsToPass; SmallVector MemOpChains; - int FirstFI = -MFI->getNumFixedObjects() - 1, LastFI = 0; + int FirstFI = -MFI->getNumFixedObjects() - 1, LastFI = 0; // Walk the register/memloc assignments, inserting copies/loads. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { @@ -1844,7 +1844,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Register can't get to this point... assert(VA.isMemLoc()); - // ByVal Arg. + // ByVal Arg. ISD::ArgFlagsTy Flags = Outs[i].Flags; if (Flags.isByVal()) { assert(Subtarget->isABI_O32() && @@ -1857,7 +1857,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } // Create the frame index object for this incoming parameter - LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, + LastFI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8, VA.getLocMemOffset(), true); SDValue PtrOff = DAG.getFrameIndex(LastFI, getPointerTy()); @@ -1924,7 +1924,7 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, } else Callee = LoadValue; - // Use chain output from LoadValue + // Use chain output from LoadValue Chain = LoadValue.getValue(1); } @@ -1986,8 +1986,8 @@ MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, SmallVectorImpl &InVals) const { // Assign locations to each value returned by this call. SmallVector RVLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), RVLocs, *DAG.getContext()); CCInfo.AnalyzeCallResult(Ins, RetCC_Mips); @@ -2051,8 +2051,8 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, // Assign locations to all of the incoming arguments. SmallVector ArgLocs; - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - ArgLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), ArgLocs, *DAG.getContext()); if (Subtarget->isABI_O32()) CCInfo.AnalyzeFormalArguments(Ins, CC_MipsO32); @@ -2165,7 +2165,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, if (isVarArg && Subtarget->isABI_O32()) { // Record the frame index of the first variable argument - // which is a value necessary to VASTART. + // which is a value necessary to VASTART. unsigned NextStackOffset = CCInfo.getNextStackOffset(); assert(NextStackOffset % 4 == 0 && "NextStackOffset must be aligned to 4-byte boundaries."); @@ -2217,8 +2217,8 @@ MipsTargetLowering::LowerReturn(SDValue Chain, SmallVector RVLocs; // CCState - Info about the registers and stack slot. - CCState CCInfo(CallConv, isVarArg, getTargetMachine(), - RVLocs, *DAG.getContext()); + CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), + getTargetMachine(), RVLocs, *DAG.getContext()); // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_Mips); -- cgit v1.1 From 6f3661fdcd10a33d225502f8b112dc5b7968ef74 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 9 Jun 2011 16:03:19 +0000 Subject: Speculatively revert 132758 and 132768 to try to fix the Windows buildbots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132777 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 47 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 6a429e3..fd90731 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -59,7 +59,6 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64"; case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64"; case MipsISD::WrapperPIC: return "MipsISD::WrapperPIC"; - case MipsISD::DynAlloc: return "MipsISD::DynAlloc"; default: return NULL; } } @@ -1190,9 +1189,6 @@ MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI, SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - MipsFunctionInfo *MipsFI = MF.getInfo(); - unsigned StackAlignment = getTargetMachine().getFrameLowering()->getStackAlignment(); assert(StackAlignment >= @@ -1215,14 +1211,24 @@ LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const // must be placed in the stack pointer register. Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, SDValue()); + // Retrieve updated $sp. There is a glue input to prevent instructions that + // clobber $sp from being inserted between copytoreg and copyfromreg. + SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, + Chain.getValue(1)); + + // The stack space reserved by alloca is located right above the argument + // area. It is aligned on a boundary that is a multiple of StackAlignment. + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / + StackAlignment * StackAlignment; + SDValue AllocPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, + DAG.getConstant(SPOffset, MVT::i32)); // This node always has two return values: a new stack pointer // value and a chain - SDVTList VTLs = DAG.getVTList(MVT::i32, MVT::Other); - SDValue Ptr = DAG.getFrameIndex(MipsFI->getDynAllocFI(), getPointerTy()); - SDValue Ops[] = { Chain, Ptr, Chain.getValue(1) }; - - return DAG.getNode(MipsISD::DynAlloc, dl, VTLs, Ops, 3); + SDValue Ops[2] = { AllocPtr, NewSP.getValue(1) }; + return DAG.getMergeValues(Ops, 2, dl); } SDValue MipsTargetLowering:: @@ -1764,10 +1770,6 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (IsPIC && !MipsFI->getGPFI()) MipsFI->setGPFI(MFI->CreateFixedObject(4, 0, true)); - // Get the frame index of the stack frame object that points to the location - // of dynamically allocated area on the stack. - int DynAllocFI = MipsFI->getDynAllocFI(); - // Update size of the maximum argument space. // For O32, a minimum of four words (16 bytes) of argument space is // allocated. @@ -1779,17 +1781,14 @@ MipsTargetLowering::LowerCall(SDValue Chain, SDValue Callee, if (MaxCallFrameSize < NextStackOffset) { MipsFI->setMaxCallFrameSize(NextStackOffset); - // Set the offsets relative to $sp of the $gp restore slot and dynamically - // allocated stack space. These offsets must be aligned to a boundary - // determined by the stack alignment of the ABI. - unsigned StackAlignment = TFL->getStackAlignment(); - NextStackOffset = (NextStackOffset + StackAlignment - 1) / - StackAlignment * StackAlignment; - - if (IsPIC) - MFI->setObjectOffset(MipsFI->getGPFI(), NextStackOffset); - - MFI->setObjectOffset(DynAllocFI, NextStackOffset); + if (IsPIC) { + // $gp restore slot must be aligned. + unsigned StackAlignment = TFL->getStackAlignment(); + NextStackOffset = (NextStackOffset + StackAlignment - 1) / + StackAlignment * StackAlignment; + int GPFI = MipsFI->getGPFI(); + MFI->setObjectOffset(GPFI, NextStackOffset); + } } // With EABI is it possible to have 16 args on registers. -- cgit v1.1 From e0b5cfcae88190bd45778e11d20bc676823098a7 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Thu, 16 Jun 2011 00:40:02 +0000 Subject: Silence warnings in non assert builds. Patch by David Blaikie git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133118 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/Target/Mips/MipsISelLowering.cpp') diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index fd90731..c42054e 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -1550,8 +1550,8 @@ SDValue MipsTargetLowering::LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) SDValue MipsTargetLowering:: LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { - unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); - assert((Depth == 0) && + // check the depth + assert((cast(Op.getOperand(0))->getZExtValue() == 0) && "Frame address can only be determined for current frame."); MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); -- cgit v1.1