1 /*===-- llvm_ocaml.c - LLVM OCaml Glue --------------------------*- C++ -*-===*\
2 |*                                                                            *|
3 |* Part of the LLVM Project, under the Apache License v2.0 with LLVM          *|
4 |* Exceptions.                                                                *|
5 |* See https://llvm.org/LICENSE.txt for license information.                  *|
6 |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception                    *|
7 |*                                                                            *|
8 |*===----------------------------------------------------------------------===*|
9 |*                                                                            *|
10 |* This file glues LLVM's OCaml interface to its C interface. These functions *|
11 |* are by and large transparent wrappers to the corresponding C functions.    *|
12 |*                                                                            *|
13 |* Note that these functions intentionally take liberties with the CAMLparamX *|
14 |* macros, since most of the parameters are not GC heap objects.              *|
15 |*                                                                            *|
16 \*===----------------------------------------------------------------------===*/
17 
18 #include <assert.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "llvm-c/Core.h"
22 #include "llvm-c/Support.h"
23 #include "llvm/Config/llvm-config.h"
24 #include "caml/memory.h"
25 #include "caml/fail.h"
26 #include "caml/callback.h"
27 #include "llvm_ocaml.h"
28 
29 #if OCAML_VERSION < 41200
caml_alloc_some(value v)30 value caml_alloc_some(value v) {
31   CAMLparam1(v);
32   value Some = caml_alloc_small(1, 0);
33   Field(Some, 0) = v;
34   CAMLreturn(Some);
35 }
36 #endif
37 
caml_alloc_tuple_uninit(mlsize_t wosize)38 value caml_alloc_tuple_uninit(mlsize_t wosize) {
39   if (wosize <= Max_young_wosize) {
40     return caml_alloc_small(wosize, 0);
41   } else {
42     return caml_alloc_shr(wosize, 0);
43   }
44 }
45 
llvm_string_of_message(char * Message)46 value llvm_string_of_message(char *Message) {
47   value String = caml_copy_string(Message);
48   LLVMDisposeMessage(Message);
49 
50   return String;
51 }
52 
ptr_to_option(void * Ptr)53 value ptr_to_option(void *Ptr) {
54   if (!Ptr)
55     return Val_none;
56   return caml_alloc_some((value)Ptr);
57 }
58 
cstr_to_string(const char * Str,mlsize_t Len)59 value cstr_to_string(const char *Str, mlsize_t Len) {
60   if (!Str)
61     return caml_alloc_string(0);
62   value String = caml_alloc_string(Len);
63   memcpy((char *)String_val(String), Str, Len);
64   return String;
65 }
66 
cstr_to_string_option(const char * CStr,mlsize_t Len)67 value cstr_to_string_option(const char *CStr, mlsize_t Len) {
68   if (!CStr)
69     return Val_none;
70   value String = caml_alloc_string(Len);
71   memcpy((char *)String_val(String), CStr, Len);
72   return caml_alloc_some(String);
73 }
74 
llvm_raise(value Prototype,char * Message)75 void llvm_raise(value Prototype, char *Message) {
76   caml_raise_with_arg(Prototype, llvm_string_of_message(Message));
77 }
78 
79 static value llvm_fatal_error_handler;
80 
llvm_fatal_error_trampoline(const char * Reason)81 static void llvm_fatal_error_trampoline(const char *Reason) {
82   callback(llvm_fatal_error_handler, caml_copy_string(Reason));
83 }
84 
llvm_install_fatal_error_handler(value Handler)85 value llvm_install_fatal_error_handler(value Handler) {
86   LLVMInstallFatalErrorHandler(llvm_fatal_error_trampoline);
87   llvm_fatal_error_handler = Handler;
88   caml_register_global_root(&llvm_fatal_error_handler);
89   return Val_unit;
90 }
91 
llvm_reset_fatal_error_handler(value Unit)92 value llvm_reset_fatal_error_handler(value Unit) {
93   caml_remove_global_root(&llvm_fatal_error_handler);
94   LLVMResetFatalErrorHandler();
95   return Val_unit;
96 }
97 
llvm_enable_pretty_stacktrace(value Unit)98 value llvm_enable_pretty_stacktrace(value Unit) {
99   LLVMEnablePrettyStackTrace();
100   return Val_unit;
101 }
102 
llvm_parse_command_line_options(value Overview,value Args)103 value llvm_parse_command_line_options(value Overview, value Args) {
104   const char *COverview;
105   if (Overview == Val_int(0)) {
106     COverview = NULL;
107   } else {
108     COverview = String_val(Field(Overview, 0));
109   }
110   LLVMParseCommandLineOptions(Wosize_val(Args),
111                               (const char *const *)Op_val(Args), COverview);
112   return Val_unit;
113 }
114 
alloc_variant(int tag,void * Value)115 static value alloc_variant(int tag, void *Value) {
116   value Iter = caml_alloc_small(1, tag);
117   Field(Iter, 0) = Val_op(Value);
118   return Iter;
119 }
120 
121 /* Macro to convert the C first/next/last/prev idiom to the Ocaml llpos/
122    llrev_pos idiom. */
123 #define DEFINE_ITERATORS(camlname, cname, pty, cty, pfun) \
124   /* llmodule -> ('a, 'b) llpos */                        \
125   value llvm_##camlname##_begin(pty Mom) {       \
126     cty First = LLVMGetFirst##cname(Mom);                 \
127     if (First)                                            \
128       return alloc_variant(1, First);                     \
129     return alloc_variant(0, Mom);                         \
130   }                                                       \
131                                                           \
132   /* llvalue -> ('a, 'b) llpos */                         \
133   value llvm_##camlname##_succ(cty Kid) {        \
134     cty Next = LLVMGetNext##cname(Kid);                   \
135     if (Next)                                             \
136       return alloc_variant(1, Next);                      \
137     return alloc_variant(0, pfun(Kid));                   \
138   }                                                       \
139                                                           \
140   /* llmodule -> ('a, 'b) llrev_pos */                    \
141   value llvm_##camlname##_end(pty Mom) {         \
142     cty Last = LLVMGetLast##cname(Mom);                   \
143     if (Last)                                             \
144       return alloc_variant(1, Last);                      \
145     return alloc_variant(0, Mom);                         \
146   }                                                       \
147                                                           \
148   /* llvalue -> ('a, 'b) llrev_pos */                     \
149   value llvm_##camlname##_pred(cty Kid) {        \
150     cty Prev = LLVMGetPrevious##cname(Kid);               \
151     if (Prev)                                             \
152       return alloc_variant(1, Prev);                      \
153     return alloc_variant(0, pfun(Kid));                   \
154   }
155 
156 /*===-- Context error handling --------------------------------------------===*/
157 
llvm_diagnostic_handler_trampoline(LLVMDiagnosticInfoRef DI,void * DiagnosticContext)158 void llvm_diagnostic_handler_trampoline(LLVMDiagnosticInfoRef DI,
159                                         void *DiagnosticContext) {
160   caml_callback(*((value *)DiagnosticContext), (value)DI);
161 }
162 
163 /* Diagnostic.t -> string */
llvm_get_diagnostic_description(value Diagnostic)164 value llvm_get_diagnostic_description(value Diagnostic) {
165   return llvm_string_of_message(
166       LLVMGetDiagInfoDescription((LLVMDiagnosticInfoRef)Diagnostic));
167 }
168 
169 /* Diagnostic.t -> DiagnosticSeverity.t */
llvm_get_diagnostic_severity(value Diagnostic)170 value llvm_get_diagnostic_severity(value Diagnostic) {
171   return Val_int(LLVMGetDiagInfoSeverity((LLVMDiagnosticInfoRef)Diagnostic));
172 }
173 
llvm_remove_diagnostic_handler(LLVMContextRef C)174 static void llvm_remove_diagnostic_handler(LLVMContextRef C) {
175   if (LLVMContextGetDiagnosticHandler(C) ==
176       llvm_diagnostic_handler_trampoline) {
177     value *Handler = (value *)LLVMContextGetDiagnosticContext(C);
178     remove_global_root(Handler);
179     free(Handler);
180   }
181 }
182 
183 /* llcontext -> (Diagnostic.t -> unit) option -> unit */
llvm_set_diagnostic_handler(LLVMContextRef C,value Handler)184 value llvm_set_diagnostic_handler(LLVMContextRef C, value Handler) {
185   llvm_remove_diagnostic_handler(C);
186   if (Handler == Val_none) {
187     LLVMContextSetDiagnosticHandler(C, NULL, NULL);
188   } else {
189     value *DiagnosticContext = malloc(sizeof(value));
190     if (DiagnosticContext == NULL)
191       caml_raise_out_of_memory();
192     caml_register_global_root(DiagnosticContext);
193     *DiagnosticContext = Field(Handler, 0);
194     LLVMContextSetDiagnosticHandler(C, llvm_diagnostic_handler_trampoline,
195                                     DiagnosticContext);
196   }
197   return Val_unit;
198 }
199 
200 /*===-- Contexts ----------------------------------------------------------===*/
201 
202 /* unit -> llcontext */
llvm_create_context(value Unit)203 LLVMContextRef llvm_create_context(value Unit) { return LLVMContextCreate(); }
204 
205 /* llcontext -> unit */
llvm_dispose_context(LLVMContextRef C)206 value llvm_dispose_context(LLVMContextRef C) {
207   llvm_remove_diagnostic_handler(C);
208   LLVMContextDispose(C);
209   return Val_unit;
210 }
211 
212 /* unit -> llcontext */
llvm_global_context(value Unit)213 LLVMContextRef llvm_global_context(value Unit) {
214   return LLVMGetGlobalContext();
215 }
216 
217 /* llcontext -> string -> int */
llvm_mdkind_id(LLVMContextRef C,value Name)218 value llvm_mdkind_id(LLVMContextRef C, value Name) {
219   unsigned MDKindID =
220       LLVMGetMDKindIDInContext(C, String_val(Name), caml_string_length(Name));
221   return Val_int(MDKindID);
222 }
223 
224 /*===-- Attributes --------------------------------------------------------===*/
225 
226 /* string -> llattrkind */
llvm_enum_attr_kind(value Name)227 value llvm_enum_attr_kind(value Name) {
228   unsigned Kind = LLVMGetEnumAttributeKindForName(String_val(Name),
229                                                   caml_string_length(Name));
230   if (Kind == 0)
231     caml_raise_with_arg(*caml_named_value("Llvm.UnknownAttribute"), Name);
232   return Val_int(Kind);
233 }
234 
235 /* llcontext -> int -> int64 -> llattribute */
llvm_create_enum_attr_by_kind(LLVMContextRef C,value Kind,value Value)236 LLVMAttributeRef llvm_create_enum_attr_by_kind(LLVMContextRef C, value Kind,
237                                                value Value) {
238   return LLVMCreateEnumAttribute(C, Int_val(Kind), Int64_val(Value));
239 }
240 
241 /* llattribute -> bool */
llvm_is_enum_attr(LLVMAttributeRef A)242 value llvm_is_enum_attr(LLVMAttributeRef A) {
243   return Val_int(LLVMIsEnumAttribute(A));
244 }
245 
246 /* llattribute -> llattrkind */
llvm_get_enum_attr_kind(LLVMAttributeRef A)247 value llvm_get_enum_attr_kind(LLVMAttributeRef A) {
248   return Val_int(LLVMGetEnumAttributeKind(A));
249 }
250 
251 /* llattribute -> int64 */
llvm_get_enum_attr_value(LLVMAttributeRef A)252 value llvm_get_enum_attr_value(LLVMAttributeRef A) {
253   return caml_copy_int64(LLVMGetEnumAttributeValue(A));
254 }
255 
256 /* llcontext -> kind:string -> name:string -> llattribute */
llvm_create_string_attr(LLVMContextRef C,value Kind,value Value)257 LLVMAttributeRef llvm_create_string_attr(LLVMContextRef C, value Kind,
258                                          value Value) {
259   return LLVMCreateStringAttribute(C, String_val(Kind),
260                                    caml_string_length(Kind), String_val(Value),
261                                    caml_string_length(Value));
262 }
263 
264 /* llattribute -> bool */
llvm_is_string_attr(LLVMAttributeRef A)265 value llvm_is_string_attr(LLVMAttributeRef A) {
266   return Val_int(LLVMIsStringAttribute(A));
267 }
268 
269 /* llattribute -> string */
llvm_get_string_attr_kind(LLVMAttributeRef A)270 value llvm_get_string_attr_kind(LLVMAttributeRef A) {
271   unsigned Length;
272   const char *String = LLVMGetStringAttributeKind(A, &Length);
273   return cstr_to_string(String, Length);
274 }
275 
276 /* llattribute -> string */
llvm_get_string_attr_value(LLVMAttributeRef A)277 value llvm_get_string_attr_value(LLVMAttributeRef A) {
278   unsigned Length;
279   const char *String = LLVMGetStringAttributeValue(A, &Length);
280   return cstr_to_string(String, Length);
281 }
282 
283 /*===-- Modules -----------------------------------------------------------===*/
284 
285 /* llcontext -> string -> llmodule */
llvm_create_module(LLVMContextRef C,value ModuleID)286 LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) {
287   return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C);
288 }
289 
290 /* llmodule -> unit */
llvm_dispose_module(LLVMModuleRef M)291 value llvm_dispose_module(LLVMModuleRef M) {
292   LLVMDisposeModule(M);
293   return Val_unit;
294 }
295 
296 /* llmodule -> string */
llvm_target_triple(LLVMModuleRef M)297 value llvm_target_triple(LLVMModuleRef M) {
298   return caml_copy_string(LLVMGetTarget(M));
299 }
300 
301 /* string -> llmodule -> unit */
llvm_set_target_triple(value Trip,LLVMModuleRef M)302 value llvm_set_target_triple(value Trip, LLVMModuleRef M) {
303   LLVMSetTarget(M, String_val(Trip));
304   return Val_unit;
305 }
306 
307 /* llmodule -> string */
llvm_data_layout(LLVMModuleRef M)308 value llvm_data_layout(LLVMModuleRef M) {
309   return caml_copy_string(LLVMGetDataLayout(M));
310 }
311 
312 /* string -> llmodule -> unit */
llvm_set_data_layout(value Layout,LLVMModuleRef M)313 value llvm_set_data_layout(value Layout, LLVMModuleRef M) {
314   LLVMSetDataLayout(M, String_val(Layout));
315   return Val_unit;
316 }
317 
318 /* llmodule -> unit */
llvm_dump_module(LLVMModuleRef M)319 value llvm_dump_module(LLVMModuleRef M) {
320   LLVMDumpModule(M);
321   return Val_unit;
322 }
323 
324 /* string -> llmodule -> unit */
llvm_print_module(value Filename,LLVMModuleRef M)325 value llvm_print_module(value Filename, LLVMModuleRef M) {
326   char *Message;
327 
328   if (LLVMPrintModuleToFile(M, String_val(Filename), &Message))
329     llvm_raise(*caml_named_value("Llvm.IoError"), Message);
330 
331   return Val_unit;
332 }
333 
334 /* llmodule -> string */
llvm_string_of_llmodule(LLVMModuleRef M)335 value llvm_string_of_llmodule(LLVMModuleRef M) {
336   char *ModuleCStr = LLVMPrintModuleToString(M);
337   value ModuleStr = caml_copy_string(ModuleCStr);
338   LLVMDisposeMessage(ModuleCStr);
339 
340   return ModuleStr;
341 }
342 
343 /* llmodule -> string */
llvm_get_module_identifier(LLVMModuleRef M)344 value llvm_get_module_identifier(LLVMModuleRef M) {
345   size_t Len;
346   const char *Name = LLVMGetModuleIdentifier(M, &Len);
347   return cstr_to_string(Name, (mlsize_t)Len);
348 }
349 
350 /* llmodule -> string -> unit */
llvm_set_module_identifier(LLVMModuleRef M,value Id)351 value llvm_set_module_identifier(LLVMModuleRef M, value Id) {
352   LLVMSetModuleIdentifier(M, String_val(Id), caml_string_length(Id));
353   return Val_unit;
354 }
355 
356 /* llmodule -> string -> unit */
llvm_set_module_inline_asm(LLVMModuleRef M,value Asm)357 value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
358   LLVMSetModuleInlineAsm(M, String_val(Asm));
359   return Val_unit;
360 }
361 
362 /* llmodule -> string -> llmetadata option */
llvm_get_module_flag(LLVMModuleRef M,value Key)363 value llvm_get_module_flag(LLVMModuleRef M, value Key) {
364   return ptr_to_option(
365       LLVMGetModuleFlag(M, String_val(Key), caml_string_length(Key)));
366 }
367 
llvm_add_module_flag(LLVMModuleRef M,LLVMModuleFlagBehavior Behaviour,value Key,LLVMMetadataRef Val)368 value llvm_add_module_flag(LLVMModuleRef M, LLVMModuleFlagBehavior Behaviour,
369                            value Key, LLVMMetadataRef Val) {
370   LLVMAddModuleFlag(M, Int_val(Behaviour), String_val(Key),
371                     caml_string_length(Key), Val);
372   return Val_unit;
373 }
374 
375 /*===-- Types -------------------------------------------------------------===*/
376 
377 /* lltype -> TypeKind.t */
llvm_classify_type(LLVMTypeRef Ty)378 value llvm_classify_type(LLVMTypeRef Ty) {
379   return Val_int(LLVMGetTypeKind(Ty));
380 }
381 
llvm_type_is_sized(LLVMTypeRef Ty)382 value llvm_type_is_sized(LLVMTypeRef Ty) {
383   return Val_bool(LLVMTypeIsSized(Ty));
384 }
385 
386 /* lltype -> llcontext */
llvm_type_context(LLVMTypeRef Ty)387 LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
388   return LLVMGetTypeContext(Ty);
389 }
390 
391 /* lltype -> unit */
llvm_dump_type(LLVMTypeRef Val)392 value llvm_dump_type(LLVMTypeRef Val) {
393 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
394   LLVMDumpType(Val);
395 #else
396   caml_raise_with_arg(*caml_named_value("Llvm.FeatureDisabled"),
397                       caml_copy_string("dump"));
398 #endif
399   return Val_unit;
400 }
401 
402 /* lltype -> string */
llvm_string_of_lltype(LLVMTypeRef M)403 value llvm_string_of_lltype(LLVMTypeRef M) {
404   char *TypeCStr = LLVMPrintTypeToString(M);
405   value TypeStr = caml_copy_string(TypeCStr);
406   LLVMDisposeMessage(TypeCStr);
407 
408   return TypeStr;
409 }
410 
411 /*--... Operations on integer types ........................................--*/
412 
413 /* llcontext -> lltype */
llvm_i1_type(LLVMContextRef Context)414 LLVMTypeRef llvm_i1_type(LLVMContextRef Context) {
415   return LLVMInt1TypeInContext(Context);
416 }
417 
418 /* llcontext -> lltype */
llvm_i8_type(LLVMContextRef Context)419 LLVMTypeRef llvm_i8_type(LLVMContextRef Context) {
420   return LLVMInt8TypeInContext(Context);
421 }
422 
423 /* llcontext -> lltype */
llvm_i16_type(LLVMContextRef Context)424 LLVMTypeRef llvm_i16_type(LLVMContextRef Context) {
425   return LLVMInt16TypeInContext(Context);
426 }
427 
428 /* llcontext -> lltype */
llvm_i32_type(LLVMContextRef Context)429 LLVMTypeRef llvm_i32_type(LLVMContextRef Context) {
430   return LLVMInt32TypeInContext(Context);
431 }
432 
433 /* llcontext -> lltype */
llvm_i64_type(LLVMContextRef Context)434 LLVMTypeRef llvm_i64_type(LLVMContextRef Context) {
435   return LLVMInt64TypeInContext(Context);
436 }
437 
438 /* llcontext -> int -> lltype */
llvm_integer_type(LLVMContextRef Context,value Width)439 LLVMTypeRef llvm_integer_type(LLVMContextRef Context, value Width) {
440   return LLVMIntTypeInContext(Context, Int_val(Width));
441 }
442 
443 /* lltype -> int */
llvm_integer_bitwidth(LLVMTypeRef IntegerTy)444 value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) {
445   return Val_int(LLVMGetIntTypeWidth(IntegerTy));
446 }
447 
448 /*--... Operations on real types ...........................................--*/
449 
450 /* llcontext -> lltype */
llvm_float_type(LLVMContextRef Context)451 LLVMTypeRef llvm_float_type(LLVMContextRef Context) {
452   return LLVMFloatTypeInContext(Context);
453 }
454 
455 /* llcontext -> lltype */
llvm_double_type(LLVMContextRef Context)456 LLVMTypeRef llvm_double_type(LLVMContextRef Context) {
457   return LLVMDoubleTypeInContext(Context);
458 }
459 
460 /* llcontext -> lltype */
llvm_x86fp80_type(LLVMContextRef Context)461 LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) {
462   return LLVMX86FP80TypeInContext(Context);
463 }
464 
465 /* llcontext -> lltype */
llvm_fp128_type(LLVMContextRef Context)466 LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) {
467   return LLVMFP128TypeInContext(Context);
468 }
469 
470 /* llcontext -> lltype */
llvm_ppc_fp128_type(LLVMContextRef Context)471 LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) {
472   return LLVMPPCFP128TypeInContext(Context);
473 }
474 
475 /*--... Operations on function types .......................................--*/
476 
477 /* lltype -> lltype array -> lltype */
llvm_function_type(LLVMTypeRef RetTy,value ParamTys)478 LLVMTypeRef llvm_function_type(LLVMTypeRef RetTy, value ParamTys) {
479   return LLVMFunctionType(RetTy, (LLVMTypeRef *)ParamTys, Wosize_val(ParamTys),
480                           0);
481 }
482 
483 /* lltype -> lltype array -> lltype */
llvm_var_arg_function_type(LLVMTypeRef RetTy,value ParamTys)484 LLVMTypeRef llvm_var_arg_function_type(LLVMTypeRef RetTy, value ParamTys) {
485   return LLVMFunctionType(RetTy, (LLVMTypeRef *)ParamTys, Wosize_val(ParamTys),
486                           1);
487 }
488 
489 /* lltype -> bool */
llvm_is_var_arg(LLVMTypeRef FunTy)490 value llvm_is_var_arg(LLVMTypeRef FunTy) {
491   return Val_bool(LLVMIsFunctionVarArg(FunTy));
492 }
493 
494 /* lltype -> lltype array */
llvm_param_types(LLVMTypeRef FunTy)495 value llvm_param_types(LLVMTypeRef FunTy) {
496   value Tys = caml_alloc_tuple_uninit(LLVMCountParamTypes(FunTy));
497   LLVMGetParamTypes(FunTy, (LLVMTypeRef *)Op_val(Tys));
498   return Tys;
499 }
500 
501 /*--... Operations on struct types .........................................--*/
502 
503 /* llcontext -> lltype array -> lltype */
llvm_struct_type(LLVMContextRef C,value ElementTypes)504 LLVMTypeRef llvm_struct_type(LLVMContextRef C, value ElementTypes) {
505   return LLVMStructTypeInContext(C, (LLVMTypeRef *)ElementTypes,
506                                  Wosize_val(ElementTypes), 0);
507 }
508 
509 /* llcontext -> lltype array -> lltype */
llvm_packed_struct_type(LLVMContextRef C,value ElementTypes)510 LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C, value ElementTypes) {
511   return LLVMStructTypeInContext(C, (LLVMTypeRef *)ElementTypes,
512                                  Wosize_val(ElementTypes), 1);
513 }
514 
515 /* llcontext -> string -> lltype */
llvm_named_struct_type(LLVMContextRef C,value Name)516 LLVMTypeRef llvm_named_struct_type(LLVMContextRef C, value Name) {
517   return LLVMStructCreateNamed(C, String_val(Name));
518 }
519 
llvm_struct_set_body(LLVMTypeRef Ty,value ElementTypes,value Packed)520 value llvm_struct_set_body(LLVMTypeRef Ty, value ElementTypes, value Packed) {
521   LLVMStructSetBody(Ty, (LLVMTypeRef *)ElementTypes, Wosize_val(ElementTypes),
522                     Bool_val(Packed));
523   return Val_unit;
524 }
525 
526 /* lltype -> string option */
llvm_struct_name(LLVMTypeRef Ty)527 value llvm_struct_name(LLVMTypeRef Ty) {
528   const char *CStr = LLVMGetStructName(Ty);
529   size_t Len;
530   if (!CStr)
531     return Val_none;
532   Len = strlen(CStr);
533   return cstr_to_string_option(CStr, Len);
534 }
535 
536 /* lltype -> lltype array */
llvm_struct_element_types(LLVMTypeRef StructTy)537 value llvm_struct_element_types(LLVMTypeRef StructTy) {
538   value Tys = caml_alloc_tuple_uninit(LLVMCountStructElementTypes(StructTy));
539   LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *)Op_val(Tys));
540   return Tys;
541 }
542 
543 /* lltype -> bool */
llvm_is_packed(LLVMTypeRef StructTy)544 value llvm_is_packed(LLVMTypeRef StructTy) {
545   return Val_bool(LLVMIsPackedStruct(StructTy));
546 }
547 
548 /* lltype -> bool */
llvm_is_opaque(LLVMTypeRef StructTy)549 value llvm_is_opaque(LLVMTypeRef StructTy) {
550   return Val_bool(LLVMIsOpaqueStruct(StructTy));
551 }
552 
553 /* lltype -> bool */
llvm_is_literal(LLVMTypeRef StructTy)554 value llvm_is_literal(LLVMTypeRef StructTy) {
555   return Val_bool(LLVMIsLiteralStruct(StructTy));
556 }
557 
558 /*--... Operations on array, pointer, and vector types .....................--*/
559 
560 /* lltype -> lltype array */
llvm_subtypes(LLVMTypeRef Ty)561 value llvm_subtypes(LLVMTypeRef Ty) {
562   unsigned Size = LLVMGetNumContainedTypes(Ty);
563   value Arr = caml_alloc_tuple_uninit(Size);
564   LLVMGetSubtypes(Ty, (LLVMTypeRef *)Op_val(Arr));
565   return Arr;
566 }
567 
568 /* lltype -> int -> lltype */
llvm_array_type(LLVMTypeRef ElementTy,value Count)569 LLVMTypeRef llvm_array_type(LLVMTypeRef ElementTy, value Count) {
570   return LLVMArrayType(ElementTy, Int_val(Count));
571 }
572 
573 /* lltype -> lltype */
llvm_pointer_type(LLVMTypeRef ElementTy)574 LLVMTypeRef llvm_pointer_type(LLVMTypeRef ElementTy) {
575   return LLVMPointerType(ElementTy, 0);
576 }
577 
578 /* lltype -> int -> lltype */
llvm_qualified_pointer_type(LLVMTypeRef ElementTy,value AddressSpace)579 LLVMTypeRef llvm_qualified_pointer_type(LLVMTypeRef ElementTy,
580                                         value AddressSpace) {
581   return LLVMPointerType(ElementTy, Int_val(AddressSpace));
582 }
583 
584 /* lltype -> int -> lltype */
llvm_vector_type(LLVMTypeRef ElementTy,value Count)585 LLVMTypeRef llvm_vector_type(LLVMTypeRef ElementTy, value Count) {
586   return LLVMVectorType(ElementTy, Int_val(Count));
587 }
588 
589 /* lltype -> int */
llvm_array_length(LLVMTypeRef ArrayTy)590 value llvm_array_length(LLVMTypeRef ArrayTy) {
591   return Val_int(LLVMGetArrayLength(ArrayTy));
592 }
593 
594 /* lltype -> int */
llvm_address_space(LLVMTypeRef PtrTy)595 value llvm_address_space(LLVMTypeRef PtrTy) {
596   return Val_int(LLVMGetPointerAddressSpace(PtrTy));
597 }
598 
599 /* lltype -> int */
llvm_vector_size(LLVMTypeRef VectorTy)600 value llvm_vector_size(LLVMTypeRef VectorTy) {
601   return Val_int(LLVMGetVectorSize(VectorTy));
602 }
603 
604 /*--... Operations on other types ..........................................--*/
605 
606 /* llcontext -> lltype */
llvm_void_type(LLVMContextRef Context)607 LLVMTypeRef llvm_void_type(LLVMContextRef Context) {
608   return LLVMVoidTypeInContext(Context);
609 }
610 
611 /* llcontext -> lltype */
llvm_label_type(LLVMContextRef Context)612 LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
613   return LLVMLabelTypeInContext(Context);
614 }
615 
616 /* llcontext -> lltype */
llvm_x86_mmx_type(LLVMContextRef Context)617 LLVMTypeRef llvm_x86_mmx_type(LLVMContextRef Context) {
618   return LLVMX86MMXTypeInContext(Context);
619 }
620 
llvm_type_by_name(LLVMModuleRef M,value Name)621 value llvm_type_by_name(LLVMModuleRef M, value Name) {
622   return ptr_to_option(LLVMGetTypeByName(M, String_val(Name)));
623 }
624 
625 /*===-- VALUES ------------------------------------------------------------===*/
626 
627 /* llvalue -> lltype */
llvm_type_of(LLVMValueRef Val)628 LLVMTypeRef llvm_type_of(LLVMValueRef Val) { return LLVMTypeOf(Val); }
629 
630 /* keep in sync with ValueKind.t */
631 enum ValueKind {
632   NullValue = 0,
633   Argument,
634   BasicBlock,
635   InlineAsm,
636   MDNode,
637   MDString,
638   BlockAddress,
639   ConstantAggregateZero,
640   ConstantArray,
641   ConstantDataArray,
642   ConstantDataVector,
643   ConstantExpr,
644   ConstantFP,
645   ConstantInt,
646   ConstantPointerNull,
647   ConstantStruct,
648   ConstantVector,
649   Function,
650   GlobalAlias,
651   GlobalIFunc,
652   GlobalVariable,
653   UndefValue,
654   PoisonValue,
655   Instruction
656 };
657 
658 /* llvalue -> ValueKind.t */
659 #define DEFINE_CASE(Val, Kind) \
660     do {if (LLVMIsA##Kind(Val)) return Val_int(Kind);} while(0)
661 
llvm_classify_value(LLVMValueRef Val)662 value llvm_classify_value(LLVMValueRef Val) {
663   if (!Val)
664     return Val_int(NullValue);
665   if (LLVMIsAConstant(Val)) {
666     DEFINE_CASE(Val, BlockAddress);
667     DEFINE_CASE(Val, ConstantAggregateZero);
668     DEFINE_CASE(Val, ConstantArray);
669     DEFINE_CASE(Val, ConstantDataArray);
670     DEFINE_CASE(Val, ConstantDataVector);
671     DEFINE_CASE(Val, ConstantExpr);
672     DEFINE_CASE(Val, ConstantFP);
673     DEFINE_CASE(Val, ConstantInt);
674     DEFINE_CASE(Val, ConstantPointerNull);
675     DEFINE_CASE(Val, ConstantStruct);
676     DEFINE_CASE(Val, ConstantVector);
677   }
678   if (LLVMIsAInstruction(Val)) {
679     value result = caml_alloc_small(1, 0);
680     Field(result, 0) = Val_int(LLVMGetInstructionOpcode(Val));
681     return result;
682   }
683   if (LLVMIsAGlobalValue(Val)) {
684     DEFINE_CASE(Val, Function);
685     DEFINE_CASE(Val, GlobalAlias);
686     DEFINE_CASE(Val, GlobalIFunc);
687     DEFINE_CASE(Val, GlobalVariable);
688   }
689   DEFINE_CASE(Val, Argument);
690   DEFINE_CASE(Val, BasicBlock);
691   DEFINE_CASE(Val, InlineAsm);
692   DEFINE_CASE(Val, MDNode);
693   DEFINE_CASE(Val, MDString);
694   DEFINE_CASE(Val, UndefValue);
695   DEFINE_CASE(Val, PoisonValue);
696   failwith("Unknown Value class");
697 }
698 
699 /* llvalue -> string */
llvm_value_name(LLVMValueRef Val)700 value llvm_value_name(LLVMValueRef Val) {
701   return caml_copy_string(LLVMGetValueName(Val));
702 }
703 
704 /* string -> llvalue -> unit */
llvm_set_value_name(value Name,LLVMValueRef Val)705 value llvm_set_value_name(value Name, LLVMValueRef Val) {
706   LLVMSetValueName(Val, String_val(Name));
707   return Val_unit;
708 }
709 
710 /* llvalue -> unit */
llvm_dump_value(LLVMValueRef Val)711 value llvm_dump_value(LLVMValueRef Val) {
712   LLVMDumpValue(Val);
713   return Val_unit;
714 }
715 
716 /* llvalue -> string */
llvm_string_of_llvalue(LLVMValueRef M)717 value llvm_string_of_llvalue(LLVMValueRef M) {
718   char *ValueCStr = LLVMPrintValueToString(M);
719   value ValueStr = caml_copy_string(ValueCStr);
720   LLVMDisposeMessage(ValueCStr);
721 
722   return ValueStr;
723 }
724 
725 /* llvalue -> llvalue -> unit */
llvm_replace_all_uses_with(LLVMValueRef OldVal,LLVMValueRef NewVal)726 value llvm_replace_all_uses_with(LLVMValueRef OldVal, LLVMValueRef NewVal) {
727   LLVMReplaceAllUsesWith(OldVal, NewVal);
728   return Val_unit;
729 }
730 
731 /*--... Operations on users ................................................--*/
732 
733 /* llvalue -> int -> llvalue */
llvm_operand(LLVMValueRef V,value I)734 LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
735   return LLVMGetOperand(V, Int_val(I));
736 }
737 
738 /* llvalue -> int -> lluse */
llvm_operand_use(LLVMValueRef V,value I)739 LLVMUseRef llvm_operand_use(LLVMValueRef V, value I) {
740   return LLVMGetOperandUse(V, Int_val(I));
741 }
742 
743 /* llvalue -> int -> llvalue -> unit */
llvm_set_operand(LLVMValueRef U,value I,LLVMValueRef V)744 value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) {
745   LLVMSetOperand(U, Int_val(I), V);
746   return Val_unit;
747 }
748 
749 /* llvalue -> int */
llvm_num_operands(LLVMValueRef V)750 value llvm_num_operands(LLVMValueRef V) {
751   return Val_int(LLVMGetNumOperands(V));
752 }
753 
754 /* llvalue -> int array */
llvm_indices(LLVMValueRef Instr)755 value llvm_indices(LLVMValueRef Instr) {
756   unsigned n = LLVMGetNumIndices(Instr);
757   const unsigned *Indices = LLVMGetIndices(Instr);
758   value indices = caml_alloc_tuple_uninit(n);
759   for (unsigned i = 0; i < n; i++) {
760     Op_val(indices)[i] = Val_int(Indices[i]);
761   }
762   return indices;
763 }
764 
765 /*--... Operations on constants of (mostly) any type .......................--*/
766 
767 /* llvalue -> bool */
llvm_is_constant(LLVMValueRef Val)768 value llvm_is_constant(LLVMValueRef Val) {
769   return Val_bool(LLVMIsConstant(Val));
770 }
771 
772 /* llvalue -> bool */
llvm_is_null(LLVMValueRef Val)773 value llvm_is_null(LLVMValueRef Val) { return Val_bool(LLVMIsNull(Val)); }
774 
775 /* llvalue -> bool */
llvm_is_undef(LLVMValueRef Val)776 value llvm_is_undef(LLVMValueRef Val) { return Val_bool(LLVMIsUndef(Val)); }
777 
778 /* llvalue -> bool */
llvm_is_poison(LLVMValueRef Val)779 value llvm_is_poison(LLVMValueRef Val) { return Val_bool(LLVMIsPoison(Val)); }
780 
781 /* llvalue -> Opcode.t */
llvm_constexpr_get_opcode(LLVMValueRef Val)782 value llvm_constexpr_get_opcode(LLVMValueRef Val) {
783   return LLVMIsAConstantExpr(Val) ? Val_int(LLVMGetConstOpcode(Val))
784                                   : Val_int(0);
785 }
786 
787 /*--... Operations on instructions .........................................--*/
788 
789 /* llvalue -> bool */
llvm_has_metadata(LLVMValueRef Val)790 value llvm_has_metadata(LLVMValueRef Val) {
791   return Val_bool(LLVMHasMetadata(Val));
792 }
793 
794 /* llvalue -> int -> llvalue option */
llvm_metadata(LLVMValueRef Val,value MDKindID)795 value llvm_metadata(LLVMValueRef Val, value MDKindID) {
796   return ptr_to_option(LLVMGetMetadata(Val, Int_val(MDKindID)));
797 }
798 
799 /* llvalue -> int -> llvalue -> unit */
llvm_set_metadata(LLVMValueRef Val,value MDKindID,LLVMValueRef MD)800 value llvm_set_metadata(LLVMValueRef Val, value MDKindID, LLVMValueRef MD) {
801   LLVMSetMetadata(Val, Int_val(MDKindID), MD);
802   return Val_unit;
803 }
804 
805 /* llvalue -> int -> unit */
llvm_clear_metadata(LLVMValueRef Val,value MDKindID)806 value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) {
807   LLVMSetMetadata(Val, Int_val(MDKindID), NULL);
808   return Val_unit;
809 }
810 
811 /*--... Operations on metadata .............................................--*/
812 
813 /* llcontext -> string -> llvalue */
llvm_mdstring(LLVMContextRef C,value S)814 LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) {
815   return LLVMMDStringInContext(C, String_val(S), caml_string_length(S));
816 }
817 
818 /* llcontext -> llvalue array -> llvalue */
llvm_mdnode(LLVMContextRef C,value ElementVals)819 LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
820   return LLVMMDNodeInContext(C, (LLVMValueRef *)Op_val(ElementVals),
821                              Wosize_val(ElementVals));
822 }
823 
824 /* llcontext -> llvalue */
llvm_mdnull(LLVMContextRef C)825 LLVMValueRef llvm_mdnull(LLVMContextRef C) { return NULL; }
826 
827 /* llvalue -> string option */
llvm_get_mdstring(LLVMValueRef V)828 value llvm_get_mdstring(LLVMValueRef V) {
829   unsigned Len;
830   const char *CStr = LLVMGetMDString(V, &Len);
831   return cstr_to_string_option(CStr, Len);
832 }
833 
llvm_get_mdnode_operands(LLVMValueRef V)834 value llvm_get_mdnode_operands(LLVMValueRef V) {
835   unsigned int n = LLVMGetMDNodeNumOperands(V);
836   value Operands = caml_alloc_tuple_uninit(n);
837   LLVMGetMDNodeOperands(V, (LLVMValueRef *)Op_val(Operands));
838   return Operands;
839 }
840 
841 /* llmodule -> string -> llvalue array */
llvm_get_namedmd(LLVMModuleRef M,value Name)842 value llvm_get_namedmd(LLVMModuleRef M, value Name) {
843   CAMLparam1(Name);
844   value Nodes = caml_alloc_tuple_uninit(
845       LLVMGetNamedMetadataNumOperands(M, String_val(Name)));
846   LLVMGetNamedMetadataOperands(M, String_val(Name),
847                                (LLVMValueRef *)Op_val(Nodes));
848   CAMLreturn(Nodes);
849 }
850 
851 /* llmodule -> string -> llvalue -> unit */
llvm_append_namedmd(LLVMModuleRef M,value Name,LLVMValueRef Val)852 value llvm_append_namedmd(LLVMModuleRef M, value Name, LLVMValueRef Val) {
853   LLVMAddNamedMetadataOperand(M, String_val(Name), Val);
854   return Val_unit;
855 }
856 
857 /* llvalue -> llmetadata */
llvm_value_as_metadata(LLVMValueRef Val)858 LLVMMetadataRef llvm_value_as_metadata(LLVMValueRef Val) {
859   return LLVMValueAsMetadata(Val);
860 }
861 
862 /* llcontext -> llmetadata -> llvalue */
llvm_metadata_as_value(LLVMContextRef C,LLVMMetadataRef MD)863 LLVMValueRef llvm_metadata_as_value(LLVMContextRef C, LLVMMetadataRef MD) {
864   return LLVMMetadataAsValue(C, MD);
865 }
866 
867 /*--... Operations on scalar constants .....................................--*/
868 
869 /* lltype -> int -> llvalue */
llvm_const_int(LLVMTypeRef IntTy,value N)870 LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
871   return LLVMConstInt(IntTy, (long long)Long_val(N), 1);
872 }
873 
874 /* lltype -> Int64.t -> bool -> llvalue */
llvm_const_of_int64(LLVMTypeRef IntTy,value N,value SExt)875 LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N, value SExt) {
876   return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt));
877 }
878 
879 /* llvalue -> Int64.t */
llvm_int64_of_const(LLVMValueRef Const)880 value llvm_int64_of_const(LLVMValueRef Const) {
881   if (!(LLVMIsAConstantInt(Const)) ||
882       !(LLVMGetIntTypeWidth(LLVMTypeOf(Const)) <= 64))
883     return Val_none;
884   return caml_alloc_some(caml_copy_int64(LLVMConstIntGetSExtValue(Const)));
885 }
886 
887 /* lltype -> string -> int -> llvalue */
llvm_const_int_of_string(LLVMTypeRef IntTy,value S,value Radix)888 LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S, value Radix) {
889   return LLVMConstIntOfStringAndSize(IntTy, String_val(S),
890                                      caml_string_length(S), Int_val(Radix));
891 }
892 
893 /* lltype -> float -> llvalue */
llvm_const_float(LLVMTypeRef RealTy,value N)894 LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) {
895   return LLVMConstReal(RealTy, Double_val(N));
896 }
897 
898 /* llvalue -> float */
llvm_float_of_const(LLVMValueRef Const)899 value llvm_float_of_const(LLVMValueRef Const) {
900   LLVMBool LosesInfo;
901   double Result;
902   if (!LLVMIsAConstantFP(Const))
903     return Val_none;
904   Result = LLVMConstRealGetDouble(Const, &LosesInfo);
905   if (LosesInfo)
906     return Val_none;
907   return caml_alloc_some(caml_copy_double(Result));
908 }
909 
910 /* lltype -> string -> llvalue */
llvm_const_float_of_string(LLVMTypeRef RealTy,value S)911 LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
912   return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
913                                       caml_string_length(S));
914 }
915 
916 /*--... Operations on composite constants ..................................--*/
917 
918 /* llcontext -> string -> llvalue */
llvm_const_string(LLVMContextRef Context,value Str,value NullTerminate)919 LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str,
920                                value NullTerminate) {
921   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
922                                   1);
923 }
924 
925 /* llcontext -> string -> llvalue */
llvm_const_stringz(LLVMContextRef Context,value Str,value NullTerminate)926 LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str,
927                                 value NullTerminate) {
928   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
929                                   0);
930 }
931 
932 /* lltype -> llvalue array -> llvalue */
llvm_const_array(LLVMTypeRef ElementTy,value ElementVals)933 LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy, value ElementVals) {
934   return LLVMConstArray(ElementTy, (LLVMValueRef *)Op_val(ElementVals),
935                         Wosize_val(ElementVals));
936 }
937 
938 /* llcontext -> llvalue array -> llvalue */
llvm_const_struct(LLVMContextRef C,value ElementVals)939 LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
940   return LLVMConstStructInContext(C, (LLVMValueRef *)Op_val(ElementVals),
941                                   Wosize_val(ElementVals), 0);
942 }
943 
944 /* lltype -> llvalue array -> llvalue */
llvm_const_named_struct(LLVMTypeRef Ty,value ElementVals)945 LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) {
946   return LLVMConstNamedStruct(Ty, (LLVMValueRef *)Op_val(ElementVals),
947                               Wosize_val(ElementVals));
948 }
949 
950 /* llcontext -> llvalue array -> llvalue */
llvm_const_packed_struct(LLVMContextRef C,value ElementVals)951 LLVMValueRef llvm_const_packed_struct(LLVMContextRef C, value ElementVals) {
952   return LLVMConstStructInContext(C, (LLVMValueRef *)Op_val(ElementVals),
953                                   Wosize_val(ElementVals), 1);
954 }
955 
956 /* llvalue array -> llvalue */
llvm_const_vector(value ElementVals)957 LLVMValueRef llvm_const_vector(value ElementVals) {
958   return LLVMConstVector((LLVMValueRef *)Op_val(ElementVals),
959                          Wosize_val(ElementVals));
960 }
961 
962 /* llvalue -> string option */
llvm_string_of_const(LLVMValueRef Const)963 value llvm_string_of_const(LLVMValueRef Const) {
964   size_t Len;
965   const char *CStr;
966   if (!LLVMIsAConstantDataSequential(Const) || !LLVMIsConstantString(Const))
967     return Val_none;
968   CStr = LLVMGetAsString(Const, &Len);
969   return cstr_to_string_option(CStr, Len);
970 }
971 
972 /* llvalue -> int -> llvalue */
llvm_const_element(LLVMValueRef Const,value N)973 LLVMValueRef llvm_const_element(LLVMValueRef Const, value N) {
974   return LLVMGetElementAsConstant(Const, Int_val(N));
975 }
976 
977 /*--... Constant expressions ...............................................--*/
978 
979 /* Icmp.t -> llvalue -> llvalue -> llvalue */
llvm_const_icmp(value Pred,LLVMValueRef LHSConstant,LLVMValueRef RHSConstant)980 LLVMValueRef llvm_const_icmp(value Pred, LLVMValueRef LHSConstant,
981                              LLVMValueRef RHSConstant) {
982   return LLVMConstICmp(Int_val(Pred) + LLVMIntEQ, LHSConstant, RHSConstant);
983 }
984 
985 /* Fcmp.t -> llvalue -> llvalue -> llvalue */
llvm_const_fcmp(value Pred,LLVMValueRef LHSConstant,LLVMValueRef RHSConstant)986 LLVMValueRef llvm_const_fcmp(value Pred, LLVMValueRef LHSConstant,
987                              LLVMValueRef RHSConstant) {
988   return LLVMConstFCmp(Int_val(Pred), LHSConstant, RHSConstant);
989 }
990 
991 /* llvalue -> llvalue array -> llvalue */
llvm_const_gep(LLVMValueRef ConstantVal,value Indices)992 LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) {
993   return LLVMConstGEP(ConstantVal, (LLVMValueRef *)Op_val(Indices),
994                       Wosize_val(Indices));
995 }
996 
997 /* lltype -> llvalue -> llvalue array -> llvalue */
llvm_const_gep2(LLVMTypeRef Ty,LLVMValueRef ConstantVal,value Indices)998 LLVMValueRef llvm_const_gep2(LLVMTypeRef Ty, LLVMValueRef ConstantVal,
999                             value Indices) {
1000   return LLVMConstGEP2(Ty, ConstantVal, (LLVMValueRef *)Op_val(Indices),
1001                        Wosize_val(Indices));
1002 }
1003 
1004 /* llvalue -> llvalue array -> llvalue */
llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,value Indices)1005 LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal, value Indices) {
1006   return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef *)Op_val(Indices),
1007                               Wosize_val(Indices));
1008 }
1009 
1010 /* llvalue -> lltype -> is_signed:bool -> llvalue */
llvm_const_intcast(LLVMValueRef CV,LLVMTypeRef T,value IsSigned)1011 LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T,
1012                                 value IsSigned) {
1013   return LLVMConstIntCast(CV, T, Bool_val(IsSigned));
1014 }
1015 
1016 /* lltype -> string -> string -> bool -> bool -> llvalue */
llvm_const_inline_asm(LLVMTypeRef Ty,value Asm,value Constraints,value HasSideEffects,value IsAlignStack)1017 LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm, value Constraints,
1018                                    value HasSideEffects, value IsAlignStack) {
1019   return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
1020                             Bool_val(HasSideEffects), Bool_val(IsAlignStack));
1021 }
1022 
1023 /*--... Operations on global variables, functions, and aliases (globals) ...--*/
1024 
1025 /* llvalue -> bool */
llvm_is_declaration(LLVMValueRef Global)1026 value llvm_is_declaration(LLVMValueRef Global) {
1027   return Val_bool(LLVMIsDeclaration(Global));
1028 }
1029 
1030 /* llvalue -> Linkage.t */
llvm_linkage(LLVMValueRef Global)1031 value llvm_linkage(LLVMValueRef Global) {
1032   return Val_int(LLVMGetLinkage(Global));
1033 }
1034 
1035 /* Linkage.t -> llvalue -> unit */
llvm_set_linkage(value Linkage,LLVMValueRef Global)1036 value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
1037   LLVMSetLinkage(Global, Int_val(Linkage));
1038   return Val_unit;
1039 }
1040 
1041 /* llvalue -> bool */
llvm_unnamed_addr(LLVMValueRef Global)1042 value llvm_unnamed_addr(LLVMValueRef Global) {
1043   return Val_bool(LLVMHasUnnamedAddr(Global));
1044 }
1045 
1046 /* bool -> llvalue -> unit */
llvm_set_unnamed_addr(value UseUnnamedAddr,LLVMValueRef Global)1047 value llvm_set_unnamed_addr(value UseUnnamedAddr, LLVMValueRef Global) {
1048   LLVMSetUnnamedAddr(Global, Bool_val(UseUnnamedAddr));
1049   return Val_unit;
1050 }
1051 
1052 /* llvalue -> string */
llvm_section(LLVMValueRef Global)1053 value llvm_section(LLVMValueRef Global) {
1054   return caml_copy_string(LLVMGetSection(Global));
1055 }
1056 
1057 /* string -> llvalue -> unit */
llvm_set_section(value Section,LLVMValueRef Global)1058 value llvm_set_section(value Section, LLVMValueRef Global) {
1059   LLVMSetSection(Global, String_val(Section));
1060   return Val_unit;
1061 }
1062 
1063 /* llvalue -> Visibility.t */
llvm_visibility(LLVMValueRef Global)1064 value llvm_visibility(LLVMValueRef Global) {
1065   return Val_int(LLVMGetVisibility(Global));
1066 }
1067 
1068 /* Visibility.t -> llvalue -> unit */
llvm_set_visibility(value Viz,LLVMValueRef Global)1069 value llvm_set_visibility(value Viz, LLVMValueRef Global) {
1070   LLVMSetVisibility(Global, Int_val(Viz));
1071   return Val_unit;
1072 }
1073 
1074 /* llvalue -> DLLStorageClass.t */
llvm_dll_storage_class(LLVMValueRef Global)1075 value llvm_dll_storage_class(LLVMValueRef Global) {
1076   return Val_int(LLVMGetDLLStorageClass(Global));
1077 }
1078 
1079 /* DLLStorageClass.t -> llvalue -> unit */
llvm_set_dll_storage_class(value Viz,LLVMValueRef Global)1080 value llvm_set_dll_storage_class(value Viz, LLVMValueRef Global) {
1081   LLVMSetDLLStorageClass(Global, Int_val(Viz));
1082   return Val_unit;
1083 }
1084 
1085 /* llvalue -> int */
llvm_alignment(LLVMValueRef Global)1086 value llvm_alignment(LLVMValueRef Global) {
1087   return Val_int(LLVMGetAlignment(Global));
1088 }
1089 
1090 /* int -> llvalue -> unit */
llvm_set_alignment(value Bytes,LLVMValueRef Global)1091 value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
1092   LLVMSetAlignment(Global, Int_val(Bytes));
1093   return Val_unit;
1094 }
1095 
1096 /* llvalue -> (llmdkind * llmetadata) array */
llvm_global_copy_all_metadata(LLVMValueRef Global)1097 value llvm_global_copy_all_metadata(LLVMValueRef Global) {
1098   CAMLparam0();
1099   CAMLlocal1(Array);
1100   size_t NumEntries;
1101   LLVMValueMetadataEntry *Entries =
1102       LLVMGlobalCopyAllMetadata(Global, &NumEntries);
1103   Array = caml_alloc_tuple(NumEntries);
1104   for (int i = 0; i < NumEntries; i++) {
1105     value Pair = caml_alloc_small(2, 0);
1106     Field(Pair, 0) = Val_int(LLVMValueMetadataEntriesGetKind(Entries, i));
1107     Field(Pair, 1) = (value)LLVMValueMetadataEntriesGetMetadata(Entries, i);
1108     Store_field(Array, i, Pair);
1109   }
1110   LLVMDisposeValueMetadataEntries(Entries);
1111   CAMLreturn(Array);
1112 }
1113 
1114 /*--... Operations on uses .................................................--*/
1115 
1116 /* llvalue -> lluse option */
llvm_use_begin(LLVMValueRef Val)1117 value llvm_use_begin(LLVMValueRef Val) {
1118   return ptr_to_option(LLVMGetFirstUse(Val));
1119 }
1120 
1121 /* lluse -> lluse option */
llvm_use_succ(LLVMUseRef U)1122 value llvm_use_succ(LLVMUseRef U) { return ptr_to_option(LLVMGetNextUse(U)); }
1123 
1124 /* lluse -> llvalue */
llvm_user(LLVMUseRef UR)1125 LLVMValueRef llvm_user(LLVMUseRef UR) { return LLVMGetUser(UR); }
1126 
1127 /* lluse -> llvalue */
llvm_used_value(LLVMUseRef UR)1128 LLVMValueRef llvm_used_value(LLVMUseRef UR) { return LLVMGetUsedValue(UR); }
1129 
1130 /*--... Operations on global variables .....................................--*/
1131 
DEFINE_ITERATORS(global,Global,LLVMModuleRef,LLVMValueRef,LLVMGetGlobalParent)1132 DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
1133                  LLVMGetGlobalParent)
1134 
1135 /* lltype -> string -> llmodule -> llvalue */
1136 LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name, LLVMModuleRef M) {
1137   LLVMValueRef GlobalVar;
1138   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
1139     if (LLVMGlobalGetValueType(GlobalVar) != Ty)
1140       return LLVMConstBitCast(GlobalVar, LLVMPointerType(Ty, 0));
1141     return GlobalVar;
1142   }
1143   return LLVMAddGlobal(M, Ty, String_val(Name));
1144 }
1145 
1146 /* lltype -> string -> int -> llmodule -> llvalue */
llvm_declare_qualified_global(LLVMTypeRef Ty,value Name,value AddressSpace,LLVMModuleRef M)1147 LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
1148                                            value AddressSpace,
1149                                            LLVMModuleRef M) {
1150   LLVMValueRef GlobalVar;
1151   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
1152     if (LLVMGlobalGetValueType(GlobalVar) != Ty)
1153       return LLVMConstBitCast(GlobalVar,
1154                               LLVMPointerType(Ty, Int_val(AddressSpace)));
1155     return GlobalVar;
1156   }
1157   return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name),
1158                                      Int_val(AddressSpace));
1159 }
1160 
1161 /* string -> llmodule -> llvalue option */
llvm_lookup_global(value Name,LLVMModuleRef M)1162 value llvm_lookup_global(value Name, LLVMModuleRef M) {
1163   return ptr_to_option(LLVMGetNamedGlobal(M, String_val(Name)));
1164 }
1165 
1166 /* string -> llvalue -> llmodule -> llvalue */
llvm_define_global(value Name,LLVMValueRef Initializer,LLVMModuleRef M)1167 LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
1168                                 LLVMModuleRef M) {
1169   LLVMValueRef GlobalVar =
1170       LLVMAddGlobal(M, LLVMTypeOf(Initializer), String_val(Name));
1171   LLVMSetInitializer(GlobalVar, Initializer);
1172   return GlobalVar;
1173 }
1174 
1175 /* string -> llvalue -> int -> llmodule -> llvalue */
llvm_define_qualified_global(value Name,LLVMValueRef Initializer,value AddressSpace,LLVMModuleRef M)1176 LLVMValueRef llvm_define_qualified_global(value Name, LLVMValueRef Initializer,
1177                                           value AddressSpace, LLVMModuleRef M) {
1178   LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(
1179       M, LLVMTypeOf(Initializer), String_val(Name), Int_val(AddressSpace));
1180   LLVMSetInitializer(GlobalVar, Initializer);
1181   return GlobalVar;
1182 }
1183 
1184 /* llvalue -> unit */
llvm_delete_global(LLVMValueRef GlobalVar)1185 value llvm_delete_global(LLVMValueRef GlobalVar) {
1186   LLVMDeleteGlobal(GlobalVar);
1187   return Val_unit;
1188 }
1189 
1190 /* llvalue -> llvalue option */
llvm_global_initializer(LLVMValueRef GlobalVar)1191 value llvm_global_initializer(LLVMValueRef GlobalVar) {
1192   return ptr_to_option(LLVMGetInitializer(GlobalVar));
1193 }
1194 
1195 /* llvalue -> llvalue -> unit */
llvm_set_initializer(LLVMValueRef ConstantVal,LLVMValueRef GlobalVar)1196 value llvm_set_initializer(LLVMValueRef ConstantVal, LLVMValueRef GlobalVar) {
1197   LLVMSetInitializer(GlobalVar, ConstantVal);
1198   return Val_unit;
1199 }
1200 
1201 /* llvalue -> unit */
llvm_remove_initializer(LLVMValueRef GlobalVar)1202 value llvm_remove_initializer(LLVMValueRef GlobalVar) {
1203   LLVMSetInitializer(GlobalVar, NULL);
1204   return Val_unit;
1205 }
1206 
1207 /* llvalue -> bool */
llvm_is_thread_local(LLVMValueRef GlobalVar)1208 value llvm_is_thread_local(LLVMValueRef GlobalVar) {
1209   return Val_bool(LLVMIsThreadLocal(GlobalVar));
1210 }
1211 
1212 /* bool -> llvalue -> unit */
llvm_set_thread_local(value IsThreadLocal,LLVMValueRef GlobalVar)1213 value llvm_set_thread_local(value IsThreadLocal, LLVMValueRef GlobalVar) {
1214   LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
1215   return Val_unit;
1216 }
1217 
1218 /* llvalue -> ThreadLocalMode.t */
llvm_thread_local_mode(LLVMValueRef GlobalVar)1219 value llvm_thread_local_mode(LLVMValueRef GlobalVar) {
1220   return Val_int(LLVMGetThreadLocalMode(GlobalVar));
1221 }
1222 
1223 /* ThreadLocalMode.t -> llvalue -> unit */
llvm_set_thread_local_mode(value ThreadLocalMode,LLVMValueRef GlobalVar)1224 value llvm_set_thread_local_mode(value ThreadLocalMode,
1225                                  LLVMValueRef GlobalVar) {
1226   LLVMSetThreadLocalMode(GlobalVar, Int_val(ThreadLocalMode));
1227   return Val_unit;
1228 }
1229 
1230 /* llvalue -> bool */
llvm_is_externally_initialized(LLVMValueRef GlobalVar)1231 value llvm_is_externally_initialized(LLVMValueRef GlobalVar) {
1232   return Val_bool(LLVMIsExternallyInitialized(GlobalVar));
1233 }
1234 
1235 /* bool -> llvalue -> unit */
llvm_set_externally_initialized(value IsExternallyInitialized,LLVMValueRef GlobalVar)1236 value llvm_set_externally_initialized(value IsExternallyInitialized,
1237                                       LLVMValueRef GlobalVar) {
1238   LLVMSetExternallyInitialized(GlobalVar, Bool_val(IsExternallyInitialized));
1239   return Val_unit;
1240 }
1241 
1242 /* llvalue -> bool */
llvm_is_global_constant(LLVMValueRef GlobalVar)1243 value llvm_is_global_constant(LLVMValueRef GlobalVar) {
1244   return Val_bool(LLVMIsGlobalConstant(GlobalVar));
1245 }
1246 
1247 /* bool -> llvalue -> unit */
llvm_set_global_constant(value Flag,LLVMValueRef GlobalVar)1248 value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
1249   LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
1250   return Val_unit;
1251 }
1252 
1253 /*--... Operations on aliases ..............................................--*/
1254 
llvm_add_alias(LLVMModuleRef M,LLVMTypeRef Ty,LLVMValueRef Aliasee,value Name)1255 LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
1256                             LLVMValueRef Aliasee, value Name) {
1257   return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
1258 }
1259 
llvm_add_alias2(LLVMModuleRef M,LLVMTypeRef ValueTy,value AddrSpace,LLVMValueRef Aliasee,value Name)1260 LLVMValueRef llvm_add_alias2(LLVMModuleRef M, LLVMTypeRef ValueTy,
1261                             value AddrSpace, LLVMValueRef Aliasee, value Name) {
1262   return LLVMAddAlias2(M, ValueTy, Int_val(AddrSpace), Aliasee,
1263                        String_val(Name));
1264 }
1265 
1266 /*--... Operations on functions ............................................--*/
1267 
DEFINE_ITERATORS(function,Function,LLVMModuleRef,LLVMValueRef,LLVMGetGlobalParent)1268 DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
1269                  LLVMGetGlobalParent)
1270 
1271 /* string -> lltype -> llmodule -> llvalue */
1272 LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
1273                                    LLVMModuleRef M) {
1274   LLVMValueRef Fn;
1275   if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
1276     if (LLVMGlobalGetValueType(Fn) != Ty)
1277       return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
1278     return Fn;
1279   }
1280   return LLVMAddFunction(M, String_val(Name), Ty);
1281 }
1282 
1283 /* string -> llmodule -> llvalue option */
llvm_lookup_function(value Name,LLVMModuleRef M)1284 value llvm_lookup_function(value Name, LLVMModuleRef M) {
1285   return ptr_to_option(LLVMGetNamedFunction(M, String_val(Name)));
1286 }
1287 
1288 /* string -> lltype -> llmodule -> llvalue */
llvm_define_function(value Name,LLVMTypeRef Ty,LLVMModuleRef M)1289 LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty, LLVMModuleRef M) {
1290   LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
1291   LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
1292   return Fn;
1293 }
1294 
1295 /* llvalue -> unit */
llvm_delete_function(LLVMValueRef Fn)1296 value llvm_delete_function(LLVMValueRef Fn) {
1297   LLVMDeleteFunction(Fn);
1298   return Val_unit;
1299 }
1300 
1301 /* llvalue -> bool */
llvm_is_intrinsic(LLVMValueRef Fn)1302 value llvm_is_intrinsic(LLVMValueRef Fn) {
1303   return Val_bool(LLVMGetIntrinsicID(Fn));
1304 }
1305 
1306 /* llvalue -> int */
llvm_function_call_conv(LLVMValueRef Fn)1307 value llvm_function_call_conv(LLVMValueRef Fn) {
1308   return Val_int(LLVMGetFunctionCallConv(Fn));
1309 }
1310 
1311 /* int -> llvalue -> unit */
llvm_set_function_call_conv(value Id,LLVMValueRef Fn)1312 value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
1313   LLVMSetFunctionCallConv(Fn, Int_val(Id));
1314   return Val_unit;
1315 }
1316 
1317 /* llvalue -> string option */
llvm_gc(LLVMValueRef Fn)1318 value llvm_gc(LLVMValueRef Fn) {
1319   const char *GC = LLVMGetGC(Fn);
1320   if (!GC)
1321     return Val_none;
1322   return caml_alloc_some(caml_copy_string(GC));
1323 }
1324 
1325 /* string option -> llvalue -> unit */
llvm_set_gc(value GC,LLVMValueRef Fn)1326 value llvm_set_gc(value GC, LLVMValueRef Fn) {
1327   LLVMSetGC(Fn, GC == Val_none ? 0 : String_val(Field(GC, 0)));
1328   return Val_unit;
1329 }
1330 
1331 /* llvalue -> llattribute -> int -> unit */
llvm_add_function_attr(LLVMValueRef F,LLVMAttributeRef A,value Index)1332 value llvm_add_function_attr(LLVMValueRef F, LLVMAttributeRef A, value Index) {
1333   LLVMAddAttributeAtIndex(F, Int_val(Index), A);
1334   return Val_unit;
1335 }
1336 
1337 /* llvalue -> int -> llattribute array */
llvm_function_attrs(LLVMValueRef F,value Index)1338 value llvm_function_attrs(LLVMValueRef F, value Index) {
1339   unsigned Length = LLVMGetAttributeCountAtIndex(F, Int_val(Index));
1340   value Array = caml_alloc_tuple_uninit(Length);
1341   LLVMGetAttributesAtIndex(F, Int_val(Index),
1342                            (LLVMAttributeRef *)Op_val(Array));
1343   return Array;
1344 }
1345 
1346 /* llvalue -> llattrkind -> int -> unit */
llvm_remove_enum_function_attr(LLVMValueRef F,value Kind,value Index)1347 value llvm_remove_enum_function_attr(LLVMValueRef F, value Kind, value Index) {
1348   LLVMRemoveEnumAttributeAtIndex(F, Int_val(Index), Int_val(Kind));
1349   return Val_unit;
1350 }
1351 
1352 /* llvalue -> string -> int -> unit */
llvm_remove_string_function_attr(LLVMValueRef F,value Kind,value Index)1353 value llvm_remove_string_function_attr(LLVMValueRef F, value Kind,
1354                                        value Index) {
1355   LLVMRemoveStringAttributeAtIndex(F, Int_val(Index), String_val(Kind),
1356                                    caml_string_length(Kind));
1357   return Val_unit;
1358 }
1359 
1360 /*--... Operations on parameters ...........................................--*/
1361 
DEFINE_ITERATORS(param,Param,LLVMValueRef,LLVMValueRef,LLVMGetParamParent)1362 DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
1363 
1364 /* llvalue -> int -> llvalue */
1365 LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
1366   return LLVMGetParam(Fn, Int_val(Index));
1367 }
1368 
1369 /* llvalue -> llvalue */
llvm_params(LLVMValueRef Fn)1370 value llvm_params(LLVMValueRef Fn) {
1371   value Params = caml_alloc_tuple_uninit(LLVMCountParams(Fn));
1372   LLVMGetParams(Fn, (LLVMValueRef *)Op_val(Params));
1373   return Params;
1374 }
1375 
1376 /*--... Operations on basic blocks .........................................--*/
1377 
DEFINE_ITERATORS(block,BasicBlock,LLVMValueRef,LLVMBasicBlockRef,LLVMGetBasicBlockParent)1378 DEFINE_ITERATORS(block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef,
1379                  LLVMGetBasicBlockParent)
1380 
1381 /* llbasicblock -> llvalue option */
1382 value llvm_block_terminator(LLVMBasicBlockRef Block) {
1383   return ptr_to_option(LLVMGetBasicBlockTerminator(Block));
1384 }
1385 
1386 /* llvalue -> llbasicblock array */
llvm_basic_blocks(LLVMValueRef Fn)1387 value llvm_basic_blocks(LLVMValueRef Fn) {
1388   value MLArray = caml_alloc_tuple_uninit(LLVMCountBasicBlocks(Fn));
1389   LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *)Op_val(MLArray));
1390   return MLArray;
1391 }
1392 
1393 /* llbasicblock -> unit */
llvm_delete_block(LLVMBasicBlockRef BB)1394 value llvm_delete_block(LLVMBasicBlockRef BB) {
1395   LLVMDeleteBasicBlock(BB);
1396   return Val_unit;
1397 }
1398 
1399 /* llbasicblock -> unit */
llvm_remove_block(LLVMBasicBlockRef BB)1400 value llvm_remove_block(LLVMBasicBlockRef BB) {
1401   LLVMRemoveBasicBlockFromParent(BB);
1402   return Val_unit;
1403 }
1404 
1405 /* llbasicblock -> llbasicblock -> unit */
llvm_move_block_before(LLVMBasicBlockRef Pos,LLVMBasicBlockRef BB)1406 value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
1407   LLVMMoveBasicBlockBefore(BB, Pos);
1408   return Val_unit;
1409 }
1410 
1411 /* llbasicblock -> llbasicblock -> unit */
llvm_move_block_after(LLVMBasicBlockRef Pos,LLVMBasicBlockRef BB)1412 value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
1413   LLVMMoveBasicBlockAfter(BB, Pos);
1414   return Val_unit;
1415 }
1416 
1417 /* string -> llvalue -> llbasicblock */
llvm_append_block(LLVMContextRef Context,value Name,LLVMValueRef Fn)1418 LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
1419                                     LLVMValueRef Fn) {
1420   return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
1421 }
1422 
1423 /* string -> llbasicblock -> llbasicblock */
llvm_insert_block(LLVMContextRef Context,value Name,LLVMBasicBlockRef BB)1424 LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
1425                                     LLVMBasicBlockRef BB) {
1426   return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
1427 }
1428 
1429 /* llvalue -> bool */
llvm_value_is_block(LLVMValueRef Val)1430 value llvm_value_is_block(LLVMValueRef Val) {
1431   return Val_bool(LLVMValueIsBasicBlock(Val));
1432 }
1433 
1434 /*--... Operations on instructions .........................................--*/
1435 
DEFINE_ITERATORS(instr,Instruction,LLVMBasicBlockRef,LLVMValueRef,LLVMGetInstructionParent)1436 DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
1437                  LLVMGetInstructionParent)
1438 
1439 /* llvalue -> Opcode.t */
1440 value llvm_instr_get_opcode(LLVMValueRef Inst) {
1441   LLVMOpcode o;
1442   if (!LLVMIsAInstruction(Inst))
1443     failwith("Not an instruction");
1444   o = LLVMGetInstructionOpcode(Inst);
1445   assert(o <= LLVMFreeze);
1446   return Val_int(o);
1447 }
1448 
1449 /* llvalue -> ICmp.t option */
llvm_instr_icmp_predicate(LLVMValueRef Val)1450 value llvm_instr_icmp_predicate(LLVMValueRef Val) {
1451   int x = LLVMGetICmpPredicate(Val);
1452   if (!x)
1453     return Val_none;
1454   return caml_alloc_some(Val_int(x - LLVMIntEQ));
1455 }
1456 
1457 /* llvalue -> FCmp.t option */
llvm_instr_fcmp_predicate(LLVMValueRef Val)1458 value llvm_instr_fcmp_predicate(LLVMValueRef Val) {
1459   int x = LLVMGetFCmpPredicate(Val);
1460   if (!x)
1461     return Val_none;
1462   return caml_alloc_some(Val_int(x - LLVMRealPredicateFalse));
1463 }
1464 
1465 /* llvalue -> llvalue */
llvm_instr_clone(LLVMValueRef Inst)1466 LLVMValueRef llvm_instr_clone(LLVMValueRef Inst) {
1467   if (!LLVMIsAInstruction(Inst))
1468     failwith("Not an instruction");
1469   return LLVMInstructionClone(Inst);
1470 }
1471 
1472 /*--... Operations on call sites ...........................................--*/
1473 
1474 /* llvalue -> int */
llvm_instruction_call_conv(LLVMValueRef Inst)1475 value llvm_instruction_call_conv(LLVMValueRef Inst) {
1476   return Val_int(LLVMGetInstructionCallConv(Inst));
1477 }
1478 
1479 /* int -> llvalue -> unit */
llvm_set_instruction_call_conv(value CC,LLVMValueRef Inst)1480 value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
1481   LLVMSetInstructionCallConv(Inst, Int_val(CC));
1482   return Val_unit;
1483 }
1484 
1485 /* llvalue -> llattribute -> int -> unit */
llvm_add_call_site_attr(LLVMValueRef F,LLVMAttributeRef A,value Index)1486 value llvm_add_call_site_attr(LLVMValueRef F, LLVMAttributeRef A, value Index) {
1487   LLVMAddCallSiteAttribute(F, Int_val(Index), A);
1488   return Val_unit;
1489 }
1490 
1491 /* llvalue -> int -> llattribute array */
llvm_call_site_attrs(LLVMValueRef F,value Index)1492 value llvm_call_site_attrs(LLVMValueRef F, value Index) {
1493   unsigned Count = LLVMGetCallSiteAttributeCount(F, Int_val(Index));
1494   value Array = caml_alloc_tuple_uninit(Count);
1495   LLVMGetCallSiteAttributes(F, Int_val(Index),
1496                             (LLVMAttributeRef *)Op_val(Array));
1497   return Array;
1498 }
1499 
1500 /* llvalue -> llattrkind -> int -> unit */
llvm_remove_enum_call_site_attr(LLVMValueRef F,value Kind,value Index)1501 value llvm_remove_enum_call_site_attr(LLVMValueRef F, value Kind, value Index) {
1502   LLVMRemoveCallSiteEnumAttribute(F, Int_val(Index), Int_val(Kind));
1503   return Val_unit;
1504 }
1505 
1506 /* llvalue -> string -> int -> unit */
llvm_remove_string_call_site_attr(LLVMValueRef F,value Kind,value Index)1507 value llvm_remove_string_call_site_attr(LLVMValueRef F, value Kind,
1508                                         value Index) {
1509   LLVMRemoveCallSiteStringAttribute(F, Int_val(Index), String_val(Kind),
1510                                     caml_string_length(Kind));
1511   return Val_unit;
1512 }
1513 
1514 /*--... Operations on call instructions (only) .............................--*/
1515 
1516 /* llvalue -> int */
llvm_num_arg_operands(LLVMValueRef V)1517 value llvm_num_arg_operands(LLVMValueRef V) {
1518   return Val_int(LLVMGetNumArgOperands(V));
1519 }
1520 
1521 /* llvalue -> bool */
llvm_is_tail_call(LLVMValueRef CallInst)1522 value llvm_is_tail_call(LLVMValueRef CallInst) {
1523   return Val_bool(LLVMIsTailCall(CallInst));
1524 }
1525 
1526 /* bool -> llvalue -> unit */
llvm_set_tail_call(value IsTailCall,LLVMValueRef CallInst)1527 value llvm_set_tail_call(value IsTailCall, LLVMValueRef CallInst) {
1528   LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
1529   return Val_unit;
1530 }
1531 
1532 /*--... Operations on load/store instructions (only)........................--*/
1533 
1534 /* llvalue -> bool */
llvm_is_volatile(LLVMValueRef MemoryInst)1535 value llvm_is_volatile(LLVMValueRef MemoryInst) {
1536   return Val_bool(LLVMGetVolatile(MemoryInst));
1537 }
1538 
1539 /* bool -> llvalue -> unit */
llvm_set_volatile(value IsVolatile,LLVMValueRef MemoryInst)1540 value llvm_set_volatile(value IsVolatile, LLVMValueRef MemoryInst) {
1541   LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile));
1542   return Val_unit;
1543 }
1544 
1545 /*--.. Operations on terminators ...........................................--*/
1546 
1547 /* llvalue -> int -> llbasicblock */
llvm_successor(LLVMValueRef V,value I)1548 LLVMBasicBlockRef llvm_successor(LLVMValueRef V, value I) {
1549   return LLVMGetSuccessor(V, Int_val(I));
1550 }
1551 
1552 /* llvalue -> int -> llvalue -> unit */
llvm_set_successor(LLVMValueRef U,value I,LLVMBasicBlockRef B)1553 value llvm_set_successor(LLVMValueRef U, value I, LLVMBasicBlockRef B) {
1554   LLVMSetSuccessor(U, Int_val(I), B);
1555   return Val_unit;
1556 }
1557 
1558 /* llvalue -> int */
llvm_num_successors(LLVMValueRef V)1559 value llvm_num_successors(LLVMValueRef V) {
1560   return Val_int(LLVMGetNumSuccessors(V));
1561 }
1562 
1563 /*--.. Operations on branch ................................................--*/
1564 
1565 /* llvalue -> llvalue */
llvm_condition(LLVMValueRef V)1566 LLVMValueRef llvm_condition(LLVMValueRef V) { return LLVMGetCondition(V); }
1567 
1568 /* llvalue -> llvalue -> unit */
llvm_set_condition(LLVMValueRef B,LLVMValueRef C)1569 value llvm_set_condition(LLVMValueRef B, LLVMValueRef C) {
1570   LLVMSetCondition(B, C);
1571   return Val_unit;
1572 }
1573 
1574 /* llvalue -> bool */
llvm_is_conditional(LLVMValueRef V)1575 value llvm_is_conditional(LLVMValueRef V) {
1576   return Val_bool(LLVMIsConditional(V));
1577 }
1578 
1579 /*--... Operations on phi nodes ............................................--*/
1580 
1581 /* (llvalue * llbasicblock) -> llvalue -> unit */
llvm_add_incoming(value Incoming,LLVMValueRef PhiNode)1582 value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
1583   LLVMAddIncoming(PhiNode, (LLVMValueRef *)&Field(Incoming, 0),
1584                   (LLVMBasicBlockRef *)&Field(Incoming, 1), 1);
1585   return Val_unit;
1586 }
1587 
1588 /* llvalue -> (llvalue * llbasicblock) list */
llvm_incoming(LLVMValueRef PhiNode)1589 value llvm_incoming(LLVMValueRef PhiNode) {
1590   unsigned I;
1591   CAMLparam0();
1592   CAMLlocal2(Hd, Tl);
1593 
1594   /* Build a tuple list of them. */
1595   Tl = Val_int(0);
1596   for (I = LLVMCountIncoming(PhiNode); I != 0;) {
1597     Hd = caml_alloc_small(2, 0);
1598     Field(Hd, 0) = (value)LLVMGetIncomingValue(PhiNode, --I);
1599     Field(Hd, 1) = (value)LLVMGetIncomingBlock(PhiNode, I);
1600 
1601     value Tmp = caml_alloc_small(2, 0);
1602     Field(Tmp, 0) = Hd;
1603     Field(Tmp, 1) = Tl;
1604     Tl = Tmp;
1605   }
1606 
1607   CAMLreturn(Tl);
1608 }
1609 
1610 /* llvalue -> unit */
llvm_delete_instruction(LLVMValueRef Instruction)1611 value llvm_delete_instruction(LLVMValueRef Instruction) {
1612   LLVMInstructionEraseFromParent(Instruction);
1613   return Val_unit;
1614 }
1615 
1616 /*===-- Instruction builders ----------------------------------------------===*/
1617 
1618 #define Builder_val(v) (*(LLVMBuilderRef *)(Data_custom_val(v)))
1619 
llvm_finalize_builder(value B)1620 static void llvm_finalize_builder(value B) {
1621   LLVMDisposeBuilder(Builder_val(B));
1622 }
1623 
1624 static struct custom_operations builder_ops = {
1625     (char *)"Llvm.llbuilder",  llvm_finalize_builder,
1626     custom_compare_default,    custom_hash_default,
1627     custom_serialize_default,  custom_deserialize_default,
1628     custom_compare_ext_default};
1629 
alloc_builder(LLVMBuilderRef B)1630 static value alloc_builder(LLVMBuilderRef B) {
1631   value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
1632   Builder_val(V) = B;
1633   return V;
1634 }
1635 
1636 /* llcontext -> llbuilder */
llvm_builder(LLVMContextRef C)1637 value llvm_builder(LLVMContextRef C) {
1638   return alloc_builder(LLVMCreateBuilderInContext(C));
1639 }
1640 
1641 /* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
llvm_position_builder(value Pos,value B)1642 value llvm_position_builder(value Pos, value B) {
1643   if (Tag_val(Pos) == 0) {
1644     LLVMBasicBlockRef BB = (LLVMBasicBlockRef)Op_val(Field(Pos, 0));
1645     LLVMPositionBuilderAtEnd(Builder_val(B), BB);
1646   } else {
1647     LLVMValueRef I = (LLVMValueRef)Op_val(Field(Pos, 0));
1648     LLVMPositionBuilderBefore(Builder_val(B), I);
1649   }
1650   return Val_unit;
1651 }
1652 
1653 /* llbuilder -> llbasicblock */
llvm_insertion_block(value B)1654 LLVMBasicBlockRef llvm_insertion_block(value B) {
1655   LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
1656   if (!InsertBlock)
1657     caml_raise_not_found();
1658   return InsertBlock;
1659 }
1660 
1661 /* llvalue -> string -> llbuilder -> unit */
llvm_insert_into_builder(LLVMValueRef I,value Name,value B)1662 value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
1663   LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
1664   return Val_unit;
1665 }
1666 
1667 /*--... Metadata ...........................................................--*/
1668 
1669 /* llbuilder -> llvalue -> unit */
llvm_set_current_debug_location(value B,LLVMValueRef V)1670 value llvm_set_current_debug_location(value B, LLVMValueRef V) {
1671   LLVMSetCurrentDebugLocation(Builder_val(B), V);
1672   return Val_unit;
1673 }
1674 
1675 /* llbuilder -> unit */
llvm_clear_current_debug_location(value B)1676 value llvm_clear_current_debug_location(value B) {
1677   LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
1678   return Val_unit;
1679 }
1680 
1681 /* llbuilder -> llvalue option */
llvm_current_debug_location(value B)1682 value llvm_current_debug_location(value B) {
1683   return ptr_to_option(LLVMGetCurrentDebugLocation(Builder_val(B)));
1684 }
1685 
1686 /* llbuilder -> llvalue -> unit */
llvm_set_inst_debug_location(value B,LLVMValueRef V)1687 value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
1688   LLVMSetInstDebugLocation(Builder_val(B), V);
1689   return Val_unit;
1690 }
1691 
1692 /*--... Terminators ........................................................--*/
1693 
1694 /* llbuilder -> llvalue */
llvm_build_ret_void(value B)1695 LLVMValueRef llvm_build_ret_void(value B) {
1696   return LLVMBuildRetVoid(Builder_val(B));
1697 }
1698 
1699 /* llvalue -> llbuilder -> llvalue */
llvm_build_ret(LLVMValueRef Val,value B)1700 LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
1701   return LLVMBuildRet(Builder_val(B), Val);
1702 }
1703 
1704 /* llvalue array -> llbuilder -> llvalue */
llvm_build_aggregate_ret(value RetVals,value B)1705 LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
1706   return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *)Op_val(RetVals),
1707                                Wosize_val(RetVals));
1708 }
1709 
1710 /* llbasicblock -> llbuilder -> llvalue */
llvm_build_br(LLVMBasicBlockRef BB,value B)1711 LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
1712   return LLVMBuildBr(Builder_val(B), BB);
1713 }
1714 
1715 /* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
llvm_build_cond_br(LLVMValueRef If,LLVMBasicBlockRef Then,LLVMBasicBlockRef Else,value B)1716 LLVMValueRef llvm_build_cond_br(LLVMValueRef If, LLVMBasicBlockRef Then,
1717                                 LLVMBasicBlockRef Else, value B) {
1718   return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
1719 }
1720 
1721 /* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
llvm_build_switch(LLVMValueRef Of,LLVMBasicBlockRef Else,value EstimatedCount,value B)1722 LLVMValueRef llvm_build_switch(LLVMValueRef Of, LLVMBasicBlockRef Else,
1723                                value EstimatedCount, value B) {
1724   return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
1725 }
1726 
1727 /* lltype -> string -> llbuilder -> llvalue */
llvm_build_malloc(LLVMTypeRef Ty,value Name,value B)1728 LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name, value B) {
1729   return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
1730 }
1731 
1732 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_array_malloc(LLVMTypeRef Ty,LLVMValueRef Val,value Name,value B)1733 LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty, LLVMValueRef Val,
1734                                      value Name, value B) {
1735   return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
1736 }
1737 
1738 /* llvalue -> llbuilder -> llvalue */
llvm_build_free(LLVMValueRef P,value B)1739 LLVMValueRef llvm_build_free(LLVMValueRef P, value B) {
1740   return LLVMBuildFree(Builder_val(B), P);
1741 }
1742 
1743 /* llvalue -> llvalue -> llbasicblock -> unit */
llvm_add_case(LLVMValueRef Switch,LLVMValueRef OnVal,LLVMBasicBlockRef Dest)1744 value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
1745                     LLVMBasicBlockRef Dest) {
1746   LLVMAddCase(Switch, OnVal, Dest);
1747   return Val_unit;
1748 }
1749 
1750 /* llvalue -> llbasicblock -> llbuilder -> llvalue */
llvm_build_indirect_br(LLVMValueRef Addr,value EstimatedDests,value B)1751 LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr, value EstimatedDests,
1752                                     value B) {
1753   return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
1754 }
1755 
1756 /* llvalue -> llvalue -> llbasicblock -> unit */
llvm_add_destination(LLVMValueRef IndirectBr,LLVMBasicBlockRef Dest)1757 value llvm_add_destination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) {
1758   LLVMAddDestination(IndirectBr, Dest);
1759   return Val_unit;
1760 }
1761 
1762 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1763    llbuilder -> llvalue */
llvm_build_invoke_nat(LLVMValueRef Fn,value Args,LLVMBasicBlockRef Then,LLVMBasicBlockRef Catch,value Name,value B)1764 LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
1765                                    LLVMBasicBlockRef Then,
1766                                    LLVMBasicBlockRef Catch, value Name,
1767                                    value B) {
1768   return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *)Op_val(Args),
1769                          Wosize_val(Args), Then, Catch, String_val(Name));
1770 }
1771 
1772 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1773    llbuilder -> llvalue */
llvm_build_invoke_bc(value Args[],int NumArgs)1774 LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
1775   return llvm_build_invoke_nat((LLVMValueRef)Args[0], Args[1],
1776                                (LLVMBasicBlockRef)Args[2],
1777                                (LLVMBasicBlockRef)Args[3], Args[4], Args[5]);
1778 }
1779 
1780 /* lltype -> llvalue -> llvalue array -> llbasicblock -> llbasicblock ->
1781    string -> llbuilder -> llvalue */
llvm_build_invoke2_nat(LLVMTypeRef FnTy,LLVMValueRef Fn,value Args,LLVMBasicBlockRef Then,LLVMBasicBlockRef Catch,value Name,value B)1782 LLVMValueRef llvm_build_invoke2_nat(LLVMTypeRef FnTy, LLVMValueRef Fn,
1783                                     value Args, LLVMBasicBlockRef Then,
1784                                     LLVMBasicBlockRef Catch, value Name,
1785                                     value B) {
1786   return LLVMBuildInvoke2(Builder_val(B), FnTy, Fn,
1787                           (LLVMValueRef *)Op_val(Args), Wosize_val(Args),
1788                           Then, Catch, String_val(Name));
1789 }
1790 
1791 /* lltype -> llvalue -> llvalue array -> llbasicblock -> llbasicblock ->
1792    string -> llbuilder -> llvalue */
llvm_build_invoke2_bc(value Args[],int NumArgs)1793 LLVMValueRef llvm_build_invoke2_bc(value Args[], int NumArgs) {
1794   return llvm_build_invoke2_nat((LLVMTypeRef)Args[0], (LLVMValueRef)Args[1],
1795                                 Args[2], (LLVMBasicBlockRef)Args[3],
1796                                (LLVMBasicBlockRef)Args[4], Args[5], Args[6]);
1797 }
1798 
1799 /* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
llvm_build_landingpad(LLVMTypeRef Ty,LLVMValueRef PersFn,value NumClauses,value Name,value B)1800 LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
1801                                    value NumClauses, value Name, value B) {
1802   return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
1803                              String_val(Name));
1804 }
1805 
1806 /* llvalue -> llvalue -> unit */
llvm_add_clause(LLVMValueRef LandingPadInst,LLVMValueRef ClauseVal)1807 value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal) {
1808   LLVMAddClause(LandingPadInst, ClauseVal);
1809   return Val_unit;
1810 }
1811 
1812 /* llvalue -> bool */
llvm_is_cleanup(LLVMValueRef LandingPadInst)1813 value llvm_is_cleanup(LLVMValueRef LandingPadInst) {
1814   return Val_bool(LLVMIsCleanup(LandingPadInst));
1815 }
1816 
1817 /* llvalue -> bool -> unit */
llvm_set_cleanup(LLVMValueRef LandingPadInst,value flag)1818 value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag) {
1819   LLVMSetCleanup(LandingPadInst, Bool_val(flag));
1820   return Val_unit;
1821 }
1822 
1823 /* llvalue -> llbuilder -> llvalue */
llvm_build_resume(LLVMValueRef Exn,value B)1824 LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B) {
1825   return LLVMBuildResume(Builder_val(B), Exn);
1826 }
1827 
1828 /* llbuilder -> llvalue */
llvm_build_unreachable(value B)1829 LLVMValueRef llvm_build_unreachable(value B) {
1830   return LLVMBuildUnreachable(Builder_val(B));
1831 }
1832 
1833 /*--... Arithmetic .........................................................--*/
1834 
1835 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_add(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1836 LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1837                             value B) {
1838   return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
1839 }
1840 
1841 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nsw_add(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1842 LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1843                                 value B) {
1844   return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1845 }
1846 
1847 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nuw_add(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1848 LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1849                                 value B) {
1850   return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1851 }
1852 
1853 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_fadd(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1854 LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1855                              value B) {
1856   return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
1857 }
1858 
1859 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_sub(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1860 LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1861                             value B) {
1862   return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
1863 }
1864 
1865 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nsw_sub(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1866 LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1867                                 value B) {
1868   return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
1869 }
1870 
1871 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nuw_sub(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1872 LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1873                                 value B) {
1874   return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
1875 }
1876 
1877 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_fsub(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1878 LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1879                              value B) {
1880   return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
1881 }
1882 
1883 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_mul(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1884 LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1885                             value B) {
1886   return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
1887 }
1888 
1889 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nsw_mul(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1890 LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1891                                 value B) {
1892   return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
1893 }
1894 
1895 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_nuw_mul(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1896 LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1897                                 value B) {
1898   return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
1899 }
1900 
1901 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_fmul(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1902 LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1903                              value B) {
1904   return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
1905 }
1906 
1907 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_udiv(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1908 LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1909                              value B) {
1910   return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
1911 }
1912 
1913 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_sdiv(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1914 LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1915                              value B) {
1916   return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1917 }
1918 
1919 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_exact_sdiv(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1920 LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1921                                    value Name, value B) {
1922   return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1923 }
1924 
1925 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_fdiv(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1926 LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1927                              value B) {
1928   return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
1929 }
1930 
1931 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_urem(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1932 LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1933                              value B) {
1934   return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
1935 }
1936 
1937 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_srem(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1938 LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1939                              value B) {
1940   return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
1941 }
1942 
1943 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_frem(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1944 LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1945                              value B) {
1946   return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
1947 }
1948 
1949 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_shl(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1950 LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1951                             value B) {
1952   return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
1953 }
1954 
1955 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_lshr(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1956 LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1957                              value B) {
1958   return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
1959 }
1960 
1961 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_ashr(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1962 LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1963                              value B) {
1964   return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
1965 }
1966 
1967 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_and(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1968 LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1969                             value B) {
1970   return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
1971 }
1972 
1973 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_or(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1974 LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1975                            value B) {
1976   return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
1977 }
1978 
1979 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_xor(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)1980 LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
1981                             value B) {
1982   return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
1983 }
1984 
1985 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_neg(LLVMValueRef X,value Name,value B)1986 LLVMValueRef llvm_build_neg(LLVMValueRef X, value Name, value B) {
1987   return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
1988 }
1989 
1990 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_nsw_neg(LLVMValueRef X,value Name,value B)1991 LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X, value Name, value B) {
1992   return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
1993 }
1994 
1995 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_nuw_neg(LLVMValueRef X,value Name,value B)1996 LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X, value Name, value B) {
1997   return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
1998 }
1999 
2000 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_fneg(LLVMValueRef X,value Name,value B)2001 LLVMValueRef llvm_build_fneg(LLVMValueRef X, value Name, value B) {
2002   return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
2003 }
2004 
2005 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_not(LLVMValueRef X,value Name,value B)2006 LLVMValueRef llvm_build_not(LLVMValueRef X, value Name, value B) {
2007   return LLVMBuildNot(Builder_val(B), X, String_val(Name));
2008 }
2009 
2010 /*--... Memory .............................................................--*/
2011 
2012 /* lltype -> string -> llbuilder -> llvalue */
llvm_build_alloca(LLVMTypeRef Ty,value Name,value B)2013 LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty, value Name, value B) {
2014   return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
2015 }
2016 
2017 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_array_alloca(LLVMTypeRef Ty,LLVMValueRef Size,value Name,value B)2018 LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
2019                                      value Name, value B) {
2020   return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
2021 }
2022 
2023 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_load(LLVMValueRef Pointer,value Name,value B)2024 LLVMValueRef llvm_build_load(LLVMValueRef Pointer, value Name, value B) {
2025   return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
2026 }
2027 
2028 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_load2(LLVMTypeRef Ty,LLVMValueRef Pointer,value Name,value B)2029 LLVMValueRef llvm_build_load2(LLVMTypeRef Ty, LLVMValueRef Pointer, value Name,
2030                               value B) {
2031   return LLVMBuildLoad2(Builder_val(B), Ty, Pointer, String_val(Name));
2032 }
2033 
2034 /* llvalue -> llvalue -> llbuilder -> llvalue */
llvm_build_store(LLVMValueRef Value,LLVMValueRef Pointer,value B)2035 LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
2036                               value B) {
2037   return LLVMBuildStore(Builder_val(B), Value, Pointer);
2038 }
2039 
2040 /* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
2041    bool -> llbuilder -> llvalue */
llvm_build_atomicrmw_native(value BinOp,LLVMValueRef Ptr,LLVMValueRef Val,value Ord,value ST,value Name,value B)2042 LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
2043                                          LLVMValueRef Val, value Ord, value ST,
2044                                          value Name, value B) {
2045   LLVMValueRef Instr;
2046   Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp), Ptr, Val,
2047                              Int_val(Ord), Bool_val(ST));
2048   LLVMSetValueName(Instr, String_val(Name));
2049   return Instr;
2050 }
2051 
llvm_build_atomicrmw_bytecode(value * argv,int argn)2052 LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
2053   return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef)argv[1],
2054                                      (LLVMValueRef)argv[2], argv[3], argv[4],
2055                                      argv[5], argv[6]);
2056 }
2057 
2058 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_gep(LLVMValueRef Pointer,value Indices,value Name,value B)2059 LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices, value Name,
2060                             value B) {
2061   return LLVMBuildGEP(Builder_val(B), Pointer, (LLVMValueRef *)Op_val(Indices),
2062                       Wosize_val(Indices), String_val(Name));
2063 }
2064 
2065 /* lltype -> llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_gep2(LLVMTypeRef Ty,LLVMValueRef Pointer,value Indices,value Name,value B)2066 LLVMValueRef llvm_build_gep2(LLVMTypeRef Ty, LLVMValueRef Pointer,
2067                              value Indices, value Name, value B) {
2068   return LLVMBuildGEP2(Builder_val(B), Ty, Pointer,
2069                        (LLVMValueRef *)Op_val(Indices), Wosize_val(Indices),
2070                        String_val(Name));
2071 }
2072 
2073 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_in_bounds_gep(LLVMValueRef Pointer,value Indices,value Name,value B)2074 LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer, value Indices,
2075                                       value Name, value B) {
2076   return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
2077                               (LLVMValueRef *)Op_val(Indices),
2078                               Wosize_val(Indices), String_val(Name));
2079 }
2080 
2081 /* lltype -> llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_in_bounds_gep2(LLVMTypeRef Ty,LLVMValueRef Pointer,value Indices,value Name,value B)2082 LLVMValueRef llvm_build_in_bounds_gep2(LLVMTypeRef Ty, LLVMValueRef Pointer,
2083                                        value Indices, value Name, value B) {
2084   return LLVMBuildInBoundsGEP2(Builder_val(B), Ty, Pointer,
2085                                (LLVMValueRef *)Op_val(Indices),
2086                                Wosize_val(Indices), String_val(Name));
2087 }
2088 
2089 /* llvalue -> int -> string -> llbuilder -> llvalue */
llvm_build_struct_gep(LLVMValueRef Pointer,value Index,value Name,value B)2090 LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer, value Index,
2091                                    value Name, value B) {
2092   return LLVMBuildStructGEP(Builder_val(B), Pointer, Int_val(Index),
2093                             String_val(Name));
2094 }
2095 
2096 /* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
llvm_build_struct_gep2(LLVMTypeRef Ty,LLVMValueRef Pointer,value Index,value Name,value B)2097 LLVMValueRef llvm_build_struct_gep2(LLVMTypeRef Ty, LLVMValueRef Pointer,
2098                                     value Index, value Name, value B) {
2099   return LLVMBuildStructGEP2(Builder_val(B), Ty, Pointer, Int_val(Index),
2100                              String_val(Name));
2101 }
2102 
2103 /* string -> string -> llbuilder -> llvalue */
llvm_build_global_string(value Str,value Name,value B)2104 LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
2105   return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
2106                                String_val(Name));
2107 }
2108 
2109 /* string -> string -> llbuilder -> llvalue */
llvm_build_global_stringptr(value Str,value Name,value B)2110 LLVMValueRef llvm_build_global_stringptr(value Str, value Name, value B) {
2111   return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
2112                                   String_val(Name));
2113 }
2114 
2115 /*--... Casts ..............................................................--*/
2116 
2117 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_trunc(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2118 LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2119                               value B) {
2120   return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
2121 }
2122 
2123 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_zext(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2124 LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2125                              value B) {
2126   return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
2127 }
2128 
2129 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_sext(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2130 LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2131                              value B) {
2132   return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
2133 }
2134 
2135 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_fptoui(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2136 LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2137                                value B) {
2138   return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
2139 }
2140 
2141 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_fptosi(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2142 LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2143                                value B) {
2144   return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
2145 }
2146 
2147 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_uitofp(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2148 LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2149                                value B) {
2150   return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
2151 }
2152 
2153 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_sitofp(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2154 LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2155                                value B) {
2156   return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
2157 }
2158 
2159 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_fptrunc(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2160 LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2161                                 value B) {
2162   return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
2163 }
2164 
2165 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_fpext(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2166 LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2167                               value B) {
2168   return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
2169 }
2170 
2171 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_prttoint(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2172 LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2173                                  value B) {
2174   return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
2175 }
2176 
2177 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_inttoptr(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2178 LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2179                                  value B) {
2180   return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
2181 }
2182 
2183 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_bitcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2184 LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2185                                 value B) {
2186   return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
2187 }
2188 
2189 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_zext_or_bitcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2190 LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2191                                         value Name, value B) {
2192   return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2193 }
2194 
2195 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_sext_or_bitcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2196 LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2197                                         value Name, value B) {
2198   return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2199 }
2200 
2201 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_trunc_or_bitcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2202 LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2203                                          value Name, value B) {
2204   return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2205 }
2206 
2207 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_pointercast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2208 LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2209                                     value B) {
2210   return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
2211 }
2212 
2213 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_intcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2214 LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2215                                 value B) {
2216   return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
2217 }
2218 
2219 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_fpcast(LLVMValueRef X,LLVMTypeRef Ty,value Name,value B)2220 LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty, value Name,
2221                                value B) {
2222   return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
2223 }
2224 
2225 /*--... Comparisons ........................................................--*/
2226 
2227 /* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_icmp(value Pred,LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)2228 LLVMValueRef llvm_build_icmp(value Pred, LLVMValueRef LHS, LLVMValueRef RHS,
2229                              value Name, value B) {
2230   return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
2231                        String_val(Name));
2232 }
2233 
2234 /* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_fcmp(value Pred,LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)2235 LLVMValueRef llvm_build_fcmp(value Pred, LLVMValueRef LHS, LLVMValueRef RHS,
2236                              value Name, value B) {
2237   return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
2238                        String_val(Name));
2239 }
2240 
2241 /*--... Miscellaneous instructions .........................................--*/
2242 
2243 /* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
llvm_build_phi(value Incoming,value Name,value B)2244 LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
2245   value Hd, Tl;
2246   LLVMValueRef FirstValue, PhiNode;
2247 
2248   assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
2249 
2250   Hd = Field(Incoming, 0);
2251   FirstValue = (LLVMValueRef)Field(Hd, 0);
2252   PhiNode =
2253       LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue), String_val(Name));
2254 
2255   for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
2256     value Hd = Field(Tl, 0);
2257     LLVMAddIncoming(PhiNode, (LLVMValueRef *)&Field(Hd, 0),
2258                     (LLVMBasicBlockRef *)&Field(Hd, 1), 1);
2259   }
2260 
2261   return PhiNode;
2262 }
2263 
2264 /* lltype -> string -> llbuilder -> value */
llvm_build_empty_phi(LLVMTypeRef Type,value Name,value B)2265 LLVMValueRef llvm_build_empty_phi(LLVMTypeRef Type, value Name, value B) {
2266   return LLVMBuildPhi(Builder_val(B), Type, String_val(Name));
2267 }
2268 
2269 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_call(LLVMValueRef Fn,value Params,value Name,value B)2270 LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params, value Name,
2271                              value B) {
2272   return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *)Op_val(Params),
2273                        Wosize_val(Params), String_val(Name));
2274 }
2275 
2276 /* lltype -> llvalue -> llvalue array -> string -> llbuilder -> llvalue */
llvm_build_call2(LLVMTypeRef FnTy,LLVMValueRef Fn,value Params,value Name,value B)2277 LLVMValueRef llvm_build_call2(LLVMTypeRef FnTy, LLVMValueRef Fn, value Params,
2278                               value Name, value B) {
2279   return LLVMBuildCall2(Builder_val(B), FnTy, Fn,
2280                         (LLVMValueRef *)Op_val(Params), Wosize_val(Params),
2281                         String_val(Name));
2282 }
2283 
2284 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_select(LLVMValueRef If,LLVMValueRef Then,LLVMValueRef Else,value Name,value B)2285 LLVMValueRef llvm_build_select(LLVMValueRef If, LLVMValueRef Then,
2286                                LLVMValueRef Else, value Name, value B) {
2287   return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
2288 }
2289 
2290 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
llvm_build_va_arg(LLVMValueRef List,LLVMTypeRef Ty,value Name,value B)2291 LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty, value Name,
2292                                value B) {
2293   return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
2294 }
2295 
2296 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_extractelement(LLVMValueRef Vec,LLVMValueRef Idx,value Name,value B)2297 LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec, LLVMValueRef Idx,
2298                                        value Name, value B) {
2299   return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
2300 }
2301 
2302 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_insertelement(LLVMValueRef Vec,LLVMValueRef Element,LLVMValueRef Idx,value Name,value B)2303 LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec, LLVMValueRef Element,
2304                                       LLVMValueRef Idx, value Name, value B) {
2305   return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
2306                                 String_val(Name));
2307 }
2308 
2309 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_shufflevector(LLVMValueRef V1,LLVMValueRef V2,LLVMValueRef Mask,value Name,value B)2310 LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
2311                                       LLVMValueRef Mask, value Name, value B) {
2312   return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
2313 }
2314 
2315 /* llvalue -> int -> string -> llbuilder -> llvalue */
llvm_build_extractvalue(LLVMValueRef Aggregate,value Idx,value Name,value B)2316 LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate, value Idx,
2317                                      value Name, value B) {
2318   return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
2319                                String_val(Name));
2320 }
2321 
2322 /* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
llvm_build_insertvalue(LLVMValueRef Aggregate,LLVMValueRef Val,value Idx,value Name,value B)2323 LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate, LLVMValueRef Val,
2324                                     value Idx, value Name, value B) {
2325   return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
2326                               String_val(Name));
2327 }
2328 
2329 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_is_null(LLVMValueRef Val,value Name,value B)2330 LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name, value B) {
2331   return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
2332 }
2333 
2334 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_is_not_null(LLVMValueRef Val,value Name,value B)2335 LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name, value B) {
2336   return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
2337 }
2338 
2339 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_ptrdiff(LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)2340 LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS, value Name,
2341                                 value B) {
2342   return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
2343 }
2344 
2345 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
llvm_build_ptrdiff2(LLVMTypeRef ElemTy,LLVMValueRef LHS,LLVMValueRef RHS,value Name,value B)2346 LLVMValueRef llvm_build_ptrdiff2(LLVMTypeRef ElemTy, LLVMValueRef LHS,
2347                                  LLVMValueRef RHS, value Name, value B) {
2348   return LLVMBuildPtrDiff2(Builder_val(B), ElemTy, LHS, RHS, String_val(Name));
2349 }
2350 
2351 /* llvalue -> string -> llbuilder -> llvalue */
llvm_build_freeze(LLVMValueRef X,value Name,value B)2352 LLVMValueRef llvm_build_freeze(LLVMValueRef X, value Name, value B) {
2353   return LLVMBuildFreeze(Builder_val(B), X, String_val(Name));
2354 }
2355 
2356 /*===-- Memory buffers ----------------------------------------------------===*/
2357 
2358 /* string -> llmemorybuffer
2359    raises IoError msg on error */
llvm_memorybuffer_of_file(value Path)2360 LLVMMemoryBufferRef llvm_memorybuffer_of_file(value Path) {
2361   char *Message;
2362   LLVMMemoryBufferRef MemBuf;
2363 
2364   if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path), &MemBuf,
2365                                                &Message))
2366     llvm_raise(*caml_named_value("Llvm.IoError"), Message);
2367 
2368   return MemBuf;
2369 }
2370 
2371 /* unit -> llmemorybuffer
2372    raises IoError msg on error */
llvm_memorybuffer_of_stdin(value Unit)2373 LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
2374   char *Message;
2375   LLVMMemoryBufferRef MemBuf;
2376 
2377   if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
2378     llvm_raise(*caml_named_value("Llvm.IoError"), Message);
2379 
2380   return MemBuf;
2381 }
2382 
2383 /* ?name:string -> string -> llmemorybuffer */
llvm_memorybuffer_of_string(value Name,value String)2384 LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
2385   LLVMMemoryBufferRef MemBuf;
2386   const char *NameCStr;
2387 
2388   if (Name == Val_int(0))
2389     NameCStr = "";
2390   else
2391     NameCStr = String_val(Field(Name, 0));
2392 
2393   MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
2394       String_val(String), caml_string_length(String), NameCStr);
2395 
2396   return MemBuf;
2397 }
2398 
2399 /* llmemorybuffer -> string */
llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf)2400 value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
2401   size_t BufferSize = LLVMGetBufferSize(MemBuf);
2402   const char *BufferStart = LLVMGetBufferStart(MemBuf);
2403   return cstr_to_string(BufferStart, BufferSize);
2404 }
2405 
2406 /* llmemorybuffer -> unit */
llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf)2407 value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
2408   LLVMDisposeMemoryBuffer(MemBuf);
2409   return Val_unit;
2410 }
2411 
2412 /*===-- Pass Managers -----------------------------------------------------===*/
2413 
2414 /* unit -> [ `Module ] PassManager.t */
llvm_passmanager_create(value Unit)2415 LLVMPassManagerRef llvm_passmanager_create(value Unit) {
2416   return LLVMCreatePassManager();
2417 }
2418 
2419 /* llmodule -> [ `Function ] PassManager.t -> bool */
llvm_passmanager_run_module(LLVMModuleRef M,LLVMPassManagerRef PM)2420 value llvm_passmanager_run_module(LLVMModuleRef M, LLVMPassManagerRef PM) {
2421   return Val_bool(LLVMRunPassManager(PM, M));
2422 }
2423 
2424 /* [ `Function ] PassManager.t -> bool */
llvm_passmanager_initialize(LLVMPassManagerRef FPM)2425 value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
2426   return Val_bool(LLVMInitializeFunctionPassManager(FPM));
2427 }
2428 
2429 /* llvalue -> [ `Function ] PassManager.t -> bool */
llvm_passmanager_run_function(LLVMValueRef F,LLVMPassManagerRef FPM)2430 value llvm_passmanager_run_function(LLVMValueRef F, LLVMPassManagerRef FPM) {
2431   return Val_bool(LLVMRunFunctionPassManager(FPM, F));
2432 }
2433 
2434 /* [ `Function ] PassManager.t -> bool */
llvm_passmanager_finalize(LLVMPassManagerRef FPM)2435 value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
2436   return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
2437 }
2438 
2439 /* PassManager.any PassManager.t -> unit */
llvm_passmanager_dispose(LLVMPassManagerRef PM)2440 value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
2441   LLVMDisposePassManager(PM);
2442   return Val_unit;
2443 }
2444