Index: include/llvm/Target/TargetCallingConv.td =================================================================== --- include/llvm/Target/TargetCallingConv.td +++ include/llvm/Target/TargetCallingConv.td @@ -147,6 +147,13 @@ /// 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 Index: lib/Target/Mips/MipsCallingConv.td =================================================================== --- lib/Target/Mips/MipsCallingConv.td +++ lib/Target/Mips/MipsCallingConv.td @@ -66,6 +66,14 @@ 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 //===----------------------------------------------------------------------===// @@ -288,6 +296,22 @@ 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. //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsISelLowering.h =================================================================== --- lib/Target/Mips/MipsISelLowering.h +++ lib/Target/Mips/MipsISelLowering.h @@ -396,9 +396,6 @@ /// 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, Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -3547,7 +3547,7 @@ "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; @@ -3560,7 +3560,7 @@ } 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); @@ -3643,20 +3643,11 @@ } 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 { Index: utils/TableGen/CallingConvEmitter.cpp =================================================================== --- utils/TableGen/CallingConvEmitter.cpp +++ utils/TableGen/CallingConvEmitter.cpp @@ -35,23 +35,26 @@ } // 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) { + 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) { - 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")) + 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); }