OSDN Git Service

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