@@ -440,12 +440,12 @@ def RetCC_X86_64_HHVM: CallingConv<[
440440 RAX, R10, R11, R13, R14, R15]>>
441441]>;
442442
443- def RetCC_X86_64_OCaml : CallingConv<[
443+ def RetCC_X86_64_OxCaml : CallingConv<[
444444 // Promote all types to i64
445445 CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
446446
447447 // Runtime registers (R14, R15) are threaded through function calls
448- // See the argument calling conventions for OCaml for more details
448+ // See the argument calling conventions for OxCaml for more details
449449 CCIfType<[i64], CCAssignToReg<[R14, R15, RAX, RBX, RDI, RSI, RDX, RCX, R8, R9, R12, R13]>>,
450450
451451 CCIfType<[f32, f64], CCAssignToReg<[
@@ -454,7 +454,13 @@ def RetCC_X86_64_OCaml : CallingConv<[
454454 ]>>
455455]>;
456456
457- def RetCC_X86_64_OCaml_C_Call : CallingConv<[
457+ def RetCC_X86_64_OxCaml_C_Call : CallingConv<[
458+ CCIfType<[i64], CCAssignToReg<[R14, R15]>>,
459+
460+ CCDelegateTo<RetCC_X86_64_C>
461+ ]>;
462+
463+ def RetCC_X86_64_OxCaml_C_Call_StackArgs : CallingConv<[
458464 CCIfType<[i64], CCAssignToReg<[R14, R15]>>,
459465
460466 CCDelegateTo<RetCC_X86_64_C>
@@ -513,9 +519,14 @@ def RetCC_X86_64 : CallingConv<[
513519 // Mingw64 and native Win64 use Win64 CC
514520 CCIfSubtarget<"isTargetWin64()", CCDelegateTo<RetCC_X86_Win64_C>>,
515521
516- // Handle OCaml calls
517- CCIfCC<"CallingConv::OCaml", CCDelegateTo<RetCC_X86_64_OCaml>>,
518- CCIfCC<"CallingConv::OCaml_C_Call", CCDelegateTo<RetCC_X86_64_OCaml_C_Call>>,
522+ // OxCaml CCs
523+ CCIfCC<"CallingConv::OxCaml", CCDelegateTo<RetCC_X86_64_OxCaml>>,
524+ CCIfCC<"CallingConv::OxCaml_C_Call", CCDelegateTo<RetCC_X86_64_OxCaml_C_Call>>,
525+ CCIfCC<"CallingConv::OxCaml_C_Call_StackArgs",
526+ CCDelegateTo<RetCC_X86_64_OxCaml_C_Call_StackArgs>>,
527+
528+ // See arg CC for OxCaml_Alloc for why we use OxCaml here.
529+ CCIfCC<"CallingConv::OxCaml_Alloc", CCDelegateTo<RetCC_X86_64_OxCaml>>,
519530
520531 // Otherwise, drop to normal X86-64 CC
521532 CCDelegateTo<RetCC_X86_64_C>
@@ -723,7 +734,7 @@ def CC_X86_Win64_VectorCall : CallingConv<[
723734 CCDelegateTo<CC_X86_Win64_C>
724735]>;
725736
726- def CC_X86_64_OCaml : CallingConv<[
737+ def CC_X86_64_OxCaml : CallingConv<[
727738 // Promote i8/i16/i32 arguments to i64.
728739 CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
729740
@@ -741,9 +752,21 @@ def CC_X86_64_OCaml : CallingConv<[
741752 ]>>
742753]>;
743754
744- def CC_X86_64_OCaml_C_Call : CallingConv<[
745- // OCaml wraps C calls with another function that transfers stack arguments.
746- // RAX contains the function address, and R12 contains the size of the stack arguments.
755+ def CC_X86_64_OxCaml_C_Call : CallingConv<[
756+ // Calling conventions followed by [caml_c_call] which wraps non-noalloc C calls.
757+ // RAX contains the function address to call.
758+ CCIfType<[i64], CCAssignToReg<[R14, R15, RAX]>>,
759+
760+ // Follow C convention normally otherwise
761+ CCDelegateTo<CC_X86_64_C>
762+ ]>;
763+
764+ def CC_X86_64_OxCaml_C_Call_StackArgs : CallingConv<[
765+ // Calling conventions followed by [caml_c_call_stack_args] to additionally handle
766+ // transfer of stack arguments. Note that this function normally takes a pair of
767+ // pointers on the stack, but since LLVM makes it hard to directly meddle with the
768+ // stack, this in reality calls yet anothr wrapper which calculates this range given
769+ // the number of stack arguments in bytes in R12.
747770 CCIfType<[i64], CCAssignToReg<[R14, R15, RAX, R12]>>,
748771
749772 // Follow C convention normally otherwise
@@ -1152,8 +1175,18 @@ def CC_X86_64 : CallingConv<[
11521175 CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_RegCall>>>,
11531176 CCIfCC<"CallingConv::X86_RegCall", CCDelegateTo<CC_X86_SysV64_RegCall>>,
11541177 CCIfCC<"CallingConv::X86_INTR", CCCustom<"CC_X86_Intr">>,
1155- CCIfCC<"CallingConv::OCaml", CCDelegateTo<CC_X86_64_OCaml>>,
1156- CCIfCC<"CallingConv::OCaml_C_Call", CCDelegateTo<CC_X86_64_OCaml_C_Call>>,
1178+
1179+ // OxCaml calling conventions
1180+ CCIfCC<"CallingConv::OxCaml", CCDelegateTo<CC_X86_64_OxCaml>>,
1181+ CCIfCC<"CallingConv::OxCaml_C_Call", CCDelegateTo<CC_X86_64_OxCaml_C_Call>>,
1182+ CCIfCC<"CallingConv::OxCaml_C_Call_StackArgs",
1183+ CCDelegateTo<CC_X86_64_OxCaml_C_Call_StackArgs>>,
1184+
1185+ // OxCaml_Alloc follows the same CC as OxCaml, but doesn't pass arguments
1186+ // (or return) in any non-runtime register. So, as long as it is used that way,
1187+ // it is safe for it to follow OxCaml's arg and ret CCs and have a different
1188+ // CSR mask.
1189+ CCIfCC<"CallingConv::OxCaml_Alloc", CCDelegateTo<CC_X86_64_OxCaml>>,
11571190
11581191 // Mingw64 and native Win64 use Win64 CC
11591192 CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,
@@ -1179,9 +1212,6 @@ def CSR_NoRegs : CalleeSavedRegs<(add)>;
11791212def CSR_32 : CalleeSavedRegs<(add ESI, EDI, EBX, EBP)>;
11801213def CSR_64 : CalleeSavedRegs<(add RBX, R12, R13, R14, R15, RBP)>;
11811214
1182- // R14 and R15 are used as return registers, so they aren't callee saved.
1183- def CSR_64_OCaml_C_Call : CalleeSavedRegs<(sub CSR_64, R14, R15)>;
1184-
11851215def CSR_64_SwiftError : CalleeSavedRegs<(sub CSR_64, R12)>;
11861216def CSR_64_SwiftTail : CalleeSavedRegs<(sub CSR_64, R13, R14)>;
11871217
@@ -1281,3 +1311,16 @@ def CSR_SysV64_RegCall_NoSSE : CalleeSavedRegs<(add RBX, RBP,
12811311 (sequence "R%u", 12, 15))>;
12821312def CSR_SysV64_RegCall : CalleeSavedRegs<(add CSR_SysV64_RegCall_NoSSE,
12831313 (sequence "XMM%u", 8, 15))>;
1314+
1315+ // Only FP-enabled OxCaml is supported for now.
1316+ def CSR_64_OxCaml_WithFP : CalleeSavedRegs<(add RBP)>;
1317+
1318+ // R14 and R15 (and also R12 in the latter) are used as return registers,
1319+ // so they aren't callee saved.
1320+ def CSR_64_OxCaml_C_Call : CalleeSavedRegs<(sub CSR_64, R14, R15)>;
1321+ def CSR_64_OxCaml_C_Call_StackArgs : CalleeSavedRegs<(sub CSR_64, R14, R15, R12)>;
1322+
1323+ // See [Proc.destroyed_at_alloc_or_poll] for more details:
1324+ // https://github.com/oxcaml/oxcaml/blob/main/backend/amd64/proc.ml#L457
1325+ // Note that R14 and R15 are also not saved since they are passed as arguments.
1326+ def CSR_64_OxCaml_Alloc : CalleeSavedRegs<(sub CSR_64_AllRegs, R10, R11, R14, R15)>;
0 commit comments