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