+CAMLprim value llvm_set_global_constant(value Flag, LLVMValueRef GlobalVar) {
+ LLVMSetGlobalConstant(GlobalVar, Bool_val(Flag));
+ return Val_unit;
+}
+
+/*--... Operations on aliases ..............................................--*/
+
+CAMLprim LLVMValueRef llvm_add_alias(LLVMModuleRef M, LLVMTypeRef Ty,
+ LLVMValueRef Aliasee, value Name) {
+ return LLVMAddAlias(M, Ty, Aliasee, String_val(Name));
+}
+
+/*--... Operations on functions ............................................--*/
+
+DEFINE_ITERATORS(function, Function, LLVMModuleRef, LLVMValueRef,
+ LLVMGetGlobalParent)
+
+/* string -> lltype -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
+ LLVMModuleRef M) {
+ LLVMValueRef Fn;
+ if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
+ if (LLVMGetElementType(LLVMTypeOf(Fn)) != Ty)
+ return LLVMConstBitCast(Fn, LLVMPointerType(Ty, 0));
+ return Fn;
+ }
+ return LLVMAddFunction(M, String_val(Name), Ty);
+}
+
+/* string -> llmodule -> llvalue option */
+CAMLprim value llvm_lookup_function(value Name, LLVMModuleRef M) {
+ CAMLparam1(Name);
+ LLVMValueRef Fn;
+ if ((Fn = LLVMGetNamedFunction(M, String_val(Name)))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) Fn;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* string -> lltype -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
+ LLVMModuleRef M) {
+ LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
+ LLVMAppendBasicBlockInContext(LLVMGetTypeContext(Ty), Fn, "entry");
+ return Fn;
+}
+
+/* llvalue -> unit */
+CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
+ LLVMDeleteFunction(Fn);
+ return Val_unit;
+}
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_intrinsic(LLVMValueRef Fn) {
+ return Val_bool(LLVMGetIntrinsicID(Fn));
+}
+
+/* llvalue -> int */
+CAMLprim value llvm_function_call_conv(LLVMValueRef Fn) {
+ return Val_int(LLVMGetFunctionCallConv(Fn));
+}
+
+/* int -> llvalue -> unit */
+CAMLprim value llvm_set_function_call_conv(value Id, LLVMValueRef Fn) {
+ LLVMSetFunctionCallConv(Fn, Int_val(Id));
+ return Val_unit;
+}
+
+/* llvalue -> string option */
+CAMLprim value llvm_gc(LLVMValueRef Fn) {
+ const char *GC;
+ CAMLparam0();
+ CAMLlocal2(Name, Option);
+
+ if ((GC = LLVMGetGC(Fn))) {
+ Name = caml_copy_string(GC);
+
+ Option = alloc(1, 0);
+ Field(Option, 0) = Name;
+ CAMLreturn(Option);
+ } else {
+ CAMLreturn(Val_int(0));
+ }
+}
+
+/* string option -> llvalue -> unit */
+CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
+ LLVMSetGC(Fn, GC == Val_int(0)? 0 : String_val(Field(GC, 0)));
+ return Val_unit;
+}
+
+/* llvalue -> int32 -> unit */
+CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
+ LLVMAddFunctionAttr(Arg, Int32_val(PA));
+ return Val_unit;
+}
+
+/* llvalue -> string -> string -> unit */
+CAMLprim value llvm_add_target_dependent_function_attr(
+ LLVMValueRef Arg, value A, value V) {
+ LLVMAddTargetDependentFunctionAttr(Arg, String_val(A), String_val(V));
+ return Val_unit;
+}
+
+/* llvalue -> int32 */
+CAMLprim value llvm_function_attr(LLVMValueRef Fn)
+{
+ CAMLparam0();
+ CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn)));
+}
+
+/* llvalue -> int32 -> unit */
+CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
+ LLVMRemoveFunctionAttr(Arg, Int32_val(PA));
+ return Val_unit;
+}
+/*--... Operations on parameters ...........................................--*/
+
+DEFINE_ITERATORS(param, Param, LLVMValueRef, LLVMValueRef, LLVMGetParamParent)
+
+/* llvalue -> int -> llvalue */
+CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
+ return LLVMGetParam(Fn, Int_val(Index));
+}
+
+/* llvalue -> int */
+CAMLprim value llvm_param_attr(LLVMValueRef Param)
+{
+ CAMLparam0();
+ CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param)));
+}
+
+/* llvalue -> llvalue */
+CAMLprim value llvm_params(LLVMValueRef Fn) {
+ value Params = alloc(LLVMCountParams(Fn), 0);
+ LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
+ return Params;
+}
+
+/* llvalue -> int32 -> unit */
+CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
+ LLVMAddAttribute(Arg, Int32_val(PA));
+ return Val_unit;
+}
+
+/* llvalue -> int32 -> unit */
+CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
+ LLVMRemoveAttribute(Arg, Int32_val(PA));
+ return Val_unit;
+}
+
+/* llvalue -> int -> unit */
+CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) {
+ LLVMSetParamAlignment(Arg, Int_val(align));
+ return Val_unit;
+}
+
+/*--... Operations on basic blocks .........................................--*/
+
+DEFINE_ITERATORS(
+ block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent)
+
+/* llbasicblock -> llvalue option */
+CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block)
+{
+ CAMLparam0();
+ LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block);
+ if (Term) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) Term;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llvalue -> llbasicblock array */
+CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) {
+ value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0);
+ LLVMGetBasicBlocks(Fn, (LLVMBasicBlockRef *) Op_val(MLArray));
+ return MLArray;
+}
+
+/* llbasicblock -> unit */
+CAMLprim value llvm_delete_block(LLVMBasicBlockRef BB) {
+ LLVMDeleteBasicBlock(BB);
+ return Val_unit;
+}
+
+/* llbasicblock -> unit */
+CAMLprim value llvm_remove_block(LLVMBasicBlockRef BB) {
+ LLVMRemoveBasicBlockFromParent(BB);
+ return Val_unit;
+}
+
+/* llbasicblock -> llbasicblock -> unit */
+CAMLprim value llvm_move_block_before(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
+ LLVMMoveBasicBlockBefore(BB, Pos);
+ return Val_unit;
+}
+
+/* llbasicblock -> llbasicblock -> unit */
+CAMLprim value llvm_move_block_after(LLVMBasicBlockRef Pos, LLVMBasicBlockRef BB) {
+ LLVMMoveBasicBlockAfter(BB, Pos);
+ return Val_unit;
+}
+
+/* string -> llvalue -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_append_block(LLVMContextRef Context, value Name,
+ LLVMValueRef Fn) {
+ return LLVMAppendBasicBlockInContext(Context, Fn, String_val(Name));
+}
+
+/* string -> llbasicblock -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_insert_block(LLVMContextRef Context, value Name,
+ LLVMBasicBlockRef BB) {
+ return LLVMInsertBasicBlockInContext(Context, BB, String_val(Name));
+}
+
+/* llvalue -> bool */
+CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
+ return Val_bool(LLVMValueIsBasicBlock(Val));
+}
+
+/*--... Operations on instructions .........................................--*/
+
+DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef,
+ LLVMGetInstructionParent)
+
+/* llvalue -> Opcode.t */
+CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) {
+ LLVMOpcode o;
+ if (!LLVMIsAInstruction(Inst))
+ failwith("Not an instruction");
+ o = LLVMGetInstructionOpcode(Inst);
+ assert (o <= LLVMLandingPad);
+ return Val_int(o);
+}
+
+/* llvalue -> ICmp.t option */
+CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) {
+ CAMLparam0();
+ int x = LLVMGetICmpPredicate(Val);
+ if (x) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = Val_int(x - LLVMIntEQ);
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llvalue -> FCmp.t option */
+CAMLprim value llvm_instr_fcmp_predicate(LLVMValueRef Val) {
+ CAMLparam0();
+ int x = LLVMGetFCmpPredicate(Val);
+ if (x) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = Val_int(x - LLVMRealPredicateFalse);
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llvalue -> llvalue */
+CAMLprim LLVMValueRef llvm_instr_clone(LLVMValueRef Inst) {
+ if (!LLVMIsAInstruction(Inst))
+ failwith("Not an instruction");
+ return LLVMInstructionClone(Inst);
+}
+
+
+/*--... Operations on call sites ...........................................--*/
+
+/* llvalue -> int */
+CAMLprim value llvm_instruction_call_conv(LLVMValueRef Inst) {
+ return Val_int(LLVMGetInstructionCallConv(Inst));
+}
+
+/* int -> llvalue -> unit */
+CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
+ LLVMSetInstructionCallConv(Inst, Int_val(CC));
+ return Val_unit;
+}
+
+/* llvalue -> int -> int32 -> unit */
+CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
+ value index,
+ value PA) {
+ LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA));
+ return Val_unit;
+}
+
+/* llvalue -> int -> int32 -> unit */
+CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
+ value index,
+ value PA) {
+ LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA));
+ return Val_unit;
+}
+
+/*--... Operations on call instructions (only) .............................--*/
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_tail_call(LLVMValueRef CallInst) {
+ return Val_bool(LLVMIsTailCall(CallInst));
+}
+
+/* bool -> llvalue -> unit */
+CAMLprim value llvm_set_tail_call(value IsTailCall,
+ LLVMValueRef CallInst) {
+ LLVMSetTailCall(CallInst, Bool_val(IsTailCall));
+ return Val_unit;
+}
+
+/*--... Operations on load/store instructions (only)........................--*/
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_volatile(LLVMValueRef MemoryInst) {
+ return Val_bool(LLVMGetVolatile(MemoryInst));
+}
+
+/* bool -> llvalue -> unit */
+CAMLprim value llvm_set_volatile(value IsVolatile,
+ LLVMValueRef MemoryInst) {
+ LLVMSetVolatile(MemoryInst, Bool_val(IsVolatile));
+ return Val_unit;
+}
+
+
+/*--.. Operations on terminators ...........................................--*/
+
+/* llvalue -> int -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_successor(LLVMValueRef V, value I) {
+ return LLVMGetSuccessor(V, Int_val(I));
+}
+
+/* llvalue -> int -> llvalue -> unit */
+CAMLprim value llvm_set_successor(LLVMValueRef U, value I, LLVMBasicBlockRef B) {
+ LLVMSetSuccessor(U, Int_val(I), B);
+ return Val_unit;
+}
+
+/* llvalue -> int */
+CAMLprim value llvm_num_successors(LLVMValueRef V) {
+ return Val_int(LLVMGetNumSuccessors(V));
+}
+
+/*--.. Operations on branch ................................................--*/
+
+/* llvalue -> llvalue */
+CAMLprim LLVMValueRef llvm_condition(LLVMValueRef V) {
+ return LLVMGetCondition(V);
+}
+
+/* llvalue -> llvalue -> unit */
+CAMLprim value llvm_set_condition(LLVMValueRef B, LLVMValueRef C) {
+ LLVMSetCondition(B, C);
+ return Val_unit;
+}
+
+/* llvalue -> bool */
+CAMLprim value llvm_is_conditional(LLVMValueRef V) {
+ return Val_bool(LLVMIsConditional(V));
+}
+
+/*--... Operations on phi nodes ............................................--*/
+
+/* (llvalue * llbasicblock) -> llvalue -> unit */
+CAMLprim value llvm_add_incoming(value Incoming, LLVMValueRef PhiNode) {
+ LLVMAddIncoming(PhiNode,
+ (LLVMValueRef*) &Field(Incoming, 0),
+ (LLVMBasicBlockRef*) &Field(Incoming, 1),
+ 1);
+ return Val_unit;
+}
+
+/* llvalue -> (llvalue * llbasicblock) list */
+CAMLprim value llvm_incoming(LLVMValueRef PhiNode) {
+ unsigned I;
+ CAMLparam0();
+ CAMLlocal3(Hd, Tl, Tmp);
+
+ /* Build a tuple list of them. */
+ Tl = Val_int(0);
+ for (I = LLVMCountIncoming(PhiNode); I != 0; ) {
+ Hd = alloc(2, 0);
+ Store_field(Hd, 0, (value) LLVMGetIncomingValue(PhiNode, --I));
+ Store_field(Hd, 1, (value) LLVMGetIncomingBlock(PhiNode, I));
+
+ Tmp = alloc(2, 0);
+ Store_field(Tmp, 0, Hd);
+ Store_field(Tmp, 1, Tl);
+ Tl = Tmp;
+ }
+
+ CAMLreturn(Tl);
+}
+
+/* llvalue -> unit */
+CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) {
+ LLVMInstructionEraseFromParent(Instruction);
+ return Val_unit;
+}
+
+/*===-- Instruction builders ----------------------------------------------===*/
+
+#define Builder_val(v) (*(LLVMBuilderRef *)(Data_custom_val(v)))
+
+static void llvm_finalize_builder(value B) {
+ LLVMDisposeBuilder(Builder_val(B));
+}
+
+static struct custom_operations builder_ops = {
+ (char *) "Llvm.llbuilder",
+ llvm_finalize_builder,
+ custom_compare_default,
+ custom_hash_default,
+ custom_serialize_default,
+ custom_deserialize_default,
+ custom_compare_ext_default
+};
+
+static value alloc_builder(LLVMBuilderRef B) {
+ value V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
+ Builder_val(V) = B;
+ return V;
+}
+
+/* llcontext -> llbuilder */
+CAMLprim value llvm_builder(LLVMContextRef C) {
+ return alloc_builder(LLVMCreateBuilderInContext(C));
+}
+
+/* (llbasicblock, llvalue) llpos -> llbuilder -> unit */
+CAMLprim value llvm_position_builder(value Pos, value B) {
+ if (Tag_val(Pos) == 0) {
+ LLVMBasicBlockRef BB = (LLVMBasicBlockRef) Op_val(Field(Pos, 0));
+ LLVMPositionBuilderAtEnd(Builder_val(B), BB);
+ } else {
+ LLVMValueRef I = (LLVMValueRef) Op_val(Field(Pos, 0));
+ LLVMPositionBuilderBefore(Builder_val(B), I);
+ }
+ return Val_unit;
+}
+
+/* llbuilder -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_insertion_block(value B) {
+ LLVMBasicBlockRef InsertBlock = LLVMGetInsertBlock(Builder_val(B));
+ if (!InsertBlock)
+ caml_raise_not_found();
+ return InsertBlock;
+}
+
+/* llvalue -> string -> llbuilder -> unit */
+CAMLprim value llvm_insert_into_builder(LLVMValueRef I, value Name, value B) {
+ LLVMInsertIntoBuilderWithName(Builder_val(B), I, String_val(Name));
+ return Val_unit;
+}
+
+/*--... Metadata ...........................................................--*/
+
+/* llbuilder -> llvalue -> unit */
+CAMLprim value llvm_set_current_debug_location(value B, LLVMValueRef V) {
+ LLVMSetCurrentDebugLocation(Builder_val(B), V);
+ return Val_unit;
+}
+
+/* llbuilder -> unit */
+CAMLprim value llvm_clear_current_debug_location(value B) {
+ LLVMSetCurrentDebugLocation(Builder_val(B), NULL);
+ return Val_unit;
+}
+
+/* llbuilder -> llvalue option */
+CAMLprim value llvm_current_debug_location(value B) {
+ CAMLparam0();
+ LLVMValueRef L;
+ if ((L = LLVMGetCurrentDebugLocation(Builder_val(B)))) {
+ value Option = alloc(1, 0);
+ Field(Option, 0) = (value) L;
+ CAMLreturn(Option);
+ }
+ CAMLreturn(Val_int(0));
+}
+
+/* llbuilder -> llvalue -> unit */
+CAMLprim value llvm_set_inst_debug_location(value B, LLVMValueRef V) {
+ LLVMSetInstDebugLocation(Builder_val(B), V);
+ return Val_unit;
+}
+
+
+/*--... Terminators ........................................................--*/
+
+/* llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_ret_void(value B) {
+ return LLVMBuildRetVoid(Builder_val(B));
+}
+
+/* llvalue -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_ret(LLVMValueRef Val, value B) {
+ return LLVMBuildRet(Builder_val(B), Val);
+}
+
+/* llvalue array -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_aggregate_ret(value RetVals, value B) {
+ return LLVMBuildAggregateRet(Builder_val(B), (LLVMValueRef *) Op_val(RetVals),
+ Wosize_val(RetVals));
+}
+
+/* llbasicblock -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_br(LLVMBasicBlockRef BB, value B) {
+ return LLVMBuildBr(Builder_val(B), BB);
+}
+
+/* llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_cond_br(LLVMValueRef If,
+ LLVMBasicBlockRef Then,
+ LLVMBasicBlockRef Else,
+ value B) {
+ return LLVMBuildCondBr(Builder_val(B), If, Then, Else);
+}
+
+/* llvalue -> llbasicblock -> int -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of,
+ LLVMBasicBlockRef Else,
+ value EstimatedCount,
+ value B) {
+ return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount));
+}
+
+/* lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name,
+ value B)
+{
+ return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name));
+}
+
+/* lltype -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty,
+ LLVMValueRef Val,
+ value Name, value B)
+{
+ return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name));
+}
+
+/* llvalue -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B)
+{
+ return LLVMBuildFree(Builder_val(B), P);
+}
+
+/* llvalue -> llvalue -> llbasicblock -> unit */
+CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal,
+ LLVMBasicBlockRef Dest) {
+ LLVMAddCase(Switch, OnVal, Dest);
+ return Val_unit;
+}
+
+/* llvalue -> llbasicblock -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_indirect_br(LLVMValueRef Addr,
+ value EstimatedDests,
+ value B) {
+ return LLVMBuildIndirectBr(Builder_val(B), Addr, EstimatedDests);
+}
+
+/* llvalue -> llvalue -> llbasicblock -> unit */
+CAMLprim value llvm_add_destination(LLVMValueRef IndirectBr,
+ LLVMBasicBlockRef Dest) {
+ LLVMAddDestination(IndirectBr, Dest);
+ return Val_unit;
+}
+
+/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
+ llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_invoke_nat(LLVMValueRef Fn, value Args,
+ LLVMBasicBlockRef Then,
+ LLVMBasicBlockRef Catch,
+ value Name, value B) {
+ return LLVMBuildInvoke(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Args),
+ Wosize_val(Args), Then, Catch, String_val(Name));
+}
+
+/* llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string ->
+ llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) {
+ return llvm_build_invoke_nat((LLVMValueRef) Args[0], Args[1],
+ (LLVMBasicBlockRef) Args[2],
+ (LLVMBasicBlockRef) Args[3],
+ Args[4], Args[5]);
+}
+
+/* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn,
+ value NumClauses, value Name,
+ value B) {
+ return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses),
+ String_val(Name));
+}
+
+/* llvalue -> llvalue -> unit */
+CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal)
+{
+ LLVMAddClause(LandingPadInst, ClauseVal);
+ return Val_unit;
+}
+
+
+/* llvalue -> bool -> unit */
+CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag)
+{
+ LLVMSetCleanup(LandingPadInst, Bool_val(flag));
+ return Val_unit;
+}
+
+/* llvalue -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B)
+{
+ return LLVMBuildResume(Builder_val(B), Exn);
+}
+
+/* llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_unreachable(value B) {
+ return LLVMBuildUnreachable(Builder_val(B));
+}
+
+/*--... Arithmetic .........................................................--*/
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_add(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildAdd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_add(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNSWAdd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_add(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWAdd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fadd(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFAdd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_sub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNSWSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_sub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fsub(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFSub(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_mul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNSWMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_mul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildNUWMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fmul(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFMul(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_udiv(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildUDiv(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildSDiv(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_exact_sdiv(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildExactSDiv(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fdiv(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFDiv(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_urem(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildURem(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_srem(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildSRem(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_frem(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFRem(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_shl(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildShl(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_lshr(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildLShr(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_ashr(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildAShr(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_and(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildAnd(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_or(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildOr(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_xor(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildXor(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_neg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNeg(Builder_val(B), X, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nsw_neg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNSWNeg(Builder_val(B), X, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_nuw_neg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNUWNeg(Builder_val(B), X, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fneg(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildFNeg(Builder_val(B), X, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_not(LLVMValueRef X,
+ value Name, value B) {
+ return LLVMBuildNot(Builder_val(B), X, String_val(Name));
+}
+
+/*--... Memory .............................................................--*/
+
+/* lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_alloca(LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildAlloca(Builder_val(B), Ty, String_val(Name));
+}
+
+/* lltype -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_array_alloca(LLVMTypeRef Ty, LLVMValueRef Size,
+ value Name, value B) {
+ return LLVMBuildArrayAlloca(Builder_val(B), Ty, Size, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_load(LLVMValueRef Pointer,
+ value Name, value B) {
+ return LLVMBuildLoad(Builder_val(B), Pointer, String_val(Name));
+}
+
+/* llvalue -> llvalue -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_store(LLVMValueRef Value, LLVMValueRef Pointer,
+ value B) {
+ return LLVMBuildStore(Builder_val(B), Value, Pointer);
+}
+
+/* AtomicRMWBinOp.t -> llvalue -> llvalue -> AtomicOrdering.t ->
+ bool -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_atomicrmw_native(value BinOp, LLVMValueRef Ptr,
+ LLVMValueRef Val, value Ord,
+ value ST, value Name, value B) {
+ LLVMValueRef Instr;
+ Instr = LLVMBuildAtomicRMW(Builder_val(B), Int_val(BinOp),
+ Ptr, Val, Int_val(Ord), Bool_val(ST));
+ LLVMSetValueName(Instr, String_val(Name));
+ return Instr;
+}
+
+CAMLprim LLVMValueRef llvm_build_atomicrmw_bytecode(value *argv, int argn) {
+ return llvm_build_atomicrmw_native(argv[0], (LLVMValueRef) argv[1],
+ (LLVMValueRef) argv[2], argv[3],
+ argv[4], argv[5], argv[6]);
+}
+
+/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_gep(LLVMValueRef Pointer, value Indices,
+ value Name, value B) {
+ return LLVMBuildGEP(Builder_val(B), Pointer,
+ (LLVMValueRef *) Op_val(Indices), Wosize_val(Indices),
+ String_val(Name));
+}
+
+/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_in_bounds_gep(LLVMValueRef Pointer,
+ value Indices, value Name,
+ value B) {
+ return LLVMBuildInBoundsGEP(Builder_val(B), Pointer,
+ (LLVMValueRef *) Op_val(Indices),
+ Wosize_val(Indices), String_val(Name));
+}
+
+/* llvalue -> int -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_struct_gep(LLVMValueRef Pointer,
+ value Index, value Name,
+ value B) {
+ return LLVMBuildStructGEP(Builder_val(B), Pointer,
+ Int_val(Index), String_val(Name));
+}
+
+/* string -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_global_string(value Str, value Name, value B) {
+ return LLVMBuildGlobalString(Builder_val(B), String_val(Str),
+ String_val(Name));
+}
+
+/* string -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_global_stringptr(value Str, value Name,
+ value B) {
+ return LLVMBuildGlobalStringPtr(Builder_val(B), String_val(Str),
+ String_val(Name));
+}
+
+/*--... Casts ..............................................................--*/
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_trunc(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildTrunc(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_zext(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildZExt(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_sext(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildSExt(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fptoui(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildFPToUI(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fptosi(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildFPToSI(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_uitofp(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildUIToFP(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_sitofp(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildSIToFP(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fptrunc(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildFPTrunc(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fpext(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildFPExt(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_prttoint(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildPtrToInt(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_inttoptr(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildIntToPtr(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildBitCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_zext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildZExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_sext_or_bitcast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildSExtOrBitCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_trunc_or_bitcast(LLVMValueRef X,
+ LLVMTypeRef Ty, value Name,
+ value B) {
+ return LLVMBuildTruncOrBitCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_pointercast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildPointerCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_intcast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildIntCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fpcast(LLVMValueRef X, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildFPCast(Builder_val(B), X, Ty, String_val(Name));
+}
+
+/*--... Comparisons ........................................................--*/
+
+/* Icmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_icmp(value Pred,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildICmp(Builder_val(B), Int_val(Pred) + LLVMIntEQ, LHS, RHS,
+ String_val(Name));
+}
+
+/* Fcmp.t -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_fcmp(value Pred,
+ LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildFCmp(Builder_val(B), Int_val(Pred), LHS, RHS,
+ String_val(Name));
+}
+
+/*--... Miscellaneous instructions .........................................--*/
+
+/* (llvalue * llbasicblock) list -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_phi(value Incoming, value Name, value B) {
+ value Hd, Tl;
+ LLVMValueRef FirstValue, PhiNode;
+
+ assert(Incoming != Val_int(0) && "Empty list passed to Llvm.build_phi!");
+
+ Hd = Field(Incoming, 0);
+ FirstValue = (LLVMValueRef) Field(Hd, 0);
+ PhiNode = LLVMBuildPhi(Builder_val(B), LLVMTypeOf(FirstValue),
+ String_val(Name));
+
+ for (Tl = Incoming; Tl != Val_int(0); Tl = Field(Tl, 1)) {
+ value Hd = Field(Tl, 0);
+ LLVMAddIncoming(PhiNode, (LLVMValueRef*) &Field(Hd, 0),
+ (LLVMBasicBlockRef*) &Field(Hd, 1), 1);
+ }
+
+ return PhiNode;
+}
+
+/* lltype -> string -> llbuilder -> value */
+CAMLprim LLVMValueRef llvm_build_empty_phi(LLVMTypeRef Type, value Name, value B) {
+ LLVMValueRef PhiNode;
+
+ return LLVMBuildPhi(Builder_val(B), Type, String_val(Name));
+
+ return PhiNode;
+}
+
+/* llvalue -> llvalue array -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_call(LLVMValueRef Fn, value Params,
+ value Name, value B) {
+ return LLVMBuildCall(Builder_val(B), Fn, (LLVMValueRef *) Op_val(Params),
+ Wosize_val(Params), String_val(Name));
+}
+
+/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_select(LLVMValueRef If,
+ LLVMValueRef Then, LLVMValueRef Else,
+ value Name, value B) {
+ return LLVMBuildSelect(Builder_val(B), If, Then, Else, String_val(Name));
+}
+
+/* llvalue -> lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_va_arg(LLVMValueRef List, LLVMTypeRef Ty,
+ value Name, value B) {
+ return LLVMBuildVAArg(Builder_val(B), List, Ty, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_extractelement(LLVMValueRef Vec,
+ LLVMValueRef Idx,
+ value Name, value B) {
+ return LLVMBuildExtractElement(Builder_val(B), Vec, Idx, String_val(Name));
+}
+
+/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_insertelement(LLVMValueRef Vec,
+ LLVMValueRef Element,
+ LLVMValueRef Idx,
+ value Name, value B) {
+ return LLVMBuildInsertElement(Builder_val(B), Vec, Element, Idx,
+ String_val(Name));
+}
+
+/* llvalue -> llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_shufflevector(LLVMValueRef V1, LLVMValueRef V2,
+ LLVMValueRef Mask,
+ value Name, value B) {
+ return LLVMBuildShuffleVector(Builder_val(B), V1, V2, Mask, String_val(Name));
+}
+
+/* llvalue -> int -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_extractvalue(LLVMValueRef Aggregate,
+ value Idx, value Name, value B) {
+ return LLVMBuildExtractValue(Builder_val(B), Aggregate, Int_val(Idx),
+ String_val(Name));
+}
+
+/* llvalue -> llvalue -> int -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_insertvalue(LLVMValueRef Aggregate,
+ LLVMValueRef Val, value Idx,
+ value Name, value B) {
+ return LLVMBuildInsertValue(Builder_val(B), Aggregate, Val, Int_val(Idx),
+ String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_is_null(LLVMValueRef Val, value Name,
+ value B) {
+ return LLVMBuildIsNull(Builder_val(B), Val, String_val(Name));
+}
+
+/* llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_is_not_null(LLVMValueRef Val, value Name,
+ value B) {
+ return LLVMBuildIsNotNull(Builder_val(B), Val, String_val(Name));
+}
+
+/* llvalue -> llvalue -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_ptrdiff(LLVMValueRef LHS, LLVMValueRef RHS,
+ value Name, value B) {
+ return LLVMBuildPtrDiff(Builder_val(B), LHS, RHS, String_val(Name));
+}
+
+/*===-- Memory buffers ----------------------------------------------------===*/
+
+/* string -> llmemorybuffer
+ raises IoError msg on error */
+CAMLprim value llvm_memorybuffer_of_file(value Path) {
+ CAMLparam1(Path);
+ char *Message;
+ LLVMMemoryBufferRef MemBuf;
+
+ if (LLVMCreateMemoryBufferWithContentsOfFile(String_val(Path),
+ &MemBuf, &Message))
+ llvm_raise(*caml_named_value("Llvm.IoError"), Message);
+
+ CAMLreturn((value) MemBuf);
+}
+
+/* unit -> llmemorybuffer
+ raises IoError msg on error */
+CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_stdin(value Unit) {
+ char *Message;
+ LLVMMemoryBufferRef MemBuf;
+
+ if (LLVMCreateMemoryBufferWithSTDIN(&MemBuf, &Message))
+ llvm_raise(*caml_named_value("Llvm.IoError"), Message);
+
+ return MemBuf;
+}
+
+/* ?name:string -> string -> llmemorybuffer */
+CAMLprim LLVMMemoryBufferRef llvm_memorybuffer_of_string(value Name, value String) {
+ LLVMMemoryBufferRef MemBuf;
+ const char *NameCStr;
+
+ if(Name == Val_int(0))
+ NameCStr = "";
+ else
+ NameCStr = String_val(Field(Name, 0));
+
+ MemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(
+ String_val(String), caml_string_length(String), NameCStr);
+
+ return MemBuf;
+}
+
+/* llmemorybuffer -> string */
+CAMLprim value llvm_memorybuffer_as_string(LLVMMemoryBufferRef MemBuf) {
+ value String = caml_alloc_string(LLVMGetBufferSize(MemBuf));
+ memcpy(String_val(String), LLVMGetBufferStart(MemBuf),
+ LLVMGetBufferSize(MemBuf));
+
+ return String;
+}
+
+/* llmemorybuffer -> unit */
+CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
+ LLVMDisposeMemoryBuffer(MemBuf);
+ return Val_unit;
+}
+
+/*===-- Pass Managers -----------------------------------------------------===*/
+
+/* unit -> [ `Module ] PassManager.t */
+CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
+ return LLVMCreatePassManager();
+}
+
+/* llmodule -> [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
+ LLVMPassManagerRef PM) {
+ return Val_bool(LLVMRunPassManager(PM, M));
+}
+
+/* [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMInitializeFunctionPassManager(FPM));
+}
+
+/* llvalue -> [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
+ LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMRunFunctionPassManager(FPM, F));
+}
+
+/* [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
+}
+
+/* PassManager.any PassManager.t -> unit */
+CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
+ LLVMDisposePassManager(PM);