Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/CallingConv.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ namespace CallingConv {
/// Preserve X2-X15, X19-X29, SP, Z0-Z31, P0-P15.
AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 = 103,

/// Calling convention for OCaml
OCaml = 104,

/// The highest possible ID. Must be some 2^k - 1.
MaxID = 1023
};
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/IR/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
case CallingConv::AMDGPU_CS: Out << "amdgpu_cs"; break;
case CallingConv::AMDGPU_KERNEL: Out << "amdgpu_kernel"; break;
case CallingConv::AMDGPU_Gfx: Out << "amdgpu_gfx"; break;
case CallingConv::OCaml: Out << "ocamlcc"; break;
}
}

Expand Down
35 changes: 35 additions & 0 deletions llvm/lib/Target/X86/X86CallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,19 @@ def RetCC_X86_64_HHVM: CallingConv<[
RAX, R10, R11, R13, R14, R15]>>
]>;

def RetCC_X86_64_OCaml : CallingConv<[
// Promote all types to i64
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,

// Every function preserves the necessary function arguments
CCIfType<[i64], CCAssignToReg<[R14, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>,

CCIfType<[f32, f64], CCAssignToReg<[
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15
]>>
]>;


defm X86_32_RegCall :
X86_RegCall_base<RC_X86_32_RegCall>;
Expand Down Expand Up @@ -494,6 +507,9 @@ def RetCC_X86_64 : CallingConv<[
// Mingw64 and native Win64 use Win64 CC
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<RetCC_X86_Win64_C>>,

// Handle OCaml calls
CCIfCC<"CallingConv::OCaml", CCDelegateTo<RetCC_X86_64_OCaml>>,

// Otherwise, drop to normal X86-64 CC
CCDelegateTo<RetCC_X86_64_C>
]>;
Expand Down Expand Up @@ -700,6 +716,24 @@ def CC_X86_Win64_VectorCall : CallingConv<[
CCDelegateTo<CC_X86_Win64_C>
]>;

def CC_X86_64_OCaml : CallingConv<[
// Promote i8/i16/i32 arguments to i64.
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,

// See https://github.com/oxcaml/oxcaml/blob/main/backend/amd64/proc.ml#L34
// for further details on the registers and their meaning. Runtime registers
// (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]>>,

CCIfType<[f32, f64], CCAssignToReg<[
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15
]>>
]>;

def CC_X86_64_GHC : CallingConv<[
// Promote i8/i16/i32 arguments to i64.
Expand Down Expand Up @@ -1103,6 +1137,7 @@ def CC_X86_64 : CallingConv<[
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_RegCall>>>,
CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_SysV64_RegCall>>,
CCIfCC<"CallingConv::X86_INTR", CCCustom<"CC_X86_Intr">>,
CCIfCC<"CallingConv::OCaml", CCDelegateTo<CC_X86_64_OCaml>>,

// Mingw64 and native Win64 use Win64 CC
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86FastISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3140,7 +3140,7 @@ static unsigned computeBytesPoppedByCalleeForSRet(const X86Subtarget *Subtarget,
return 0;
if (CC == CallingConv::Fast || CC == CallingConv::GHC ||
CC == CallingConv::HiPE || CC == CallingConv::Tail ||
CC == CallingConv::SwiftTail)
CC == CallingConv::SwiftTail || CC == CallingConv::OCaml)
return 0;

if (CB)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3670,7 +3670,7 @@ static bool canGuaranteeTCO(CallingConv::ID CC) {
return (CC == CallingConv::Fast || CC == CallingConv::GHC ||
CC == CallingConv::X86_RegCall || CC == CallingConv::HiPE ||
CC == CallingConv::HHVM || CC == CallingConv::Tail ||
CC == CallingConv::SwiftTail);
CC == CallingConv::SwiftTail || CC == CallingConv::OCaml);
}

/// Return true if we might ever do TCO for calls with this calling convention.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
switch (CC) {
case CallingConv::GHC:
case CallingConv::HiPE:
case CallingConv::OCaml:
return CSR_NoRegs_SaveList;
case CallingConv::AnyReg:
if (HasAVX)
Expand Down Expand Up @@ -423,6 +424,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
switch (CC) {
case CallingConv::GHC:
case CallingConv::HiPE:
case CallingConv::OCaml:
return CSR_NoRegs_RegMask;
case CallingConv::AnyReg:
if (HasAVX)
Expand Down