llvm_ocaml.c revision 31116410de16f435d8c76c53e3d6b95fa812cd2c
1/*===-- llvm_ocaml.c - LLVM Ocaml Glue --------------------------*- C++ -*-===*\
2|*                                                                            *|
3|*                     The LLVM Compiler Infrastructure                       *|
4|*                                                                            *|
5|* This file is distributed under the University of Illinois Open Source      *|
6|* License. See LICENSE.TXT for details.                                      *|
7|*                                                                            *|
8|*===----------------------------------------------------------------------===*|
9|*                                                                            *|
10|* This file glues LLVM's ocaml interface to its C interface. These functions *|
11|* are by and large transparent wrappers to the corresponding C functions.    *|
12|*                                                                            *|
13|* Note that these functions intentionally take liberties with the CAMLparamX *|
14|* macros, since most of the parameters are not GC heap objects.              *|
15|*                                                                            *|
16\*===----------------------------------------------------------------------===*/
17
18#include "llvm-c/Core.h"
19#include "caml/alloc.h"
20#include "caml/custom.h"
21#include "caml/memory.h"
22#include "caml/fail.h"
23#include "caml/callback.h"
24#include "llvm/Config/config.h"
25#include <assert.h>
26#include <stdlib.h>
27#include <string.h>
28
29
30/* Can't use the recommended caml_named_value mechanism for backwards
31   compatibility reasons. This is largely equivalent. */
32static value llvm_ioerror_exn;
33
34CAMLprim value llvm_register_core_exns(value IoError) {
35  llvm_ioerror_exn = Field(IoError, 0);
36  register_global_root(&llvm_ioerror_exn);
37  return Val_unit;
38}
39
40static void llvm_raise(value Prototype, char *Message) {
41  CAMLparam1(Prototype);
42  CAMLlocal1(CamlMessage);
43
44  CamlMessage = copy_string(Message);
45  LLVMDisposeMessage(Message);
46
47  raise_with_arg(Prototype, CamlMessage);
48  abort(); /* NOTREACHED */
49#ifdef CAMLnoreturn
50  CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
51#endif
52}
53
54static value alloc_variant(int tag, void *Value) {
55  value Iter = alloc_small(1, tag);
56  Field(Iter, 0) = Val_op(Value);
57  return Iter;
58}
59
60/* Macro to convert the C first/next/last/prev idiom to the Ocaml llpos/
61   llrev_pos idiom. */
62#define DEFINE_ITERATORS(camlname, cname, pty, cty, pfun) \
63  /* llmodule -> ('a, 'b) llpos */                        \
64  CAMLprim value llvm_##camlname##_begin(pty Mom) {       \
65    cty First = LLVMGetFirst##cname(Mom);                 \
66    if (First)                                            \
67      return alloc_variant(1, First);                     \
68    return alloc_variant(0, Mom);                         \
69  }                                                       \
70                                                          \
71  /* llvalue -> ('a, 'b) llpos */                         \
72  CAMLprim value llvm_##camlname##_succ(cty Kid) {        \
73    cty Next = LLVMGetNext##cname(Kid);                   \
74    if (Next)                                             \
75      return alloc_variant(1, Next);                      \
76    return alloc_variant(0, pfun(Kid));                   \
77  }                                                       \
78                                                          \
79  /* llmodule -> ('a, 'b) llrev_pos */                    \
80  CAMLprim value llvm_##camlname##_end(pty Mom) {         \
81    cty Last = LLVMGetLast##cname(Mom);                   \
82    if (Last)                                             \
83      return alloc_variant(1, Last);                      \
84    return alloc_variant(0, Mom);                         \
85  }                                                       \
86                                                          \
87  /* llvalue -> ('a, 'b) llrev_pos */                     \
88  CAMLprim value llvm_##camlname##_pred(cty Kid) {        \
89    cty Prev = LLVMGetPrevious##cname(Kid);               \
90    if (Prev)                                             \
91      return alloc_variant(1, Prev);                      \
92    return alloc_variant(0, pfun(Kid));                   \
93  }
94
95
96/*===-- Contexts ----------------------------------------------------------===*/
97
98/* unit -> llcontext */
99CAMLprim LLVMContextRef llvm_create_context(value Unit) {
100  return LLVMContextCreate();
101}
102
103/* llcontext -> unit */
104CAMLprim value llvm_dispose_context(LLVMContextRef C) {
105  LLVMContextDispose(C);
106  return Val_unit;
107}
108
109/* unit -> llcontext */
110CAMLprim LLVMContextRef llvm_global_context(value Unit) {
111  return LLVMGetGlobalContext();
112}
113
114/* llcontext -> string -> int */
115CAMLprim value llvm_mdkind_id(LLVMContextRef C, value Name) {
116  unsigned MDKindID = LLVMGetMDKindIDInContext(C, String_val(Name),
117                                               caml_string_length(Name));
118  return Val_int(MDKindID);
119}
120
121/*===-- Modules -----------------------------------------------------------===*/
122
123/* llcontext -> string -> llmodule */
124CAMLprim LLVMModuleRef llvm_create_module(LLVMContextRef C, value ModuleID) {
125  return LLVMModuleCreateWithNameInContext(String_val(ModuleID), C);
126}
127
128/* llmodule -> unit */
129CAMLprim value llvm_dispose_module(LLVMModuleRef M) {
130  LLVMDisposeModule(M);
131  return Val_unit;
132}
133
134/* llmodule -> string */
135CAMLprim value llvm_target_triple(LLVMModuleRef M) {
136  return copy_string(LLVMGetTarget(M));
137}
138
139/* string -> llmodule -> unit */
140CAMLprim value llvm_set_target_triple(value Trip, LLVMModuleRef M) {
141  LLVMSetTarget(M, String_val(Trip));
142  return Val_unit;
143}
144
145/* llmodule -> string */
146CAMLprim value llvm_data_layout(LLVMModuleRef M) {
147  return copy_string(LLVMGetDataLayout(M));
148}
149
150/* string -> llmodule -> unit */
151CAMLprim value llvm_set_data_layout(value Layout, LLVMModuleRef M) {
152  LLVMSetDataLayout(M, String_val(Layout));
153  return Val_unit;
154}
155
156/* llmodule -> unit */
157CAMLprim value llvm_dump_module(LLVMModuleRef M) {
158  LLVMDumpModule(M);
159  return Val_unit;
160}
161
162/* llmodule -> string -> unit */
163CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
164  LLVMSetModuleInlineAsm(M, String_val(Asm));
165  return Val_unit;
166}
167
168/*===-- Types -------------------------------------------------------------===*/
169
170/* lltype -> TypeKind.t */
171CAMLprim value llvm_classify_type(LLVMTypeRef Ty) {
172  return Val_int(LLVMGetTypeKind(Ty));
173}
174
175CAMLprim value llvm_type_is_sized(LLVMTypeRef Ty) {
176    return Val_bool(LLVMTypeIsSized(Ty));
177}
178
179/* lltype -> llcontext */
180CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) {
181  return LLVMGetTypeContext(Ty);
182}
183
184/*--... Operations on integer types ........................................--*/
185
186/* llcontext -> lltype */
187CAMLprim LLVMTypeRef llvm_i1_type (LLVMContextRef Context) {
188  return LLVMInt1TypeInContext(Context);
189}
190
191/* llcontext -> lltype */
192CAMLprim LLVMTypeRef llvm_i8_type (LLVMContextRef Context) {
193  return LLVMInt8TypeInContext(Context);
194}
195
196/* llcontext -> lltype */
197CAMLprim LLVMTypeRef llvm_i16_type (LLVMContextRef Context) {
198  return LLVMInt16TypeInContext(Context);
199}
200
201/* llcontext -> lltype */
202CAMLprim LLVMTypeRef llvm_i32_type (LLVMContextRef Context) {
203  return LLVMInt32TypeInContext(Context);
204}
205
206/* llcontext -> lltype */
207CAMLprim LLVMTypeRef llvm_i64_type (LLVMContextRef Context) {
208  return LLVMInt64TypeInContext(Context);
209}
210
211/* llcontext -> int -> lltype */
212CAMLprim LLVMTypeRef llvm_integer_type(LLVMContextRef Context, value Width) {
213  return LLVMIntTypeInContext(Context, Int_val(Width));
214}
215
216/* lltype -> int */
217CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) {
218  return Val_int(LLVMGetIntTypeWidth(IntegerTy));
219}
220
221/*--... Operations on real types ...........................................--*/
222
223/* llcontext -> lltype */
224CAMLprim LLVMTypeRef llvm_float_type(LLVMContextRef Context) {
225  return LLVMFloatTypeInContext(Context);
226}
227
228/* llcontext -> lltype */
229CAMLprim LLVMTypeRef llvm_double_type(LLVMContextRef Context) {
230  return LLVMDoubleTypeInContext(Context);
231}
232
233/* llcontext -> lltype */
234CAMLprim LLVMTypeRef llvm_x86fp80_type(LLVMContextRef Context) {
235  return LLVMX86FP80TypeInContext(Context);
236}
237
238/* llcontext -> lltype */
239CAMLprim LLVMTypeRef llvm_fp128_type(LLVMContextRef Context) {
240  return LLVMFP128TypeInContext(Context);
241}
242
243/* llcontext -> lltype */
244CAMLprim LLVMTypeRef llvm_ppc_fp128_type(LLVMContextRef Context) {
245  return LLVMPPCFP128TypeInContext(Context);
246}
247
248/* llcontext -> lltype */
249CAMLprim LLVMTypeRef llvm_x86mmx_type(LLVMContextRef Context) {
250  return LLVMX86MMXTypeInContext(Context);
251}
252
253/*--... Operations on function types .......................................--*/
254
255/* lltype -> lltype array -> lltype */
256CAMLprim LLVMTypeRef llvm_function_type(LLVMTypeRef RetTy, value ParamTys) {
257  return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
258                          Wosize_val(ParamTys), 0);
259}
260
261/* lltype -> lltype array -> lltype */
262CAMLprim LLVMTypeRef llvm_var_arg_function_type(LLVMTypeRef RetTy,
263                                                value ParamTys) {
264  return LLVMFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
265                          Wosize_val(ParamTys), 1);
266}
267
268/* lltype -> bool */
269CAMLprim value llvm_is_var_arg(LLVMTypeRef FunTy) {
270  return Val_bool(LLVMIsFunctionVarArg(FunTy));
271}
272
273/* lltype -> lltype array */
274CAMLprim value llvm_param_types(LLVMTypeRef FunTy) {
275  value Tys = alloc(LLVMCountParamTypes(FunTy), 0);
276  LLVMGetParamTypes(FunTy, (LLVMTypeRef *) Tys);
277  return Tys;
278}
279
280/*--... Operations on struct types .........................................--*/
281
282/* llcontext -> lltype array -> lltype */
283CAMLprim LLVMTypeRef llvm_struct_type(LLVMContextRef C, value ElementTypes) {
284  return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
285                                 Wosize_val(ElementTypes), 0);
286}
287
288/* llcontext -> lltype array -> lltype */
289CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C,
290                                             value ElementTypes) {
291  return LLVMStructTypeInContext(C, (LLVMTypeRef *) ElementTypes,
292                                 Wosize_val(ElementTypes), 1);
293}
294
295/* lltype -> string option */
296CAMLprim value llvm_struct_name(LLVMTypeRef Ty)
297{
298  CAMLparam0();
299  const char *C = LLVMGetStructName(Ty);
300  if (C) {
301    CAMLlocal1(result);
302    result = caml_alloc_small(1, 0);
303    Store_field(result, 0, caml_copy_string(C));
304    CAMLreturn(result);
305  }
306  CAMLreturn(Val_int(0));
307}
308
309/* lltype -> lltype array */
310CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) {
311  value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
312  LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
313  return Tys;
314}
315
316/* lltype -> bool */
317CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
318  return Val_bool(LLVMIsPackedStruct(StructTy));
319}
320
321/*--... Operations on array, pointer, and vector types .....................--*/
322
323/* lltype -> int -> lltype */
324CAMLprim LLVMTypeRef llvm_array_type(LLVMTypeRef ElementTy, value Count) {
325  return LLVMArrayType(ElementTy, Int_val(Count));
326}
327
328/* lltype -> lltype */
329CAMLprim LLVMTypeRef llvm_pointer_type(LLVMTypeRef ElementTy) {
330  return LLVMPointerType(ElementTy, 0);
331}
332
333/* lltype -> int -> lltype */
334CAMLprim LLVMTypeRef llvm_qualified_pointer_type(LLVMTypeRef ElementTy,
335                                                 value AddressSpace) {
336  return LLVMPointerType(ElementTy, Int_val(AddressSpace));
337}
338
339/* lltype -> int -> lltype */
340CAMLprim LLVMTypeRef llvm_vector_type(LLVMTypeRef ElementTy, value Count) {
341  return LLVMVectorType(ElementTy, Int_val(Count));
342}
343
344/* lltype -> int */
345CAMLprim value llvm_array_length(LLVMTypeRef ArrayTy) {
346  return Val_int(LLVMGetArrayLength(ArrayTy));
347}
348
349/* lltype -> int */
350CAMLprim value llvm_address_space(LLVMTypeRef PtrTy) {
351  return Val_int(LLVMGetPointerAddressSpace(PtrTy));
352}
353
354/* lltype -> int */
355CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) {
356  return Val_int(LLVMGetVectorSize(VectorTy));
357}
358
359/*--... Operations on other types ..........................................--*/
360
361/* llcontext -> lltype */
362CAMLprim LLVMTypeRef llvm_void_type (LLVMContextRef Context) {
363  return LLVMVoidTypeInContext(Context);
364}
365
366/* llcontext -> lltype */
367CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) {
368  return LLVMLabelTypeInContext(Context);
369}
370
371/*===-- VALUES ------------------------------------------------------------===*/
372
373/* llvalue -> lltype */
374CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) {
375  return LLVMTypeOf(Val);
376}
377
378/* llvalue -> string */
379CAMLprim value llvm_value_name(LLVMValueRef Val) {
380  return copy_string(LLVMGetValueName(Val));
381}
382
383/* string -> llvalue -> unit */
384CAMLprim value llvm_set_value_name(value Name, LLVMValueRef Val) {
385  LLVMSetValueName(Val, String_val(Name));
386  return Val_unit;
387}
388
389/* llvalue -> unit */
390CAMLprim value llvm_dump_value(LLVMValueRef Val) {
391  LLVMDumpValue(Val);
392  return Val_unit;
393}
394
395/*--... Operations on users ................................................--*/
396
397/* llvalue -> int -> llvalue */
398CAMLprim LLVMValueRef llvm_operand(LLVMValueRef V, value I) {
399  return LLVMGetOperand(V, Int_val(I));
400}
401
402/* llvalue -> int -> llvalue -> unit */
403CAMLprim value llvm_set_operand(LLVMValueRef U, value I, LLVMValueRef V) {
404  LLVMSetOperand(U, Int_val(I), V);
405  return Val_unit;
406}
407
408/* llvalue -> int */
409CAMLprim value llvm_num_operands(LLVMValueRef V) {
410  return Val_int(LLVMGetNumOperands(V));
411}
412
413/*--... Operations on constants of (mostly) any type .......................--*/
414
415/* llvalue -> bool */
416CAMLprim value llvm_is_constant(LLVMValueRef Val) {
417  return Val_bool(LLVMIsConstant(Val));
418}
419
420/* llvalue -> bool */
421CAMLprim value llvm_is_null(LLVMValueRef Val) {
422  return Val_bool(LLVMIsNull(Val));
423}
424
425/* llvalue -> bool */
426CAMLprim value llvm_is_undef(LLVMValueRef Val) {
427  return Val_bool(LLVMIsUndef(Val));
428}
429
430/*--... Operations on instructions .........................................--*/
431
432/* llvalue -> bool */
433CAMLprim value llvm_has_metadata(LLVMValueRef Val) {
434  return Val_bool(LLVMHasMetadata(Val));
435}
436
437/* llvalue -> int -> llvalue option */
438CAMLprim value llvm_metadata(LLVMValueRef Val, value MDKindID) {
439  CAMLparam1(MDKindID);
440  LLVMValueRef MD;
441  if ((MD = LLVMGetMetadata(Val, Int_val(MDKindID)))) {
442    value Option = alloc(1, 0);
443    Field(Option, 0) = (value) MD;
444    CAMLreturn(Option);
445  }
446  CAMLreturn(Val_int(0));
447}
448
449/* llvalue -> int -> llvalue -> unit */
450CAMLprim value llvm_set_metadata(LLVMValueRef Val, value MDKindID,
451                                 LLVMValueRef MD) {
452  LLVMSetMetadata(Val, Int_val(MDKindID), MD);
453  return Val_unit;
454}
455
456/* llvalue -> int -> unit */
457CAMLprim value llvm_clear_metadata(LLVMValueRef Val, value MDKindID) {
458  LLVMSetMetadata(Val, Int_val(MDKindID), NULL);
459  return Val_unit;
460}
461
462
463/*--... Operations on metadata .............................................--*/
464
465/* llcontext -> string -> llvalue */
466CAMLprim LLVMValueRef llvm_mdstring(LLVMContextRef C, value S) {
467  return LLVMMDStringInContext(C, String_val(S), caml_string_length(S));
468}
469
470/* llcontext -> llvalue array -> llvalue */
471CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) {
472  return LLVMMDNodeInContext(C, (LLVMValueRef*) Op_val(ElementVals),
473                             Wosize_val(ElementVals));
474}
475
476/* llvalue -> string option */
477CAMLprim value llvm_get_mdstring(LLVMValueRef V) {
478  CAMLparam0();
479  const char *S;
480  unsigned Len;
481
482  if ((S = LLVMGetMDString(V, &Len))) {
483    CAMLlocal2(Option, Str);
484
485    Str = caml_alloc_string(Len);
486    memcpy(String_val(Str), S, Len);
487    Option = alloc(1,0);
488    Store_field(Option, 0, Str);
489    CAMLreturn(Option);
490  }
491  CAMLreturn(Val_int(0));
492}
493
494CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value name)
495{
496  CAMLparam1(name);
497  CAMLlocal1(Nodes);
498  Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(name)), 0);
499  LLVMGetNamedMetadataOperands(M, String_val(name), (LLVMValueRef *) Nodes);
500  CAMLreturn(Nodes);
501}
502/*--... Operations on scalar constants .....................................--*/
503
504/* lltype -> int -> llvalue */
505CAMLprim LLVMValueRef llvm_const_int(LLVMTypeRef IntTy, value N) {
506  return LLVMConstInt(IntTy, (long long) Int_val(N), 1);
507}
508
509/* lltype -> Int64.t -> bool -> llvalue */
510CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N,
511                                          value SExt) {
512  return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt));
513}
514
515/* lltype -> string -> int -> llvalue */
516CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S,
517                                               value Radix) {
518  return LLVMConstIntOfStringAndSize(IntTy, String_val(S), caml_string_length(S),
519                                     Int_val(Radix));
520}
521
522/* lltype -> float -> llvalue */
523CAMLprim LLVMValueRef llvm_const_float(LLVMTypeRef RealTy, value N) {
524  return LLVMConstReal(RealTy, Double_val(N));
525}
526
527/* lltype -> string -> llvalue */
528CAMLprim LLVMValueRef llvm_const_float_of_string(LLVMTypeRef RealTy, value S) {
529  return LLVMConstRealOfStringAndSize(RealTy, String_val(S),
530                                      caml_string_length(S));
531}
532
533/*--... Operations on composite constants ..................................--*/
534
535/* llcontext -> string -> llvalue */
536CAMLprim LLVMValueRef llvm_const_string(LLVMContextRef Context, value Str,
537                                        value NullTerminate) {
538  return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
539                                  1);
540}
541
542/* llcontext -> string -> llvalue */
543CAMLprim LLVMValueRef llvm_const_stringz(LLVMContextRef Context, value Str,
544                                         value NullTerminate) {
545  return LLVMConstStringInContext(Context, String_val(Str), string_length(Str),
546                                  0);
547}
548
549/* lltype -> llvalue array -> llvalue */
550CAMLprim LLVMValueRef llvm_const_array(LLVMTypeRef ElementTy,
551                                               value ElementVals) {
552  return LLVMConstArray(ElementTy, (LLVMValueRef*) Op_val(ElementVals),
553                        Wosize_val(ElementVals));
554}
555
556/* llcontext -> llvalue array -> llvalue */
557CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) {
558  return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
559                                  Wosize_val(ElementVals), 0);
560}
561
562/* llcontext -> llvalue array -> llvalue */
563CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C,
564                                               value ElementVals) {
565  return LLVMConstStructInContext(C, (LLVMValueRef *) Op_val(ElementVals),
566                                  Wosize_val(ElementVals), 1);
567}
568
569/* llvalue array -> llvalue */
570CAMLprim LLVMValueRef llvm_const_vector(value ElementVals) {
571  return LLVMConstVector((LLVMValueRef*) Op_val(ElementVals),
572                         Wosize_val(ElementVals));
573}
574
575/*--... Constant expressions ...............................................--*/
576
577/* Icmp.t -> llvalue -> llvalue -> llvalue */
578CAMLprim LLVMValueRef llvm_const_icmp(value Pred,
579                                      LLVMValueRef LHSConstant,
580                                      LLVMValueRef RHSConstant) {
581  return LLVMConstICmp(Int_val(Pred) + LLVMIntEQ, LHSConstant, RHSConstant);
582}
583
584/* Fcmp.t -> llvalue -> llvalue -> llvalue */
585CAMLprim LLVMValueRef llvm_const_fcmp(value Pred,
586                                      LLVMValueRef LHSConstant,
587                                      LLVMValueRef RHSConstant) {
588  return LLVMConstFCmp(Int_val(Pred), LHSConstant, RHSConstant);
589}
590
591/* llvalue -> llvalue array -> llvalue */
592CAMLprim LLVMValueRef llvm_const_gep(LLVMValueRef ConstantVal, value Indices) {
593  return LLVMConstGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
594                      Wosize_val(Indices));
595}
596
597/* llvalue -> llvalue array -> llvalue */
598CAMLprim LLVMValueRef llvm_const_in_bounds_gep(LLVMValueRef ConstantVal,
599                                               value Indices) {
600  return LLVMConstInBoundsGEP(ConstantVal, (LLVMValueRef*) Op_val(Indices),
601                              Wosize_val(Indices));
602}
603
604/* llvalue -> int array -> llvalue */
605CAMLprim LLVMValueRef llvm_const_extractvalue(LLVMValueRef Aggregate,
606                                              value Indices) {
607  CAMLparam1(Indices);
608  int size = Wosize_val(Indices);
609  int i;
610  LLVMValueRef result;
611
612  unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
613  for (i = 0; i < size; i++) {
614    idxs[i] = Int_val(Field(Indices, i));
615  }
616
617  result = LLVMConstExtractValue(Aggregate, idxs, size);
618  free(idxs);
619  CAMLreturnT(LLVMValueRef, result);
620}
621
622/* llvalue -> llvalue -> int array -> llvalue */
623CAMLprim LLVMValueRef llvm_const_insertvalue(LLVMValueRef Aggregate,
624                                             LLVMValueRef Val, value Indices) {
625  CAMLparam1(Indices);
626  int size = Wosize_val(Indices);
627  int i;
628  LLVMValueRef result;
629
630  unsigned* idxs = (unsigned*)malloc(size * sizeof(unsigned));
631  for (i = 0; i < size; i++) {
632    idxs[i] = Int_val(Field(Indices, i));
633  }
634
635  result = LLVMConstInsertValue(Aggregate, Val, idxs, size);
636  free(idxs);
637  CAMLreturnT(LLVMValueRef, result);
638}
639
640/* lltype -> string -> string -> bool -> bool -> llvalue */
641CAMLprim LLVMValueRef llvm_const_inline_asm(LLVMTypeRef Ty, value Asm,
642                                     value Constraints, value HasSideEffects,
643                                     value IsAlignStack) {
644  return LLVMConstInlineAsm(Ty, String_val(Asm), String_val(Constraints),
645                            Bool_val(HasSideEffects), Bool_val(IsAlignStack));
646}
647
648/*--... Operations on global variables, functions, and aliases (globals) ...--*/
649
650/* llvalue -> bool */
651CAMLprim value llvm_is_declaration(LLVMValueRef Global) {
652  return Val_bool(LLVMIsDeclaration(Global));
653}
654
655/* llvalue -> Linkage.t */
656CAMLprim value llvm_linkage(LLVMValueRef Global) {
657  return Val_int(LLVMGetLinkage(Global));
658}
659
660/* Linkage.t -> llvalue -> unit */
661CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
662  LLVMSetLinkage(Global, Int_val(Linkage));
663  return Val_unit;
664}
665
666/* llvalue -> string */
667CAMLprim value llvm_section(LLVMValueRef Global) {
668  return copy_string(LLVMGetSection(Global));
669}
670
671/* string -> llvalue -> unit */
672CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) {
673  LLVMSetSection(Global, String_val(Section));
674  return Val_unit;
675}
676
677/* llvalue -> Visibility.t */
678CAMLprim value llvm_visibility(LLVMValueRef Global) {
679  return Val_int(LLVMGetVisibility(Global));
680}
681
682/* Visibility.t -> llvalue -> unit */
683CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
684  LLVMSetVisibility(Global, Int_val(Viz));
685  return Val_unit;
686}
687
688/* llvalue -> int */
689CAMLprim value llvm_alignment(LLVMValueRef Global) {
690  return Val_int(LLVMGetAlignment(Global));
691}
692
693/* int -> llvalue -> unit */
694CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
695  LLVMSetAlignment(Global, Int_val(Bytes));
696  return Val_unit;
697}
698
699/*--... Operations on uses .................................................--*/
700
701/* llvalue -> lluse option */
702CAMLprim value llvm_use_begin(LLVMValueRef Val) {
703  CAMLparam0();
704  LLVMUseRef First;
705  if ((First = LLVMGetFirstUse(Val))) {
706    value Option = alloc(1, 0);
707    Field(Option, 0) = (value) First;
708    CAMLreturn(Option);
709  }
710  CAMLreturn(Val_int(0));
711}
712
713/* lluse -> lluse option */
714CAMLprim value llvm_use_succ(LLVMUseRef U) {
715  CAMLparam0();
716  LLVMUseRef Next;
717  if ((Next = LLVMGetNextUse(U))) {
718    value Option = alloc(1, 0);
719    Field(Option, 0) = (value) Next;
720    CAMLreturn(Option);
721  }
722  CAMLreturn(Val_int(0));
723}
724
725/* lluse -> llvalue */
726CAMLprim LLVMValueRef llvm_user(LLVMUseRef UR) {
727  return LLVMGetUser(UR);
728}
729
730/* lluse -> llvalue */
731CAMLprim LLVMValueRef llvm_used_value(LLVMUseRef UR) {
732  return LLVMGetUsedValue(UR);
733}
734
735/*--... Operations on global variables .....................................--*/
736
737DEFINE_ITERATORS(global, Global, LLVMModuleRef, LLVMValueRef,
738                 LLVMGetGlobalParent)
739
740/* lltype -> string -> llmodule -> llvalue */
741CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
742                                          LLVMModuleRef M) {
743  LLVMValueRef GlobalVar;
744  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
745    if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
746      return LLVMConstBitCast(GlobalVar, LLVMPointerType(Ty, 0));
747    return GlobalVar;
748  }
749  return LLVMAddGlobal(M, Ty, String_val(Name));
750}
751
752/* lltype -> string -> int -> llmodule -> llvalue */
753CAMLprim LLVMValueRef llvm_declare_qualified_global(LLVMTypeRef Ty, value Name,
754                                                    value AddressSpace,
755                                                    LLVMModuleRef M) {
756  LLVMValueRef GlobalVar;
757  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
758    if (LLVMGetElementType(LLVMTypeOf(GlobalVar)) != Ty)
759      return LLVMConstBitCast(GlobalVar,
760                              LLVMPointerType(Ty, Int_val(AddressSpace)));
761    return GlobalVar;
762  }
763  return LLVMAddGlobal(M, Ty, String_val(Name));
764}
765
766/* string -> llmodule -> llvalue option */
767CAMLprim value llvm_lookup_global(value Name, LLVMModuleRef M) {
768  CAMLparam1(Name);
769  LLVMValueRef GlobalVar;
770  if ((GlobalVar = LLVMGetNamedGlobal(M, String_val(Name)))) {
771    value Option = alloc(1, 0);
772    Field(Option, 0) = (value) GlobalVar;
773    CAMLreturn(Option);
774  }
775  CAMLreturn(Val_int(0));
776}
777
778/* string -> llvalue -> llmodule -> llvalue */
779CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
780                                         LLVMModuleRef M) {
781  LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer),
782                                         String_val(Name));
783  LLVMSetInitializer(GlobalVar, Initializer);
784  return GlobalVar;
785}
786
787/* string -> llvalue -> int -> llmodule -> llvalue */
788CAMLprim LLVMValueRef llvm_define_qualified_global(value Name,
789                                                   LLVMValueRef Initializer,
790                                                   value AddressSpace,
791                                                   LLVMModuleRef M) {
792  LLVMValueRef GlobalVar = LLVMAddGlobalInAddressSpace(M,
793                                                       LLVMTypeOf(Initializer),
794                                                       String_val(Name),
795                                                       Int_val(AddressSpace));
796  LLVMSetInitializer(GlobalVar, Initializer);
797  return GlobalVar;
798}
799
800/* llvalue -> unit */
801CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
802  LLVMDeleteGlobal(GlobalVar);
803  return Val_unit;
804}
805
806/* llvalue -> llvalue -> unit */
807CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal,
808                                    LLVMValueRef GlobalVar) {
809  LLVMSetInitializer(GlobalVar, ConstantVal);
810  return Val_unit;
811}
812
813/* llvalue -> unit */
814CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) {
815  LLVMSetInitializer(GlobalVar, NULL);
816  return Val_unit;
817}
818
819/* llvalue -> bool */
820CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) {
821  return Val_bool(LLVMIsThreadLocal(GlobalVar));
822}
823
824/* bool -> llvalue -> unit */
825CAMLprim value llvm_set_thread_local(value IsThreadLocal,
826                                     LLVMValueRef GlobalVar) {
827  LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
828  return Val_unit;
829}
830
831/* llvalue -> bool */
832CAMLprim value llvm_is_global_constant(LLVMValueRef GlobalVar) {
833  return Val_bool(LLVMIsGlobalConstant(GlobalVar));
834}
835
836/* bool -> llvalue -> unit */
837CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
838  LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
839  return Val_unit;
840}
841
842/*--... Operations on aliases ..............................................--*/
843
844CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
845                                     LLVMValueRef Aliasee, value Name) {
846  return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
847}
848
849/*--... Operations on functions ............................................--*/
850
851DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
852                 LLVMGetGlobalParent)
853
854/* string -> lltype -> llmodule -> llvalue */
855CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
856                                            LLVMModuleRef M) {
857  LLVMValueRef Fn;
858  if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
859    if (LLVMGetElementType(LLVMTypeOf(Fn)) != Ty)
860      return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
861    return Fn;
862  }
863  return LLVMAddFunction(M, String_val(Name), Ty);
864}
865
866/* string -> llmodule -> llvalue option */
867CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) {
868  CAMLparam1(Name);
869  LLVMValueRef Fn;
870  if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
871    value Option = alloc(1, 0);
872    Field(Option, 0) = (value) Fn;
873    CAMLreturn(Option);
874  }
875  CAMLreturn(Val_int(0));
876}
877
878/* string -> lltype -> llmodule -> llvalue */
879CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
880                                           LLVMModuleRef M) {
881  LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
882  LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
883  return Fn;
884}
885
886/* llvalue -> unit */
887CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
888  LLVMDeleteFunction(Fn);
889  return Val_unit;
890}
891
892/* llvalue -> bool */
893CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) {
894  return Val_bool(LLVMGetIntrinsicID(Fn));
895}
896
897/* llvalue -> int */
898CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) {
899  return Val_int(LLVMGetFunctionCallConv(Fn));
900}
901
902/* int -> llvalue -> unit */
903CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
904  LLVMSetFunctionCallConv(Fn, Int_val(Id));
905  return Val_unit;
906}
907
908/* llvalue -> string option */
909CAMLprim value llvm_gc(LLVMValueRef Fn) {
910  const char *GC;
911  CAMLparam0();
912  CAMLlocal2(Name, Option);
913
914  if ((GC = LLVMGetGC(Fn))) {
915    Name = copy_string(GC);
916
917    Option = alloc(1, 0);
918    Field(Option, 0) = Name;
919    CAMLreturn(Option);
920  } else {
921    CAMLreturn(Val_int(0));
922  }
923}
924
925/* string option -> llvalue -> unit */
926CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
927  LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
928  return Val_unit;
929}
930
931/* llvalue -> Attribute.t -> unit */
932CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
933  LLVMAddFunctionAttr(Arg, Int_val(PA));
934  return Val_unit;
935}
936
937/* llvalue -> Attribute.t -> unit */
938CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
939  LLVMRemoveFunctionAttr(Arg, Int_val(PA));
940  return Val_unit;
941}
942/*--... Operations on parameters ...........................................--*/
943
944DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
945
946/* llvalue -> int -> llvalue */
947CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
948  return LLVMGetParam(Fn, Int_val(Index));
949}
950
951/* llvalue -> llvalue */
952CAMLprim value llvm_params(LLVMValueRef Fn) {
953  value Params = alloc(LLVMCountParams(Fn), 0);
954  LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
955  return Params;
956}
957
958/* llvalue -> Attribute.t -> unit */
959CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
960  LLVMAddAttribute(Arg, Int_val(PA));
961  return Val_unit;
962}
963
964/* llvalue -> Attribute.t -> unit */
965CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
966  LLVMRemoveAttribute(Arg, Int_val(PA));
967  return Val_unit;
968}
969
970/* llvalue -> int -> unit */
971CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
972  LLVMSetParamAlignment(Arg, Int_val(align));
973  return Val_unit;
974}
975
976/*--... Operations on basic blocks .........................................--*/
977
978DEFINE_ITERATORS(
979  block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
980
981/* llvalue -> llbasicblock array */
982CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
983  value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
984  LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray));
985  return MLArray;
986}
987
988/* llbasicblock -> unit */
989CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
990  LLVMDeleteBasicBlock(BB);
991  return Val_unit;
992}
993
994/* string -> llvalue -> llbasicblock */
995CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
996                                             LLVMValueRef Fn) {
997  return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
998}
999
1000/* string -> llbasicblock -> llbasicblock */
1001CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
1002                                             LLVMBasicBlockRef BB) {
1003  return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
1004}
1005
1006/* llvalue -> bool */
1007CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
1008  return Val_bool(LLVMValueIsBasicBlock(Val));
1009}
1010
1011/*--... Operations on instructions .........................................--*/
1012
1013DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
1014                 LLVMGetInstructionParent)
1015
1016
1017/* llvalue -> ICmp.t */
1018CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
1019  CAMLparam0();
1020  int x = LLVMGetICmpPredicate(Val);
1021  if (x) {
1022    value Option = alloc(1, 0);
1023    Field(Option, 0) = Val_int(x - LLVMIntEQ);
1024    CAMLreturn(Option);
1025  }
1026  CAMLreturn(Val_int(0));
1027}
1028
1029
1030/*--... Operations on call sites ...........................................--*/
1031
1032/* llvalue -> int */
1033CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) {
1034  return Val_int(LLVMGetInstructionCallConv(Inst));
1035}
1036
1037/* int -> llvalue -> unit */
1038CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
1039  LLVMSetInstructionCallConv(Inst, Int_val(CC));
1040  return Val_unit;
1041}
1042
1043/* llvalue -> int -> Attribute.t -> unit */
1044CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
1045                                               value index,
1046                                               value PA) {
1047  LLVMAddInstrAttribute(Instr, Int_val(index), Int_val(PA));
1048  return Val_unit;
1049}
1050
1051/* llvalue -> int -> Attribute.t -> unit */
1052CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
1053                                                  value index,
1054                                                  value PA) {
1055  LLVMRemoveInstrAttribute(Instr, Int_val(index), Int_val(PA));
1056  return Val_unit;
1057}
1058
1059/*--... Operations on call instructions (only) .............................--*/
1060
1061/* llvalue -> bool */
1062CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
1063  return Val_bool(LLVMIsTailCall(CallInst));
1064}
1065
1066/* bool -> llvalue -> unit */
1067CAMLprim value llvm_set_tail_call(value IsTailCall,
1068                                  LLVMValueRef CallInst) {
1069  LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
1070  return Val_unit;
1071}
1072
1073/*--... Operations on phi nodes ............................................--*/
1074
1075/* (llvalue * llbasicblock) -> llvalue -> unit */
1076CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
1077  LLVMAddIncoming(PhiNode,
1078                  (LLVMValueRef*) &Field(Incoming, 0),
1079                  (LLVMBasicBlockRef*) &Field(Incoming, 1),
1080                  1);
1081  return Val_unit;
1082}
1083
1084/* llvalue -> (llvalue * llbasicblock) list */
1085CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
1086  unsigned I;
1087  CAMLparam0();
1088  CAMLlocal3(Hd, Tl, Tmp);
1089
1090  /* Build a tuple list of them. */
1091  Tl = Val_int(0);
1092  for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
1093    Hd = alloc(2, 0);
1094    Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
1095    Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
1096
1097    Tmp = alloc(2, 0);
1098    Store_field(Tmp, 0, Hd);
1099    Store_field(Tmp, 1, Tl);
1100    Tl = Tmp;
1101  }
1102
1103  CAMLreturn(Tl);
1104}
1105
1106
1107/*===-- Instruction builders ----------------------------------------------===*/
1108
1109#define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
1110
1111static void llvm_finalize_builder(value B) {
1112  LLVMDisposeBuilder(Builder_val(B));
1113}
1114
1115static struct custom_operations builder_ops = {
1116  (char *) "IRBuilder",
1117  llvm_finalize_builder,
1118  custom_compare_default,
1119  custom_hash_default,
1120  custom_serialize_default,
1121  custom_deserialize_default
1122};
1123
1124static value alloc_builder(LLVMBuilderRef B) {
1125  value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
1126  Builder_val(V) = B;
1127  return V;
1128}
1129
1130/* llcontext -> llbuilder */
1131CAMLprim value llvm_builder(LLVMContextRef C) {
1132  return alloc_builder(LLVMCreateBuilderInContext(C));
1133}
1134
1135/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
1136CAMLprim value llvm_position_builder(value Pos, value B) {
1137  if (Tag_val(Pos) == 0) {
1138    LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
1139    LLVMPositionBuilderAtEnd(Builder_val(B), BB);
1140  } else {
1141    LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
1142    LLVMPositionBuilderBefore(Builder_val(B), I);
1143  }
1144  return Val_unit;
1145}
1146
1147/* llbuilder -> llbasicblock */
1148CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
1149  LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
1150  if (!InsertBlock)
1151    raise_not_found();
1152  return InsertBlock;
1153}
1154
1155/* llvalue -> string -> llbuilder -> unit */
1156CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
1157  LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
1158  return Val_unit;
1159}
1160
1161/*--... Metadata ...........................................................--*/
1162
1163/* llbuilder -> llvalue -> unit */
1164CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
1165  LLVMSetCurrentDebugLocation(Builder_val(B), V);
1166  return Val_unit;
1167}
1168
1169/* llbuilder -> unit */
1170CAMLprim value llvm_clear_current_debug_location(value B) {
1171  LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
1172  return Val_unit;
1173}
1174
1175/* llbuilder -> llvalue option */
1176CAMLprim value llvm_current_debug_location(value B) {
1177  CAMLparam0();
1178  LLVMValueRef L;
1179  if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
1180    value Option = alloc(1, 0);
1181    Field(Option, 0) = (value) L;
1182    CAMLreturn(Option);
1183  }
1184  CAMLreturn(Val_int(0));
1185}
1186
1187/* llbuilder -> llvalue -> unit */
1188CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
1189  LLVMSetInstDebugLocation(Builder_val(B), V);
1190  return Val_unit;
1191}
1192
1193
1194/*--... Terminators ........................................................--*/
1195
1196/* llbuilder -> llvalue */
1197CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
1198  return LLVMBuildRetVoid(Builder_val(B));
1199}
1200
1201/* llvalue -> llbuilder -> llvalue */
1202CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
1203  return LLVMBuildRet(Builder_val(B), Val);
1204}
1205
1206/* llvalue array -> llbuilder -> llvalue */
1207CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
1208  return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
1209                               Wosize_val(RetVals));
1210}
1211
1212/* llbasicblock -> llbuilder -> llvalue */
1213CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
1214  return LLVMBuildBr(Builder_val(B), BB);
1215}
1216
1217/* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
1218CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
1219                                         LLVMBasicBlockRef Then,
1220                                         LLVMBasicBlockRef Else,
1221                                         value B) {
1222  return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
1223}
1224
1225/* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
1226CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
1227                                        LLVMBasicBlockRef Else,
1228                                        value EstimatedCount,
1229                                        value B) {
1230  return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
1231}
1232
1233/* llvalue -> llvalue -> llbasicblock -> unit */
1234CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
1235                             LLVMBasicBlockRef Dest) {
1236  LLVMAddCase(Switch, OnVal, Dest);
1237  return Val_unit;
1238}
1239
1240/* llvalue -> llbasicblock -> llbuilder -> llvalue */
1241CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
1242                                             value EstimatedDests,
1243                                             value B) {
1244  return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
1245}
1246
1247/* llvalue -> llvalue -> llbasicblock -> unit */
1248CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
1249                                    LLVMBasicBlockRef Dest) {
1250  LLVMAddDestination(IndirectBr, Dest);
1251  return Val_unit;
1252}
1253
1254/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1255   llbuilder -> llvalue */
1256CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
1257                                            LLVMBasicBlockRef Then,
1258                                            LLVMBasicBlockRef Catch,
1259                                            value Name, value B) {
1260  return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
1261                         Wosize_val(Args), Then, Catch, String_val(Name));
1262}
1263
1264/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
1265   llbuilder -> llvalue */
1266CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
1267  return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
1268                               (LLVMBasicBlockRef) Args[2],
1269                               (LLVMBasicBlockRef) Args[3],
1270                               Args[4], Args[5]);
1271}
1272
1273CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
1274                                            value NumClauses,  value Name,
1275                                            value B) {
1276    return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
1277                               String_val(Name));
1278}
1279
1280CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
1281{
1282    LLVMSetCleanup(LandingPadInst, Bool_val(flag));
1283    return Val_unit;
1284}
1285
1286/* llbuilder -> llvalue */
1287CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
1288  return LLVMBuildUnreachable(Builder_val(B));
1289}
1290
1291/*--... Arithmetic .........................................................--*/
1292
1293/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1294CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
1295                                     value Name, value B) {
1296  return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
1297}
1298
1299/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1300CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1301                                         value Name, value B) {
1302  return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1303}
1304
1305/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1306CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
1307                                         value Name, value B) {
1308  return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
1309}
1310
1311/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1312CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
1313                                      value Name, value B) {
1314  return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
1315}
1316
1317/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1318CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1319                                     value Name, value B) {
1320  return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
1321}
1322
1323/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1324CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1325                                         value Name, value B) {
1326  return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
1327}
1328
1329/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1330CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
1331                                         value Name, value B) {
1332  return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
1333}
1334
1335/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1336CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
1337                                      value Name, value B) {
1338  return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
1339}
1340
1341/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1342CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1343                                     value Name, value B) {
1344  return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
1345}
1346
1347/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1348CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1349                                         value Name, value B) {
1350  return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
1351}
1352
1353/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1354CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
1355                                         value Name, value B) {
1356  return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
1357}
1358
1359/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1360CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
1361                                      value Name, value B) {
1362  return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
1363}
1364
1365/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1366CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
1367                                      value Name, value B) {
1368  return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
1369}
1370
1371/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1372CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1373                                      value Name, value B) {
1374  return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1375}
1376
1377/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1378CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1379                                            value Name, value B) {
1380  return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
1381}
1382
1383/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1384CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
1385                                      value Name, value B) {
1386  return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
1387}
1388
1389/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1390CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
1391                                      value Name, value B) {
1392  return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
1393}
1394
1395/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1396CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
1397                                      value Name, value B) {
1398  return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
1399}
1400
1401/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1402CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
1403                                      value Name, value B) {
1404  return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
1405}
1406
1407/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1408CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
1409                                     value Name, value B) {
1410  return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
1411}
1412
1413/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1414CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
1415                                      value Name, value B) {
1416  return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
1417}
1418
1419/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1420CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
1421                                      value Name, value B) {
1422  return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
1423}
1424
1425/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1426CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
1427                                     value Name, value B) {
1428  return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
1429}
1430
1431/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1432CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
1433                                    value Name, value B) {
1434  return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
1435}
1436
1437/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1438CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
1439                                     value Name, value B) {
1440  return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
1441}
1442
1443/* llvalue -> string -> llbuilder -> llvalue */
1444CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
1445                                     value Name, value B) {
1446  return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
1447}
1448
1449/* llvalue -> string -> llbuilder -> llvalue */
1450CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
1451                                         value Name, value B) {
1452  return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
1453}
1454
1455/* llvalue -> string -> llbuilder -> llvalue */
1456CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
1457                                         value Name, value B) {
1458  return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
1459}
1460
1461/* llvalue -> string -> llbuilder -> llvalue */
1462CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
1463                                     value Name, value B) {
1464  return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
1465}
1466
1467/* llvalue -> string -> llbuilder -> llvalue */
1468CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
1469                                     value Name, value B) {
1470  return LLVMBuildNot(Builder_val(B), X, String_val(Name));
1471}
1472
1473/*--... Memory .............................................................--*/
1474
1475/* lltype -> string -> llbuilder -> llvalue */
1476CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
1477                                        value Name, value B) {
1478  return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
1479}
1480
1481/* lltype -> llvalue -> string -> llbuilder -> llvalue */
1482CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
1483                                              value Name, value B) {
1484  return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
1485}
1486
1487/* llvalue -> string -> llbuilder -> llvalue */
1488CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
1489                                      value Name, value B) {
1490  return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
1491}
1492
1493/* llvalue -> llvalue -> llbuilder -> llvalue */
1494CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
1495                                       value B) {
1496  return LLVMBuildStore(Builder_val(B), Value, Pointer);
1497}
1498
1499/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1500CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
1501                                     value Name, value B) {
1502  return LLVMBuildGEP(Builder_val(B), Pointer,
1503                      (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
1504                      String_val(Name));
1505}
1506
1507/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1508CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
1509                                               value Indices, value Name,
1510                                               value B) {
1511  return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
1512                              (LLVMValueRef *) Op_val(Indices),
1513                              Wosize_val(Indices), String_val(Name));
1514}
1515
1516/* llvalue -> int -> string -> llbuilder -> llvalue */
1517CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
1518                                               value Index, value Name,
1519                                               value B) {
1520  return LLVMBuildStructGEP(Builder_val(B), Pointer,
1521                              Int_val(Index), String_val(Name));
1522}
1523
1524/* string -> string -> llbuilder -> llvalue */
1525CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
1526  return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
1527                               String_val(Name));
1528}
1529
1530/* string -> string -> llbuilder -> llvalue */
1531CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
1532                                                  value B) {
1533  return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
1534                                  String_val(Name));
1535}
1536
1537/*--... Casts ..............................................................--*/
1538
1539/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1540CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
1541                                       value Name, value B) {
1542  return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
1543}
1544
1545/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1546CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
1547                                      value Name, value B) {
1548  return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
1549}
1550
1551/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1552CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
1553                                      value Name, value B) {
1554  return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
1555}
1556
1557/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1558CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
1559                                        value Name, value B) {
1560  return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
1561}
1562
1563/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1564CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
1565                                        value Name, value B) {
1566  return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
1567}
1568
1569/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1570CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
1571                                        value Name, value B) {
1572  return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
1573}
1574
1575/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1576CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
1577                                        value Name, value B) {
1578  return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
1579}
1580
1581/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1582CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
1583                                         value Name, value B) {
1584  return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
1585}
1586
1587/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1588CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
1589                                       value Name, value B) {
1590  return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
1591}
1592
1593/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1594CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
1595                                          value Name, value B) {
1596  return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
1597}
1598
1599/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1600CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
1601                                          value Name, value B) {
1602  return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
1603}
1604
1605/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1606CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1607                                         value Name, value B) {
1608  return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
1609}
1610
1611/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1612CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1613                                                 value Name, value B) {
1614  return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1615}
1616
1617/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1618CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
1619                                                 value Name, value B) {
1620  return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1621}
1622
1623/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1624CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
1625                                                  LLVMTypeRef Ty, value Name,
1626                                                  value B) {
1627  return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
1628}
1629
1630/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1631CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
1632                                             value Name, value B) {
1633  return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
1634}
1635
1636/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1637CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
1638                                         value Name, value B) {
1639  return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
1640}
1641
1642/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1643CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
1644                                        value Name, value B) {
1645  return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
1646}
1647
1648/*--... Comparisons ........................................................--*/
1649
1650/* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1651CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
1652                                      LLVMValueRef LHS, LLVMValueRef RHS,
1653                                      value Name, value B) {
1654  return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
1655                       String_val(Name));
1656}
1657
1658/* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1659CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
1660                                      LLVMValueRef LHS, LLVMValueRef RHS,
1661                                      value Name, value B) {
1662  return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
1663                       String_val(Name));
1664}
1665
1666/*--... Miscellaneous instructions .........................................--*/
1667
1668/* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
1669CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
1670  value Hd, Tl;
1671  LLVMValueRef FirstValue, PhiNode;
1672
1673  assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
1674
1675  Hd = Field(Incoming, 0);
1676  FirstValue = (LLVMValueRef) Field(Hd, 0);
1677  PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
1678                         String_val(Name));
1679
1680  for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
1681    value Hd = Field(Tl, 0);
1682    LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
1683                    (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
1684  }
1685
1686  return PhiNode;
1687}
1688
1689/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
1690CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
1691                                      value Name, value B) {
1692  return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
1693                       Wosize_val(Params), String_val(Name));
1694}
1695
1696/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1697CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
1698                                        LLVMValueRef Then, LLVMValueRef Else,
1699                                        value Name, value B) {
1700  return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
1701}
1702
1703/* llvalue -> lltype -> string -> llbuilder -> llvalue */
1704CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
1705                                        value Name, value B) {
1706  return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
1707}
1708
1709/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1710CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
1711                                                LLVMValueRef Idx,
1712                                                value Name, value B) {
1713  return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
1714}
1715
1716/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1717CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
1718                                               LLVMValueRef Element,
1719                                               LLVMValueRef Idx,
1720                                               value Name, value B) {
1721  return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
1722                                String_val(Name));
1723}
1724
1725/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
1726CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
1727                                               LLVMValueRef Mask,
1728                                               value Name, value B) {
1729  return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
1730}
1731
1732/* llvalue -> int -> string -> llbuilder -> llvalue */
1733CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
1734                                              value Idx, value Name, value B) {
1735  return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
1736                               String_val(Name));
1737}
1738
1739/* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
1740CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
1741                                             LLVMValueRef Val, value Idx,
1742                                             value Name, value B) {
1743  return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
1744                              String_val(Name));
1745}
1746
1747/* llvalue -> string -> llbuilder -> llvalue */
1748CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
1749                                         value B) {
1750  return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
1751}
1752
1753/* llvalue -> string -> llbuilder -> llvalue */
1754CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
1755                                             value B) {
1756  return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
1757}
1758
1759/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
1760CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
1761                                         value Name, value B) {
1762  return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
1763}
1764
1765
1766/*===-- Memory buffers ----------------------------------------------------===*/
1767
1768/* string -> llmemorybuffer
1769   raises IoError msg on error */
1770CAMLprim value llvm_memorybuffer_of_file(value Path) {
1771  CAMLparam1(Path);
1772  char *Message;
1773  LLVMMemoryBufferRef MemBuf;
1774
1775  if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
1776                                               &MemBuf, &Message))
1777    llvm_raise(llvm_ioerror_exn, Message);
1778
1779  CAMLreturn((value) MemBuf);
1780}
1781
1782/* unit -> llmemorybuffer
1783   raises IoError msg on error */
1784CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
1785  char *Message;
1786  LLVMMemoryBufferRef MemBuf;
1787
1788  if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
1789    llvm_raise(llvm_ioerror_exn, Message);
1790
1791  return MemBuf;
1792}
1793
1794/* llmemorybuffer -> unit */
1795CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
1796  LLVMDisposeMemoryBuffer(MemBuf);
1797  return Val_unit;
1798}
1799
1800/*===-- Pass Managers -----------------------------------------------------===*/
1801
1802/* unit -> [ `Module ] PassManager.t */
1803CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
1804  return LLVMCreatePassManager();
1805}
1806
1807/* llmodule -> [ `Function ] PassManager.t -> bool */
1808CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
1809                                           LLVMPassManagerRef PM) {
1810  return Val_bool(LLVMRunPassManager(PM, M));
1811}
1812
1813/* [ `Function ] PassManager.t -> bool */
1814CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
1815  return Val_bool(LLVMInitializeFunctionPassManager(FPM));
1816}
1817
1818/* llvalue -> [ `Function ] PassManager.t -> bool */
1819CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
1820                                             LLVMPassManagerRef FPM) {
1821  return Val_bool(LLVMRunFunctionPassManager(FPM, F));
1822}
1823
1824/* [ `Function ] PassManager.t -> bool */
1825CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
1826  return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
1827}
1828
1829/* PassManager.any PassManager.t -> unit */
1830CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
1831  LLVMDisposePassManager(PM);
1832  return Val_unit;
1833}
1834