From: Reid Kleckner Date: Wed, 16 Jan 2019 22:05:36 +0000 (+0000) Subject: [X86] Sink complex MCU CC helper to .cpp file from .h file, NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6f067fd08babeb0a6a09249d47b162f318f9451;p=llvm [X86] Sink complex MCU CC helper to .cpp file from .h file, NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351384 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86CallingConv.cpp b/lib/Target/X86/X86CallingConv.cpp index 59dde982f51..81f13f98e7b 100644 --- a/lib/Target/X86/X86CallingConv.cpp +++ b/lib/Target/X86/X86CallingConv.cpp @@ -205,4 +205,60 @@ bool CC_X86_32_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT, return false; // No register was assigned - Continue the search. } +bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, + CCValAssign::LocInfo &LocInfo, + ISD::ArgFlagsTy &ArgFlags, CCState &State) { + // This is similar to CCAssignToReg<[EAX, EDX, ECX]>, but makes sure + // not to split i64 and double between a register and stack + static const MCPhysReg RegList[] = {X86::EAX, X86::EDX, X86::ECX}; + static const unsigned NumRegs = sizeof(RegList) / sizeof(RegList[0]); + + SmallVectorImpl &PendingMembers = State.getPendingLocs(); + + // If this is the first part of an double/i64/i128, or if we're already + // in the middle of a split, add to the pending list. If this is not + // the end of the split, return, otherwise go on to process the pending + // list + if (ArgFlags.isSplit() || !PendingMembers.empty()) { + PendingMembers.push_back( + CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); + if (!ArgFlags.isSplitEnd()) + return true; + } + + // If there are no pending members, we are not in the middle of a split, + // so do the usual inreg stuff. + if (PendingMembers.empty()) { + if (unsigned Reg = State.AllocateReg(RegList)) { + State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); + return true; + } + return false; + } + + assert(ArgFlags.isSplitEnd()); + + // We now have the entire original argument in PendingMembers, so decide + // whether to use registers or the stack. + // Per the MCU ABI: + // a) To use registers, we need to have enough of them free to contain + // the entire argument. + // b) We never want to use more than 2 registers for a single argument. + + unsigned FirstFree = State.getFirstUnallocated(RegList); + bool UseRegs = PendingMembers.size() <= std::min(2U, NumRegs - FirstFree); + + for (auto &It : PendingMembers) { + if (UseRegs) + It.convertToReg(State.AllocateReg(RegList[FirstFree++])); + else + It.convertToMem(State.AllocateStack(4, 4)); + State.addLoc(It); + } + + PendingMembers.clear(); + + return true; +} + } // End llvm namespace diff --git a/lib/Target/X86/X86CallingConv.h b/lib/Target/X86/X86CallingConv.h index d0fcbd31331..eb1b7736f33 100644 --- a/lib/Target/X86/X86CallingConv.h +++ b/lib/Target/X86/X86CallingConv.h @@ -57,63 +57,9 @@ inline bool CC_X86_AnyReg_Error(unsigned &, MVT &, MVT &, return false; } -inline bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, - CCValAssign::LocInfo &LocInfo, - ISD::ArgFlagsTy &ArgFlags, - CCState &State) { - // This is similar to CCAssignToReg<[EAX, EDX, ECX]>, but makes sure - // not to split i64 and double between a register and stack - static const MCPhysReg RegList[] = {X86::EAX, X86::EDX, X86::ECX}; - static const unsigned NumRegs = sizeof(RegList)/sizeof(RegList[0]); - - SmallVectorImpl &PendingMembers = State.getPendingLocs(); - - // If this is the first part of an double/i64/i128, or if we're already - // in the middle of a split, add to the pending list. If this is not - // the end of the split, return, otherwise go on to process the pending - // list - if (ArgFlags.isSplit() || !PendingMembers.empty()) { - PendingMembers.push_back( - CCValAssign::getPending(ValNo, ValVT, LocVT, LocInfo)); - if (!ArgFlags.isSplitEnd()) - return true; - } - - // If there are no pending members, we are not in the middle of a split, - // so do the usual inreg stuff. - if (PendingMembers.empty()) { - if (unsigned Reg = State.AllocateReg(RegList)) { - State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); - return true; - } - return false; - } - - assert(ArgFlags.isSplitEnd()); - - // We now have the entire original argument in PendingMembers, so decide - // whether to use registers or the stack. - // Per the MCU ABI: - // a) To use registers, we need to have enough of them free to contain - // the entire argument. - // b) We never want to use more than 2 registers for a single argument. - - unsigned FirstFree = State.getFirstUnallocated(RegList); - bool UseRegs = PendingMembers.size() <= std::min(2U, NumRegs - FirstFree); - - for (auto &It : PendingMembers) { - if (UseRegs) - It.convertToReg(State.AllocateReg(RegList[FirstFree++])); - else - It.convertToMem(State.AllocateStack(4, 4)); - State.addLoc(It); - } - - PendingMembers.clear(); - - return true; -} +bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, + CCValAssign::LocInfo &LocInfo, + ISD::ArgFlagsTy &ArgFlags, CCState &State); } // End llvm namespace