1493cd8c0SSylvestre Ledru /*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
22a8cd89dSGordon Henriksen |*                                                                            *|
32946cd70SChandler Carruth |* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
42946cd70SChandler Carruth |* Exceptions.                                                                *|
52946cd70SChandler Carruth |* See https://llvm.org/LICENSE.txt for license information.                  *|
62946cd70SChandler Carruth |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
72a8cd89dSGordon Henriksen |*                                                                            *|
82a8cd89dSGordon Henriksen |*===----------------------------------------------------------------------===*|
92a8cd89dSGordon Henriksen |*                                                                            *|
10493cd8c0SSylvestre Ledru |* This file glues LLVM's OCaml interface to its C interface. These functions *|
112a8cd89dSGordon Henriksen |* are by and large transparent wrappers to the corresponding C functions.    *|
122a8cd89dSGordon Henriksen |*                                                                            *|
132a8cd89dSGordon Henriksen |* Note that these functions intentionally take liberties with the CAMLparamX *|
142a8cd89dSGordon Henriksen |* macros, since most of the parameters are not GC heap objects.              *|
152a8cd89dSGordon Henriksen |*                                                                            *|
162a8cd89dSGordon Henriksen \*===----------------------------------------------------------------------===*/
172a8cd89dSGordon Henriksen 
18662538acSPeter Zotov #include <string.h>
19662538acSPeter Zotov #include <assert.h>
2052aadc8eSJeroen Ketema #include "llvm-c/Core.h"
212a8cd89dSGordon Henriksen #include "llvm-c/ExecutionEngine.h"
22a1d3e660SBob Wilson #include "llvm-c/Target.h"
232a8cd89dSGordon Henriksen #include "caml/alloc.h"
242a8cd89dSGordon Henriksen #include "caml/custom.h"
252a8cd89dSGordon Henriksen #include "caml/fail.h"
262a8cd89dSGordon Henriksen #include "caml/memory.h"
27662538acSPeter Zotov #include "caml/callback.h"
282a8cd89dSGordon Henriksen 
291b254f9aSPeter Zotov void llvm_raise(value Prototype, char *Message);
302a8cd89dSGordon Henriksen 
31662538acSPeter Zotov /* unit -> bool */
llvm_ee_initialize(value Unit)328e4fc55aSJosh Berdine value llvm_ee_initialize(value Unit) {
33662538acSPeter Zotov   LLVMLinkInMCJIT();
34662538acSPeter Zotov 
35662538acSPeter Zotov   return Val_bool(!LLVMInitializeNativeTarget() &&
36662538acSPeter Zotov                   !LLVMInitializeNativeAsmParser() &&
37662538acSPeter Zotov                   !LLVMInitializeNativeAsmPrinter());
38662538acSPeter Zotov }
39662538acSPeter Zotov 
40d1531a23SPeter Zotov /* llmodule -> llcompileroption -> ExecutionEngine.t */
llvm_ee_create(value OptRecordOpt,LLVMModuleRef M)418e4fc55aSJosh Berdine LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) {
42b1f54ff4SPeter Zotov   value OptRecord;
43d1531a23SPeter Zotov   LLVMExecutionEngineRef MCJIT;
44d1531a23SPeter Zotov   char *Error;
45662538acSPeter Zotov   struct LLVMMCJITCompilerOptions Options;
46662538acSPeter Zotov 
47662538acSPeter Zotov   LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
48b1f54ff4SPeter Zotov   if (OptRecordOpt != Val_int(0)) {
49b1f54ff4SPeter Zotov     OptRecord = Field(OptRecordOpt, 0);
50662538acSPeter Zotov     Options.OptLevel = Int_val(Field(OptRecord, 0));
51662538acSPeter Zotov     Options.CodeModel = Int_val(Field(OptRecord, 1));
52662538acSPeter Zotov     Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));
53662538acSPeter Zotov     Options.EnableFastISel = Int_val(Field(OptRecord, 3));
54662538acSPeter Zotov     Options.MCJMM = NULL;
55b1f54ff4SPeter Zotov   }
56662538acSPeter Zotov 
57*f4d156aeSJosh Berdine   if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options, sizeof(Options),
58*f4d156aeSJosh Berdine                                        &Error))
59662538acSPeter Zotov     llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
60d1531a23SPeter Zotov   return MCJIT;
61d1531a23SPeter Zotov }
62d1531a23SPeter Zotov 
632a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_dispose(LLVMExecutionEngineRef EE)648e4fc55aSJosh Berdine value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
652a8cd89dSGordon Henriksen   LLVMDisposeExecutionEngine(EE);
662a8cd89dSGordon Henriksen   return Val_unit;
672a8cd89dSGordon Henriksen }
682a8cd89dSGordon Henriksen 
6998b05d67SErick Tryzelaar /* llmodule -> ExecutionEngine.t -> unit */
llvm_ee_add_module(LLVMModuleRef M,LLVMExecutionEngineRef EE)708e4fc55aSJosh Berdine value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
7198b05d67SErick Tryzelaar   LLVMAddModule(EE, M);
722a8cd89dSGordon Henriksen   return Val_unit;
732a8cd89dSGordon Henriksen }
742a8cd89dSGordon Henriksen 
7598b05d67SErick Tryzelaar /* llmodule -> ExecutionEngine.t -> llmodule */
llvm_ee_remove_module(LLVMModuleRef M,LLVMExecutionEngineRef EE)768e4fc55aSJosh Berdine value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
772a8cd89dSGordon Henriksen   LLVMModuleRef RemovedModule;
782a8cd89dSGordon Henriksen   char *Error;
7998b05d67SErick Tryzelaar   if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
80662538acSPeter Zotov     llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
81b1f54ff4SPeter Zotov   return Val_unit;
822a8cd89dSGordon Henriksen }
832a8cd89dSGordon Henriksen 
842a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE)858e4fc55aSJosh Berdine value llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE) {
862a8cd89dSGordon Henriksen   LLVMRunStaticConstructors(EE);
872a8cd89dSGordon Henriksen   return Val_unit;
882a8cd89dSGordon Henriksen }
892a8cd89dSGordon Henriksen 
902a8cd89dSGordon Henriksen /* ExecutionEngine.t -> unit */
llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE)918e4fc55aSJosh Berdine value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) {
922a8cd89dSGordon Henriksen   LLVMRunStaticDestructors(EE);
932a8cd89dSGordon Henriksen   return Val_unit;
942a8cd89dSGordon Henriksen }
952a8cd89dSGordon Henriksen 
968a1a3bfcSPeter Zotov extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);
97d52cf175SPeter Zotov 
988a1a3bfcSPeter Zotov /* ExecutionEngine.t -> Llvm_target.DataLayout.t */
llvm_ee_get_data_layout(LLVMExecutionEngineRef EE)998e4fc55aSJosh Berdine value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) {
1008a1a3bfcSPeter Zotov   value DataLayout;
1018a1a3bfcSPeter Zotov   LLVMTargetDataRef OrigDataLayout;
1028a1a3bfcSPeter Zotov   char *TargetDataCStr;
103662538acSPeter Zotov 
104662538acSPeter Zotov   OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
1058a1a3bfcSPeter Zotov   TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
1068a1a3bfcSPeter Zotov   DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
1078a1a3bfcSPeter Zotov   LLVMDisposeMessage(TargetDataCStr);
1088a1a3bfcSPeter Zotov 
1098a1a3bfcSPeter Zotov   return DataLayout;
110d52cf175SPeter Zotov }
111b1f54ff4SPeter Zotov 
112b1f54ff4SPeter Zotov /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
llvm_ee_add_global_mapping(LLVMValueRef Global,value Ptr,LLVMExecutionEngineRef EE)1138e4fc55aSJosh Berdine value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr,
114b1f54ff4SPeter Zotov                                  LLVMExecutionEngineRef EE) {
115b1f54ff4SPeter Zotov   LLVMAddGlobalMapping(EE, Global, (void *)(Int64_val(Ptr)));
116b1f54ff4SPeter Zotov   return Val_unit;
117b1f54ff4SPeter Zotov }
118b1f54ff4SPeter Zotov 
llvm_ee_get_global_value_address(value Name,LLVMExecutionEngineRef EE)119*f4d156aeSJosh Berdine value llvm_ee_get_global_value_address(value Name, LLVMExecutionEngineRef EE) {
120*f4d156aeSJosh Berdine   return caml_copy_int64(
121*f4d156aeSJosh Berdine       (int64_t)LLVMGetGlobalValueAddress(EE, String_val(Name)));
122af6535bfSPeter Zotov }
123af6535bfSPeter Zotov 
llvm_ee_get_function_address(value Name,LLVMExecutionEngineRef EE)124*f4d156aeSJosh Berdine value llvm_ee_get_function_address(value Name, LLVMExecutionEngineRef EE) {
125af6535bfSPeter Zotov   return caml_copy_int64((int64_t)LLVMGetFunctionAddress(EE, String_val(Name)));
126b1f54ff4SPeter Zotov }
127