diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td index d0bdd369839..d785aa8f453 100644 --- a/include/llvm/Target/TargetCallingConv.td +++ b/include/llvm/Target/TargetCallingConv.td @@ -147,6 +147,13 @@ class CCDelegateTo : CCAction { /// that the target supports. class CallingConv actions> { list Actions = actions; + bit Custom = 0; +} + +/// CustomCallingConv - An instance of this is used to declare calling +/// conventions that are implemented using a custom function of the same name. +class CustomCallingConv : CallingConv<[]> { + let Custom = 1; } /// CalleeSavedRegs - A list of callee saved registers for a given calling diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index 3e75bbdde3b..37f861949af 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -66,6 +66,14 @@ def RetCC_MipsO32 : CallingConv<[ CCIfType<[f64], CCIfSubtargetNot<"isFP64bit()", CCAssignToReg<[D0, D1]>>> ]>; +def CC_MipsO32_FP32 : CustomCallingConv; +def CC_MipsO32_FP64 : CustomCallingConv; + +def CC_MipsO32_FP : CallingConv<[ + CCIfSubtargetNot<"isFP64bit()", CCDelegateTo>, + CCIfSubtarget<"isFP64bit()", CCDelegateTo> +]>; + //===----------------------------------------------------------------------===// // Mips N32/64 Calling Convention //===----------------------------------------------------------------------===// @@ -289,6 +297,22 @@ def RetCC_Mips : CallingConv<[ CCDelegateTo ]>; +def CC_Mips_FixedArg : CallingConv<[ + CCIfCC<"CallingConv::Fast", CCDelegateTo>, + + // FIXME: There wasn't an EABI case in the original code and it seems unlikely + // that it's the same as CC_MipsN + CCIfSubtarget<"isABI_O32()", CCDelegateTo>, + CCDelegateTo +]>; + +def CC_Mips_VarArg : CallingConv<[ + // FIXME: There wasn't an EABI case in the original code and it seems unlikely + // that it's the same as CC_MipsN_VarArg + CCIfSubtarget<"isABI_O32()", CCDelegateTo>, + CCDelegateTo +]>; + //===----------------------------------------------------------------------===// // Callee-saved register lists. //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 1c4e9ba5ee7..43e8ee8ba05 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -3528,7 +3528,7 @@ analyzeCallOperands(const SmallVectorImpl &Args, "CallingConv::Fast shouldn't be used for vararg functions."); unsigned NumOpnds = Args.size(); - llvm::CCAssignFn *FixedFn = fixedArgFn(), *VarFn = varArgFn(); + llvm::CCAssignFn *FixedFn = fixedArgFn(); for (unsigned I = 0; I != NumOpnds; ++I) { MVT ArgVT = Args[I].VT; @@ -3541,7 +3541,7 @@ analyzeCallOperands(const SmallVectorImpl &Args, } if (IsVarArg && !Args[I].IsFixed) - R = VarFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo); + R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo); else { MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode, IsSoftFloat); @@ -3624,20 +3624,11 @@ const ArrayRef MipsTargetLowering::MipsCC::intArgRegs() const { } llvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const { - if (CallConv == CallingConv::Fast) - return CC_Mips_FastCC; - - if (SpecialCallingConv == Mips16RetHelperConv) + if (CallConv != CallingConv::Fast && + SpecialCallingConv == Mips16RetHelperConv) return CC_Mips16RetHelper; - return Subtarget.isABI_O32() - ? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32) - : CC_MipsN; -} -llvm::CCAssignFn *MipsTargetLowering::MipsCC::varArgFn() const { - return Subtarget.isABI_O32() - ? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32) - : CC_MipsN_VarArg; + return CC_Mips_FixedArg; } const MCPhysReg *MipsTargetLowering::MipsCC::shadowRegs() const { diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 1cc975b6d07..1c42179b385 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -395,9 +395,6 @@ namespace llvm { /// Return the function that analyzes fixed argument list functions. llvm::CCAssignFn *fixedArgFn() const; - /// Return the function that analyzes variable argument list functions. - llvm::CCAssignFn *varArgFn() const; - const MCPhysReg *shadowRegs() const; void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize, diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index e79e8cbbde8..ec2251d934c 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -35,23 +35,26 @@ private: } // End anonymous namespace void CallingConvEmitter::run(raw_ostream &O) { - std::vector CCs = Records.getAllDerivedDefinitions("CallingConv"); - - // Emit prototypes for all of the CC's so that they can forward ref each - // other. + + // Emit prototypes for all of the non-custom CC's so that they can forward ref + // each other. for (unsigned i = 0, e = CCs.size(); i != e; ++i) { - O << "static bool " << CCs[i]->getName() - << "(unsigned ValNo, MVT ValVT,\n" - << std::string(CCs[i]->getName().size()+13, ' ') - << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" - << std::string(CCs[i]->getName().size()+13, ' ') - << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n"; + if (!CCs[i]->getValueAsBit("Custom")) { + O << "static bool " << CCs[i]->getName() + << "(unsigned ValNo, MVT ValVT,\n" + << std::string(CCs[i]->getName().size() + 13, ' ') + << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" + << std::string(CCs[i]->getName().size() + 13, ' ') + << "ISD::ArgFlagsTy ArgFlags, CCState &State);\n"; + } + } + + // Emit each non-custom calling convention description in full. + for (unsigned i = 0, e = CCs.size(); i != e; ++i) { + if (!CCs[i]->getValueAsBit("Custom")) + EmitCallingConv(CCs[i], O); } - - // Emit each calling convention description in full. - for (unsigned i = 0, e = CCs.size(); i != e; ++i) - EmitCallingConv(CCs[i], O); }