93a9972379c51a3e2886408dadacb34db05a6e5b
[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 /* lltype -> string -> llvalue */
738 CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
739   return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
740                                       caml_string_length(S));
741 }
742
743 /*--... Operations on composite constants ..................................--*/
744
745 /* llcontext -> string -> llvalue */
746 CAMLprim LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str,
747                                         value NullTerminate) {
748   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
749                                   1);
750 }
751
752 /* llcontext -> string -> llvalue */
753 CAMLprim LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str,
754                                          value NullTerminate) {
755   return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
756                                   0);
757 }
758
759 /* lltype -> llvalue array -> llvalue */
760 CAMLprim LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy,
761                                                value ElementVals) {
762   return LLVMConstArray(ElementTy, (LLVMValueRef*) Op_val(ElementVals),
763                         Wosize_val(ElementVals));
764 }
765
766 /* llcontext -> llvalue array -> llvalue */
767 CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
768   return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
769                                   Wosize_val(ElementVals), 0);
770 }
771
772 /* lltype -> llvalue array -> llvalue */
773 CAMLprim LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) {
774     return LLVMConstNamedStruct(Ty, (LLVMValueRef *) Op_val(ElementVals),  Wosize_val(ElementVals));
775 }
776
777 /* llcontext -> llvalue array -> llvalue */
778 CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C,
779                                                value ElementVals) {
780   return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
781                                   Wosize_val(ElementVals), 1);
782 }
783
784 /* llvalue array -> llvalue */
785 CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) {
786   return LLVMConstVector((LLVMValueRef*) Op_val(ElementVals),
787                          Wosize_val(ElementVals));
788 }
789
790 /* llvalue -> string option */
791 CAMLprim value llvm_string_of_const(LLVMValueRef Const) {
792   const char *S;
793   size_t Len;
794   CAMLparam0();
795   CAMLlocal2(Option, Str);
796
797   if(LLVMIsAConstantDataSequential(Const) && LLVMIsConstantString(Const)) {
798     S = LLVMGetAsString(Const, &Len);
799     Str = caml_alloc_string(Len);
800     memcpy(String_val(Str), S, Len);
801
802     Option = alloc(1, 0);
803     Field(Option, 0) = Str;
804     CAMLreturn(Option);
805   } else {
806     CAMLreturn(Val_int(0));
807   }
808 }
809
810 /* llvalue -> int -> llvalue */
811 CAMLprim LLVMValueRef llvm_const_element(LLVMValueRef Const, value N) {
812   return LLVMGetElementAsConstant(Const, Int_val(N));
813 }
814
815 /*--... Constant expressions ...............................................--*/
816
817 /* Icmp.t -> llvalue -> llvalue -> llvalue */
818 CAMLprim LLVMValueRef llvm_const_icmp(value Pred,
819                                       LLVMValueRef LHSConstant,
820                                       LLVMValueRef RHSConstant) {
821   return LLVMConstICmp(Int_val(Pred) + LLVMIntEQ, LHSConstant, RHSConstant);
822 }
823
824 /* Fcmp.t -> llvalue -> llvalue -> llvalue */
825 CAMLprim LLVMValueRef llvm_const_fcmp(value Pred,
826                                       LLVMValueRef LHSConstant,
827                                       LLVMValueRef RHSConstant) {
828   return LLVMConstFCmp(Int_val(Pred), LHSConstant, RHSConstant);
829 }
830
831 /* llvalue -> llvalue array -> llvalue */
832 CAMLprim LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) {
833   return LLVMConstGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
834                       Wosize_val(Indices));
835 }
836
837 /* llvalue -> llvalue array -> llvalue */
838 CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,
839                                                value Indices) {
840   return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
841                               Wosize_val(Indices));
842 }
843
844 /* llvalue -> lltype -> is_signed:bool -> llvalue */
845 CAMLprim LLVMValueRef llvm_const_intcast(LLVMValueRef CV, LLVMTypeRef T,
846                                          value IsSigned) {
847   return LLVMConstIntCast(CV, T, Bool_val(IsSigned));
848 }
849
850 /* llvalue -> int array -> llvalue */
851 CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate,
852                                               value Indices) {
853   CAMLparam1(Indices);
854   int size = Wosize_val(Indices);
855   int i;
856   LLVMValueRef result;
857
858   unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
859   for (i = 0; i < size; i++) {
860     idxs[i] = Int_val(Field(Indices, i));
861   }
862
863   result = LLVMConstExtractValue(Aggregate, idxs, size);
864   free(idxs);
865   CAMLreturnT(LLVMValueRef, result);
866 }
867
868 /* llvalue -> llvalue -> int array -> llvalue */
869 CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
870                                              LLVMValueRef Val, value Indices) {
871   CAMLparam1(Indices);
872   int size = Wosize_val(Indices);
873   int i;
874   LLVMValueRef result;
875
876   unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
877   for (i = 0; i < size; i++) {
878     idxs[i] = Int_val(Field(Indices, i));
879   }
880
881   result = LLVMConstInsertValue(Aggregate, Val, idxs, size);
882   free(idxs);
883   CAMLreturnT(LLVMValueRef, result);
884 }
885
886 /* lltype -> string -> string -> bool -> bool -> llvalue */
887 CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm,
888                                      value Constraints, value HasSideEffects,
889                                      value IsAlignStack) {
890   return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
891                             Bool_val(HasSideEffects), Bool_val(IsAlignStack));
892 }
893
894 /*--... Operations on global variables, functions, and aliases (globals) ...--*/
895
896 /* llvalue -> bool */
897 CAMLprim value llvm_is_declaration(LLVMValueRef Global) {
898   return Val_bool(LLVMIsDeclaration(Global));
899 }
900
901 /* llvalue -> Linkage.t */
902 CAMLprim value llvm_linkage(LLVMValueRef Global) {
903   return Val_int(LLVMGetLinkage(Global));
904 }
905
906 /* Linkage.t -> llvalue -> unit */
907 CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
908   LLVMSetLinkage(Global, Int_val(Linkage));
909   return Val_unit;
910 }
911
912 /* llvalue -> string */
913 CAMLprim value llvm_section(LLVMValueRef Global) {
914   return copy_string(LLVMGetSection(Global));
915 }
916
917 /* string -> llvalue -> unit */
918 CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) {
919   LLVMSetSection(Global, String_val(Section));
920   return Val_unit;
921 }
922
923 /* llvalue -> Visibility.t */
924 CAMLprim value llvm_visibility(LLVMValueRef Global) {
925   return Val_int(LLVMGetVisibility(Global));
926 }
927
928 /* Visibility.t -> llvalue -> unit */
929 CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
930   LLVMSetVisibility(Global, Int_val(Viz));
931   return Val_unit;
932 }
933
934 /* llvalue -> int */
935 CAMLprim value llvm_alignment(LLVMValueRef Global) {
936   return Val_int(LLVMGetAlignment(Global));
937 }
938
939 /* int -> llvalue -> unit */
940 CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
941   LLVMSetAlignment(Global, Int_val(Bytes));
942   return Val_unit;
943 }
944
945 /*--... Operations on uses .................................................--*/
946
947 /* llvalue -> lluse option */
948 CAMLprim value llvm_use_begin(LLVMValueRef Val) {
949   CAMLparam0();
950   LLVMUseRef First;
951   if ((First = LLVMGetFirstUse(Val))) {
952     value Option = alloc(1, 0);
953     Field(Option, 0) = (value) First;
954     CAMLreturn(Option);
955   }
956   CAMLreturn(Val_int(0));
957 }
958
959 /* lluse -> lluse option */
960 CAMLprim value llvm_use_succ(LLVMUseRef U) {
961   CAMLparam0();
962   LLVMUseRef Next;
963   if ((Next = LLVMGetNextUse(U))) {
964     value Option = alloc(1, 0);
965     Field(Option, 0) = (value) Next;
966     CAMLreturn(Option);
967   }
968   CAMLreturn(Val_int(0));
969 }
970
971 /* lluse -> llvalue */
972 CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) {
973   return LLVMGetUser(UR);
974 }
975
976 /* lluse -> llvalue */
977 CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) {
978   return LLVMGetUsedValue(UR);
979 }
980
981 /*--... Operations on global variables .....................................--*/
982
983 DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
984                  LLVMGetGlobalParent)
985
986 /* lltype -> string -> llmodule -> llvalue */
987 CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
988                                           LLVMModuleRef M) {
989   LLVMValueRef GlobalVar;
990   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
991     if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
992       return LLVMConstBitCast(GlobalVar, LLVMPointerType(Ty, 0));
993     return GlobalVar;
994   }
995   return LLVMAddGlobal(M, Ty, String_val(Name));
996 }
997
998 /* lltype -> string -> int -> llmodule -> llvalue */
999 CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
1000                                                     value AddressSpace,
1001                                                     LLVMModuleRef M) {
1002   LLVMValueRef GlobalVar;
1003   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
1004     if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
1005       return LLVMConstBitCast(GlobalVar,
1006                               LLVMPointerType(Ty, Int_val(AddressSpace)));
1007     return GlobalVar;
1008   }
1009   return LLVMAddGlobalInAddressSpace(M, Ty, String_val(Name),
1010                                      Int_val(AddressSpace));
1011 }
1012
1013 /* string -> llmodule -> llvalue option */
1014 CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
1015   CAMLparam1(Name);
1016   LLVMValueRef GlobalVar;
1017   if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
1018     value Option = alloc(1, 0);
1019     Field(Option, 0) = (value) GlobalVar;
1020     CAMLreturn(Option);
1021   }
1022   CAMLreturn(Val_int(0));
1023 }
1024
1025 /* string -> llvalue -> llmodule -> llvalue */
1026 CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
1027                                          LLVMModuleRef M) {
1028   LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer),
1029                                          String_val(Name));
1030   LLVMSetInitializer(GlobalVar, Initializer);
1031   return GlobalVar;
1032 }
1033
1034 /* string -> llvalue -> int -> llmodule -> llvalue */
1035 CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
1036                                                    LLVMValueRef Initializer,
1037                                                    value AddressSpace,
1038                                                    LLVMModuleRef M) {
1039   LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
1040                                                        LLVMTypeOf(Initializer),
1041                                                        String_val(Name),
1042                                                        Int_val(AddressSpace));
1043   LLVMSetInitializer(GlobalVar, Initializer);
1044   return GlobalVar;
1045 }
1046
1047 /* llvalue -> unit */
1048 CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
1049   LLVMDeleteGlobal(GlobalVar);
1050   return Val_unit;
1051 }
1052
1053 /* llvalue -> llvalue -> unit */
1054 CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal,
1055                                     LLVMValueRef GlobalVar) {
1056   LLVMSetInitializer(GlobalVar, ConstantVal);
1057   return Val_unit;
1058 }
1059
1060 /* llvalue -> unit */
1061 CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) {
1062   LLVMSetInitializer(GlobalVar, NULL);
1063   return Val_unit;
1064 }
1065
1066 /* llvalue -> bool */
1067 CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) {
1068   return Val_bool(LLVMIsThreadLocal(GlobalVar));
1069 }
1070
1071 /* bool -> llvalue -> unit */
1072 CAMLprim value llvm_set_thread_local(value IsThreadLocal,
1073                                      LLVMValueRef GlobalVar) {
1074   LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
1075   return Val_unit;
1076 }
1077
1078 /* llvalue -> ThreadLocalMode.t */
1079 CAMLprim value llvm_thread_local_mode(LLVMValueRef GlobalVar) {
1080   return Val_int(LLVMGetThreadLocalMode(GlobalVar));
1081 }
1082
1083 /* ThreadLocalMode.t -> llvalue -> unit */
1084 CAMLprim value llvm_set_thread_local_mode(value ThreadLocalMode,
1085                                           LLVMValueRef GlobalVar) {
1086   LLVMSetThreadLocalMode(GlobalVar, Int_val(ThreadLocalMode));
1087   return Val_unit;
1088 }
1089
1090 /* llvalue -> bool */
1091 CAMLprim value llvm_is_externally_initialized(LLVMValueRef GlobalVar) {
1092   return Val_bool(LLVMIsExternallyInitialized(GlobalVar));
1093 }
1094
1095 /* bool -> llvalue -> unit */
1096 CAMLprim value llvm_set_externally_initialized(value IsExternallyInitialized,
1097                                                LLVMValueRef GlobalVar) {
1098   LLVMSetExternallyInitialized(GlobalVar, Bool_val(IsExternallyInitialized));
1099   return Val_unit;
1100 }
1101
1102 /* llvalue -> bool */
1103 CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) {
1104   return Val_bool(LLVMIsGlobalConstant(GlobalVar));
1105 }
1106
1107 /* bool -> llvalue -> unit */
1108 CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
1109   LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
1110   return Val_unit;
1111 }
1112
1113 /*--... Operations on aliases ..............................................--*/
1114
1115 CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
1116                                      LLVMValueRef Aliasee, value Name) {
1117   return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
1118 }
1119
1120 /*--... Operations on functions ............................................--*/
1121
1122 DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
1123                  LLVMGetGlobalParent)
1124
1125 /* string -> lltype -> llmodule -> llvalue */
1126 CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
1127                                             LLVMModuleRef M) {
1128   LLVMValueRef Fn;
1129   if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
1130     if (LLVMGetElementType(LLVMTypeOf(Fn)) != Ty)
1131       return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
1132     return Fn;
1133   }
1134   return LLVMAddFunction(M, String_val(Name), Ty);
1135 }
1136
1137 /* string -> llmodule -> llvalue option */
1138 CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) {
1139   CAMLparam1(Name);
1140   LLVMValueRef Fn;
1141   if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
1142     value Option = alloc(1, 0);
1143     Field(Option, 0) = (value) Fn;
1144     CAMLreturn(Option);
1145   }
1146   CAMLreturn(Val_int(0));
1147 }
1148
1149 /* string -> lltype -> llmodule -> llvalue */
1150 CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
1151                                            LLVMModuleRef M) {
1152   LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
1153   LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
1154   return Fn;
1155 }
1156
1157 /* llvalue -> unit */
1158 CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
1159   LLVMDeleteFunction(Fn);
1160   return Val_unit;
1161 }
1162
1163 /* llvalue -> bool */
1164 CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) {
1165   return Val_bool(LLVMGetIntrinsicID(Fn));
1166 }
1167
1168 /* llvalue -> int */
1169 CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) {
1170   return Val_int(LLVMGetFunctionCallConv(Fn));
1171 }
1172
1173 /* int -> llvalue -> unit */
1174 CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
1175   LLVMSetFunctionCallConv(Fn, Int_val(Id));
1176   return Val_unit;
1177 }
1178
1179 /* llvalue -> string option */
1180 CAMLprim value llvm_gc(LLVMValueRef Fn) {
1181   const char *GC;
1182   CAMLparam0();
1183   CAMLlocal2(Name, Option);
1184
1185   if ((GC = LLVMGetGC(Fn))) {
1186     Name = copy_string(GC);
1187
1188     Option = alloc(1, 0);
1189     Field(Option, 0) = Name;
1190     CAMLreturn(Option);
1191   } else {
1192     CAMLreturn(Val_int(0));
1193   }
1194 }
1195
1196 /* string option -> llvalue -> unit */
1197 CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
1198   LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
1199   return Val_unit;
1200 }
1201
1202 /* llvalue -> int32 -> unit */
1203 CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
1204   LLVMAddFunctionAttr(Arg, Int32_val(PA));
1205   return Val_unit;
1206 }
1207
1208 /* llvalue -> string -> string -> unit */
1209 CAMLprim value llvm_add_target_dependent_function_attr(
1210                   LLVMValueRef Arg, value A, value V) {
1211   LLVMAddTargetDependentFunctionAttr(Arg, String_val(A), String_val(V));
1212   return Val_unit;
1213 }
1214
1215 /* llvalue -> int32 */
1216 CAMLprim value llvm_function_attr(LLVMValueRef Fn)
1217 {
1218     CAMLparam0();
1219     CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn)));
1220 }
1221
1222 /* llvalue -> int32 -> unit */
1223 CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
1224   LLVMRemoveFunctionAttr(Arg, Int32_val(PA));
1225   return Val_unit;
1226 }
1227 /*--... Operations on parameters ...........................................--*/
1228
1229 DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
1230
1231 /* llvalue -> int -> llvalue */
1232 CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
1233   return LLVMGetParam(Fn, Int_val(Index));
1234 }
1235
1236 /* llvalue -> int */
1237 CAMLprim value llvm_param_attr(LLVMValueRef Param)
1238 {
1239     CAMLparam0();
1240     CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param)));
1241 }
1242
1243 /* llvalue -> llvalue */
1244 CAMLprim value llvm_params(LLVMValueRef Fn) {
1245   value Params = alloc(LLVMCountParams(Fn), 0);
1246   LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
1247   return Params;
1248 }
1249
1250 /* llvalue -> int32 -> unit */
1251 CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
1252   LLVMAddAttribute(Arg, Int32_val(PA));
1253   return Val_unit;
1254 }
1255
1256 /* llvalue -> int32 -> unit */
1257 CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
1258   LLVMRemoveAttribute(Arg, Int32_val(PA));
1259   return Val_unit;
1260 }
1261
1262 /* llvalue -> int -> unit */
1263 CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
1264   LLVMSetParamAlignment(Arg, Int_val(align));
1265   return Val_unit;
1266 }
1267
1268 /*--... Operations on basic blocks .........................................--*/
1269
1270 DEFINE_ITERATORS(
1271   block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
1272
1273 /* llbasicblock -> llvalue option */
1274 CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block)
1275 {
1276   CAMLparam0();
1277   LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block);
1278   if (Term) {
1279     value Option = alloc(1, 0);
1280     Field(Option, 0) = (value) Term;
1281     CAMLreturn(Option);
1282   }
1283   CAMLreturn(Val_int(0));
1284 }
1285
1286 /* llvalue -> llbasicblock array */
1287 CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
1288   value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
1289   LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray));
1290   return MLArray;
1291 }
1292
1293 /* llbasicblock -> unit */
1294 CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
1295   LLVMDeleteBasicBlock(BB);
1296   return Val_unit;
1297 }
1298
1299 /* llbasicblock -> unit */
1300 CAMLprim value llvm_remove_block(LLVMBasicBlockRef BB) {
1301   LLVMRemoveBasicBlockFromParent(BB);
1302   return Val_unit;
1303 }
1304
1305 /* llbasicblock -> llbasicblock -> unit */
1306 CAMLprim value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
1307   LLVMMoveBasicBlockBefore(BB, Pos);
1308   return Val_unit;
1309 }
1310
1311 /* llbasicblock -> llbasicblock -> unit */
1312 CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
1313   LLVMMoveBasicBlockAfter(BB, Pos);
1314   return Val_unit;
1315 }
1316
1317 /* string -> llvalue -> llbasicblock */
1318 CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
1319                                              LLVMValueRef Fn) {
1320   return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
1321 }
1322
1323 /* string -> llbasicblock -> llbasicblock */
1324 CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
1325                                              LLVMBasicBlockRef BB) {
1326   return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
1327 }
1328
1329 /* llvalue -> bool */
1330 CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
1331   return Val_bool(LLVMValueIsBasicBlock(Val));
1332 }
1333
1334 /*--... Operations on instructions .........................................--*/
1335
1336 DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
1337                  LLVMGetInstructionParent)
1338
1339 /* llvalue -> Opcode.t */
1340 CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) {
1341   LLVMOpcode o;
1342   if (!LLVMIsAInstruction(Inst))
1343       failwith("Not an instruction");
1344   o = LLVMGetInstructionOpcode(Inst);
1345   assert (o <= LLVMLandingPad);
1346   return Val_int(o);
1347 }
1348
1349 /* llvalue -> ICmp.t option */
1350 CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
1351   CAMLparam0();
1352   int x = LLVMGetICmpPredicate(Val);
1353   if (x) {
1354     value Option = alloc(1, 0);
1355     Field(Option, 0) = Val_int(x - LLVMIntEQ);
1356     CAMLreturn(Option);
1357   }
1358   CAMLreturn(Val_int(0));
1359 }
1360
1361 /* llvalue -> llvalue */
1362 CAMLprim LLVMValueRef llvm_instr_clone(LLVMValueRef Inst) {
1363   if (!LLVMIsAInstruction(Inst))
1364       failwith("Not an instruction");
1365   return LLVMInstructionClone(Inst);
1366 }
1367
1368
1369 /*--... Operations on call sites ...........................................--*/
1370
1371 /* llvalue -> int */
1372 CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) {
1373   return Val_int(LLVMGetInstructionCallConv(Inst));
1374 }
1375
1376 /* int -> llvalue -> unit */
1377 CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
1378   LLVMSetInstructionCallConv(Inst, Int_val(CC));
1379   return Val_unit;
1380 }
1381
1382 /* llvalue -> int -> int32 -> unit */
1383 CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
1384                                                value index,
1385                                                value PA) {
1386   LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA));
1387   return Val_unit;
1388 }
1389
1390 /* llvalue -> int -> int32 -> unit */
1391 CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
1392                                                   value index,
1393                                                   value PA) {
1394   LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA));
1395   return Val_unit;
1396 }
1397
1398 /*--... Operations on call instructions (only) .............................--*/
1399
1400 /* llvalue -> bool */
1401 CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
1402   return Val_bool(LLVMIsTailCall(CallInst));
1403 }
1404
1405 /* bool -> llvalue -> unit */
1406 CAMLprim value llvm_set_tail_call(value IsTailCall,
1407                                   LLVMValueRef CallInst) {
1408   LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
1409   return Val_unit;
1410 }
1411
1412 /*--... Operations on load/store instructions (only)........................--*/
1413
1414 /* llvalue -> bool */
1415 CAMLprim value llvm_is_volatile(LLVMValueRef MemoryInst) {
1416   return Val_bool(LLVMGetVolatile(MemoryInst));
1417 }
1418
1419 /* bool -> llvalue -> unit */
1420 CAMLprim value llvm_set_volatile(value IsVolatile,
1421                                   LLVMValueRef MemoryInst) {
1422   LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile));
1423   return Val_unit;
1424 }
1425
1426 /*--... Operations on phi nodes ............................................--*/
1427
1428 /* (llvalue * llbasicblock) -> llvalue -> unit */
1429 CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
1430   LLVMAddIncoming(PhiNode,
1431                   (LLVMValueRef*) &Field(Incoming, 0),
1432                   (LLVMBasicBlockRef*) &Field(Incoming, 1),
1433                   1);
1434   return Val_unit;
1435 }
1436
1437 /* llvalue -> (llvalue * llbasicblock) list */
1438 CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
1439   unsigned I;
1440   CAMLparam0();
1441   CAMLlocal3(Hd, Tl, Tmp);
1442
1443   /* Build a tuple list of them. */
1444   Tl = Val_int(0);
1445   for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
1446     Hd = alloc(2, 0);
1447     Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
1448     Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
1449
1450     Tmp = alloc(2, 0);
1451     Store_field(Tmp, 0, Hd);
1452     Store_field(Tmp, 1, Tl);
1453     Tl = Tmp;
1454   }
1455
1456   CAMLreturn(Tl);
1457 }
1458
1459 /* llvalue -> unit */
1460 CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) {
1461   LLVMInstructionEraseFromParent(Instruction);
1462   return Val_unit;
1463 }
1464
1465 /*===-- Instruction builders ----------------------------------------------===*/
1466
1467 #define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
1468
1469 static void llvm_finalize_builder(value B) {
1470   LLVMDisposeBuilder(Builder_val(B));
1471 }
1472
1473 static struct custom_operations builder_ops = {
1474   (char *) "LLVMIRBuilder",
1475   llvm_finalize_builder,
1476   custom_compare_default,
1477   custom_hash_default,
1478   custom_serialize_default,
1479   custom_deserialize_default
1480 #ifdef custom_compare_ext_default
1481   , custom_compare_ext_default
1482 #endif
1483 };
1484
1485 static value alloc_builder(LLVMBuilderRef B) {
1486   value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
1487   Builder_val(V) = B;
1488   return V;
1489 }
1490
1491 /* llcontext -> llbuilder */
1492 CAMLprim value llvm_builder(LLVMContextRef C) {
1493   return alloc_builder(LLVMCreateBuilderInContext(C));
1494 }
1495
1496 /* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
1497 CAMLprim value llvm_position_builder(value Pos, value B) {
1498   if (Tag_val(Pos) == 0) {
1499     LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
1500     LLVMPositionBuilderAtEnd(Builder_val(B), BB);
1501   } else {
1502     LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
1503     LLVMPositionBuilderBefore(Builder_val(B), I);
1504   }
1505   return Val_unit;
1506 }
1507
1508 /* llbuilder -> llbasicblock */
1509 CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
1510   LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
1511   if (!InsertBlock)
1512     raise_not_found();
1513   return InsertBlock;
1514 }
1515
1516 /* llvalue -> string -> llbuilder -> unit */
1517 CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
1518   LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
1519   return Val_unit;
1520 }
1521
1522 /*--... Metadata ...........................................................--*/
1523
1524 /* llbuilder -> llvalue -> unit */
1525 CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
1526   LLVMSetCurrentDebugLocation(Builder_val(B), V);
1527   return Val_unit;
1528 }
1529
1530 /* llbuilder -> unit */
1531 CAMLprim value llvm_clear_current_debug_location(value B) {
1532   LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
1533   return Val_unit;
1534 }
1535
1536 /* llbuilder -> llvalue option */
1537 CAMLprim value llvm_current_debug_location(value B) {
1538   CAMLparam0();
1539   LLVMValueRef L;
1540   if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
1541     value Option = alloc(1, 0);
1542     Field(Option, 0) = (value) L;
1543     CAMLreturn(Option);
1544   }
1545   CAMLreturn(Val_int(0));
1546 }
1547
1548 /* llbuilder -> llvalue -> unit */
1549 CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
1550   LLVMSetInstDebugLocation(Builder_val(B), V);
1551   return Val_unit;
1552 }
1553
1554
1555 /*--... Terminators ........................................................--*/
1556
1557 /* llbuilder -> llvalue */
1558 CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
1559   return LLVMBuildRetVoid(Builder_val(B));
1560 }
1561
1562 /* llvalue -> llbuilder -> llvalue */
1563 CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
1564   return LLVMBuildRet(Builder_val(B), Val);
1565 }
1566
1567 /* llvalue array -> llbuilder -> llvalue */
1568 CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
1569   return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
1570                                Wosize_val(RetVals));
1571 }
1572
1573 /* llbasicblock -> llbuilder -> llvalue */
1574 CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
1575   return LLVMBuildBr(Builder_val(B), BB);
1576 }
1577
1578 /* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
1579 CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
1580                                          LLVMBasicBlockRef Then,
1581                                          LLVMBasicBlockRef Else,
1582                                          value B) {
1583   return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
1584 }
1585
1586 /* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
1587 CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
1588                                         LLVMBasicBlockRef Else,
1589                                         value EstimatedCount,
1590                                         value B) {
1591   return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
1592 }
1593
1594 /* lltype -> string -> llbuilder -> llvalue */
1595 CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name,
1596                                         value B)
1597 {
1598   return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
1599 }
1600
1601 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
1602 CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty,
1603                                               LLVMValueRef Val,
1604                                               value Name, value B)
1605 {
1606   return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
1607 }
1608
1609 /* llvalue -> llbuilder -> llvalue */
1610 CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B)
1611 {
1612   return LLVMBuildFree(Builder_val(B), P);
1613 }
1614
1615 /* llvalue -> llvalue -> llbasicblock -> unit */
1616 CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
1617                              LLVMBasicBlockRef Dest) {
1618   LLVMAddCase(Switch, OnVal, Dest);
1619   return Val_unit;
1620 }
1621
1622 /* llvalue -> llbasicblock -> llbuilder -> llvalue */
1623 CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
1624                                              value EstimatedDests,
1625                                              value B) {
1626   return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
1627 }
1628
1629 /* llvalue -> llvalue -> llbasicblock -> unit */
1630 CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
1631                                     LLVMBasicBlockRef Dest) {
1632   LLVMAddDestination(IndirectBr, Dest);
1633   return Val_unit;
1634 }
1635
1636 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1637    llbuilder -> llvalue */
1638 CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
1639                                             LLVMBasicBlockRef Then,
1640                                             LLVMBasicBlockRef Catch,
1641                                             value Name, value B) {
1642   return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
1643                          Wosize_val(Args), Then, Catch, String_val(Name));
1644 }
1645
1646 /* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1647    llbuilder -> llvalue */
1648 CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
1649   return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
1650                                (LLVMBasicBlockRef) Args[2],
1651                                (LLVMBasicBlockRef) Args[3],
1652                                Args[4], Args[5]);
1653 }
1654
1655 /* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
1656 CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
1657                                             value NumClauses,  value Name,
1658                                             value B) {
1659     return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
1660                                String_val(Name));
1661 }
1662
1663 /* llvalue -> llvalue -> unit */
1664 CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal)
1665 {
1666     LLVMAddClause(LandingPadInst, ClauseVal);
1667     return Val_unit;
1668 }
1669
1670
1671 /* llvalue -> bool -> unit */
1672 CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
1673 {
1674     LLVMSetCleanup(LandingPadInst, Bool_val(flag));
1675     return Val_unit;
1676 }
1677
1678 /* llvalue -> llbuilder -> llvalue */
1679 CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B)
1680 {
1681     return LLVMBuildResume(Builder_val(B), Exn);
1682 }
1683
1684 /* llbuilder -> llvalue */
1685 CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
1686   return LLVMBuildUnreachable(Builder_val(B));
1687 }
1688
1689 /*--... Arithmetic .........................................................--*/
1690
1691 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1692 CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
1693                                      value Name, value B) {
1694   return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
1695 }
1696
1697 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1698 CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1699                                          value Name, value B) {
1700   return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1701 }
1702
1703 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1704 CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1705                                          value Name, value B) {
1706   return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1707 }
1708
1709 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1710 CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
1711                                       value Name, value B) {
1712   return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
1713 }
1714
1715 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1716 CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1717                                      value Name, value B) {
1718   return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
1719 }
1720
1721 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1722 CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1723                                          value Name, value B) {
1724   return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
1725 }
1726
1727 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1728 CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1729                                          value Name, value B) {
1730   return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
1731 }
1732
1733 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1734 CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
1735                                       value Name, value B) {
1736   return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
1737 }
1738
1739 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1740 CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1741                                      value Name, value B) {
1742   return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
1743 }
1744
1745 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1746 CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1747                                          value Name, value B) {
1748   return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
1749 }
1750
1751 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1752 CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1753                                          value Name, value B) {
1754   return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
1755 }
1756
1757 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1758 CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
1759                                       value Name, value B) {
1760   return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
1761 }
1762
1763 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1764 CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
1765                                       value Name, value B) {
1766   return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
1767 }
1768
1769 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1770 CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1771                                       value Name, value B) {
1772   return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1773 }
1774
1775 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1776 CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1777                                             value Name, value B) {
1778   return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1779 }
1780
1781 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1782 CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1783                                       value Name, value B) {
1784   return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
1785 }
1786
1787 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1788 CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
1789                                       value Name, value B) {
1790   return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
1791 }
1792
1793 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1794 CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
1795                                       value Name, value B) {
1796   return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
1797 }
1798
1799 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1800 CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
1801                                       value Name, value B) {
1802   return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
1803 }
1804
1805 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1806 CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
1807                                      value Name, value B) {
1808   return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
1809 }
1810
1811 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1812 CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
1813                                       value Name, value B) {
1814   return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
1815 }
1816
1817 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1818 CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
1819                                       value Name, value B) {
1820   return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
1821 }
1822
1823 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1824 CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
1825                                      value Name, value B) {
1826   return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
1827 }
1828
1829 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1830 CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
1831                                     value Name, value B) {
1832   return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
1833 }
1834
1835 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1836 CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
1837                                      value Name, value B) {
1838   return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
1839 }
1840
1841 /* llvalue -> string -> llbuilder -> llvalue */
1842 CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
1843                                      value Name, value B) {
1844   return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
1845 }
1846
1847 /* llvalue -> string -> llbuilder -> llvalue */
1848 CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
1849                                          value Name, value B) {
1850   return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
1851 }
1852
1853 /* llvalue -> string -> llbuilder -> llvalue */
1854 CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
1855                                          value Name, value B) {
1856   return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
1857 }
1858
1859 /* llvalue -> string -> llbuilder -> llvalue */
1860 CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
1861                                      value Name, value B) {
1862   return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
1863 }
1864
1865 /* llvalue -> string -> llbuilder -> llvalue */
1866 CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
1867                                      value Name, value B) {
1868   return LLVMBuildNot(Builder_val(B), X, String_val(Name));
1869 }
1870
1871 /*--... Memory .............................................................--*/
1872
1873 /* lltype -> string -> llbuilder -> llvalue */
1874 CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
1875                                         value Name, value B) {
1876   return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
1877 }
1878
1879 /* lltype -> llvalue -> string -> llbuilder -> llvalue */
1880 CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
1881                                               value Name, value B) {
1882   return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
1883 }
1884
1885 /* llvalue -> string -> llbuilder -> llvalue */
1886 CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
1887                                       value Name, value B) {
1888   return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
1889 }
1890
1891 /* llvalue -> llvalue -> llbuilder -> llvalue */
1892 CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
1893                                        value B) {
1894   return LLVMBuildStore(Builder_val(B), Value, Pointer);
1895 }
1896
1897 /* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
1898    bool -> llbuilder -> llvalue */
1899 CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
1900                                                   LLVMValueRef Val, value Ord,
1901                                                   value ST, value Name, value B) {
1902   LLVMValueRef Instr;
1903   Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp),
1904                              Ptr, Val, Int_val(Ord), Bool_val(ST));
1905   LLVMSetValueName(Instr, String_val(Name));
1906   return Instr;
1907 }
1908
1909 CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
1910   return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1],
1911                                      (LLVMValueRef) argv[2], argv[3],
1912                                      argv[4], argv[5], argv[6]);
1913 }
1914
1915 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1916 CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
1917                                      value Name, value B) {
1918   return LLVMBuildGEP(Builder_val(B), Pointer,
1919                       (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
1920                       String_val(Name));
1921 }
1922
1923 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1924 CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
1925                                                value Indices, value Name,
1926                                                value B) {
1927   return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
1928                               (LLVMValueRef *) Op_val(Indices),
1929                               Wosize_val(Indices), String_val(Name));
1930 }
1931
1932 /* llvalue -> int -> string -> llbuilder -> llvalue */
1933 CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
1934                                                value Index, value Name,
1935                                                value B) {
1936   return LLVMBuildStructGEP(Builder_val(B), Pointer,
1937                               Int_val(Index), String_val(Name));
1938 }
1939
1940 /* string -> string -> llbuilder -> llvalue */
1941 CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
1942   return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
1943                                String_val(Name));
1944 }
1945
1946 /* string -> string -> llbuilder -> llvalue */
1947 CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
1948                                                   value B) {
1949   return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
1950                                   String_val(Name));
1951 }
1952
1953 /*--... Casts ..............................................................--*/
1954
1955 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1956 CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
1957                                        value Name, value B) {
1958   return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
1959 }
1960
1961 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1962 CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
1963                                       value Name, value B) {
1964   return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
1965 }
1966
1967 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1968 CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
1969                                       value Name, value B) {
1970   return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
1971 }
1972
1973 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1974 CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
1975                                         value Name, value B) {
1976   return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
1977 }
1978
1979 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1980 CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
1981                                         value Name, value B) {
1982   return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
1983 }
1984
1985 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1986 CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
1987                                         value Name, value B) {
1988   return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
1989 }
1990
1991 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1992 CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
1993                                         value Name, value B) {
1994   return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
1995 }
1996
1997 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
1998 CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
1999                                          value Name, value B) {
2000   return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
2001 }
2002
2003 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2004 CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
2005                                        value Name, value B) {
2006   return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
2007 }
2008
2009 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2010 CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
2011                                           value Name, value B) {
2012   return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
2013 }
2014
2015 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2016 CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
2017                                           value Name, value B) {
2018   return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
2019 }
2020
2021 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2022 CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2023                                          value Name, value B) {
2024   return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
2025 }
2026
2027 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2028 CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2029                                                  value Name, value B) {
2030   return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2031 }
2032
2033 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2034 CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
2035                                                  value Name, value B) {
2036   return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2037 }
2038
2039 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2040 CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
2041                                                   LLVMTypeRef Ty, value Name,
2042                                                   value B) {
2043   return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
2044 }
2045
2046 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2047 CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
2048                                              value Name, value B) {
2049   return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
2050 }
2051
2052 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2053 CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
2054                                          value Name, value B) {
2055   return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
2056 }
2057
2058 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2059 CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
2060                                         value Name, value B) {
2061   return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
2062 }
2063
2064 /*--... Comparisons ........................................................--*/
2065
2066 /* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2067 CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
2068                                       LLVMValueRef LHS, LLVMValueRef RHS,
2069                                       value Name, value B) {
2070   return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
2071                        String_val(Name));
2072 }
2073
2074 /* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2075 CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
2076                                       LLVMValueRef LHS, LLVMValueRef RHS,
2077                                       value Name, value B) {
2078   return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
2079                        String_val(Name));
2080 }
2081
2082 /*--... Miscellaneous instructions .........................................--*/
2083
2084 /* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
2085 CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
2086   value Hd, Tl;
2087   LLVMValueRef FirstValue, PhiNode;
2088
2089   assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
2090
2091   Hd = Field(Incoming, 0);
2092   FirstValue = (LLVMValueRef) Field(Hd, 0);
2093   PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
2094                          String_val(Name));
2095
2096   for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
2097     value Hd = Field(Tl, 0);
2098     LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
2099                     (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
2100   }
2101
2102   return PhiNode;
2103 }
2104
2105 /* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
2106 CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
2107                                       value Name, value B) {
2108   return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
2109                        Wosize_val(Params), String_val(Name));
2110 }
2111
2112 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2113 CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
2114                                         LLVMValueRef Then, LLVMValueRef Else,
2115                                         value Name, value B) {
2116   return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
2117 }
2118
2119 /* llvalue -> lltype -> string -> llbuilder -> llvalue */
2120 CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
2121                                         value Name, value B) {
2122   return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
2123 }
2124
2125 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
2126 CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
2127                                                 LLVMValueRef Idx,
2128                                                 value Name, value B) {
2129   return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
2130 }
2131
2132 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2133 CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
2134                                                LLVMValueRef Element,
2135                                                LLVMValueRef Idx,
2136                                                value Name, value B) {
2137   return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
2138                                 String_val(Name));
2139 }
2140
2141 /* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
2142 CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
2143                                                LLVMValueRef Mask,
2144                                                value Name, value B) {
2145   return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
2146 }
2147
2148 /* llvalue -> int -> string -> llbuilder -> llvalue */
2149 CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
2150                                               value Idx, value Name, value B) {
2151   return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
2152                                String_val(Name));
2153 }
2154
2155 /* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
2156 CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
2157                                              LLVMValueRef Val, value Idx,
2158                                              value Name, value B) {
2159   return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
2160                               String_val(Name));
2161 }
2162
2163 /* llvalue -> string -> llbuilder -> llvalue */
2164 CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
2165                                          value B) {
2166   return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
2167 }
2168
2169 /* llvalue -> string -> llbuilder -> llvalue */
2170 CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
2171                                              value B) {
2172   return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
2173 }
2174
2175 /* llvalue -> llvalue -> string -> llbuilder -> llvalue */
2176 CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
2177                                          value Name, value B) {
2178   return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
2179 }
2180
2181 /*===-- Memory buffers ----------------------------------------------------===*/
2182
2183 /* string -> llmemorybuffer
2184    raises IoError msg on error */
2185 CAMLprim value llvm_memorybuffer_of_file(value Path) {
2186   CAMLparam1(Path);
2187   char *Message;
2188   LLVMMemoryBufferRef MemBuf;
2189
2190   if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
2191                                                &MemBuf, &Message))
2192     llvm_raise(llvm_ioerror_exn, Message);
2193
2194   CAMLreturn((value) MemBuf);
2195 }
2196
2197 /* unit -> llmemorybuffer
2198    raises IoError msg on error */
2199 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
2200   char *Message;
2201   LLVMMemoryBufferRef MemBuf;
2202
2203   if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
2204     llvm_raise(llvm_ioerror_exn, Message);
2205
2206   return MemBuf;
2207 }
2208
2209 /* ?name:string -> string -> llmemorybuffer */
2210 CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
2211   const char *NameCStr;
2212   if(Name == Val_int(0))
2213     NameCStr = "";
2214   else
2215     NameCStr = String_val(Field(Name, 0));
2216
2217   LLVMMemoryBufferRef MemBuf;
2218   MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
2219                 String_val(String), caml_string_length(String), NameCStr);
2220
2221   return MemBuf;
2222 }
2223
2224 /* llmemorybuffer -> string */
2225 CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
2226   value String = caml_alloc_string(LLVMGetBufferSize(MemBuf));
2227   memcpy(String_val(String), LLVMGetBufferStart(MemBuf),
2228          LLVMGetBufferSize(MemBuf));
2229
2230   return String;
2231 }
2232
2233 /* llmemorybuffer -> unit */
2234 CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
2235   LLVMDisposeMemoryBuffer(MemBuf);
2236   return Val_unit;
2237 }
2238
2239 /*===-- Pass Managers -----------------------------------------------------===*/
2240
2241 /* unit -> [ `Module ] PassManager.t */
2242 CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
2243   return LLVMCreatePassManager();
2244 }
2245
2246 /* llmodule -> [ `Function ] PassManager.t -> bool */
2247 CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
2248                                            LLVMPassManagerRef PM) {
2249   return Val_bool(LLVMRunPassManager(PM, M));
2250 }
2251
2252 /* [ `Function ] PassManager.t -> bool */
2253 CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
2254   return Val_bool(LLVMInitializeFunctionPassManager(FPM));
2255 }
2256
2257 /* llvalue -> [ `Function ] PassManager.t -> bool */
2258 CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
2259                                              LLVMPassManagerRef FPM) {
2260   return Val_bool(LLVMRunFunctionPassManager(FPM, F));
2261 }
2262
2263 /* [ `Function ] PassManager.t -> bool */
2264 CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
2265   return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
2266 }
2267
2268 /* PassManager.any PassManager.t -> unit */
2269 CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
2270   LLVMDisposePassManager(PM);
2271   return Val_unit;
2272 }