/// that the target supports.
class CallingConv<list<CCAction> actions> {
list<CCAction> 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
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<CC_MipsO32_FP32>>,
+ CCIfSubtarget<"isFP64bit()", CCDelegateTo<CC_MipsO32_FP64>>
+]>;
+
//===----------------------------------------------------------------------===//
// Mips N32/64 Calling Convention
//===----------------------------------------------------------------------===//
CCDelegateTo<RetCC_MipsO32>
]>;
+def CC_Mips_FixedArg : CallingConv<[
+ CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
+
+ // 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<CC_MipsO32_FP>>,
+ CCDelegateTo<CC_MipsN>
+]>;
+
+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<CC_MipsO32_FP>>,
+ CCDelegateTo<CC_MipsN_VarArg>
+]>;
+
//===----------------------------------------------------------------------===//
// Callee-saved register lists.
//===----------------------------------------------------------------------===//
"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;
}
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);
}
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 {
/// 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,
} // End anonymous namespace
void CallingConvEmitter::run(raw_ostream &O) {
-
std::vector<Record*> 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);
}