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