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