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