diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index 05dd537ec4280..e50e74aafe301 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -444,8 +444,9 @@ def RetCC_X86_64_OCaml : CallingConv<[ // Promote all types to i64 CCIfType<[i8, i16, i32], CCPromoteToType>, - // Every function preserves the necessary function arguments - CCIfType<[i64], CCAssignToReg<[R14, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>, + // Runtime registers (R14, R15) are threaded through function calls + // See the argument calling conventions for OCaml for more details + CCIfType<[i64], CCAssignToReg<[R14, R15, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>, CCIfType<[f32, f64], CCAssignToReg<[ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, @@ -453,6 +454,11 @@ def RetCC_X86_64_OCaml : CallingConv<[ ]>> ]>; +def RetCC_X86_64_OCaml_C_Call : CallingConv<[ + CCIfType<[i64], CCAssignToReg<[R14, R15]>>, + + CCDelegateTo +]>; defm X86_32_RegCall : X86_RegCall_base; @@ -509,6 +515,7 @@ def RetCC_X86_64 : CallingConv<[ // Handle OCaml calls CCIfCC<"CallingConv::OCaml", CCDelegateTo>, + CCIfCC<"CallingConv::OCaml_C_Call", CCDelegateTo>, // Otherwise, drop to normal X86-64 CC CCDelegateTo @@ -725,9 +732,8 @@ def CC_X86_64_OCaml : CallingConv<[ // (registers containing pointers to data structures maintained by the // runtime) must be preserved through the run of the program. To ensure LLVM // doesn't mess with them, they are explicitly threaded through function calls - // and returns. These are R14 and R15. Note that R15 isn't listed since it is - // not implemented yet. - CCIfType<[i64], CCAssignToReg<[R14, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>, + // and returns. These are R14 and R15. + CCIfType<[i64], CCAssignToReg<[R14, R15, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>, CCIfType<[f32, f64], CCAssignToReg<[ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, @@ -738,7 +744,7 @@ def CC_X86_64_OCaml : CallingConv<[ def CC_X86_64_OCaml_C_Call : CallingConv<[ // OCaml wraps C calls with another function that transfers stack arguments. // RAX contains the function address, and R12 contains the size of the stack arguments. - CCIfType<[i64], CCAssignToReg<[RAX, R12]>>, + CCIfType<[i64], CCAssignToReg<[R14, R15, RAX, R12]>>, // Follow C convention normally otherwise CCDelegateTo @@ -1173,6 +1179,9 @@ def CSR_NoRegs : CalleeSavedRegs<(add)>; def CSR_32 : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>; def CSR_64 : CalleeSavedRegs<(add RBX, R12, R13, R14, R15, RBP)>; +// R14 and R15 are used as return registers, so they aren't callee saved. +def CSR_64_OCaml_C_Call : CalleeSavedRegs<(sub CSR_64, R14, R15)>; + def CSR_64_SwiftError : CalleeSavedRegs<(sub CSR_64, R12)>; def CSR_64_SwiftTail : CalleeSavedRegs<(sub CSR_64, R13, R14)>; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 3ca9a0b09a24a..07872da230769 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -302,6 +302,8 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { case CallingConv::HiPE: case CallingConv::OCaml: return CSR_NoRegs_SaveList; + case CallingConv::OCaml_C_Call: + return CSR_64_OCaml_C_Call_SaveList; case CallingConv::AnyReg: if (HasAVX) return CSR_64_AllRegs_AVX_SaveList; @@ -426,6 +428,8 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, case CallingConv::HiPE: case CallingConv::OCaml: return CSR_NoRegs_RegMask; + case CallingConv::OCaml_C_Call: + return CSR_64_OCaml_C_Call_RegMask; case CallingConv::AnyReg: if (HasAVX) return CSR_64_AllRegs_AVX_RegMask;