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