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