Added C and Ocaml bindings for functions, basic blocks, and
authorGordon Henriksen <gordonhenriksen@mac.com>
Wed, 26 Sep 2007 20:56:12 +0000 (20:56 +0000)
committerGordon Henriksen <gordonhenriksen@mac.com>
Wed, 26 Sep 2007 20:56:12 +0000 (20:56 +0000)
instruction creation. No support yet for instruction introspection.

Also eliminated allocas from the Ocaml bindings for portability,
and avoided unnecessary casts.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42367 91177308-0d34-0410-b5e6-96231b3b80d8

Xcode/LLVM.xcodeproj/project.pbxproj
bindings/ocaml/Makefile.ocaml
bindings/ocaml/bitwriter/Makefile
bindings/ocaml/llvm/llvm.ml
bindings/ocaml/llvm/llvm.mli
bindings/ocaml/llvm/llvm_ocaml.c
include/llvm-c/Core.h
include/llvm/CHelpers.h
lib/VMCore/Core.cpp
test/Bindings/Ocaml/bitwriter.ml
test/Bindings/Ocaml/vmcore.ml

index 1ae711a..0763ae3 100644 (file)
                9FA638EA0C77B252007F12AE /* InlinerPass.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlinerPass.h; sourceTree = "<group>"; };
                9FA638EB0C77B26B007F12AE /* BasicInliner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BasicInliner.h; sourceTree = "<group>"; };
                9FA638EC0C77B26B007F12AE /* InlineCost.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InlineCost.h; sourceTree = "<group>"; };
+               9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = bitwriter_ocaml.c; sourceTree = "<group>"; };
+               9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.ml; sourceTree = "<group>"; };
+               9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm_bitwriter.mli; sourceTree = "<group>"; };
+               9FD3E57B0CA0116100E54D15 /* llvm.ml */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.ml; sourceTree = "<group>"; };
+               9FD3E57C0CA0116100E54D15 /* llvm.mli */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = llvm.mli; sourceTree = "<group>"; };
+               9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = llvm_ocaml.c; sourceTree = "<group>"; };
+               9FD3E58D0CA0125F00E54D15 /* BitWriter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BitWriter.h; sourceTree = "<group>"; };
+               9FD3E58E0CA0125F00E54D15 /* Core.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Core.h; sourceTree = "<group>"; };
+               9FD3E5900CA0129D00E54D15 /* Core.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Core.cpp; path = ../lib/VMCore/Core.cpp; sourceTree = SOURCE_ROOT; };
+               9FD3E5920CA012B300E54D15 /* BitWriter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BitWriter.cpp; sourceTree = "<group>"; };
                9FE4508B0C77A77000C4FEA4 /* ARMCodeEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ARMCodeEmitter.cpp; sourceTree = "<group>"; };
                9FE4508C0C77A77000C4FEA4 /* ARMGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenAsmWriter.inc; sourceTree = "<group>"; };
                9FE4508D0C77A77000C4FEA4 /* ARMGenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.pascal; path = ARMGenDAGISel.inc; sourceTree = "<group>"; };
                                DE66F2BD08ABF14400323D32 /* tools */,
                                DE816FAC08CFB44C0093BDEF /* utils */,
                                DE66F38D08ABF35C00323D32 /* docs */,
+                               9FD3E56D0CA0116100E54D15 /* bindings */,
                                DE66F3FD08ABF37000323D32 /* examples */,
                                DE66F38C08ABF35300323D32 /* CREDITS.TXT */,
                                CFD99AA80AFE827B0068D19C /* LICENSE.TXT */,
                9F68EB110C77AD2C004AA152 /* Writer */ = {
                        isa = PBXGroup;
                        children = (
+                               9FD3E5920CA012B300E54D15 /* BitWriter.cpp */,
                                9F68EB120C77AD2C004AA152 /* BitcodeWriter.cpp */,
                                9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */,
                                9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */,
                        path = IPO;
                        sourceTree = "<group>";
                };
+               9FD3E56D0CA0116100E54D15 /* bindings */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9FD3E56F0CA0116100E54D15 /* ocaml */,
+                       );
+                       name = bindings;
+                       path = ../bindings;
+                       sourceTree = SOURCE_ROOT;
+               };
+               9FD3E56F0CA0116100E54D15 /* ocaml */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9FD3E5700CA0116100E54D15 /* bitwriter */,
+                               9FD3E57A0CA0116100E54D15 /* llvm */,
+                       );
+                       path = ocaml;
+                       sourceTree = "<group>";
+               };
+               9FD3E5700CA0116100E54D15 /* bitwriter */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9FD3E5710CA0116100E54D15 /* bitwriter_ocaml.c */,
+                               9FD3E5720CA0116100E54D15 /* llvm_bitwriter.ml */,
+                               9FD3E5730CA0116100E54D15 /* llvm_bitwriter.mli */,
+                       );
+                       path = bitwriter;
+                       sourceTree = "<group>";
+               };
+               9FD3E57A0CA0116100E54D15 /* llvm */ = {
+                       isa = PBXGroup;
+                       children = (
+                               9FD3E57B0CA0116100E54D15 /* llvm.ml */,
+                               9FD3E57C0CA0116100E54D15 /* llvm.mli */,
+                               9FD3E57D0CA0116100E54D15 /* llvm_ocaml.c */,
+                       );
+                       path = llvm;
+                       sourceTree = "<group>";
+               };
                9FE450DE0C77ABE400C4FEA4 /* lib/Archive */ = {
                        isa = PBXGroup;
                        children = (
                CF8F1B480B64F7AB00BB4199 /* llvm-c */ = {
                        isa = PBXGroup;
                        children = (
+                               9FD3E58D0CA0125F00E54D15 /* BitWriter.h */,
+                               9FD3E58E0CA0125F00E54D15 /* Core.h */,
                                CF8F1B490B64F7AB00BB4199 /* LinkTimeOptimizer.h */,
                        );
                        name = "llvm-c";
                                9F77937C0C73C4F400551F9C /* ConstantFold.cpp */,
                                9F77937D0C73C4F400551F9C /* ConstantFold.h */,
                                DE66EC6008ABE86A00323D32 /* Constants.cpp */,
+                               9FD3E5900CA0129D00E54D15 /* Core.cpp */,
                                DE66EC6108ABE86A00323D32 /* Dominators.cpp */,
                                DE66EC6208ABE86A00323D32 /* Function.cpp */,
                                DE66EC6308ABE86A00323D32 /* Globals.cpp */,
index 4c65ca8..8ad085e 100644 (file)
@@ -92,6 +92,8 @@ $(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
                                    $(OcamlDir)/.dir $(ObjDir)/.dir
        $(Verb) $(OCAMLDEP) $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeader) > $@
 
+$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
+
 -include $(ObjDir)/$(LIBRARYNAME).ocamldep
 
 
index aef41f5..953ab4c 100644 (file)
@@ -19,5 +19,6 @@ LEVEL := ../../..
 LIBRARYNAME := llvm_bitwriter
 DONT_BUILD_RELINKED := 1
 UsedComponents := bitwriter
+UsedOcamlInterfaces := llvm
 
 include ../Makefile.ocaml
index b8a62dc..63079f2 100644 (file)
@@ -17,6 +17,9 @@
 type llmodule
 type lltype
 type llvalue
+type llbasicblock (* These are actually values, but
+                     benefit from type checking. *)
+type llbuilder
 
 type type_kind =
   Void_type
@@ -50,6 +53,42 @@ type visibility =
 | Hidden_visibility
 | Protected_visibility
 
+let ccc = 0
+let fastcc = 8
+let coldcc = 9
+let x86_stdcallcc = 64
+let x86_fastcallcc = 65
+
+type int_predicate =
+  Icmp_eq
+| Icmp_ne
+| Icmp_ugt
+| Icmp_uge
+| Icmp_ult
+| Icmp_ule
+| Icmp_sgt
+| Icmp_sge
+| Icmp_slt
+| Icmp_sle
+
+type real_predicate =
+  Fcmp_false
+| Fcmp_oeq
+| Fcmp_ogt
+| Fcmp_oge
+| Fcmp_olt
+| Fcmp_ole
+| Fcmp_one
+| Fcmp_ord
+| Fcmp_uno
+| Fcmp_ueq
+| Fcmp_ugt
+| Fcmp_uge
+| Fcmp_ult
+| Fcmp_ule
+| Fcmp_une
+| Fcmp_true
+
 
 (*===-- Modules -----------------------------------------------------------===*)
 
@@ -63,8 +102,11 @@ external dispose_module : llmodule -> unit = "llvm_dispose_module"
 
 (* Adds a named type to the module's symbol table. Returns true if successful.
    If such a name already exists, then no entry is added and returns false. *)
-external add_type_name : string -> lltype -> llmodule -> bool
-                       = "llvm_add_type_name"
+external define_type_name : string -> lltype -> llmodule -> bool
+                          = "llvm_add_type_name"
+
+external delete_type_name : string -> llmodule -> unit
+                          = "llvm_delete_type_name"
 
 
 (*===-- Types -------------------------------------------------------------===*)
@@ -142,9 +184,9 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
 
 (*--... Operations on constants of (mostly) any type .......................--*)
 external is_constant : llvalue -> bool = "llvm_is_constant"
-external make_null : lltype -> llvalue = "llvm_make_null"
-external make_all_ones : (*int|vec*)lltype -> llvalue = "llvm_make_all_ones"
-external make_undef : lltype -> llvalue = "llvm_make_undef"
+external make_null : lltype -> llvalue = "LLVMGetNull"
+external make_all_ones : (*int|vec*)lltype -> llvalue = "LLVMGetAllOnes"
+external make_undef : lltype -> llvalue = "LLVMGetUndef"
 external is_null : llvalue -> bool = "llvm_is_null"
 external is_undef : llvalue -> bool = "llvm_is_undef"
 
@@ -183,12 +225,160 @@ external declare_global : lltype -> string -> llmodule -> llvalue
 external define_global : string -> llvalue -> llmodule -> llvalue
                        = "llvm_define_global"
 external delete_global : llvalue -> unit = "llvm_delete_global"
-external global_initializer : llvalue -> llvalue = "llvm_global_initializer"
+external global_initializer : llvalue -> llvalue = "LLVMGetInitializer"
 external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer"
 external remove_initializer : llvalue -> unit = "llvm_remove_initializer"
 external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
 external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
 
+(*--... Operations on functions ............................................--*)
+external declare_function : string -> lltype -> llmodule -> llvalue
+                          = "llvm_declare_function"
+external define_function : string -> lltype -> llmodule -> llvalue
+                         = "llvm_define_function"
+external delete_function : llvalue -> unit = "llvm_delete_function"
+external params : llvalue -> llvalue array = "llvm_params"
+external param : llvalue -> int -> llvalue = "llvm_param"
+external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic"
+external function_call_conv : llvalue -> int = "llvm_function_call_conv"
+external set_function_call_conv : int -> llvalue -> unit
+                                = "llvm_set_function_call_conv"
+
+(* TODO: param attrs *)
+
+(*--... Operations on basic blocks .........................................--*)
+external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks"
+external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock"
+external delete_block : llbasicblock -> unit = "llvm_delete_block"
+external append_block : string -> llvalue -> llbasicblock = "llvm_append_block"
+external insert_block : string -> llbasicblock -> llbasicblock
+                      = "llvm_insert_block"
+external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue"
+external value_is_block : llvalue -> bool = "llvm_value_is_block"
+external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock"
+
+
+(*===-- Instruction builders ----------------------------------------------===*)
+external builder_before : llvalue -> llbuilder = "llvm_builder_before"
+external builder_at_end : llbasicblock -> llbuilder = "llvm_builder_at_end"
+external position_before : llvalue -> llbuilder -> unit = "llvm_position_before"
+external position_at_end : llbasicblock -> llbuilder -> unit
+                         = "llvm_position_at_end"
+
+(*--... Terminators ........................................................--*)
+external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void"
+external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret"
+external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br"
+external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
+                         llvalue = "llvm_build_cond_br"
+external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
+                      = "llvm_build_switch"
+external build_invoke : llvalue -> llvalue array -> llbasicblock ->
+                        llbasicblock -> string -> llbuilder -> llvalue
+                      = "llvm_build_invoke_bc" "llvm_build_invoke_nat"
+external build_unwind : llbuilder -> llvalue = "llvm_build_unwind"
+external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
+
+(*--... Arithmetic .........................................................--*)
+external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_add"
+external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_sub"
+external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_mul"
+external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_udiv"
+external build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_sdiv"
+external build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_fdiv"
+external build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_urem"
+external build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_srem"
+external build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_frem"
+external build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_shl"
+external build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_lshr"
+external build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_ashr"
+external build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_and"
+external build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                  = "llvm_build_or"
+external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_xor"
+external build_neg : llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_neg"
+external build_not : llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_not"
+
+(*--... Memory .............................................................--*)
+external build_malloc : lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_malloc"
+external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
+                              llvalue = "llvm_build_array_malloc"
+external build_alloca : lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_alloca"
+external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
+                              llvalue = "llvm_build_array_alloca"
+external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
+external build_load : llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_load"
+external build_store : llvalue -> llvalue -> llbuilder -> llvalue
+                     = "llvm_build_store"
+external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue
+                   = "llvm_build_gep"
+
+(*--... Casts ..............................................................--*)
+external build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue
+                     = "llvm_build_trunc"
+external build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                    = "llvm_build_zext"
+external build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                    = "llvm_build_sext"
+external build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_fptoui"
+external build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_fptosi"
+external build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_uitofp"
+external build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_sitofp"
+external build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue
+                       = "llvm_build_fptrunc"
+external build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                     = "llvm_build_fpext"
+external build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue
+                        = "llvm_build_prttoint"
+external build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue
+                        = "llvm_build_inttoptr"
+external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue
+                       = "llvm_build_bitcast"
+
+(*--... Comparisons ........................................................--*)
+external build_icmp : int_predicate -> llvalue -> llvalue -> string ->
+                      llbuilder -> llvalue = "llvm_build_icmp"
+external build_fcmp : real_predicate -> llvalue -> llvalue -> string ->
+                      llbuilder -> llvalue = "llvm_build_fcmp"
+
+(*--... Miscellaneous instructions .........................................--*)
+external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi"
+external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue
+                    = "llvm_build_call"
+external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder ->
+                        llvalue = "llvm_build_select"
+external build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_va_arg"
+external build_extractelement : llvalue -> llvalue -> string -> llbuilder ->
+                                llvalue = "llvm_build_extractelement"
+external build_insertelement : llvalue -> llvalue -> llvalue -> string ->
+                               llbuilder -> llvalue = "llvm_build_insertelement"
+external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
+                               llbuilder -> llvalue = "llvm_build_shufflevector"
+
 
 (*===-- Non-Externs -------------------------------------------------------===*)
 (* These functions are built using the externals, so must be declared late.   *)
index 0e38ca0..6275941 100644 (file)
@@ -17,6 +17,9 @@
 type llmodule
 type lltype
 type llvalue
+type llbasicblock (* These are actually values, but
+                     benefit from type checking. *)
+type llbuilder
 
 type type_kind =
   Void_type
@@ -50,6 +53,42 @@ type visibility =
 | Hidden_visibility
 | Protected_visibility
 
+val ccc : int
+val fastcc : int
+val coldcc : int
+val x86_stdcallcc : int
+val x86_fastcallcc : int
+
+type int_predicate =
+  Icmp_eq
+| Icmp_ne
+| Icmp_ugt
+| Icmp_uge
+| Icmp_ult
+| Icmp_ule
+| Icmp_sgt
+| Icmp_sge
+| Icmp_slt
+| Icmp_sle
+
+type real_predicate =
+  Fcmp_false
+| Fcmp_oeq
+| Fcmp_ogt
+| Fcmp_oge
+| Fcmp_olt
+| Fcmp_ole
+| Fcmp_one
+| Fcmp_ord
+| Fcmp_uno
+| Fcmp_ueq
+| Fcmp_ugt
+| Fcmp_uge
+| Fcmp_ult
+| Fcmp_ule
+| Fcmp_une
+| Fcmp_true
+
 
 (*===-- Modules -----------------------------------------------------------===*)
 
@@ -63,8 +102,11 @@ external dispose_module : llmodule -> unit = "llvm_dispose_module"
 
 (* Adds a named type to the module's symbol table. Returns true if successful.
    If such a name already exists, then no entry is added and returns false. *)
-external add_type_name : string -> lltype -> llmodule -> bool
-                       = "llvm_add_type_name"
+external define_type_name : string -> lltype -> llmodule -> bool
+                          = "llvm_add_type_name"
+
+external delete_type_name : string -> llmodule -> unit
+                          = "llvm_delete_type_name"
 
 
 (*===-- Types -------------------------------------------------------------===*)
@@ -125,9 +167,9 @@ external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
 
 (*--... Operations on constants of (mostly) any type .......................--*)
 external is_constant : llvalue -> bool = "llvm_is_constant"
-external make_null : lltype -> llvalue = "llvm_make_null"
-external make_all_ones : (*int|vec*)lltype -> llvalue = "llvm_make_all_ones"
-external make_undef : lltype -> llvalue = "llvm_make_undef"
+external make_null : lltype -> llvalue = "LLVMGetNull"
+external make_all_ones : (*int|vec*)lltype -> llvalue = "LLVMGetAllOnes"
+external make_undef : lltype -> llvalue = "LLVMGetUndef"
 external is_null : llvalue -> bool = "llvm_is_null"
 external is_undef : llvalue -> bool = "llvm_is_undef"
 
@@ -166,9 +208,154 @@ external declare_global : lltype -> string -> llmodule -> llvalue
 external define_global : string -> llvalue -> llmodule -> llvalue
                        = "llvm_define_global"
 external delete_global : llvalue -> unit = "llvm_delete_global"
-external global_initializer : llvalue -> llvalue = "llvm_global_initializer"
+external global_initializer : llvalue -> llvalue = "LLVMGetInitializer"
 external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer"
 external remove_initializer : llvalue -> unit = "llvm_remove_initializer"
 external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
 external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
 
+(*--... Operations on functions ............................................--*)
+external declare_function : string -> lltype -> llmodule -> llvalue
+                          = "llvm_declare_function"
+external define_function : string -> lltype -> llmodule -> llvalue
+                         = "llvm_define_function"
+external delete_function : llvalue -> unit = "llvm_delete_function"
+external params : llvalue -> llvalue array = "llvm_params"
+external param : llvalue -> int -> llvalue = "llvm_param"
+external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic"
+external function_call_conv : llvalue -> int = "llvm_function_call_conv"
+external set_function_call_conv : int -> llvalue -> unit
+                                = "llvm_set_function_call_conv"
+
+(*--... Operations on basic blocks .........................................--*)
+external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks"
+external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock"
+external delete_block : llbasicblock -> unit = "llvm_delete_block"
+external append_block : string -> llvalue -> llbasicblock = "llvm_append_block"
+external insert_block : string -> llbasicblock -> llbasicblock
+                      = "llvm_insert_block"
+external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue"
+external value_is_block : llvalue -> bool = "llvm_value_is_block"
+external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock"
+
+
+(*===-- Instruction builders ----------------------------------------------===*)
+external builder_before : llvalue -> llbuilder = "llvm_builder_before"
+external builder_at_end : llbasicblock -> llbuilder = "llvm_builder_at_end"
+external position_before : llvalue -> llbuilder -> unit = "llvm_position_before"
+external position_at_end : llbasicblock -> llbuilder -> unit
+                         = "llvm_position_at_end"
+
+(*--... Terminators ........................................................--*)
+external build_ret_void : llbuilder -> llvalue = "llvm_build_ret_void"
+external build_ret : llvalue -> llbuilder -> llvalue = "llvm_build_ret"
+external build_br : llbasicblock -> llbuilder -> llvalue = "llvm_build_br"
+external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder ->
+                         llvalue = "llvm_build_cond_br"
+external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
+                      = "llvm_build_switch"
+external build_invoke : llvalue -> llvalue array -> llbasicblock ->
+                        llbasicblock -> string -> llbuilder -> llvalue
+                      = "llvm_build_invoke_bc" "llvm_build_invoke_nat"
+external build_unwind : llbuilder -> llvalue = "llvm_build_unwind"
+external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable"
+
+(*--... Arithmetic .........................................................--*)
+external build_add : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_add"
+external build_sub : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_sub"
+external build_mul : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_mul"
+external build_udiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_udiv"
+external build_sdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_sdiv"
+external build_fdiv : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_fdiv"
+external build_urem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_urem"
+external build_srem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_srem"
+external build_frem : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_frem"
+external build_shl : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_shl"
+external build_lshr : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_lshr"
+external build_ashr : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_ashr"
+external build_and : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_and"
+external build_or : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                  = "llvm_build_or"
+external build_xor : llvalue -> llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_xor"
+external build_neg : llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_neg"
+external build_not : llvalue -> string -> llbuilder -> llvalue
+                   = "llvm_build_not"
+
+(*--... Memory .............................................................--*)
+external build_malloc : lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_malloc"
+external build_array_malloc : lltype -> llvalue -> string -> llbuilder ->
+                              llvalue = "llvm_build_array_malloc"
+external build_alloca : lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_alloca"
+external build_array_alloca : lltype -> llvalue -> string -> llbuilder ->
+                              llvalue = "llvm_build_array_alloca"
+external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free"
+external build_load : llvalue -> string -> llbuilder -> llvalue
+                    = "llvm_build_load"
+external build_store : llvalue -> llvalue -> llbuilder -> llvalue
+                     = "llvm_build_store"
+external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue
+                   = "llvm_build_gep"
+
+(*--... Casts ..............................................................--*)
+external build_trunc : llvalue -> lltype -> string -> llbuilder -> llvalue
+                     = "llvm_build_trunc"
+external build_zext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                    = "llvm_build_zext"
+external build_sext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                    = "llvm_build_sext"
+external build_fptoui : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_fptoui"
+external build_fptosi : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_fptosi"
+external build_uitofp : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_uitofp"
+external build_sitofp : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_sitofp"
+external build_fptrunc : llvalue -> lltype -> string -> llbuilder -> llvalue
+                       = "llvm_build_fptrunc"
+external build_fpext : llvalue -> lltype -> string -> llbuilder -> llvalue
+                     = "llvm_build_fpext"
+external build_ptrtoint : llvalue -> lltype -> string -> llbuilder -> llvalue
+                        = "llvm_build_prttoint"
+external build_inttoptr : llvalue -> lltype -> string -> llbuilder -> llvalue
+                        = "llvm_build_inttoptr"
+external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue
+                       = "llvm_build_bitcast"
+
+(*--... Comparisons ........................................................--*)
+external build_icmp : int_predicate -> llvalue -> llvalue -> string ->
+                      llbuilder -> llvalue = "llvm_build_icmp"
+external build_fcmp : real_predicate -> llvalue -> llvalue -> string ->
+                      llbuilder -> llvalue = "llvm_build_fcmp"
+
+(*--... Miscellaneous instructions .........................................--*)
+external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi"
+external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue
+                    = "llvm_build_call"
+external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder ->
+                        llvalue = "llvm_build_select"
+external build_va_arg : llvalue -> lltype -> string -> llbuilder -> llvalue
+                      = "llvm_build_va_arg"
+external build_extractelement : llvalue -> llvalue -> string -> llbuilder ->
+                                llvalue = "llvm_build_extractelement"
+external build_insertelement : llvalue -> llvalue -> llvalue -> string ->
+                               llbuilder -> llvalue = "llvm_build_insertelement"
+external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
+                               llbuilder -> llvalue = "llvm_build_shufflevector"
index f735666..ffa872d 100644 (file)
 
 #include "llvm-c/Core.h"
 #include "caml/alloc.h"
+#include "caml/custom.h"
 #include "caml/mlvalues.h"
 #include "caml/memory.h"
 #include "llvm/Config/config.h" 
 #include <stdio.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
+#include <string.h>
 
 
 /*===-- Modules -----------------------------------------------------------===*/
 
 /* string -> llmodule */
-CAMLprim value llvm_create_module(value ModuleID) {
-  return (value) LLVMModuleCreateWithName(String_val(ModuleID));
+CAMLprim LLVMModuleRef llvm_create_module(value ModuleID) {
+  return LLVMModuleCreateWithName(String_val(ModuleID));
 }
 
 /* llmodule -> unit */
-CAMLprim value llvm_dispose_module(value M) {
-  LLVMDisposeModule((LLVMModuleRef) M);
+CAMLprim value llvm_dispose_module(LLVMModuleRef M) {
+  LLVMDisposeModule(M);
   return Val_unit;
 }
 
 /* string -> lltype -> llmodule -> bool */
-CAMLprim value llvm_add_type_name(value Name, value Ty, value M) {
-  int res = LLVMAddTypeName((LLVMModuleRef) M,
-                            String_val(Name), (LLVMTypeRef) Ty);
+CAMLprim value llvm_add_type_name(value Name, LLVMTypeRef Ty, LLVMModuleRef M) {
+  int res = LLVMAddTypeName(M, String_val(Name), Ty);
   return Val_bool(res == 0);
 }
 
+/* string -> llmodule -> unit */
+CAMLprim value llvm_delete_type_name(value Name, LLVMModuleRef M) {
+  LLVMDeleteTypeName(M, String_val(Name));
+  return Val_unit;
+}
+
 
 /*===-- Types -------------------------------------------------------------===*/
 
 /* lltype -> type_kind */
-CAMLprim value llvm_classify_type(value Ty) {
-  return Val_int(LLVMGetTypeKind((LLVMTypeRef) Ty));
+CAMLprim value llvm_classify_type(LLVMTypeRef Ty) {
+  return Val_int(LLVMGetTypeKind(Ty));
 }
 
 /* lltype -> lltype -> unit */
-CAMLprim value llvm_refine_abstract_type(value ConcreteTy, value AbstractTy) {
-  LLVMRefineAbstractType((LLVMTypeRef) AbstractTy, (LLVMTypeRef) ConcreteTy);
-  return (value) Val_unit;
+CAMLprim value llvm_refine_abstract_type(LLVMTypeRef ConcreteTy,
+                                         LLVMTypeRef AbstractTy) {
+  LLVMRefineAbstractType(AbstractTy, ConcreteTy);
+  return Val_unit;
 }
 
 /*--... Operations on integer types ........................................--*/
 
 /* unit -> lltype */
-CAMLprim value llvm_i1_type (value Unit) { return (value) LLVMInt1Type();  }
-CAMLprim value llvm_i8_type (value Unit) { return (value) LLVMInt8Type();  }
-CAMLprim value llvm_i16_type(value Unit) { return (value) LLVMInt16Type(); }
-CAMLprim value llvm_i32_type(value Unit) { return (value) LLVMInt32Type(); }
-CAMLprim value llvm_i64_type(value Unit) { return (value) LLVMInt64Type(); }
+CAMLprim LLVMTypeRef llvm_i1_type (value Unit) { return LLVMInt1Type();  }
+CAMLprim LLVMTypeRef llvm_i8_type (value Unit) { return LLVMInt8Type();  }
+CAMLprim LLVMTypeRef llvm_i16_type(value Unit) { return LLVMInt16Type(); }
+CAMLprim LLVMTypeRef llvm_i32_type(value Unit) { return LLVMInt32Type(); }
+CAMLprim LLVMTypeRef llvm_i64_type(value Unit) { return LLVMInt64Type(); }
 
 /* int -> lltype */
-CAMLprim value llvm_make_integer_type(value Width) {
-  return (value) LLVMCreateIntegerType(Int_val(Width));
+CAMLprim LLVMTypeRef llvm_make_integer_type(value Width) {
+  return LLVMCreateIntType(Int_val(Width));
 }
 
 /* lltype -> int */
-CAMLprim value llvm_integer_bitwidth(value IntegerTy) {
-  return Val_int(LLVMGetIntegerTypeWidth((LLVMTypeRef) IntegerTy));
+CAMLprim value llvm_integer_bitwidth(LLVMTypeRef IntegerTy) {
+  return Val_int(LLVMGetIntTypeWidth(IntegerTy));
 }
 
 /*--... Operations on real types ...........................................--*/
 
 /* unit -> lltype */
-CAMLprim value llvm_float_type(value Unit) {
-  return (value) LLVMFloatType();
+CAMLprim LLVMTypeRef llvm_float_type(value Unit) {
+  return LLVMFloatType();
 }
 
 /* unit -> lltype */
-CAMLprim value llvm_double_type(value Unit) {
-  return (value) LLVMDoubleType();
+CAMLprim LLVMTypeRef llvm_double_type(value Unit) {
+  return LLVMDoubleType();
 }
 
 /* unit -> lltype */
-CAMLprim value llvm_x86fp80_type(value Unit) {
-  return (value) LLVMX86FP80Type();
+CAMLprim LLVMTypeRef llvm_x86fp80_type(value Unit) {
+  return LLVMX86FP80Type();
 }
 
 /* unit -> lltype */
-CAMLprim value llvm_fp128_type(value Unit) {
-  return (value) LLVMFP128Type();
+CAMLprim LLVMTypeRef llvm_fp128_type(value Unit) {
+  return LLVMFP128Type();
 }
 
 /* unit -> lltype */
-CAMLprim value llvm_ppc_fp128_type(value Unit) {
-  return (value) LLVMPPCFP128Type();
+CAMLprim LLVMTypeRef llvm_ppc_fp128_type(value Unit) {
+  return LLVMPPCFP128Type();
 }
 
 /*--... Operations on function types .......................................--*/
 
 /* lltype -> lltype array -> bool -> lltype */
-CAMLprim value llvm_make_function_type(value RetTy, value ParamTys,
-                                       value IsVarArg) {
-  return (value) LLVMCreateFunctionType((LLVMTypeRef) RetTy,
-                                        (LLVMTypeRef *) ParamTys,
-                                        Wosize_val(ParamTys),
-                                        Bool_val(IsVarArg));
+CAMLprim LLVMTypeRef llvm_make_function_type(LLVMTypeRef RetTy, value ParamTys,
+                                             value IsVarArg) {
+  return LLVMCreateFunctionType(RetTy, (LLVMTypeRef *) ParamTys,
+                                Wosize_val(ParamTys),
+                                Bool_val(IsVarArg));
 }
 
 /* lltype -> bool */
-CAMLprim value llvm_is_var_arg(value FunTy) {
-  return Val_bool(LLVMIsFunctionVarArg((LLVMTypeRef) FunTy));
+CAMLprim value llvm_is_var_arg(LLVMTypeRef FunTy) {
+  return Val_bool(LLVMIsFunctionVarArg(FunTy));
 }
 
 /* lltype -> lltype */
-CAMLprim value llvm_return_type(value FunTy) {
-  return (value) LLVMGetFunctionReturnType((LLVMTypeRef) FunTy);
+CAMLprim LLVMTypeRef llvm_return_type(LLVMTypeRef FunTy) {
+  return LLVMGetReturnType(FunTy);
 }
 
 /* lltype -> lltype array */
-CAMLprim value llvm_param_types(value FunTy) {
-  unsigned Count = LLVMGetFunctionParamCount((LLVMTypeRef) FunTy);
-  LLVMTypeRef *FunTys = alloca(Count * sizeof(LLVMTypeRef));
-  
-  /* copy into an ocaml array */
-  unsigned i;
-  value ParamTys = alloc(Count, 0);
-  
-  LLVMGetFunctionParamTypes((LLVMTypeRef) FunTy, FunTys);
-  for (i = 0; i != Count; ++i)
-    Store_field(ParamTys, i, (value) FunTys[i]);
-  
-  return ParamTys;
+CAMLprim value llvm_param_types(LLVMTypeRef FunTy) {
+  value Tys = alloc(LLVMCountParamTypes(FunTy), 0);
+  LLVMGetParamTypes(FunTy, (LLVMTypeRef *) Tys);
+  return Tys;
 }
 
 /*--... Operations on struct types .........................................--*/
@@ -153,123 +148,101 @@ CAMLprim value llvm_make_struct_type(value ElementTypes, value Packed) {
 }
 
 /* lltype -> lltype array */
-CAMLprim value llvm_element_types(value StructTy) {
-  unsigned Count = LLVMGetStructElementCount((LLVMTypeRef) StructTy);
-  LLVMTypeRef *Tys = alloca(Count * sizeof(LLVMTypeRef));
-  
-  /* copy into an ocaml array */
-  unsigned i;
-  value ElementTys = alloc(Count, 0);
-  
-  LLVMGetStructElementTypes((LLVMTypeRef) StructTy, Tys);
-  for (i = 0; i != Count; ++i)
-    Store_field(ElementTys, i, (value) Tys[i]);
-  
-  return ElementTys;
+CAMLprim value llvm_element_types(LLVMTypeRef StructTy) {
+  value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0);
+  LLVMGetStructElementTypes(StructTy, (LLVMTypeRef *) Tys);
+  return Tys;
 }
 
-CAMLprim value llvm_is_packed(value StructTy) {
-  return Val_bool(LLVMIsPackedStruct((LLVMTypeRef) StructTy));
+/* lltype -> bool */
+CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) {
+  return Val_bool(LLVMIsPackedStruct(StructTy));
 }
 
 /*--... Operations on array, pointer, and vector types .....................--*/
 
 /* lltype -> int -> lltype */
-CAMLprim value llvm_make_array_type(value ElementTy, value Count) {
-  return (value) LLVMCreateArrayType((LLVMTypeRef) ElementTy, Int_val(Count));
+CAMLprim value llvm_make_array_type(LLVMTypeRef ElementTy, value Count) {
+  return (value) LLVMCreateArrayType(ElementTy, Int_val(Count));
 }
 
 /* lltype -> lltype */
-CAMLprim value llvm_make_pointer_type(value ElementTy) {
-  return (value) LLVMCreatePointerType((LLVMTypeRef) ElementTy);
+CAMLprim LLVMTypeRef llvm_make_pointer_type(LLVMTypeRef ElementTy) {
+  return LLVMCreatePointerType(ElementTy);
 }
 
 /* lltype -> int -> lltype */
-CAMLprim value llvm_make_vector_type(value ElementTy, value Count) {
-  return (value) LLVMCreateVectorType((LLVMTypeRef) ElementTy, Int_val(Count));
+CAMLprim LLVMTypeRef llvm_make_vector_type(LLVMTypeRef ElementTy, value Count) {
+  return LLVMCreateVectorType(ElementTy, Int_val(Count));
 }
 
 /* lltype -> lltype */
-CAMLprim value llvm_element_type(value Ty) {
-  return (value) LLVMGetElementType((LLVMTypeRef) Ty);
+CAMLprim LLVMTypeRef llvm_element_type(LLVMTypeRef Ty) {
+  return LLVMGetElementType(Ty);
 }
 
 /* lltype -> int */
-CAMLprim value llvm_array_length(value ArrayTy) {
-  return Val_int(LLVMGetArrayLength((LLVMTypeRef) ArrayTy));
+CAMLprim value llvm_array_length(LLVMTypeRef ArrayTy) {
+  return Val_int(LLVMGetArrayLength(ArrayTy));
 }
 
 /* lltype -> int */
-CAMLprim value llvm_vector_size(value VectorTy) {
-  return Val_int(LLVMGetVectorSize((LLVMTypeRef) VectorTy));
+CAMLprim value llvm_vector_size(LLVMTypeRef VectorTy) {
+  return Val_int(LLVMGetVectorSize(VectorTy));
 }
 
 /*--... Operations on other types ..........................................--*/
 
 /* unit -> lltype */
-CAMLprim value llvm_void_type (value Unit) { return (value) LLVMVoidType();  }
-CAMLprim value llvm_label_type(value Unit) { return (value) LLVMLabelType(); }
+CAMLprim LLVMTypeRef llvm_void_type (value Unit) { return LLVMVoidType();  }
+CAMLprim LLVMTypeRef llvm_label_type(value Unit) { return LLVMLabelType(); }
 
 /* unit -> lltype */
-CAMLprim value llvm_make_opaque_type(value Unit) {
-  return (value) LLVMCreateOpaqueType();
+CAMLprim LLVMTypeRef llvm_make_opaque_type(value Unit) {
+  return LLVMCreateOpaqueType();
 }
 
 
 /*===-- VALUES ------------------------------------------------------------===*/
 
 /* llvalue -> lltype */
-CAMLprim value llvm_type_of(value Val) {
-  return (value) LLVMGetTypeOfValue((LLVMValueRef) Val);
+CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) {
+  return LLVMTypeOf(Val);
 }
 
 /* llvalue -> string */
-CAMLprim value llvm_value_name(value Val) {
-  return copy_string(LLVMGetValueName((LLVMValueRef) Val));
+CAMLprim value llvm_value_name(LLVMValueRef Val) {
+  return copy_string(LLVMGetValueName(Val));
 }
 
 /* string -> llvalue -> unit */
-CAMLprim value llvm_set_value_name(value Name, value Val) {
-  LLVMSetValueName((LLVMValueRef) Val, String_val(Name));
+CAMLprim value llvm_set_value_name(value Name, LLVMValueRef Val) {
+  LLVMSetValueName(Val, String_val(Name));
   return Val_unit;
 }
 
 /*--... Operations on constants of (mostly) any type .......................--*/
 
-/* lltype -> llvalue */
-CAMLprim value llvm_make_null(value Ty) {
-  return (value) LLVMGetNull((LLVMTypeRef) Ty);
-}
-
-/* lltype -> llvalue */
-CAMLprim value llvm_make_all_ones(value Ty) {
-  return (value) LLVMGetAllOnes((LLVMTypeRef) Ty);
-}
-
-/* lltype -> llvalue */
-CAMLprim value llvm_make_undef(value Ty) {
-  return (value) LLVMGetUndef((LLVMTypeRef) Ty);
-}
-
 /* llvalue -> bool */
-CAMLprim value llvm_is_constant(value Ty) {
-  return Val_bool(LLVMIsConstant((LLVMValueRef) Ty));
+CAMLprim value llvm_is_constant(LLVMValueRef Val) {
+  return Val_bool(LLVMIsConstant(Val));
 }
 
 /* llvalue -> bool */
-CAMLprim value llvm_is_null(value Val) {
-  return Val_bool(LLVMIsNull((LLVMValueRef) Val));
+CAMLprim value llvm_is_null(LLVMValueRef Val) {
+  return Val_bool(LLVMIsNull(Val));
 }
 
 /* llvalue -> bool */
-CAMLprim value llvm_is_undef(value Ty) {
-  return Val_bool(LLVMIsUndef((LLVMValueRef) Ty));
+CAMLprim value llvm_is_undef(LLVMValueRef Val) {
+  return Val_bool(LLVMIsUndef(Val));
 }
 
 /*--... Operations on scalar constants .....................................--*/
 
 /* lltype -> int -> bool -> llvalue */
-CAMLprim value llvm_make_int_constant(value IntTy, value N, value SExt) {
+CAMLprim LLVMValueRef llvm_make_int_constant(LLVMTypeRef IntTy, value N,
+                                             value SExt) {
   /* GCC warns if we use the ternary operator. */
   unsigned long long N2;
   if (Bool_val(SExt))
@@ -277,41 +250,40 @@ CAMLprim value llvm_make_int_constant(value IntTy, value N, value SExt) {
   else
     N2 = (mlsize_t) Int_val(N);
   
-  return (value) LLVMGetIntConstant((LLVMTypeRef) IntTy, N2, Bool_val(SExt));
+  return LLVMGetIntConstant(IntTy, N2, Bool_val(SExt));
 }
 
 /* lltype -> Int64.t -> bool -> llvalue */
-CAMLprim value llvm_make_int64_constant(value IntTy, value N, value SExt) {
-  return (value) LLVMGetIntConstant((LLVMTypeRef) IntTy, Int64_val(N),
-                                    Bool_val(SExt));
+CAMLprim LLVMValueRef llvm_make_int64_constant(LLVMTypeRef IntTy, value N,
+                                               value SExt) {
+  return LLVMGetIntConstant(IntTy, Int64_val(N), Bool_val(SExt));
 }
 
 /* lltype -> float -> llvalue */
-CAMLprim value llvm_make_real_constant(value RealTy, value N) {
-  return (value) LLVMGetRealConstant((LLVMTypeRef) RealTy, Double_val(N));
+CAMLprim LLVMValueRef llvm_make_real_constant(LLVMTypeRef RealTy, value N) {
+  return LLVMGetRealConstant(RealTy, Double_val(N));
 }
 
 /*--... Operations on composite constants ..................................--*/
 
 /* string -> bool -> llvalue */
-CAMLprim value llvm_make_string_constant(value Str, value NullTerminate) {
-  return (value) LLVMGetStringConstant(String_val(Str),
-                                       string_length(Str),
-                                       Bool_val(NullTerminate) == 0);
+CAMLprim LLVMValueRef llvm_make_string_constant(value Str, value NullTerminate) {
+  return LLVMGetStringConstant(String_val(Str), string_length(Str),
+                               Bool_val(NullTerminate) == 0);
 }
 
 /* lltype -> llvalue array -> llvalue */
-CAMLprim value llvm_make_array_constant(value ElementTy, value ElementVals) {
-  return (value) LLVMGetArrayConstant((LLVMTypeRef) ElementTy,
-                                      (LLVMValueRef*) Op_val(ElementVals),
-                                      Wosize_val(ElementVals));
+CAMLprim LLVMValueRef llvm_make_array_constant(LLVMTypeRef ElementTy,
+                                               value ElementVals) {
+  return LLVMGetArrayConstant(ElementTy, (LLVMValueRef*) Op_val(ElementVals),
+                              Wosize_val(ElementVals));
 }
 
 /* llvalue array -> bool -> llvalue */
-CAMLprim value llvm_make_struct_constant(value ElementVals, value Packed) {
-  return (value) LLVMGetStructConstant((LLVMValueRef*) Op_val(ElementVals),
-                                       Wosize_val(ElementVals),
-                                       Bool_val(Packed));
+CAMLprim LLVMValueRef llvm_make_struct_constant(value ElementVals,
+                                                value Packed) {
+  return LLVMGetStructConstant((LLVMValueRef *) Op_val(ElementVals),
+                               Wosize_val(ElementVals), Bool_val(Packed));
 }
 
 /* llvalue array -> llvalue */
@@ -323,108 +295,591 @@ CAMLprim value llvm_make_vector_constant(value ElementVals) {
 /*--... Operations on global variables, functions, and aliases (globals) ...--*/
 
 /* llvalue -> bool */
-CAMLprim value llvm_is_declaration(value Global) {
-  return Val_bool(LLVMIsDeclaration((LLVMValueRef) Global));
+CAMLprim value llvm_is_declaration(LLVMValueRef Global) {
+  return Val_bool(LLVMIsDeclaration(Global));
 }
 
 /* llvalue -> linkage */
-CAMLprim value llvm_linkage(value Global) {
-  return Val_int(LLVMGetLinkage((LLVMValueRef) Global));
+CAMLprim value llvm_linkage(LLVMValueRef Global) {
+  return Val_int(LLVMGetLinkage(Global));
 }
 
 /* linkage -> llvalue -> unit */
-CAMLprim value llvm_set_linkage(value Linkage, value Global) {
-  LLVMSetLinkage((LLVMValueRef) Global, Int_val(Linkage));
+CAMLprim value llvm_set_linkage(value Linkage, LLVMValueRef Global) {
+  LLVMSetLinkage(Global, Int_val(Linkage));
   return Val_unit;
 }
 
 /* llvalue -> string */
-CAMLprim value llvm_section(value Global) {
-  return copy_string(LLVMGetSection((LLVMValueRef) Global));
+CAMLprim value llvm_section(LLVMValueRef Global) {
+  return copy_string(LLVMGetSection(Global));
 }
 
 /* string -> llvalue -> unit */
-CAMLprim value llvm_set_section(value Section, value Global) {
-  LLVMSetSection((LLVMValueRef) Global, String_val(Section));
+CAMLprim value llvm_set_section(value Section, LLVMValueRef Global) {
+  LLVMSetSection(Global, String_val(Section));
   return Val_unit;
 }
 
 /* llvalue -> visibility */
-CAMLprim value llvm_visibility(value Global) {
-  return Val_int(LLVMGetVisibility((LLVMValueRef) Global));
+CAMLprim value llvm_visibility(LLVMValueRef Global) {
+  return Val_int(LLVMGetVisibility(Global));
 }
 
 /* visibility -> llvalue -> unit */
-CAMLprim value llvm_set_visibility(value Viz, value Global) {
-  LLVMSetVisibility((LLVMValueRef) Global, Int_val(Viz));
+CAMLprim value llvm_set_visibility(value Viz, LLVMValueRef Global) {
+  LLVMSetVisibility(Global, Int_val(Viz));
   return Val_unit;
 }
 
 /* llvalue -> int */
-CAMLprim value llvm_alignment(value Global) {
-  return Val_int(LLVMGetAlignment((LLVMValueRef) Global));
+CAMLprim value llvm_alignment(LLVMValueRef Global) {
+  return Val_int(LLVMGetAlignment(Global));
 }
 
 /* int -> llvalue -> unit */
-CAMLprim value llvm_set_alignment(value Bytes, value Global) {
-  LLVMSetAlignment((LLVMValueRef) Global, Int_val(Bytes));
+CAMLprim value llvm_set_alignment(value Bytes, LLVMValueRef Global) {
+  LLVMSetAlignment(Global, Int_val(Bytes));
   return Val_unit;
 }
 
 /*--... Operations on global variables .....................................--*/
 
 /* lltype -> string -> llmodule -> llvalue */
-CAMLprim value llvm_add_global(value Ty, value Name, value M) {
-  return (value) LLVMAddGlobal((LLVMModuleRef) M,
-                               (LLVMTypeRef) Ty, String_val(Name));
-}
-
-/* lltype -> string -> llmodule -> llvalue */
-CAMLprim value llvm_declare_global(value Ty, value Name, value M) {
-  return (value) LLVMAddGlobal((LLVMModuleRef) M,
-                               (LLVMTypeRef) Ty, String_val(Name));
+CAMLprim LLVMValueRef llvm_declare_global(LLVMTypeRef Ty, value Name,
+                                          LLVMModuleRef M) {
+  return LLVMAddGlobal(M, Ty, String_val(Name));
 }
 
 /* string -> llvalue -> llmodule -> llvalue */
-CAMLprim value llvm_define_global(value Name, value ConstantVal, value M) {
-  LLVMValueRef Initializer = (LLVMValueRef) ConstantVal;
-  LLVMValueRef GlobalVar = LLVMAddGlobal((LLVMModuleRef) M,
-                                         LLVMGetTypeOfValue(Initializer),
+CAMLprim LLVMValueRef llvm_define_global(value Name, LLVMValueRef Initializer,
+                                         LLVMModuleRef M) {
+  LLVMValueRef GlobalVar = LLVMAddGlobal(M, LLVMTypeOf(Initializer),
                                          String_val(Name));
   LLVMSetInitializer(GlobalVar, Initializer);
-  return (value) GlobalVar;
+  return GlobalVar;
 }
 
 /* llvalue -> unit */
-CAMLprim value llvm_delete_global(value GlobalVar) {
-  LLVMDeleteGlobal((LLVMValueRef) GlobalVar);
+CAMLprim value llvm_delete_global(LLVMValueRef GlobalVar) {
+  LLVMDeleteGlobal(GlobalVar);
   return Val_unit;
 }
 
-/* llvalue -> llvalue */
-CAMLprim value llvm_global_initializer(value GlobalVar) {
-  return (value) LLVMGetInitializer((LLVMValueRef) GlobalVar);
-}
-
 /* llvalue -> llvalue -> unit */
-CAMLprim value llvm_set_initializer(value ConstantVal, value GlobalVar) {
-  LLVMSetInitializer((LLVMValueRef) GlobalVar, (LLVMValueRef) ConstantVal);
+CAMLprim value llvm_set_initializer(LLVMValueRef ConstantVal,
+                                    LLVMValueRef GlobalVar) {
+  LLVMSetInitializer(GlobalVar, ConstantVal);
   return Val_unit;
 }
 
 /* llvalue -> unit */
-CAMLprim value llvm_remove_initializer(value GlobalVar) {
-  LLVMSetInitializer((LLVMValueRef) GlobalVar, NULL);
+CAMLprim value llvm_remove_initializer(LLVMValueRef GlobalVar) {
+  LLVMSetInitializer(GlobalVar, NULL);
   return Val_unit;
 }
 
 /* llvalue -> bool */
-CAMLprim value llvm_is_thread_local(value GlobalVar) {
-  return Val_bool(LLVMIsThreadLocal((LLVMValueRef) GlobalVar));
+CAMLprim value llvm_is_thread_local(LLVMValueRef GlobalVar) {
+  return Val_bool(LLVMIsThreadLocal(GlobalVar));
 }
 
 /* bool -> llvalue -> unit */
-CAMLprim value llvm_set_thread_local(value IsThreadLocal, value GlobalVar) {
-  LLVMSetThreadLocal((LLVMValueRef) GlobalVar, Bool_val(IsThreadLocal));
+CAMLprim value llvm_set_thread_local(value IsThreadLocal,
+                                     LLVMValueRef GlobalVar) {
+  LLVMSetThreadLocal(GlobalVar, Bool_val(IsThreadLocal));
+  return Val_unit;
+}
+
+/*--... Operations on functions ............................................--*/
+
+/* string -> lltype -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_declare_function(value Name, LLVMTypeRef Ty,
+                                            LLVMModuleRef M) {
+  return LLVMAddFunction(M, String_val(Name), Ty);
+}
+
+/* string -> lltype -> llmodule -> llvalue */
+CAMLprim LLVMValueRef llvm_define_function(value Name, LLVMTypeRef Ty,
+                                           LLVMModuleRef M) {
+  LLVMValueRef Fn = LLVMAddFunction(M, String_val(Name), Ty);
+  LLVMAppendBasicBlock(Fn, "entry");
+  return Fn;
+}
+
+/* llvalue -> unit */
+CAMLprim value llvm_delete_function(LLVMValueRef Fn) {
+  LLVMDeleteFunction(Fn);
+  return Val_unit;
+}
+
+/* llvalue -> int -> llvalue */
+CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) {
+  return LLVMGetParam(Fn, Int_val(Index));
+}
+
+/* llvalue -> int -> llvalue */
+CAMLprim value llvm_params(LLVMValueRef Fn, value Index) {
+  value Params = alloc(LLVMCountParams(Fn), 0);
+  LLVMGetParams(Fn, (LLVMValueRef *) Op_val(Params));
+  return Params;
+}
+
+/* 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;
+}
+
+/*--... Operations on basic blocks .........................................--*/
+
+/* 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;
+}
+
+/* string -> llvalue -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_append_block(value Name, LLVMValueRef Fn) {
+  return LLVMAppendBasicBlock(Fn, String_val(Name));
+}
+
+/* string -> llbasicblock -> llbasicblock */
+CAMLprim LLVMBasicBlockRef llvm_insert_block(value Name, LLVMBasicBlockRef BB) {
+  return LLVMInsertBasicBlock(BB, String_val(Name));
+}
+
+/* llvalue -> bool */
+CAMLprim value llvm_value_is_block(LLVMValueRef Val) {
+  return Val_bool(LLVMValueIsBasicBlock(Val));
+}
+
+
+/*===-- Instruction builders ----------------------------------------------===*/
+
+#define Builder_val(v)  (*(LLVMBuilderRef *)(Data_custom_val(v)))
+
+void llvm_finalize_builder(value B) {
+  fprintf(stderr, "disposing builder = 0x%08x\n", (int) Builder_val(B));
+  LLVMDisposeBuilder(Builder_val(B));
+}
+
+static struct custom_operations builder_ops = {
+  (char *) "LLVMBuilder",
+  llvm_finalize_builder,
+  custom_compare_default,
+  custom_hash_default,
+  custom_serialize_default,
+  custom_deserialize_default
+};
+
+/* llvalue -> llbuilder */
+CAMLprim value llvm_builder_before(LLVMValueRef Inst) {
+  value V;
+  LLVMBuilderRef B = LLVMCreateBuilder();
+  LLVMPositionBuilderBefore(B, Inst);
+  V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
+  Builder_val(V) = B;
+  return V;
+}
+
+/* llbasicblock -> llbuilder */
+CAMLprim value llvm_builder_at_end(LLVMBasicBlockRef BB) {
+  value V;
+  LLVMBuilderRef B = LLVMCreateBuilder();
+  LLVMPositionBuilderAtEnd(B, BB);
+  fprintf(stderr, "returning builder = 0x%08x\n", (int) B);
+  V = alloc_custom(&builder_ops, sizeof(LLVMBuilderRef), 0, 1);
+  Builder_val(V) = B;
+  return V;
+}
+
+/* llvalue -> llbuilder -> unit */
+CAMLprim value llvm_position_before(LLVMValueRef Inst, value B) {
+  LLVMPositionBuilderBefore(Builder_val(B), Inst);
+  return Val_unit;
+}
+
+/* llbasicblock -> llbuilder -> unit */
+CAMLprim value llvm_position_at_end(LLVMBasicBlockRef BB, value B) {
+  LLVMPositionBuilderAtEnd(Builder_val(B), BB);
   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);
+}
+
+/* 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));
+}
+
+/* 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]);
+}
+
+/* llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_unwind(value B) {
+  return LLVMBuildUnwind(Builder_val(B));
+}
+
+/* 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_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_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_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_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_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_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 Size,
+                                              value Name, value B) {
+  return LLVMBuildArrayMalloc(Builder_val(B), Ty, Size, String_val(Name));
+}
+
+/* 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 -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef Pointer, value B) {
+  return LLVMBuildFree(Builder_val(B), Pointer);
+}
+
+/* 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);
+}
+
+/* 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));
+}
+
+/*--... 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));
+}
+
+/*--... Comparisons ........................................................--*/
+
+/* int_predicate -> 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));
+}
+
+/* real_predicate -> 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 .........................................--*/
+
+/* lltype -> string -> llbuilder -> llvalue */
+CAMLprim LLVMValueRef llvm_build_phi(LLVMTypeRef Ty,
+                                     value Name, value B) {
+  return LLVMBuildPhi(Builder_val(B), Ty, String_val(Name));
+}
+
+/* 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));
+}
+
index 9aa5f07..47b89aa 100644 (file)
@@ -37,9 +37,11 @@ extern "C" {
 typedef struct LLVMOpaqueModule *LLVMModuleRef;
 typedef struct LLVMOpaqueType *LLVMTypeRef;
 typedef struct LLVMOpaqueValue *LLVMValueRef;
+typedef struct LLVMOpaqueBasicBlock *LLVMBasicBlockRef;
+typedef struct LLVMOpaqueBuilder *LLVMBuilderRef;
 
 typedef enum {
-  LLVMVoidTypeKind = 0,    /* type with no size */
+  LLVMVoidTypeKind,        /* type with no size */
   LLVMFloatTypeKind,       /* 32 bit floating point type */
   LLVMDoubleTypeKind,      /* 64 bit floating point type */
   LLVMX86_FP80TypeKind,    /* 80 bit floating point type (X87) */
@@ -56,7 +58,7 @@ typedef enum {
 } LLVMTypeKind;
 
 typedef enum {
-  LLVMExternalLinkage = 0,/* Externally visible function */
+  LLVMExternalLinkage,    /* Externally visible function */
   LLVMLinkOnceLinkage,    /* Keep one copy of function when linking (inline) */
   LLVMWeakLinkage,        /* Keep one copy of function when linking (weak) */
   LLVMAppendingLinkage,   /* Special purpose, only applies to global arrays */
@@ -68,11 +70,51 @@ typedef enum {
 } LLVMLinkage;
 
 typedef enum {
-  LLVMDefaultVisibility = 0,  /* The GV is visible */
-  LLVMHiddenVisibility,       /* The GV is hidden */
-  LLVMProtectedVisibility     /* The GV is protected */
+  LLVMDefaultVisibility,  /* The GV is visible */
+  LLVMHiddenVisibility,   /* The GV is hidden */
+  LLVMProtectedVisibility /* The GV is protected */
 } LLVMVisibility;
 
+typedef enum {
+  LLVMCCallConv           = 0,
+  LLVMFastCallConv        = 8,
+  LLVMColdCallConv        = 9,
+  LLVMX86StdcallCallConv  = 64,
+  LLVMX86FastcallCallConv = 65
+} LLVMCallConv;
+
+typedef enum {
+  LLVMIntEQ = 32, /* equal */
+  LLVMIntNE,      /* not equal */
+  LLVMIntUGT,     /* unsigned greater than */
+  LLVMIntUGE,     /* unsigned greater or equal */
+  LLVMIntULT,     /* unsigned less than */
+  LLVMIntULE,     /* unsigned less or equal */
+  LLVMIntSGT,     /* signed greater than */
+  LLVMIntSGE,     /* signed greater or equal */
+  LLVMIntSLT,     /* signed less than */
+  LLVMIntSLE      /* signed less or equal */
+} LLVMIntPredicate;
+
+typedef enum {
+  LLVMRealPredicateFalse, /* Always false (always folded) */
+  LLVMRealOEQ,            /* True if ordered and equal */
+  LLVMRealOGT,            /* True if ordered and greater than */
+  LLVMRealOGE,            /* True if ordered and greater than or equal */
+  LLVMRealOLT,            /* True if ordered and less than */
+  LLVMRealOLE,            /* True if ordered and less than or equal */
+  LLVMRealONE,            /* True if ordered and operands are unequal */
+  LLVMRealORD,            /* True if ordered (no nans) */
+  LLVMRealUNO,            /* True if unordered: isnan(X) | isnan(Y) */
+  LLVMRealUEQ,            /* True if unordered or equal */
+  LLVMRealUGT,            /* True if unordered or greater than */
+  LLVMRealUGE,            /* True if unordered, greater than, or equal */
+  LLVMRealULT,            /* True if unordered or less than */
+  LLVMRealULE,            /* True if unordered, less than, or equal */
+  LLVMRealUNE,            /* True if unordered or not equal */
+  LLVMRealPredicateTrue   /* Always true (always folded) */
+} LLVMRealPredicate;
+
 
 /*===-- Modules -----------------------------------------------------------===*/
 
@@ -82,10 +124,10 @@ void LLVMDisposeModule(LLVMModuleRef M);
 
 /* Same as Module::addTypeName. */
 int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty);
-int LLVMDeleteTypeName(LLVMModuleRef M, const char *Name);
+void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name);
 
 
-/*===-- Types --------------------------------------------------------------===*/
+/*===-- Types -------------------------------------------------------------===*/
 
 /* LLVM types conform to the following hierarchy:
  * 
@@ -111,8 +153,8 @@ LLVMTypeRef LLVMInt8Type();
 LLVMTypeRef LLVMInt16Type();
 LLVMTypeRef LLVMInt32Type();
 LLVMTypeRef LLVMInt64Type();
-LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits);
-unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy);
+LLVMTypeRef LLVMCreateIntType(unsigned NumBits);
+unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy);
 
 /* Operations on real types */
 LLVMTypeRef LLVMFloatType();
@@ -126,14 +168,14 @@ LLVMTypeRef LLVMCreateFunctionType(LLVMTypeRef ReturnType,
                                    LLVMTypeRef *ParamTypes, unsigned ParamCount,
                                    int IsVarArg);
 int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy);
-LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy);
-unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy);
-void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
+LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy);
+unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy);
+void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest);
 
 /* Operations on struct types */
 LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes,
                                  unsigned ElementCount, int Packed);
-unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy);
+unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy);
 void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest);
 int LLVMIsPackedStruct(LLVMTypeRef StructTy);
 
@@ -165,10 +207,11 @@ LLVMTypeRef LLVMCreateOpaqueType();
  *         global variable
  *         function
  *         alias
+ *       basic blocks
  */
 
 /* Operations on all values */
-LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val);
+LLVMTypeRef LLVMTypeOf(LLVMValueRef Val);
 const char *LLVMGetValueName(LLVMValueRef Val);
 void LLVMSetValueName(LLVMValueRef Val, const char *Name);
 
@@ -215,6 +258,157 @@ void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal);
 int LLVMIsThreadLocal(LLVMValueRef GlobalVar);
 void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal);
 
+/* Operations on functions */
+LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
+                             LLVMTypeRef FunctionTy);
+void LLVMDeleteFunction(LLVMValueRef Fn);
+unsigned LLVMCountParams(LLVMValueRef Fn);
+void LLVMGetParams(LLVMValueRef Fn, LLVMValueRef *Params);
+LLVMValueRef LLVMGetParam(LLVMValueRef Fn, unsigned Index);
+unsigned LLVMGetIntrinsicID(LLVMValueRef Fn);
+unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn);
+void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC);
+
+/* Operations on basic blocks */
+LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb);
+int LLVMValueIsBasicBlock(LLVMValueRef Val);
+LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val);
+unsigned LLVMCountBasicBlocks(LLVMValueRef Fn);
+void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks);
+LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn);
+LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name);
+LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB,
+                                       const char *Name);
+void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB);
+
+
+/*===-- Instruction builders ----------------------------------------------===*/
+
+/* An instruction builder represents a point within a basic block, and is the
+ * exclusive means of building instructions using the C interface.
+ */
+
+LLVMBuilderRef LLVMCreateBuilder();
+void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr);
+void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block);
+void LLVMDisposeBuilder(LLVMBuilderRef Builder);
+
+/* Terminators */
+LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef);
+LLVMValueRef LLVMBuildRet(LLVMBuilderRef, LLVMValueRef V);
+LLVMValueRef LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef Dest);
+LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef If,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Else);
+LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef V,
+                             LLVMBasicBlockRef Else, unsigned NumCases);
+LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
+                             LLVMValueRef *Args, unsigned NumArgs,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
+                             const char *Name);
+LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
+LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
+
+/* Arithmetic */
+LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildSub(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildMul(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildURem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildShl(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildOr(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildXor(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name);
+LLVMValueRef LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
+
+/* Memory */
+LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name);
+LLVMValueRef LLVMBuildFree(LLVMBuilderRef, LLVMValueRef PointerVal);
+LLVMValueRef LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef PointerVal,
+                           const char *Name);
+LLVMValueRef LLVMBuildStore(LLVMBuilderRef, LLVMValueRef Val, LLVMValueRef Ptr);
+LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+                          LLVMValueRef *Indices, unsigned NumIndices,
+                          const char *Name);
+
+/* Casts */
+LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name);
+LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name);
+
+/* Comparisons */
+LLVMValueRef LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name);
+
+/* Miscellaneous instructions */
+LLVMValueRef LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
+LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn,
+                           LLVMValueRef *Args, unsigned NumArgs,
+                           const char *Name);
+LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If,
+                             LLVMValueRef Then, LLVMValueRef Else,
+                             const char *Name);
+LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef List, LLVMTypeRef Ty,
+                            const char *Name);
+LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef VecVal,
+                                     LLVMValueRef Index, const char *Name);
+LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef VecVal,
+                                    LLVMValueRef EltVal, LLVMValueRef Index,
+                                    const char *Name);
+LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
+                                    LLVMValueRef V2, LLVMValueRef Mask,
+                                    const char *Name);
 
 #ifdef __cplusplus
 }
index d00aba3..0ae7503 100644 (file)
@@ -89,6 +89,16 @@ namespace llvm {
   inline LLVMValueRef *wrap(const Value **Vals) {
     return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
   }
+  
+  /// Basic block conversions
+  /// 
+  inline BasicBlock *unwrap(LLVMBasicBlockRef BBRef) {
+    return reinterpret_cast<BasicBlock*>(BBRef);
+  }
+  
+  inline LLVMBasicBlockRef wrap(const BasicBlock *BB) {
+    return reinterpret_cast<LLVMBasicBlockRef>(const_cast<BasicBlock*>(BB));
+  }
 }
 
 #endif
index b809db2..9fc4d40 100644 (file)
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/GlobalVariable.h"
-#include <ostream>
-#include <fstream>
+#include "llvm/Support/LLVMBuilder.h"
+#include "llvm/TypeSymbolTable.h"
 #include <cassert>
 
 using namespace llvm;
 
+namespace {
+  /// Opaque builder conversions.
+  /// 
+  inline LLVMBuilder *unwrap(LLVMBuilderRef B) {
+    return reinterpret_cast<LLVMBuilder*>(B);
+  }
+  
+  inline LLVMBuilderRef wrap(LLVMBuilder *B) {
+    return reinterpret_cast<LLVMBuilderRef>(B);
+  }
+}
+
 
 /*===-- Operations on modules ---------------------------------------------===*/
 
@@ -39,6 +51,15 @@ int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) {
   return unwrap(M)->addTypeName(Name, unwrap(Ty));
 }
 
+void LLVMDeleteTypeName(LLVMModuleRef M, const char *Name) {
+  std::string N(Name);
+  
+  TypeSymbolTable &TST = unwrap(M)->getTypeSymbolTable();
+  for (TypeSymbolTable::iterator I = TST.begin(), E = TST.end(); I != E; ++I)
+    if (I->first == N)
+      TST.remove(I);
+}
+
 
 /*===-- Operations on types -----------------------------------------------===*/
 
@@ -61,11 +82,11 @@ LLVMTypeRef LLVMInt16Type() { return (LLVMTypeRef) Type::Int16Ty; }
 LLVMTypeRef LLVMInt32Type() { return (LLVMTypeRef) Type::Int32Ty; }
 LLVMTypeRef LLVMInt64Type() { return (LLVMTypeRef) Type::Int64Ty; }
 
-LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits) {
+LLVMTypeRef LLVMCreateIntType(unsigned NumBits) {
   return wrap(IntegerType::get(NumBits));
 }
 
-unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy) {
+unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) {
   return unwrap<IntegerType>(IntegerTy)->getBitWidth();
 }
 
@@ -93,15 +114,15 @@ int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) {
   return unwrap<FunctionType>(FunctionTy)->isVarArg();
 }
 
-LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy) {
+LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy) {
   return wrap(unwrap<FunctionType>(FunctionTy)->getReturnType());
 }
 
-unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy) {
+unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy) {
   return unwrap<FunctionType>(FunctionTy)->getNumParams();
 }
 
-void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) {
+void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) {
   FunctionType *Ty = unwrap<FunctionType>(FunctionTy);
   for (FunctionType::param_iterator I = Ty->param_begin(),
                                     E = Ty->param_end(); I != E; ++I)
@@ -120,7 +141,7 @@ LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes,
   return wrap(StructType::get(Tys, Packed != 0));
 }
 
-unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy) {
+unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) {
   return unwrap<StructType>(StructTy)->getNumElements();
 }
 
@@ -175,7 +196,7 @@ LLVMTypeRef LLVMCreateOpaqueType() {
 
 /*--.. Operations on all values ............................................--*/
 
-LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val) {
+LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) {
   return wrap(unwrap(Val)->getType());
 }
 
@@ -328,3 +349,426 @@ void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal) {
   unwrap<GlobalVariable>(GlobalVar)->setThreadLocal(IsThreadLocal != 0);
 }
 
+/*--.. Operations on functions .............................................--*/
+
+LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name,
+                             LLVMTypeRef FunctionTy) {
+  return wrap(new Function(unwrap<FunctionType>(FunctionTy),
+                           GlobalValue::ExternalLinkage, Name, unwrap(M)));
+}
+
+void LLVMDeleteFunction(LLVMValueRef Fn) {
+  unwrap<Function>(Fn)->eraseFromParent();
+}
+
+unsigned LLVMCountParams(LLVMValueRef FnRef) {
+  // This function is strictly redundant to
+  //   LLVMCountParamTypes(LLVMGetElementType(LLVMTypeOf(FnRef)))
+  return unwrap<Function>(FnRef)->getArgumentList().size();
+}
+
+LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) {
+  Function::arg_iterator AI = unwrap<Function>(FnRef)->arg_begin();
+  while (index --> 0)
+    AI++;
+  return wrap(AI);
+}
+
+void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) {
+  Function *Fn = unwrap<Function>(FnRef);
+  for (Function::arg_iterator I = Fn->arg_begin(),
+                              E = Fn->arg_end(); I != E; I++)
+    *ParamRefs++ = wrap(I);
+}
+
+unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) {
+  if (Function *F = dyn_cast<Function>(unwrap(Fn)))
+    return F->getIntrinsicID();
+  return 0;
+}
+
+unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) {
+  return unwrap<Function>(Fn)->getCallingConv();
+}
+
+void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) {
+  return unwrap<Function>(Fn)->setCallingConv(CC);
+}
+
+/*--.. Operations on basic blocks ..........................................--*/
+
+LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef Bb) {
+  return wrap(static_cast<Value*>(unwrap(Bb)));
+}
+
+int LLVMValueIsBasicBlock(LLVMValueRef Val) {
+  return isa<BasicBlock>(unwrap(Val));
+}
+
+LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) {
+  return wrap(unwrap<BasicBlock>(Val));
+}
+
+unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) {
+  return unwrap<Function>(FnRef)->getBasicBlockList().size();
+}
+
+void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){
+  Function *Fn = unwrap<Function>(FnRef);
+  for (Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++)
+    *BasicBlocksRefs++ = wrap(I);
+}
+
+LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) {
+  return wrap(&unwrap<Function>(Fn)->getEntryBlock());
+}
+
+LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) {
+  return wrap(new BasicBlock(Name, unwrap<Function>(FnRef)));
+}
+
+LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBBRef,
+                                       const char *Name) {
+  BasicBlock *InsertBeforeBB = unwrap(InsertBeforeBBRef);
+  return wrap(new BasicBlock(Name, InsertBeforeBB->getParent(),
+                             InsertBeforeBB));
+}
+
+void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) {
+  unwrap(BBRef)->eraseFromParent();
+}
+
+/*--.. Call and invoke instructions ........................................--*/
+
+unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) {
+  Value *V = unwrap(Instr);
+  if (CallInst *CI = dyn_cast<CallInst>(V))
+    return CI->getCallingConv();
+  else if (InvokeInst *II = dyn_cast<InvokeInst>(V))
+    return II->getCallingConv();
+  assert(0 && "LLVMGetInstructionCallConv applies only to call and invoke!");
+  return 0;
+}
+
+void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) {
+  Value *V = unwrap(Instr);
+  if (CallInst *CI = dyn_cast<CallInst>(V))
+    return CI->setCallingConv(CC);
+  else if (InvokeInst *II = dyn_cast<InvokeInst>(V))
+    return II->setCallingConv(CC);
+  assert(0 && "LLVMSetInstructionCallConv applies only to call and invoke!");
+}
+
+
+/*===-- Instruction builders ----------------------------------------------===*/
+
+LLVMBuilderRef LLVMCreateBuilder() {
+  return wrap(new LLVMBuilder());
+}
+
+void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) {
+  Instruction *I = unwrap<Instruction>(Instr);
+  unwrap(Builder)->SetInsertPoint(I->getParent(), I);
+}
+
+void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) {
+  BasicBlock *BB = unwrap(Block);
+  unwrap(Builder)->SetInsertPoint(BB);
+}
+
+void LLVMDisposeBuilder(LLVMBuilderRef Builder) {
+  delete unwrap(Builder);
+}
+
+/*--.. Instruction builders ................................................--*/
+
+LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) {
+  return wrap(unwrap(B)->CreateRetVoid());
+}
+
+LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) {
+  return wrap(unwrap(B)->CreateRet(unwrap(V)));
+}
+
+LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) {
+  return wrap(unwrap(B)->CreateBr(unwrap(Dest)));
+}
+
+LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) {
+  return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else)));
+}
+
+LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V,
+                             LLVMBasicBlockRef Else, unsigned NumCases) {
+  return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases));
+}
+
+LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn,
+                             LLVMValueRef *Args, unsigned NumArgs,
+                             LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
+                             const char *Name) {
+  return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
+                                      unwrap(Args), unwrap(Args) + NumArgs,
+                                      Name));
+}
+
+LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) {
+  return wrap(unwrap(B)->CreateUnwind());
+}
+
+LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) {
+  return wrap(unwrap(B)->CreateUnreachable());
+}
+
+/*--.. Arithmetic ..........................................................--*/
+
+LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                         const char *Name) {
+  return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
+  return wrap(unwrap(B)->CreateNeg(unwrap(V), Name));
+}
+
+LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
+  return wrap(unwrap(B)->CreateNot(unwrap(V), Name));
+}
+
+/*--.. Memory ..............................................................--*/
+
+LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
+                             const char *Name) {
+  return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), 0, Name));
+}
+
+LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name) {
+  return wrap(unwrap(B)->CreateMalloc(unwrap(Ty), unwrap(Val), Name));
+}
+
+LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
+                             const char *Name) {
+  return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), 0, Name));
+}
+
+LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
+                                  LLVMValueRef Val, const char *Name) {
+  return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name));
+}
+
+LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) {
+  return wrap(unwrap(B)->CreateFree(unwrap(PointerVal)));
+}
+
+
+LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name));
+}
+
+LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, 
+                            LLVMValueRef PointerVal) {
+  return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal)));
+}
+
+LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer,
+                          LLVMValueRef *Indices, unsigned NumIndices,
+                          const char *Name) {
+  return wrap(unwrap(B)->CreateGEP(unwrap(Pointer), unwrap(Indices),
+                                   unwrap(Indices) + NumIndices, Name));
+}
+
+/*--.. Casts ...............................................................--*/
+
+LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val,
+                           LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val,
+                             LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val,
+                            LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val,
+                               LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name));
+}
+
+LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val,
+                              LLVMTypeRef DestTy, const char *Name) {
+  return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name));
+}
+
+/*--.. Comparisons .........................................................--*/
+
+LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateICmp(static_cast<ICmpInst::Predicate>(Op),
+                                    unwrap(LHS), unwrap(RHS), Name));
+}
+
+LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op,
+                           LLVMValueRef LHS, LLVMValueRef RHS,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateFCmp(static_cast<FCmpInst::Predicate>(Op),
+                                    unwrap(LHS), unwrap(RHS), Name));
+}
+
+/*--.. Miscellaneous instructions ..........................................--*/
+
+LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) {
+  return wrap(unwrap(B)->CreatePHI(unwrap(Ty), Name));
+}
+
+LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn,
+                           LLVMValueRef *Args, unsigned NumArgs,
+                           const char *Name) {
+  return wrap(unwrap(B)->CreateCall(unwrap(Fn), unwrap(Args),
+                                    unwrap(Args) + NumArgs, Name));
+}
+
+LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If,
+                             LLVMValueRef Then, LLVMValueRef Else,
+                             const char *Name) {
+  return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else),
+                                      Name));
+}
+
+LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List,
+                            LLVMTypeRef Ty, const char *Name) {
+  return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name));
+}
+
+LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal,
+                                      LLVMValueRef Index, const char *Name) {
+  return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index),
+                                              Name));
+}
+
+LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal,
+                                    LLVMValueRef EltVal, LLVMValueRef Index,
+                                    const char *Name) {
+  return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal),
+                                             unwrap(Index), Name));
+}
+
+LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1,
+                                    LLVMValueRef V2, LLVMValueRef Mask,
+                                    const char *Name) {
+  return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2),
+                                             unwrap(Mask), Name));
+}
index 5421e09..7bcdd47 100644 (file)
@@ -11,6 +11,6 @@ let test x = if not x then exit 1 else ()
 let _ =
   let m = Llvm.create_module "ocaml_test_module" in
   
-  ignore (Llvm.add_type_name "caml_int_ty" Llvm.i32_type m);
+  ignore (Llvm.define_type_name "caml_int_ty" Llvm.i32_type m);
   
   test (Llvm_bitwriter.write_bitcode_file m Sys.argv.(1))
index 6d04638..b1d2736 100644 (file)
@@ -44,43 +44,43 @@ let test_types () =
   (* RUN: grep {Ty01.*void} < %t.ll
    *)
   group "void";
-  insist (add_type_name "Ty01" void_type m);
+  insist (define_type_name "Ty01" void_type m);
   insist (Void_type == classify_type void_type);
 
   (* RUN: grep {Ty02.*i1} < %t.ll
    *)
   group "i1";
-  insist (add_type_name "Ty02" i1_type m);
+  insist (define_type_name "Ty02" i1_type m);
   insist (Integer_type == classify_type i1_type);
 
   (* RUN: grep {Ty03.*i32} < %t.ll
    *)
   group "i32";
-  insist (add_type_name "Ty03" i32_type m);
+  insist (define_type_name "Ty03" i32_type m);
 
   (* RUN: grep {Ty04.*i42} < %t.ll
    *)
   group "i42";
   let ty = make_integer_type 42 in
-  insist (add_type_name "Ty04" ty m);
+  insist (define_type_name "Ty04" ty m);
 
   (* RUN: grep {Ty05.*float} < %t.ll
    *)
   group "float";
-  insist (add_type_name "Ty05" float_type m);
+  insist (define_type_name "Ty05" float_type m);
   insist (Float_type == classify_type float_type);
 
   (* RUN: grep {Ty06.*double} < %t.ll
    *)
   group "double";
-  insist (add_type_name "Ty06" double_type m);
+  insist (define_type_name "Ty06" double_type m);
   insist (Double_type == classify_type double_type);
 
   (* RUN: grep {Ty07.*i32.*i1, double} < %t.ll
    *)
   group "function";
   let ty = make_function_type i32_type [| i1_type; double_type |] false in
-  insist (add_type_name "Ty07" ty m);
+  insist (define_type_name "Ty07" ty m);
   insist (Function_type = classify_type ty);
   insist (not (is_var_arg ty));
   insist (i32_type == return_type ty);
@@ -90,14 +90,14 @@ let test_types () =
    *)
   group "vararg";
   let ty = make_function_type void_type [| i32_type |] true in
-  insist (add_type_name "Ty08" ty m);
+  insist (define_type_name "Ty08" ty m);
   insist (is_var_arg ty);
   
   (* RUN: grep {Ty09.*\\\[7 x i8\\\]} < %t.ll
    *)
   group "array";
   let ty = make_array_type i8_type 7 in
-  insist (add_type_name "Ty09" ty m);
+  insist (define_type_name "Ty09" ty m);
   insist (7 = array_length ty);
   insist (i8_type == element_type ty);
   insist (Array_type == classify_type ty);
@@ -106,7 +106,7 @@ let test_types () =
    *)
   group "pointer";
   let ty = make_pointer_type float_type in
-  insist (add_type_name "Ty10" ty m);
+  insist (define_type_name "Ty10" ty m);
   insist (float_type == element_type ty);
   insist (Pointer_type == classify_type ty);
   
@@ -114,7 +114,7 @@ let test_types () =
    *)
   group "vector";
   let ty = make_vector_type i16_type 4 in
-  insist (add_type_name "Ty11" ty m);
+  insist (define_type_name "Ty11" ty m);
   insist (i16_type == element_type ty);
   insist (4 = vector_size ty);
   
@@ -122,9 +122,16 @@ let test_types () =
    *)
   group "opaque";
   let ty = make_opaque_type () in
-  insist (add_type_name "Ty12" ty m);
+  insist (define_type_name "Ty12" ty m);
   insist (ty == ty);
-  insist (ty <> make_opaque_type ())
+  insist (ty <> make_opaque_type ());
+  
+  (* RUN: grep -v {Ty13} < %t.ll
+   *)
+  group "delete";
+  let ty = make_opaque_type () in
+  insist (define_type_name "Ty13" ty m);
+  delete_type_name "Ty13" m
 
 
 (*===-- Constants ---------------------------------------------------------===*)
@@ -163,9 +170,6 @@ let test_constants () =
    *)
   group "string w/ null";
   let c = make_string_constant "hi\000again" true in
-  prerr_string "====> ";
-  prerr_int (array_length (type_of c));
-  prerr_endline " <====";
   ignore (define_global "Const05" c m);
   insist ((make_array_type i8_type 9) = type_of c);
 
@@ -306,6 +310,317 @@ let test_global_variables () =
   delete_global g
 
 
+(*===-- Functions ---------------------------------------------------------===*)
+
+let test_functions () =
+  let ty = make_function_type i32_type [| i32_type; i64_type |] false in
+  let pty = make_pointer_type ty in
+  
+  (* RUN: grep {declare i32 @Fn1\(i32, i64\)} < %t.ll
+   *)
+  group "declare";
+  let fn = declare_function "Fn1" ty m in
+  insist (pty = type_of fn);
+  insist (is_declaration fn);
+  insist (0 = Array.length (basic_blocks fn));
+  
+  (* RUN: grep -v {Fn2} < %t.ll
+   *)
+  group "delete";
+  let fn = declare_function "Fn2" ty m in
+  delete_function fn;
+  
+  (* RUN: grep {define.*Fn3} < %t.ll
+   *)
+  group "define";
+  let fn = define_function "Fn3" ty m in
+  insist (not (is_declaration fn));
+  insist (1 = Array.length (basic_blocks fn));
+  (* this function is not valid because init bb lacks a terminator *)
+  
+  (* RUN: grep {define.*Fn4.*Param1.*Param2} < %t.ll
+   *)
+  group "params";
+  let fn = define_function "Fn4" ty m in
+  let params = params fn in
+  insist (2 = Array.length params);
+  insist (params.(0) = param fn 0);
+  insist (params.(1) = param fn 1);
+  insist (i32_type = type_of params.(0));
+  insist (i64_type = type_of params.(1));
+  set_value_name "Param1" params.(0);
+  set_value_name "Param2" params.(1);
+  (* this function is not valid because init bb lacks a terminator *)
+  
+  (* RUN: grep {fastcc.*Fn5} < %t.ll
+   *)
+  group "callconv";
+  let fn = define_function "Fn5" ty m in
+  insist (ccc = function_call_conv fn);
+  set_function_call_conv fastcc fn;
+  insist (fastcc = function_call_conv fn)
+
+
+(*===-- Basic Blocks ------------------------------------------------------===*)
+
+let test_basic_blocks () =
+  let ty = make_function_type void_type [| |] false in
+  
+  (* RUN: grep {Bb1} < %t.ll
+   *)
+  group "entry";
+  let fn = declare_function "X" ty m in
+  let bb = append_block "Bb1" fn in
+  insist (bb = entry_block fn);
+  
+  (* RUN: grep -v Bb2 < %t.ll
+   *)
+  group "delete";
+  let fn = declare_function "X2" ty m in
+  let bb = append_block "Bb2" fn in
+  delete_block bb;
+  
+  group "insert";
+  let fn = declare_function "X3" ty m in
+  let bbb = append_block "" fn in
+  let bba = insert_block "" bbb in
+  insist ([| bba; bbb |] = basic_blocks fn);
+  
+  (* RUN: grep Bb3 < %t.ll
+   *)
+  group "name/value";
+  let fn = define_function "X4" ty m in
+  let bb = entry_block fn in
+  let bbv = value_of_block bb in
+  set_value_name "Bb3" bbv;
+  insist ("Bb3" = value_name bbv);
+  
+  group "casts";
+  let fn = define_function "X5" ty m in
+  let bb = entry_block fn in
+  insist (bb = block_of_value (value_of_block bb));
+  insist (value_is_block (value_of_block bb));
+  insist (not (value_is_block (make_null i32_type)))
+
+
+(*===-- Builder -----------------------------------------------------------===*)
+
+let test_builder () =
+  let (++) x f = f x; x in
+  
+  group "ret void";
+  begin
+    (* RUN: grep {ret void} < %t.ll
+     *)
+    let fty = make_function_type void_type [| |] false in
+    let fn = declare_function "X6" fty m in
+    let b = builder_at_end (append_block "Bb01" fn) in
+    ignore (build_ret_void b)
+  end;
+  
+  (* The rest of the tests will use one big function. *)
+  let fty = make_function_type i32_type [| i32_type; i32_type |] false in
+  let fn = define_function "X7" fty m in
+  let atentry = builder_at_end (entry_block fn) in
+  let p1 = param fn 0 ++ set_value_name "P1" in
+  let p2 = param fn 1 ++ set_value_name "P2" in
+  let f1 = build_uitofp p1 float_type "F1" atentry in
+  let f2 = build_uitofp p2 float_type "F2" atentry in
+  
+  let bb00 = append_block "Bb00" fn in
+  ignore (build_unreachable (builder_at_end bb00));
+  
+  group "ret"; begin
+    (* RUN: grep {ret.*P1} < %t.ll
+     *)
+    let ret = build_ret p1 atentry in
+    position_before ret atentry
+  end;
+  
+  group "br"; begin
+    (* RUN: grep {br.*Bb02} < %t.ll
+     *)
+    let bb02 = append_block "Bb02" fn in
+    let b = builder_at_end bb02 in
+    ignore (build_br bb02 b)
+  end;
+  
+  group "cond_br"; begin
+    (* RUN: grep {br.*Inst01.*Bb03.*Bb00} < %t.ll
+     *)
+    let bb03 = append_block "Bb03" fn in
+    let b = builder_at_end bb03 in
+    let cond = build_trunc p1 i1_type "Inst01" b in
+    ignore (build_cond_br cond bb03 bb00 b)
+  end;
+  
+  (* TODO: Switch *)
+  
+  group "invoke"; begin
+    (* RUN: grep {Inst02.*invoke.*P1.*P2} < %t.ll
+     * RUN: grep {to.*Bb04.*unwind.*Bb00} < %t.ll
+     *)
+    let bb04 = append_block "Bb04" fn in
+    let b = builder_at_end bb04 in
+    ignore (build_invoke fn [| p1; p2 |] bb04 bb00 "Inst02" b)
+  end;
+  
+  group "unwind"; begin
+    (* RUN: grep {unwind} < %t.ll
+     *)
+    let bb05 = append_block "Bb05" fn in
+    let b = builder_at_end bb05 in
+    ignore (build_unwind b)
+  end;
+  
+  group "unreachable"; begin
+    (* RUN: grep {unreachable} < %t.ll
+     *)
+    let bb06 = append_block "Bb06" fn in
+    let b = builder_at_end bb06 in
+    ignore (build_unreachable b)
+  end;
+  
+  group "arithmetic"; begin
+    let bb07 = append_block "Bb07" fn in
+    let b = builder_at_end bb07 in
+    
+    (* RUN: grep {Inst03.*add.*P1.*P2} < %t.ll
+     * RUN: grep {Inst04.*sub.*P1.*Inst03} < %t.ll
+     * RUN: grep {Inst05.*mul.*P1.*Inst04} < %t.ll
+     * RUN: grep {Inst06.*udiv.*P1.*Inst05} < %t.ll
+     * RUN: grep {Inst07.*sdiv.*P1.*Inst06} < %t.ll
+     * RUN: grep {Inst08.*fdiv.*F1.*F2} < %t.ll
+     * RUN: grep {Inst09.*urem.*P1.*Inst07} < %t.ll
+     * RUN: grep {Inst10.*srem.*P1.*Inst09} < %t.ll
+     * RUN: grep {Inst11.*frem.*F1.*Inst08} < %t.ll
+     * RUN: grep {Inst12.*shl.*P1.*Inst10} < %t.ll
+     * RUN: grep {Inst13.*lshr.*P1.*Inst12} < %t.ll
+     * RUN: grep {Inst14.*ashr.*P1.*Inst13} < %t.ll
+     * RUN: grep {Inst15.*and.*P1.*Inst14} < %t.ll
+     * RUN: grep {Inst16.*or.*P1.*Inst15} < %t.ll
+     * RUN: grep {Inst17.*xor.*P1.*Inst16} < %t.ll
+     * RUN: grep {Inst18.*sub.*0.*Inst17} < %t.ll
+     * RUN: grep {Inst19.*xor.*Inst18.*-1} < %t.ll
+     *)
+    let inst03 = build_add  p1 p2     "Inst03" b in
+    let inst04 = build_sub  p1 inst03 "Inst04" b in
+    let inst05 = build_mul  p1 inst04 "Inst05" b in
+    let inst06 = build_udiv p1 inst05 "Inst06" b in
+    let inst07 = build_sdiv p1 inst06 "Inst07" b in
+    let inst08 = build_fdiv f1 f2     "Inst08" b in
+    let inst09 = build_urem p1 inst07 "Inst09" b in
+    let inst10 = build_srem p1 inst09 "Inst10" b in
+          ignore(build_frem f1 inst08 "Inst11" b);
+    let inst12 = build_shl  p1 inst10 "Inst12" b in
+    let inst13 = build_lshr p1 inst12 "Inst13" b in
+    let inst14 = build_ashr p1 inst13 "Inst14" b in
+    let inst15 = build_and  p1 inst14 "Inst15" b in
+    let inst16 = build_or   p1 inst15 "Inst16" b in
+    let inst17 = build_xor  p1 inst16 "Inst17" b in
+    let inst18 = build_neg  inst17    "Inst18" b in
+         ignore (build_not  inst18    "Inst19" b)
+  end;
+  
+  group "memory"; begin
+    let bb08 = append_block "Bb08" fn in
+    let b = builder_at_end bb08 in
+    
+    (* RUN: grep {Inst20.*malloc.*i8   } < %t.ll
+     * RUN: grep {Inst21.*malloc.*i8.*P1} < %t.ll
+     * RUN: grep {Inst22.*alloca.*i32  } < %t.ll
+     * RUN: grep {Inst23.*alloca.*i32.*P2} < %t.ll
+     * RUN: grep {free.*Inst20} < %t.ll
+     * RUN: grep {Inst25.*load.*Inst21} < %t.ll
+     * RUN: grep {store.*P2.*Inst22} < %t.ll
+     * RUN: grep {Inst27.*getelementptr.*Inst23.*P2} < %t.ll
+     *)
+    let inst20 = build_malloc i8_type "Inst20" b in
+    let inst21 = build_array_malloc i8_type p1 "Inst21" b in
+    let inst22 = build_alloca i32_type "Inst22" b in
+    let inst23 = build_array_alloca i32_type p2 "Inst23" b in
+          ignore(build_free inst20 b);
+          ignore(build_load inst21 "Inst25" b);
+          ignore(build_store p2 inst22 b);
+          ignore(build_gep inst23 [| p2 |] "Inst27" b)
+  end;
+  
+  group "casts"; begin
+    let void_ptr = make_pointer_type i8_type in
+    
+    (* RUN: grep {Inst28.*trunc.*P1.*i8} < %t.ll
+     * RUN: grep {Inst29.*zext.*Inst28.*i32} < %t.ll
+     * RUN: grep {Inst30.*sext.*Inst29.*i64} < %t.ll
+     * RUN: grep {Inst31.*uitofp.*Inst30.*float} < %t.ll
+     * RUN: grep {Inst32.*sitofp.*Inst29.*double} < %t.ll
+     * RUN: grep {Inst33.*fptoui.*Inst31.*i32} < %t.ll
+     * RUN: grep {Inst34.*fptosi.*Inst32.*i64} < %t.ll
+     * RUN: grep {Inst35.*fptrunc.*Inst32.*float} < %t.ll
+     * RUN: grep {Inst36.*fpext.*Inst35.*double} < %t.ll
+     * RUN: grep {Inst37.*inttoptr.*P1.*i8\*} < %t.ll
+     * RUN: grep {Inst38.*ptrtoint.*Inst37.*i64} < %t.ll
+     * RUN: grep {Inst39.*bitcast.*Inst38.*double} < %t.ll
+     *)
+    let inst28 = build_trunc p1 i8_type "Inst28" atentry in
+    let inst29 = build_zext inst28 i32_type "Inst29" atentry in
+    let inst30 = build_sext inst29 i64_type "Inst30" atentry in
+    let inst31 = build_uitofp inst30 float_type "Inst31" atentry in
+    let inst32 = build_sitofp inst29 double_type "Inst32" atentry in
+          ignore(build_fptoui inst31 i32_type "Inst33" atentry);
+          ignore(build_fptosi inst32 i64_type "Inst34" atentry);
+    let inst35 = build_fptrunc inst32 float_type "Inst35" atentry in
+          ignore(build_fpext inst35 double_type "Inst36" atentry);
+    let inst37 = build_inttoptr p1 void_ptr "Inst37" atentry in
+    let inst38 = build_ptrtoint inst37 i64_type "Inst38" atentry in
+          ignore(build_bitcast inst38 double_type "Inst39" atentry)
+  end;
+  
+  group "comparisons"; begin
+    (* RUN: grep {Inst40.*icmp.*ne.*P1.*P2} < %t.ll
+     * RUN: grep {Inst41.*icmp.*sle.*P2.*P1} < %t.ll
+     * RUN: grep {Inst42.*fcmp.*false.*F1.*F2} < %t.ll
+     * RUN: grep {Inst43.*fcmp.*true.*F2.*F1} < %t.ll
+     *)
+    ignore (build_icmp Icmp_ne    p1 p2 "Inst40" atentry);
+    ignore (build_icmp Icmp_sle   p2 p1 "Inst41" atentry);
+    ignore (build_fcmp Fcmp_false f1 f2 "Inst42" atentry);
+    ignore (build_fcmp Fcmp_true  f2 f1 "Inst43" atentry)
+  end;
+  
+  group "miscellaneous"; begin
+    (* RUN: grep {Inst45.*call.*P2.*P1} < %t.ll
+     * RUN: grep {Inst47.*select.*Inst46.*P1.*P2} < %t.ll
+     * RUN: grep {Inst48.*va_arg.*null.*i32} < %t.ll
+     * RUN: grep {Inst49.*extractelement.*Vec1.*P2} < %t.ll
+     * RUN: grep {Inst50.*insertelement.*Vec1.*P1.*P2} < %t.ll
+     * RUN: grep {Inst51.*shufflevector.*Vec1.*Vec2.*Vec3} < %t.ll
+     *)
+    
+    (* TODO: %Inst44 = Phi *)
+    
+         ignore (build_call fn [| p2; p1 |] "Inst45" atentry);
+    let inst46 = build_icmp Icmp_eq p1 p2 "Inst46" atentry in
+         ignore (build_select inst46 p1 p2 "Inst47" atentry);
+         ignore (build_va_arg
+                  (make_null (make_pointer_type (make_pointer_type i8_type)))
+                  i32_type "Inst48" atentry);
+    
+    (* Set up some vector vregs. *)
+    let one = make_int_constant i32_type (-1) true in
+    let zero = make_int_constant i32_type 1 true in
+    let t1 = make_vector_constant [| one; zero; one; zero |] in
+    let t2 = make_vector_constant [| zero; one; zero; one |] in
+    let t3 = make_vector_constant [| one; one; zero; zero |] in
+    let vec1 = build_insertelement t1 p1 p2 "Vec1" atentry in
+    let vec2 = build_insertelement t2 p1 p2 "Vec2" atentry in
+    let vec3 = build_insertelement t3 p1 p2 "Vec3" atentry in
+    
+    ignore (build_extractelement vec1 p2 "Inst49" atentry);
+    ignore (build_insertelement vec1 p1 p2 "Inst50" atentry);
+    ignore (build_shufflevector vec1 vec2 vec3 "Inst51" atentry);
+  end
+
+
 (*===-- Writer ------------------------------------------------------------===*)
 
 let test_writer () =
@@ -322,5 +637,8 @@ let _ =
   suite "constants"        test_constants;
   suite "global values"    test_global_values;
   suite "global variables" test_global_variables;
+  suite "functions"        test_functions;
+  suite "basic blocks"     test_basic_blocks;
+  suite "builder"          test_builder;
   suite "writer"           test_writer;
   exit !exit_status