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