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