[OCaml] PR19859: Add functions to query and modify branches.
[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
1455 /*--.. Operations on terminators ...........................................--*/
1456
1457 /* llvalue -> int -> llbasicblock */
1458 CAMLprim LLVMBasicBlockRef llvm_successor(LLVMValueRef V, value I) {
1459   return LLVMGetSuccessor(V, Int_val(I));
1460 }
1461
1462 /* llvalue -> int -> llvalue -> unit */
1463 CAMLprim value llvm_set_successor(LLVMValueRef U, value I, LLVMBasicBlockRef B) {
1464   LLVMSetSuccessor(U, Int_val(I), B);
1465   return Val_unit;
1466 }
1467
1468 /* llvalue -> int */
1469 CAMLprim value llvm_num_successors(LLVMValueRef V) {
1470   return Val_int(LLVMGetNumSuccessors(V));
1471 }
1472
1473 /*--.. Operations on branch ................................................--*/
1474
1475 /* llvalue -> llvalue */
1476 CAMLprim LLVMValueRef llvm_condition(LLVMValueRef V) {
1477   return LLVMGetCondition(V);
1478 }
1479
1480 /* llvalue -> llvalue -> unit */
1481 CAMLprim value llvm_set_condition(LLVMValueRef B, LLVMValueRef C) {
1482   LLVMSetCondition(B, C);
1483   return Val_unit;
1484 }
1485
1486 /* llvalue -> bool */
1487 CAMLprim value llvm_is_conditional(LLVMValueRef V) {
1488   return Val_bool(LLVMIsConditional(V));
1489 }
1490
1491 /*--... Operations on phi nodes ............................................--*/
1492
1493 /* (llvalue * llbasicblock) -> llvalue -> unit */
1494 CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
1495   LLVMAddIncoming(PhiNode,
1496                   (LLVMValueRef*) &Field(Incoming, 0),
1497                   (LLVMBasicBlockRef*) &Field(Incoming, 1),
1498                   1);
1499   return Val_unit;
1500 }
1501
1502 /* llvalue -> (llvalue * llbasicblock) list */
1503 CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
1504   unsigned I;
1505   CAMLparam0();
1506   CAMLlocal3(Hd, Tl, Tmp);
1507
1508   /* Build a tuple list of them. */
1509   Tl = Val_int(0);
1510   for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
1511     Hd = alloc(2, 0);
1512     Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
1513     Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
1514
1515     Tmp = alloc(2, 0);
1516     Store_field(Tmp, 0, Hd);
1517     Store_field(Tmp, 1, Tl);
1518     Tl = Tmp;
1519   }
1520
1521   CAMLreturn(Tl);
1522 }
1523
1524 /* llvalue -> unit */
1525 CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) {
1526   LLVMInstructionEraseFromParent(Instruction);
1527   return Val_unit;
1528 }
1529
1530 /*===-- Instruction builders ----------------------------------------------===*/
1531
1532 #define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
1533
1534 static void llvm_finalize_builder(value B) {
1535   LLVMDisposeBuilder(Builder_val(B));
1536 }
1537
1538 static struct custom_operations builder_ops = {
1539   (char *) "LLVMIRBuilder",
1540   llvm_finalize_builder,
1541   custom_compare_default,
1542   custom_hash_default,
1543   custom_serialize_default,
1544   custom_deserialize_default
1545 #ifdef custom_compare_ext_default
1546   , custom_compare_ext_default
1547 #endif
1548 };
1549
1550 static value alloc_builder(LLVMBuilderRef B) {
1551   value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
1552   Builder_val(V) = B;
1553   return V;
1554 }
1555
1556 /* llcontext -> llbuilder */
1557 CAMLprim value llvm_builder(LLVMContextRef C) {
1558   return alloc_builder(LLVMCreateBuilderInContext(C));
1559 }
1560
1561 /* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
1562 CAMLprim value llvm_position_builder(value Pos, value B) {
1563   if (Tag_val(Pos) == 0) {
1564     LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
1565     LLVMPositionBuilderAtEnd(Builder_val(B), BB);
1566   } else {
1567     LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
1568     LLVMPositionBuilderBefore(Builder_val(B), I);
1569   }
1570   return Val_unit;
1571 }
1572
1573 /* llbuilder -> llbasicblock */
1574 CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
1575   LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
1576   if (!InsertBlock)
1577     raise_not_found();
1578   return InsertBlock;
1579 }
1580
1581 /* llvalue -> string -> llbuilder -> unit */
1582 CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
1583   LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
1584   return Val_unit;
1585 }
1586
1587 /*--... Metadata ...........................................................--*/
1588
1589 /* llbuilder -> llvalue -> unit */
1590 CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
1591   LLVMSetCurrentDebugLocation(Builder_val(B), V);
1592   return Val_unit;
1593 }
1594
1595 /* llbuilder -> unit */
1596 CAMLprim value llvm_clear_current_debug_location(value B) {
1597   LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
1598   return Val_unit;
1599 }
1600
1601 /* llbuilder -> llvalue option */
1602 CAMLprim value llvm_current_debug_location(value B) {
1603   CAMLparam0();
1604   LLVMValueRef L;
1605   if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
1606     value Option = alloc(1, 0);
1607     Field(Option, 0) = (value) L;
1608     CAMLreturn(Option);
1609   }
1610   CAMLreturn(Val_int(0));
1611 }
1612
1613 /* llbuilder -> llvalue -> unit */
1614 CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
1615   LLVMSetInstDebugLocation(Builder_val(B), V);
1616   return Val_unit;
1617 }
1618
1619
1620 /*--... Terminators ........................................................--*/
1621
1622 /* llbuilder -> llvalue */
1623 CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
1624   return LLVMBuildRetVoid(Builder_val(B));
1625 }
1626
1627 /* llvalue -> llbuilder -> llvalue */
1628 CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
1629   return LLVMBuildRet(Builder_val(B), Val);
1630 }
1631
1632 /* llvalue array -> llbuilder -> llvalue */
1633 CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
1634   return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
1635                                Wosize_val(RetVals));
1636 }
1637
1638 /* llbasicblock -> llbuilder -> llvalue */
1639 CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
1640   return LLVMBuildBr(Builder_val(B), BB);
1641 }
1642
1643 /* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
1644 CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
1645                                          LLVMBasicBlockRef Then,
1646                                          LLVMBasicBlockRef Else,
1647                                          value B) {
1648   return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
1649 }
1650
1651 /* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
1652 CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
1653                                         LLVMBasicBlockRef Else,
1654                                         value EstimatedCount,
1655                                         value B) {
1656   return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
1657 }
1658
1659 /* lltype -> string -> llbuilder -> llvalue */
1660 CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name,
1661                                         value B)
1662 {
1663   return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
1664 }
1665
1666 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
1667 CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty,
1668                                               LLVMValueRef Val,
1669                                               value Name, value B)
1670 {
1671   return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
1672 }
1673
1674 /* llvalue -> llbuilder -> llvalue */
1675 CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B)
1676 {
1677   return LLVMBuildFree(Builder_val(B), P);
1678 }
1679
1680 /* llvalue -> llvalue -> llbasicblock -> unit */
1681 CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
1682                              LLVMBasicBlockRef Dest) {
1683   LLVMAddCase(Switch, OnVal, Dest);
1684   return Val_unit;
1685 }
1686
1687 /* llvalue -> llbasicblock -> llbuilder -> llvalue */
1688 CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
1689                                              value EstimatedDests,
1690                                              value B) {
1691   return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
1692 }
1693
1694 /* llvalue -> llvalue -> llbasicblock -> unit */
1695 CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
1696                                     LLVMBasicBlockRef Dest) {
1697   LLVMAddDestination(IndirectBr, Dest);
1698   return Val_unit;
1699 }
1700
1701 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1702    llbuilder -> llvalue */
1703 CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
1704                                             LLVMBasicBlockRef Then,
1705                                             LLVMBasicBlockRef Catch,
1706                                             value Name, value B) {
1707   return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
1708                          Wosize_val(Args), Then, Catch, String_val(Name));
1709 }
1710
1711 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1712    llbuilder -> llvalue */
1713 CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
1714   return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
1715                                (LLVMBasicBlockRef) Args[2],
1716                                (LLVMBasicBlockRef) Args[3],
1717                                Args[4], Args[5]);
1718 }
1719
1720 /* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
1721 CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
1722                                             value NumClauses,  value Name,
1723                                             value B) {
1724     return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
1725                                String_val(Name));
1726 }
1727
1728 /* llvalue -> llvalue -> unit */
1729 CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal)
1730 {
1731     LLVMAddClause(LandingPadInst, ClauseVal);
1732     return Val_unit;
1733 }
1734
1735
1736 /* llvalue -> bool -> unit */
1737 CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
1738 {
1739     LLVMSetCleanup(LandingPadInst, Bool_val(flag));
1740     return Val_unit;
1741 }
1742
1743 /* llvalue -> llbuilder -> llvalue */
1744 CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B)
1745 {
1746     return LLVMBuildResume(Builder_val(B), Exn);
1747 }
1748
1749 /* llbuilder -> llvalue */
1750 CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
1751   return LLVMBuildUnreachable(Builder_val(B));
1752 }
1753
1754 /*--... Arithmetic .........................................................--*/
1755
1756 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1757 CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
1758                                      value Name, value B) {
1759   return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
1760 }
1761
1762 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1763 CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1764                                          value Name, value B) {
1765   return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1766 }
1767
1768 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1769 CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1770                                          value Name, value B) {
1771   return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1772 }
1773
1774 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1775 CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
1776                                       value Name, value B) {
1777   return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
1778 }
1779
1780 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1781 CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1782                                      value Name, value B) {
1783   return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
1784 }
1785
1786 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1787 CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1788                                          value Name, value B) {
1789   return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
1790 }
1791
1792 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1793 CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1794                                          value Name, value B) {
1795   return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
1796 }
1797
1798 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1799 CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
1800                                       value Name, value B) {
1801   return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
1802 }
1803
1804 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1805 CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1806                                      value Name, value B) {
1807   return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
1808 }
1809
1810 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1811 CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1812                                          value Name, value B) {
1813   return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
1814 }
1815
1816 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1817 CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1818                                          value Name, value B) {
1819   return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
1820 }
1821
1822 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1823 CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
1824                                       value Name, value B) {
1825   return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
1826 }
1827
1828 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1829 CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
1830                                       value Name, value B) {
1831   return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
1832 }
1833
1834 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1835 CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1836                                       value Name, value B) {
1837   return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1838 }
1839
1840 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1841 CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1842                                             value Name, value B) {
1843   return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1844 }
1845
1846 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1847 CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1848                                       value Name, value B) {
1849   return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
1850 }
1851
1852 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1853 CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
1854                                       value Name, value B) {
1855   return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
1856 }
1857
1858 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1859 CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
1860                                       value Name, value B) {
1861   return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
1862 }
1863
1864 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1865 CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
1866                                       value Name, value B) {
1867   return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
1868 }
1869
1870 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1871 CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
1872                                      value Name, value B) {
1873   return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
1874 }
1875
1876 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1877 CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
1878                                       value Name, value B) {
1879   return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
1880 }
1881
1882 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1883 CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
1884                                       value Name, value B) {
1885   return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
1886 }
1887
1888 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1889 CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
1890                                      value Name, value B) {
1891   return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
1892 }
1893
1894 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1895 CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
1896                                     value Name, value B) {
1897   return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
1898 }
1899
1900 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1901 CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
1902                                      value Name, value B) {
1903   return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
1904 }
1905
1906 /* llvalue -> string -> llbuilder -> llvalue */
1907 CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
1908                                      value Name, value B) {
1909   return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
1910 }
1911
1912 /* llvalue -> string -> llbuilder -> llvalue */
1913 CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
1914                                          value Name, value B) {
1915   return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
1916 }
1917
1918 /* llvalue -> string -> llbuilder -> llvalue */
1919 CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
1920                                          value Name, value B) {
1921   return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
1922 }
1923
1924 /* llvalue -> string -> llbuilder -> llvalue */
1925 CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
1926                                      value Name, value B) {
1927   return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
1928 }
1929
1930 /* llvalue -> string -> llbuilder -> llvalue */
1931 CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
1932                                      value Name, value B) {
1933   return LLVMBuildNot(Builder_val(B), X, String_val(Name));
1934 }
1935
1936 /*--... Memory .............................................................--*/
1937
1938 /* lltype -> string -> llbuilder -> llvalue */
1939 CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
1940                                         value Name, value B) {
1941   return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
1942 }
1943
1944 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
1945 CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
1946                                               value Name, value B) {
1947   return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
1948 }
1949
1950 /* llvalue -> string -> llbuilder -> llvalue */
1951 CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
1952                                       value Name, value B) {
1953   return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
1954 }
1955
1956 /* llvalue -> llvalue -> llbuilder -> llvalue */
1957 CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
1958                                        value B) {
1959   return LLVMBuildStore(Builder_val(B), Value, Pointer);
1960 }
1961
1962 /* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
1963    bool -> llbuilder -> llvalue */
1964 CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
1965                                                   LLVMValueRef Val, value Ord,
1966                                                   value ST, value Name, value B) {
1967   LLVMValueRef Instr;
1968   Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp),
1969                              Ptr, Val, Int_val(Ord), Bool_val(ST));
1970   LLVMSetValueName(Instr, String_val(Name));
1971   return Instr;
1972 }
1973
1974 CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
1975   return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1],
1976                                      (LLVMValueRef) argv[2], argv[3],
1977                                      argv[4], argv[5], argv[6]);
1978 }
1979
1980 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1981 CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
1982                                      value Name, value B) {
1983   return LLVMBuildGEP(Builder_val(B), Pointer,
1984                       (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
1985                       String_val(Name));
1986 }
1987
1988 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1989 CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
1990                                                value Indices, value Name,
1991                                                value B) {
1992   return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
1993                               (LLVMValueRef *) Op_val(Indices),
1994                               Wosize_val(Indices), String_val(Name));
1995 }
1996
1997 /* llvalue -> int -> string -> llbuilder -> llvalue */
1998 CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
1999                                                value Index, value Name,
2000                                                value B) {
2001   return LLVMBuildStructGEP(Builder_val(B), Pointer,
2002                               Int_val(Index), String_val(Name));
2003 }
2004
2005 /* string -> string -> llbuilder -> llvalue */
2006 CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
2007   return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
2008                                String_val(Name));
2009 }
2010
2011 /* string -> string -> llbuilder -> llvalue */
2012 CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
2013                                                   value B) {
2014   return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
2015                                   String_val(Name));
2016 }
2017
2018 /*--... Casts ..............................................................--*/
2019
2020 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2021 CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
2022                                        value Name, value B) {
2023   return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
2024 }
2025
2026 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2027 CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
2028                                       value Name, value B) {
2029   return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
2030 }
2031
2032 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2033 CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
2034                                       value Name, value B) {
2035   return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
2036 }
2037
2038 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2039 CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
2040                                         value Name, value B) {
2041   return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
2042 }
2043
2044 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2045 CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
2046                                         value Name, value B) {
2047   return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
2048 }
2049
2050 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2051 CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
2052                                         value Name, value B) {
2053   return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
2054 }
2055
2056 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2057 CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
2058                                         value Name, value B) {
2059   return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
2060 }
2061
2062 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2063 CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
2064                                          value Name, value B) {
2065   return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
2066 }
2067
2068 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2069 CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
2070                                        value Name, value B) {
2071   return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
2072 }
2073
2074 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2075 CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
2076                                           value Name, value B) {
2077   return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
2078 }
2079
2080 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2081 CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
2082                                           value Name, value B) {
2083   return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
2084 }
2085
2086 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2087 CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2088                                          value Name, value B) {
2089   return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
2090 }
2091
2092 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2093 CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2094                                                  value Name, value B) {
2095   return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2096 }
2097
2098 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2099 CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2100                                                  value Name, value B) {
2101   return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2102 }
2103
2104 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2105 CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
2106                                                   LLVMTypeRef Ty, value Name,
2107                                                   value B) {
2108   return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2109 }
2110
2111 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2112 CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
2113                                              value Name, value B) {
2114   return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
2115 }
2116
2117 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2118 CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
2119                                          value Name, value B) {
2120   return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
2121 }
2122
2123 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2124 CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
2125                                         value Name, value B) {
2126   return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
2127 }
2128
2129 /*--... Comparisons ........................................................--*/
2130
2131 /* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2132 CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
2133                                       LLVMValueRef LHS, LLVMValueRef RHS,
2134                                       value Name, value B) {
2135   return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
2136                        String_val(Name));
2137 }
2138
2139 /* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2140 CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
2141                                       LLVMValueRef LHS, LLVMValueRef RHS,
2142                                       value Name, value B) {
2143   return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
2144                        String_val(Name));
2145 }
2146
2147 /*--... Miscellaneous instructions .........................................--*/
2148
2149 /* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
2150 CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
2151   value Hd, Tl;
2152   LLVMValueRef FirstValue, PhiNode;
2153
2154   assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
2155
2156   Hd = Field(Incoming, 0);
2157   FirstValue = (LLVMValueRef) Field(Hd, 0);
2158   PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
2159                          String_val(Name));
2160
2161   for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
2162     value Hd = Field(Tl, 0);
2163     LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
2164                     (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
2165   }
2166
2167   return PhiNode;
2168 }
2169
2170 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
2171 CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
2172                                       value Name, value B) {
2173   return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
2174                        Wosize_val(Params), String_val(Name));
2175 }
2176
2177 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2178 CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
2179                                         LLVMValueRef Then, LLVMValueRef Else,
2180                                         value Name, value B) {
2181   return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
2182 }
2183
2184 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2185 CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
2186                                         value Name, value B) {
2187   return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
2188 }
2189
2190 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
2191 CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
2192                                                 LLVMValueRef Idx,
2193                                                 value Name, value B) {
2194   return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
2195 }
2196
2197 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2198 CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
2199                                                LLVMValueRef Element,
2200                                                LLVMValueRef Idx,
2201                                                value Name, value B) {
2202   return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
2203                                 String_val(Name));
2204 }
2205
2206 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2207 CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
2208                                                LLVMValueRef Mask,
2209                                                value Name, value B) {
2210   return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
2211 }
2212
2213 /* llvalue -> int -> string -> llbuilder -> llvalue */
2214 CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
2215                                               value Idx, value Name, value B) {
2216   return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
2217                                String_val(Name));
2218 }
2219
2220 /* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
2221 CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
2222                                              LLVMValueRef Val, value Idx,
2223                                              value Name, value B) {
2224   return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
2225                               String_val(Name));
2226 }
2227
2228 /* llvalue -> string -> llbuilder -> llvalue */
2229 CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
2230                                          value B) {
2231   return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
2232 }
2233
2234 /* llvalue -> string -> llbuilder -> llvalue */
2235 CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
2236                                              value B) {
2237   return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
2238 }
2239
2240 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
2241 CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
2242                                          value Name, value B) {
2243   return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
2244 }
2245
2246 /*===-- Memory buffers ----------------------------------------------------===*/
2247
2248 /* string -> llmemorybuffer
2249    raises IoError msg on error */
2250 CAMLprim value llvm_memorybuffer_of_file(value Path) {
2251   CAMLparam1(Path);
2252   char *Message;
2253   LLVMMemoryBufferRef MemBuf;
2254
2255   if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
2256                                                &MemBuf, &Message))
2257     llvm_raise(llvm_ioerror_exn, Message);
2258
2259   CAMLreturn((value) MemBuf);
2260 }
2261
2262 /* unit -> llmemorybuffer
2263    raises IoError msg on error */
2264 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
2265   char *Message;
2266   LLVMMemoryBufferRef MemBuf;
2267
2268   if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
2269     llvm_raise(llvm_ioerror_exn, Message);
2270
2271   return MemBuf;
2272 }
2273
2274 /* ?name:string -> string -> llmemorybuffer */
2275 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
2276   const char *NameCStr;
2277   if(Name == Val_int(0))
2278     NameCStr = "";
2279   else
2280     NameCStr = String_val(Field(Name, 0));
2281
2282   LLVMMemoryBufferRef MemBuf;
2283   MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
2284                 String_val(String), caml_string_length(String), NameCStr);
2285
2286   return MemBuf;
2287 }
2288
2289 /* llmemorybuffer -> string */
2290 CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
2291   value String = caml_alloc_string(LLVMGetBufferSize(MemBuf));
2292   memcpy(String_val(String), LLVMGetBufferStart(MemBuf),
2293          LLVMGetBufferSize(MemBuf));
2294
2295   return String;
2296 }
2297
2298 /* llmemorybuffer -> unit */
2299 CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
2300   LLVMDisposeMemoryBuffer(MemBuf);
2301   return Val_unit;
2302 }
2303
2304 /*===-- Pass Managers -----------------------------------------------------===*/
2305
2306 /* unit -> [ `Module ] PassManager.t */
2307 CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
2308   return LLVMCreatePassManager();
2309 }
2310
2311 /* llmodule -> [ `Function ] PassManager.t -> bool */
2312 CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
2313                                            LLVMPassManagerRef PM) {
2314   return Val_bool(LLVMRunPassManager(PM, M));
2315 }
2316
2317 /* [ `Function ] PassManager.t -> bool */
2318 CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
2319   return Val_bool(LLVMInitializeFunctionPassManager(FPM));
2320 }
2321
2322 /* llvalue -> [ `Function ] PassManager.t -> bool */
2323 CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
2324                                              LLVMPassManagerRef FPM) {
2325   return Val_bool(LLVMRunFunctionPassManager(FPM, F));
2326 }
2327
2328 /* [ `Function ] PassManager.t -> bool */
2329 CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
2330   return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
2331 }
2332
2333 /* PassManager.any PassManager.t -> unit */
2334 CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
2335   LLVMDisposePassManager(PM);
2336   return Val_unit;
2337 }